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

#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include <base/callback.h>
#include <base/callback_helpers.h>
#include <base/check.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/test/simple_test_clock.h>
#include <base/test/task_environment.h>
#include <brillo/asan.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <brillo/file_utils.h>
#include <cryptohome/proto_bindings/UserDataAuth.pb.h>
#include <dbus/bus.h>
#include <dbus/cryptohome/dbus-constants.h>
#include <dbus/login_manager/dbus-constants.h>
#include <dbus/message.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <dbus/mock_object_proxy.h>
#include <dbus/object_path.h>
#include <dbus/scoped_dbus_error.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <login_manager/proto_bindings/policy_descriptor.pb.h>
#include <policy/device_policy_impl.h>
#include <user_data_auth-client-test/user_data_auth/dbus-proxy-mocks.h>

#include "authpolicy/anonymizer.h"
#include "authpolicy/cryptohome_client.h"
#include "authpolicy/path_service.h"
#include "authpolicy/policy/preg_policy_writer.h"
#include "authpolicy/proto_bindings/active_directory_info.pb.h"
#include "authpolicy/samba_interface.h"
#include "authpolicy/stub_common.h"
#include "bindings/chrome_device_policy.pb.h"
#include "bindings/cloud_policy.pb.h"
#include "bindings/device_management_backend.pb.h"
#include "bindings/policy_constants.h"

using brillo::dbus_utils::DBusObject;
using brillo::dbus_utils::ExtractMethodCallResults;
using dbus::MessageWriter;
using dbus::MockBus;
using dbus::MockExportedObject;
using dbus::MockObjectProxy;
using dbus::ObjectPath;
using dbus::ObjectProxy;
using dbus::Response;
using login_manager::PolicyDescriptor;
using testing::_;
using testing::AnyNumber;
using testing::DoAll;
using testing::Invoke;
using testing::NiceMock;
using testing::Return;
using testing::SaveArg;
using testing::SetArgPointee;

namespace em = enterprise_management;

namespace authpolicy {
namespace {

// Some arbitrary D-Bus message serial number. Required for mocking D-Bus calls.
const int kDBusSerial = 123;

// Some constants for policy testing.
const bool kPolicyBool = true;
const int kPolicyInt = 321;

const bool kOtherPolicyBool = false;
const int kOtherPolicyInt = 234;

constexpr char kPolicyStr[] = "Str";
constexpr char kOtherPolicyStr[] = "OtherStr";

constexpr char kExtensionId[] = "abcdeFGHabcdefghAbcdefGhabcdEfgh";
constexpr char kOtherExtensionId[] = "ababababcdcdcdcdefefefefghghghgh";

constexpr char kExtensionPolicy1[] = "Policy1";
constexpr char kExtensionPolicy2[] = "Policy2";

constexpr char kMandatoryKey[] = "Policy";
constexpr char kRecommendedKey[] = "Recommended";

// Encryption types in krb5.conf.
constexpr char kKrb5EncTypesAll[] =
    "aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac";
constexpr char kKrb5EncTypesStrong[] =
    "aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96";

// Error message when passing different account IDs to authpolicy.
constexpr char kMultiUserNotSupported[] = "Multi-user not supported";

// Stub user hash, returned from the stub Cryptohome proxy's
// GetSanitizedUsername call. Used as part of the user daemon store path.
constexpr char kSanitizedUsername[] = "user_hash";
// Stub daemon store directory used to back up auth state.
constexpr char kDaemonStoreDir[] = "daemon-store";

// SessionStateChanged signal payload we care about.
constexpr char kSessionStarted[] = "started";
constexpr char kSessionStopped[] = "stopped";

// Stub data for auth data cache testing.
constexpr char kCacheTestUserWorkgroup[] = "cache_test_user_workgroup";
constexpr char kCacheTestUserKdcIp[] = "cache_test_user_kdc_ip";
constexpr char kCacheTestUserDcName[] = "cache_test_user_dc_name";
constexpr char kCacheTestMachineWorkgroup[] = "cache_test_machine_workgroup";
constexpr char kCacheTestMachineDcName[] = "cache_test_machine_dc_name";

// See stub_net_main for the strings. Don't bother to make those constants.
constexpr char kDefaultKdcIp[] = "111.222.33.2";
constexpr char kDefaultDcName[] = "DCNAME.EXAMPLE.COM";

// Policy values for cache testing.
const int kZeroHours = 0;
const int kNonZeroHours = 1;

struct SmbConf {
  std::string machine_name;
  std::string realm;
  std::string kerberos_encryption_types;
  std::string workgroup;
};

struct Krb5Conf {
  std::string default_tgs_enctypes;
  std::string default_tkt_enctypes;
  std::string permitted_enctypes;
  std::string allow_weak_crypto;
  std::string kdc;
};

// Checks and casts an integer |error| to the corresponding ErrorType.
[[nodiscard]] ErrorType CastError(int error) {
  EXPECT_GE(error, 0);
  EXPECT_LT(error, ERROR_COUNT);
  return static_cast<ErrorType>(error);
}

// Create a file descriptor pointing to a pipe that contains the given data.
base::ScopedFD MakeFileDescriptor(const char* data) {
  int fds[2];
  EXPECT_TRUE(base::CreateLocalNonBlockingPipe(fds));
  base::ScopedFD read_scoped_fd(fds[0]);
  base::ScopedFD write_scoped_fd(fds[1]);
  EXPECT_TRUE(base::WriteFileDescriptor(write_scoped_fd.get(), data));
  return read_scoped_fd;
}

// Shortcut to create a file descriptor from a valid password (valid in the
// sense that the stub executables won't trigger any error behavior).
base::ScopedFD MakePasswordFd() {
  return MakeFileDescriptor(kPassword);
}

// Stub completion callback for RegisterAsync().
void DoNothing(bool /* unused */) {}

// Creates a D-Bus response with the given |response_str| as message.
std::unique_ptr<dbus::Response> RespondWithString(
    dbus::MethodCall* method_call, const std::string& response_str) {
  method_call->SetSerial(kDBusSerial);
  std::unique_ptr<dbus::Response> response =
      dbus::Response::FromMethodCall(method_call);
  dbus::MessageWriter writer(response.get());
  writer.AppendString(response_str);
  return response;
}

// If |error| is ERROR_NONE, parses |proto_blob| into the |proto| if given.
// Otherwise, makes sure |proto_blob| is empty.
template <typename T>
void MaybeParseProto(int error,
                     const std::vector<uint8_t>& proto_blob,
                     T* proto) {
  if (error != ERROR_NONE) {
    EXPECT_TRUE(proto_blob.empty());
    return;
  }
  if (proto) {
    EXPECT_TRUE(proto->ParseFromArray(proto_blob.data(),
                                      static_cast<int>(proto_blob.size())));
  }
}

// Reads the smb.conf file at |smb_conf_path| and extracts some values.
void ReadSmbConf(const std::string& smb_conf_path, SmbConf* conf) {
  std::string smb_conf;
  EXPECT_TRUE(base::ReadFileToString(base::FilePath(smb_conf_path), &smb_conf));
  FindToken(smb_conf, '=', "netbios name", &conf->machine_name);
  EXPECT_TRUE(FindToken(smb_conf, '=', "realm", &conf->realm));
  EXPECT_TRUE(FindToken(smb_conf, '=', "kerberos encryption types",
                        &conf->kerberos_encryption_types));
  EXPECT_TRUE(FindToken(smb_conf, '=', "workgroup", &conf->workgroup));
}

// Checks whether the file at smb_conf_path is an smb.conf file and has the
// expected encryption types |expected_enc_types| set.
void CheckSmbEncTypes(const std::string& smb_conf_path,
                      const char* expected_enc_types) {
  SmbConf conf;
  ReadSmbConf(smb_conf_path, &conf);
  EXPECT_EQ(expected_enc_types, conf.kerberos_encryption_types);
}

// Reads the krb5.conf file at |krb5_conf_path| and extracts some values.
void ReadKrb5Conf(const std::string& krb5_conf_path, Krb5Conf* conf) {
  std::string krb5_conf;
  EXPECT_TRUE(
      base::ReadFileToString(base::FilePath(krb5_conf_path), &krb5_conf));
  EXPECT_TRUE(FindToken(krb5_conf, '=', "default_tgs_enctypes",
                        &conf->default_tgs_enctypes));
  EXPECT_TRUE(FindToken(krb5_conf, '=', "default_tkt_enctypes",
                        &conf->default_tkt_enctypes));
  EXPECT_TRUE(FindToken(krb5_conf, '=', "permitted_enctypes",
                        &conf->permitted_enctypes));
  EXPECT_TRUE(
      FindToken(krb5_conf, '=', "allow_weak_crypto", &conf->allow_weak_crypto));

  // KDC is optional.
  if (!FindToken(krb5_conf, '=', "kdc", &conf->kdc))
    conf->kdc.clear();
}

// Checks whether the file at krb5_conf_path is a krb5.conf file and has the
// expected encryption types |expected_enc_types| set.
void CheckKrb5EncTypes(const std::string& krb5_conf_path,
                       const char* expected_enc_types) {
  Krb5Conf conf;
  ReadKrb5Conf(krb5_conf_path, &conf);
  EXPECT_EQ(expected_enc_types, conf.default_tgs_enctypes);
  EXPECT_EQ(expected_enc_types, conf.default_tkt_enctypes);
  EXPECT_EQ(expected_enc_types, conf.permitted_enctypes);
  EXPECT_EQ("false", conf.allow_weak_crypto);
}

// Returns [|ip|].
std::string EmbraceIp(const std::string& ip) {
  return "[" + ip + "]";
}

// Helper class that points some paths to convenient locations we can write to.
class TestPathService : public PathService {
 public:
  explicit TestPathService(const base::FilePath& base_path)
      : PathService(false) {
    // Stub binaries are in the OUT folder politely provided by the test script.
    base::FilePath stub_path(getenv("OUT"));
    CHECK(!stub_path.empty());

    // Need to create the run dir since it is usually created by the ebuild.
    base::FilePath run_dir = base_path.Append("run");
    CHECK(base::CreateDirectory(run_dir));

    // Override base directories.
    Insert(Path::TEMP_DIR, base_path.Append("temp").value());
    Insert(Path::STATE_DIR, base_path.Append("state").value());
    Insert(Path::RUN_DIR, run_dir.value());
    Insert(Path::DAEMON_STORE_DIR, base_path.Append(kDaemonStoreDir).value());

    // Override binaries.
    Insert(Path::KINIT, stub_path.Append("stub_kinit").value());
    Insert(Path::KLIST, stub_path.Append("stub_klist").value());
    Insert(Path::KPASSWD, stub_path.Append("stub_kpasswd").value());
    Insert(Path::NET, stub_path.Append("stub_net").value());
    Insert(Path::SMBCLIENT, stub_path.Append("stub_smbclient").value());

    // Fill in the rest of the paths and build dependend paths.
    Initialize();
  }
};

// Metrics library that eats in particular timer errors.
class TestMetricsLibrary : public MetricsLibrary {
 public:
  bool SendToUMA(const std::string&, int, int, int, int) override {
    return true;
  }
};

// Version of AuthPolicyMetrics that just counts stats.
class TestMetrics : public AuthPolicyMetrics {
 public:
  TestMetrics() {
    // Prevent some error messages from timers.
    chromeos_metrics::TimerReporter::set_metrics_lib(&test_metrics_);
  }

  ~TestMetrics() override {
    chromeos_metrics::TimerReporter::set_metrics_lib(nullptr);
  }

  void Report(MetricType metric_type, int sample) override {
    last_metrics_sample_[metric_type] = sample;
    metrics_report_count_[metric_type]++;
  }

  void ReportError(ErrorMetricType metric_type,
                   ErrorType /* error */) override {
    error_report_count_[metric_type]++;
  }

  // Returns the most recently reported sample for the given |metric_type| or
  // -1 if the metric has not been reported.
  int GetLastMetricSample(MetricType metric_type) {
    auto iter = last_metrics_sample_.find(metric_type);
    return iter != last_metrics_sample_.end() ? iter->second : -1;
  }

  // Returns how often Report() was called with given |metric_type| and erases
  // the count. Inefficient if metric_type isn't in the map, but shorter :)
  int GetNumMetricReports(MetricType metric_type) {
    const int count = metrics_report_count_[metric_type];
    metrics_report_count_.erase(metric_type);
    return count;
  }

  // Returns how often ReportDBusResult() was called with given |metric_type|
  // and erases the count. Inefficient if |metric_type| isn't in the map, but
  // shorter :)
  int GetNumErrorReports(ErrorMetricType metric_type) {
    const int count = error_report_count_[metric_type];
    error_report_count_.erase(metric_type);
    return count;
  }

 private:
  TestMetricsLibrary test_metrics_;
  std::map<MetricType, int> last_metrics_sample_;
  std::map<MetricType, int> metrics_report_count_;
  std::map<ErrorMetricType, int> error_report_count_;
};

// Helper to check the ErrorType value returned by authpolicy D-Bus calls.
// |was_called| is a marker used by the code that queues this callback to make
// sure that this callback was indeed called.
void CheckError(ErrorType expected_error,
                bool* was_called,
                std::unique_ptr<Response> response) {
  EXPECT_TRUE(response.get());
  dbus::MessageReader reader(response.get());
  int32_t int_error;
  EXPECT_TRUE(reader.PopInt32(&int_error));
  ErrorType actual_error = CastError(int_error);
  EXPECT_EQ(expected_error, actual_error);
  EXPECT_TRUE(was_called);
  EXPECT_FALSE(*was_called);
  *was_called = true;
}

// Response callback for AuthenticateUser calls in Auth(). Sets |was_called| to
// true and deserializes the |error| and |account_info_blob| parameters.
void AuthResponseCallback(bool* was_called,
                          int* error,
                          std::vector<uint8_t>* account_info_blob,
                          std::unique_ptr<Response> response) {
  EXPECT_TRUE(response.get());
  dbus::MessageReader reader(response.get());
  EXPECT_TRUE(reader.PopInt32(error));
  // Note: reader owns buf.
  const uint8_t* buf = NULL;
  size_t buf_size = 0;
  EXPECT_TRUE(reader.PopArrayOfBytes(&buf, &buf_size));
  if (*error == ERROR_NONE) {
    EXPECT_TRUE(buf);
    EXPECT_LT(0, buf_size);
    EXPECT_TRUE(account_info_blob);
    account_info_blob->assign(buf, buf + buf_size);
  } else {
    account_info_blob->clear();
  }
  EXPECT_TRUE(was_called);
  EXPECT_FALSE(*was_called);
  *was_called = true;
}

// Matcher for D-Bus method names to be used in CallMethod*().
MATCHER_P(IsMethod, method_name, "") {
  return arg->GetMember() == method_name;
}

}  // namespace

// Integration test for the authpolicyd D-Bus interface.
//
// Since the Active Directory protocols are a black box to us, a stub local
// server cannot be used. Instead, the Samba/Kerberos binaries are stubbed out.
//
// Error behavior is triggered by passing special user principals or passwords
// to the stub binaries. For instance, using |kNonExistingUserPrincipal| makes
// stub_kinit behave as if the requested account does not exist on the server.
// The same principle is used throughout this test.
//
// During policy fetch, authpolicy sends D-Bus messages to Session Manager. This
// communication is mocked out.
class AuthPolicyTest : public testing::Test {
 public:
  void SetUp() override {
    // The message loop registers a task runner with the current thread, which
    // is used by TgtManager to post automatic TGT renewal tasks.
    const ObjectPath object_path(std::string("/object/path"));
    auto dbus_object =
        std::make_unique<DBusObject>(nullptr, mock_bus_, object_path);

    metrics_ = std::make_unique<TestMetrics>();

    // Create path service with all paths pointing into a temp directory.
    CHECK(base::CreateNewTempDirectory("" /* prefix (ignored) */, &base_path_));
    paths_ = std::make_unique<TestPathService>(base_path_);

    // Create the state directory since authpolicyd assumes its existence.
    const base::FilePath state_path =
        base::FilePath(paths_->Get(Path::STATE_DIR));
    CHECK(base::CreateDirectory(state_path));

    // Create daemon store directory where authpolicyd backs up auth state.
    user_daemon_store_path_ =
        base_path_.Append(kDaemonStoreDir).Append(kSanitizedUsername);
    CHECK(base::CreateDirectory(user_daemon_store_path_));

    // Stub path where the Kerberos ticket is backed up.
    backup_path_ = user_daemon_store_path_.Append("user_backup_data");

    // Set stub preg path. Since it is not trivial to pass the full path to the
    // stub binaries, we simply use the directory from the krb5.conf file.
    const base::FilePath gpo_dir =
        base::FilePath(paths_->Get(Path::USER_KRB5_CONF)).DirName();
    DCHECK(gpo_dir ==
           base::FilePath(paths_->Get(Path::DEVICE_KRB5_CONF)).DirName());
    stub_gpo1_path_ = gpo_dir.Append(kGpo1Filename);
    stub_gpo2_path_ = gpo_dir.Append(kGpo2Filename);

    // Mock out D-Bus initialization.
    mock_exported_object_ =
        new MockExportedObject(mock_bus_.get(), object_path);
    EXPECT_CALL(*mock_bus_, GetExportedObject(object_path))
        .Times(1)
        .WillOnce(Return(mock_exported_object_.get()));
    EXPECT_CALL(*mock_bus_, GetDBusTaskRunner())
        .Times(1)
        .WillOnce(Return(task_environment_.GetMainThreadTaskRunner().get()));
    EXPECT_CALL(*mock_exported_object_, ExportMethod(_, _, _, _))
        .Times(AnyNumber());
    EXPECT_CALL(*mock_exported_object_, SendSignal(_))
        .WillRepeatedly(
            Invoke(this, &AuthPolicyTest::HandleUserKerberosFilesChanged));

    // Set up mock object proxy for session manager called from authpolicy.
    mock_session_manager_proxy_ = new MockObjectProxy(
        mock_bus_.get(), login_manager::kSessionManagerServiceName,
        dbus::ObjectPath(login_manager::kSessionManagerServicePath));
    EXPECT_CALL(*mock_bus_,
                GetObjectProxy(login_manager::kSessionManagerServiceName, _))
        .WillOnce(Return(mock_session_manager_proxy_.get()));
    EXPECT_CALL(
        *mock_session_manager_proxy_,
        DoCallMethodWithErrorCallback(
            IsMethod(login_manager::kSessionManagerStoreUnsignedPolicyEx), _, _,
            _))
        .WillRepeatedly(
            Invoke(this, &AuthPolicyTest::StubCallStorePolicyMethod));
    EXPECT_CALL(
        *mock_session_manager_proxy_,
        CallMethodAndBlockWithErrorDetails(
            IsMethod(login_manager::kSessionManagerListStoredComponentPolicies),
            _, _))
        .WillRepeatedly(
            Invoke(this, &AuthPolicyTest::StubListComponentIdsMethod));
    EXPECT_CALL(
        *mock_session_manager_proxy_,
        DoConnectToSignal(login_manager::kSessionManagerInterface,
                          login_manager::kSessionStateChangedSignal, _, _))
        .WillOnce((SaveArg<2>(&session_state_changed_callback_)));
    EXPECT_CALL(
        *mock_session_manager_proxy_.get(),
        CallMethodAndBlockWithErrorDetails(
            IsMethod(login_manager::kSessionManagerRetrieveSessionState), _, _))
        .WillOnce(Invoke([](dbus::MethodCall* method_call, int timeout,
                            dbus::ScopedDBusError* error) {
          return RespondWithString(method_call, kSessionStopped);
        }));

    // Setup expectation for cryptohome UserDataAuth dbus proxies so it doesn't
    // fail.
    scoped_refptr<MockObjectProxy> mock_user_data_auth_proxy =
        new MockObjectProxy(
            mock_bus_.get(), user_data_auth::kUserDataAuthServiceName,
            dbus::ObjectPath(user_data_auth::kUserDataAuthServicePath));
    EXPECT_CALL(*mock_bus_,
                GetObjectProxy(user_data_auth::kUserDataAuthServiceName, _))
        .WillOnce(Return(mock_user_data_auth_proxy.get()));

    // Create AuthPolicy instance. Do this AFTER creating the proxy mocks since
    // they might be accessed during initialization.
    authpolicy_ = std::make_unique<AuthPolicy>(metrics_.get(), paths_.get());
    EXPECT_EQ(ERROR_NONE, authpolicy_->Initialize(false /* expect_config */));
    authpolicy_->RegisterAsync(std::move(dbus_object), base::Bind(&DoNothing));

    // Setup the cryptohome dbus mock.
    std::unique_ptr<org::chromium::CryptohomeMiscInterfaceProxyMock>
        cryptohome_misc_proxy =
            std::make_unique<org::chromium::CryptohomeMiscInterfaceProxyMock>();
    cryptohome_misc_proxy_ = cryptohome_misc_proxy.get();
    samba()
        .get_cryptohome_client_for_testing()
        ->set_cryptohome_misc_proxy_for_testing(
            std::move(cryptohome_misc_proxy));

    sanitized_username_reply_.set_sanitized_username(kSanitizedUsername);
    ON_CALL(*cryptohome_misc_proxy_, GetSanitizedUsername(_, _, _, _))
        .WillByDefault(
            DoAll(SetArgPointee<1>(sanitized_username_reply_), Return(true)));

    // Don't sleep for kinit/smbclient retries, it just prolongs our tests.
    samba().DisableRetrySleepForTesting();

    // Unit tests usually run code that only exists in tests (like the
    // framework), so disable the seccomp filters.
    samba().DisableSeccompForTesting(true);
  }

  // Stub method called by the Session Manager mock to store policy. Validates
  // the type of policy (user/device) contained in the |method_call|. If set by
  // the individual unit tests, calls |validate_user_policy_| or
  // |validate_device_policy_|  to validate the contents of the policy proto.
  void StubCallStorePolicyMethod(
      dbus::MethodCall* method_call,
      int /* timeout_ms */,
      ObjectProxy::ResponseCallback* callback,
      dbus::ObjectProxy::ErrorCallback* error_callback) {
    // Safety check to make sure that old values are not carried along.
    if (!store_policy_called_) {
      EXPECT_FALSE(user_policy_validated_);
      EXPECT_FALSE(device_policy_validated_);
      EXPECT_EQ(0, validated_extension_ids_.size());
    } else {
      // The first policy stored is always user or device policy.
      EXPECT_TRUE(user_policy_validated_ ^ device_policy_validated_);
    }
    store_policy_called_ = true;

    // Based on the method name, check whether this is user or device policy.
    EXPECT_TRUE(method_call);
    EXPECT_TRUE(method_call->GetMember() ==
                login_manager::kSessionManagerStoreUnsignedPolicyEx);

    // Extract the policy blob from the method call.
    std::vector<uint8_t> descriptor_blob;
    std::vector<uint8_t> response_blob;
    brillo::ErrorPtr error;
    EXPECT_TRUE(ExtractMethodCallResults(method_call, &error, &descriptor_blob,
                                         &response_blob));

    // Unpack descriptor.
    PolicyDescriptor descriptor;
    const std::string descriptor_blob_str(descriptor_blob.begin(),
                                          descriptor_blob.end());
    EXPECT_TRUE(descriptor.ParseFromString(descriptor_blob_str));

    // If policy is deleted, response_blob is an empty string.
    if (response_blob.empty()) {
      EXPECT_EQ(descriptor.domain(), login_manager::POLICY_DOMAIN_EXTENSIONS);
      deleted_extension_ids_.insert(descriptor.component_id());
    } else {
      // Unwrap the three gazillion layers or policy.
      const std::string response_blob_str(response_blob.begin(),
                                          response_blob.end());
      em::PolicyFetchResponse policy_response;
      EXPECT_TRUE(policy_response.ParseFromString(response_blob_str));
      em::PolicyData policy_data;
      EXPECT_TRUE(policy_data.ParseFromString(policy_response.policy_data()));

      // Run the policy through the appropriate policy validator.
      ValidatePolicy(descriptor, policy_data);
    }

    // Answer authpolicy with an empty response to signal that policy has been
    // stored.
    EXPECT_FALSE((*callback).is_null());
    std::move(*callback).Run(Response::CreateEmpty().get());
  }

  // Stub method called by the Session Manager mock to list stored component
  // policy ids.
  std::unique_ptr<dbus::Response> StubListComponentIdsMethod(
      dbus::MethodCall* method_call,
      int /* timeout_ms */,
      dbus::ScopedDBusError* error) {
    method_call->SetSerial(kDBusSerial);
    auto response = dbus::Response::FromMethodCall(method_call);
    dbus::MessageWriter writer(response.get());
    writer.AppendArrayOfStrings(stored_extension_ids_);

    // Note: The mock wraps this back into a std::unique_ptr.
    return response;
  }

  void TearDown() override {
    EXPECT_EQ(expected_error_reports[ERROR_OF_AUTHENTICATE_USER],
              metrics_->GetNumErrorReports(ERROR_OF_AUTHENTICATE_USER));
    EXPECT_EQ(expected_error_reports[ERROR_OF_GET_USER_STATUS],
              metrics_->GetNumErrorReports(ERROR_OF_GET_USER_STATUS));
    EXPECT_EQ(expected_error_reports[ERROR_OF_GET_USER_KERBEROS_FILES],
              metrics_->GetNumErrorReports(ERROR_OF_GET_USER_KERBEROS_FILES));
    EXPECT_EQ(expected_error_reports[ERROR_OF_JOIN_AD_DOMAIN],
              metrics_->GetNumErrorReports(ERROR_OF_JOIN_AD_DOMAIN));
    EXPECT_EQ(expected_error_reports[ERROR_OF_REFRESH_USER_POLICY],
              metrics_->GetNumErrorReports(ERROR_OF_REFRESH_USER_POLICY));
    EXPECT_EQ(expected_error_reports[ERROR_OF_REFRESH_DEVICE_POLICY],
              metrics_->GetNumErrorReports(ERROR_OF_REFRESH_DEVICE_POLICY));

    EXPECT_CALL(*mock_exported_object_, Unregister()).Times(1);
    // Don't not leave no mess behind.
    base::DeletePathRecursively(base_path_);
  }

 protected:
  // Joins a (stub) Active Directory domain. Returns the error code.
  [[nodiscard]] ErrorType Join(const std::string& machine_name,
                               const std::string& user_principal,
                               base::ScopedFD password_fd) {
    JoinDomainRequest request;
    request.set_machine_name(machine_name);
    request.set_user_principal_name(user_principal);
    return JoinEx(request, std::move(password_fd));
  }

  // Joins a (stub) Active Directory domain, locks the device and fetches empty
  // device policy. Expects success.
  void JoinAndFetchDevicePolicy(const std::string& machine_name) {
    EXPECT_EQ(ERROR_NONE, Join(machine_name, kUserPrincipal, MakePasswordFd()));
    MarkDeviceAsLocked();
    validate_device_policy_ = &CheckDevicePolicyEmpty;
    FetchAndValidateDevicePolicy(ERROR_NONE);
  }

  // Extended Join() that takes a full JoinDomainRequest proto.
  [[nodiscard]] ErrorType JoinEx(const JoinDomainRequest& request,
                                 base::ScopedFD password_fd,
                                 std::string* joined_domain = nullptr) {
    expected_error_reports[ERROR_OF_JOIN_AD_DOMAIN]++;
    std::vector<uint8_t> blob(request.ByteSizeLong());
    request.SerializeToArray(blob.data(), blob.size());
    int error;
    authpolicy_->JoinADDomain(blob, password_fd, &error, joined_domain);
    return CastError(error);
  }

  // Authenticates to a (stub) Active Directory domain with the given
  // credentials and returns the error code. Assigns the user account info to
  // |account_info| if a non-nullptr is provided.
  [[nodiscard]] ErrorType Auth(
      const std::string& user_principal,
      const std::string& account_id,
      base::ScopedFD password_fd,
      ActiveDirectoryAccountInfo* account_info = nullptr) {
    int32_t error = ERROR_NONE;
    std::vector<uint8_t> account_info_blob;
    expected_error_reports[ERROR_OF_AUTHENTICATE_USER]++;
    int prev_files_changed_count = user_kerberos_files_changed_count_;
    AuthenticateUserRequest request;
    request.set_user_principal_name(user_principal);
    request.set_account_id(account_id);
    std::vector<uint8_t> request_blob(request.ByteSizeLong());
    request.SerializeToArray(request_blob.data(), request_blob.size());

    bool callback_was_called = false;
    dbus::MethodCall method_call(kAuthPolicyInterface, kAuthenticateUserMethod);
    method_call.SetSerial(kDBusSerial);
    auto callback = std::make_unique<
        brillo::dbus_utils::DBusMethodResponse<int32_t, std::vector<uint8_t>>>(
        &method_call,
        base::BindOnce(&AuthResponseCallback, &callback_was_called, &error,
                       &account_info_blob));
    authpolicy_->AuthenticateUser(std::move(callback), request_blob,
                                  password_fd);
    EXPECT_TRUE(callback_was_called);

    MaybeParseProto(error, account_info_blob, account_info);
    // At most one UserKerberosFilesChanged signal should have been fired.
    EXPECT_LE(user_kerberos_files_changed_count_, prev_files_changed_count + 1);
    return CastError(error);
  }

  // Gets a fake user status from a (stub) Active Directory service.
  // |account_id| is the id (aka objectGUID) of the user. Assigns the user's
  // status to |user_status| if a non-nullptr is given.
  [[nodiscard]] ErrorType GetUserStatus(
      const std::string& user_principal,
      const std::string& account_id,
      ActiveDirectoryUserStatus* user_status = nullptr) {
    int32_t error = ERROR_NONE;
    std::vector<uint8_t> user_status_blob;
    expected_error_reports[ERROR_OF_GET_USER_STATUS]++;
    GetUserStatusRequest request;
    request.set_user_principal_name(user_principal);
    request.set_account_id(account_id);
    std::vector<uint8_t> blob(request.ByteSizeLong());
    request.SerializeToArray(blob.data(), blob.size());
    authpolicy_->GetUserStatus(blob, &error, &user_status_blob);
    MaybeParseProto(error, user_status_blob, user_status);
    return CastError(error);
  }

  [[nodiscard]] ErrorType GetUserKerberosFiles(
      const std::string& account_id, KerberosFiles* kerberos_files = nullptr) {
    int32_t error = ERROR_NONE;
    std::vector<uint8_t> kerberos_files_blob;
    expected_error_reports[ERROR_OF_GET_USER_KERBEROS_FILES]++;
    authpolicy_->GetUserKerberosFiles(account_id, &error, &kerberos_files_blob);
    MaybeParseProto(error, kerberos_files_blob, kerberos_files);
    return CastError(error);
  }

  // Authenticates to a (stub) Active Directory domain with default credentials.
  // Returns the account id.
  std::string DefaultAuth() {
    ActiveDirectoryAccountInfo account_info;
    EXPECT_EQ(ERROR_NONE,
              Auth(kUserPrincipal, "", MakePasswordFd(), &account_info));
    return account_info.account_id();
  }

  // Calls AuthPolicy::RefreshUserPolicy(). Verifies that
  // StubCallStorePolicyMethod() and validate_user_policy_ are called as
  // expected. These callbacks verify that the policy protobuf is valid and
  // validate the contents.
  void FetchAndValidateUserPolicy(const std::string& account_id,
                                  ErrorType expected_error) {
    dbus::MethodCall method_call(kAuthPolicyInterface,
                                 kRefreshUserPolicyMethod);
    method_call.SetSerial(kDBusSerial);
    store_policy_called_ = false;
    user_policy_validated_ = false;
    device_policy_validated_ = false;
    validated_extension_ids_.clear();
    deleted_extension_ids_.clear();
    bool callback_was_called = false;
    AuthPolicy::PolicyResponseCallback callback =
        std::make_unique<brillo::dbus_utils::DBusMethodResponse<int32_t>>(
            &method_call,
            base::BindOnce(&CheckError, expected_error, &callback_was_called));
    expected_error_reports[ERROR_OF_REFRESH_USER_POLICY]++;
    authpolicy_->RefreshUserPolicy(std::move(callback), account_id);

    // If policy fetch succeeds, authpolicy_ makes a D-Bus call to Session
    // Manager to store policy. We intercept this call and point it to
    // StubCallStorePolicyMethod(), which validates policy and calls CheckError.
    // If policy fetch fails, StubCallStorePolicyMethod() is not called, but
    // authpolicy calls CheckError directly.
    EXPECT_EQ(expected_error == ERROR_NONE, store_policy_called_);
    EXPECT_EQ(expected_error == ERROR_NONE, user_policy_validated_);
    EXPECT_FALSE(expected_error != ERROR_NONE &&
                 validated_extension_ids_.size() > 0);
    EXPECT_FALSE(device_policy_validated_);
    EXPECT_TRUE(callback_was_called);  // Make sure CheckError() was called.
  }

  // Calls AuthPolicy::RefreshDevicePolicy(). Verifies that
  // StubCallStorePolicyMethod() and validate_device_policy_ are called as
  // expected. These callbacks verify that the policy protobuf is valid and
  // validate the contents.
  void FetchAndValidateDevicePolicy(ErrorType expected_error) {
    dbus::MethodCall method_call(kAuthPolicyInterface,
                                 kRefreshDevicePolicyMethod);
    method_call.SetSerial(kDBusSerial);
    store_policy_called_ = false;
    user_policy_validated_ = false;
    device_policy_validated_ = false;
    validated_extension_ids_.clear();
    deleted_extension_ids_.clear();
    bool callback_was_called = false;
    AuthPolicy::PolicyResponseCallback callback =
        std::make_unique<brillo::dbus_utils::DBusMethodResponse<int32_t>>(
            &method_call,
            base::BindOnce(&CheckError, expected_error, &callback_was_called));
    expected_error_reports[ERROR_OF_REFRESH_DEVICE_POLICY]++;
    authpolicy_->RefreshDevicePolicy(std::move(callback));

    // If policy fetch succeeds, authpolicy_ makes a D-Bus call to Session
    // Manager to store policy. We intercept this call and point it to
    // StubCallStorePolicyMethod(), which validates policy and calls CheckError.
    // If policy fetch fails, StubCallStorePolicyMethod() is not called, but
    // authpolicy calls CheckError directly.
    EXPECT_EQ(expected_error == ERROR_NONE, store_policy_called_);
    EXPECT_EQ(expected_error == ERROR_NONE, device_policy_validated_);
    EXPECT_FALSE(expected_error != ERROR_NONE &&
                 validated_extension_ids_.size());
    EXPECT_FALSE(user_policy_validated_);
    EXPECT_TRUE(callback_was_called);  // Make sure CheckError() was called.
  }

  // Runs the policy stored in |policy_data| through the validator function
  // for the corresponding policy type.
  void ValidatePolicy(const PolicyDescriptor& descriptor,
                      const em::PolicyData& policy_data) {
    if (policy_data.policy_type() == kChromeUserPolicyType) {
      EXPECT_EQ(descriptor.account_type(), login_manager::ACCOUNT_TYPE_USER);
      EXPECT_FALSE(descriptor.account_id().empty());
      EXPECT_EQ(descriptor.domain(), login_manager::POLICY_DOMAIN_CHROME);
      EXPECT_TRUE(descriptor.component_id().empty());
      em::CloudPolicySettings policy;
      EXPECT_TRUE(policy.ParseFromString(policy_data.policy_value()));
      if (validate_user_policy_) {
        validate_user_policy_(policy);
        user_policy_validated_ = true;
      }
      user_affiliation_marker_set_ =
          policy_data.user_affiliation_ids_size() == 1 &&
          policy_data.user_affiliation_ids(0) == kAffiliationMarker;
    } else if (policy_data.policy_type() == kChromeDevicePolicyType) {
      EXPECT_EQ(descriptor.account_type(), login_manager::ACCOUNT_TYPE_DEVICE);
      EXPECT_TRUE(descriptor.account_id().empty());
      EXPECT_EQ(descriptor.domain(), login_manager::POLICY_DOMAIN_CHROME);
      EXPECT_TRUE(descriptor.component_id().empty());
      em::ChromeDeviceSettingsProto policy;
      EXPECT_TRUE(policy.ParseFromString(policy_data.policy_value()));
      if (validate_device_policy_) {
        validate_device_policy_(policy);
        device_policy_validated_ = true;
      }
      EXPECT_EQ(1, policy_data.device_affiliation_ids_size());
      EXPECT_EQ(kAffiliationMarker, policy_data.device_affiliation_ids(0));
    } else if (policy_data.policy_type() == kChromeExtensionPolicyType) {
      EXPECT_EQ(descriptor.domain(), login_manager::POLICY_DOMAIN_EXTENSIONS);
      EXPECT_EQ(descriptor.component_id(), policy_data.settings_entity_id());
      if (validate_extension_policy_) {
        // policy_value() is the raw JSON string here.
        validate_extension_policy_(descriptor.component_id(),
                                   policy_data.policy_value());
        validated_extension_ids_.insert(descriptor.component_id());
      }
    }
  }

  // Checks whether the user |policy| is empty.
  static void CheckUserPolicyEmpty(const em::CloudPolicySettings& policy) {
    em::CloudPolicySettings empty_policy;
    EXPECT_EQ(policy.ByteSizeLong(), empty_policy.ByteSizeLong());
  }

  // Does not validate user policy. Use if you're testing something unrelated.
  static void DontValidateUserPolicy(
      const em::CloudPolicySettings& /* policy */) {}

  // Checks whether the device |policy| is empty.
  static void CheckDevicePolicyEmpty(
      const em::ChromeDeviceSettingsProto& policy) {
    em::ChromeDeviceSettingsProto empty_policy;
    EXPECT_EQ(policy.ByteSizeLong(), empty_policy.ByteSizeLong());
  }

  // Does not validate device policy. Use if you're testing something unrelated.
  static void DontValidateDevicePolicy(
      const em::ChromeDeviceSettingsProto& /* policy */) {}

  // Checks whether the extension |policy_json| is empty.
  static void CheckExtensionPolicyEmpty(const std::string& /* extension_id */,
                                        const std::string& policy_json) {
    EXPECT_TRUE(policy_json.empty());
  }

  // Writes some default extension to the given writer.
  static void WriteDefaultExtensionPolicy(policy::PRegPolicyWriter* writer) {
    writer->SetKeysForExtensionPolicy(kExtensionId);
    writer->AppendString(kExtensionPolicy1, kPolicyStr);
    writer->SetKeysForExtensionPolicy(kOtherExtensionId);
    writer->AppendBoolean(kExtensionPolicy2, kPolicyBool,
                          policy::POLICY_LEVEL_RECOMMENDED);
  }

  // Checks some default extension |policy_json| we're using for this test.
  static void CheckDefaultExtensionPolicy(const std::string& extension_id,
                                          const std::string& policy_json) {
    std::string expected_policy_json;
    if (extension_id == kExtensionId) {
      expected_policy_json =
          base::StringPrintf("{\"%s\":{\"%s\":\"%s\"}}", kMandatoryKey,
                             kExtensionPolicy1, kPolicyStr);
    } else if (extension_id == kOtherExtensionId) {
      expected_policy_json = base::StringPrintf(
          "{\"%s\":{\"%s\":1}}", kRecommendedKey, kExtensionPolicy2);
    } else {
      FAIL() << "Unexpected extension id " << extension_id;
    }
    EXPECT_EQ(policy_json, expected_policy_json);
  }

  // Authpolicyd revokes write permissions on config.dat. Some tests perform two
  // domain joins, though, and need to overwrite the previously generated config
  // file.
  bool MakeConfigWriteable() {
    const base::FilePath config_path(paths_->Get(Path::CONFIG_DAT));
    const int mode = base::FILE_PERMISSION_READ_BY_USER |
                     base::FILE_PERMISSION_WRITE_BY_USER;
    return base::SetPosixFilePermissions(config_path, mode);
  }

  SambaInterface& samba() { return authpolicy_->GetSambaInterfaceForTesting(); }
  void MarkDeviceAsLocked() { authpolicy_->SetDeviceIsLockedForTesting(); }

  // Writes one file to |gpo_path| with a few policies. Sets up
  // |validate_device_policy_| callback with corresponding expectations.
  void SetupDeviceOneGpo(const base::FilePath& gpo_path) {
    policy::PRegUserDevicePolicyWriter writer;
    writer.AppendBoolean(policy::key::kDeviceGuestModeEnabled, kPolicyBool);
    writer.AppendInteger(policy::key::kDevicePolicyRefreshRate, kPolicyInt);
    writer.AppendString(policy::key::kSystemTimezone, kPolicyStr);
    const std::vector<std::string> str_list = {"str1", "str2"};
    writer.AppendStringList(policy::key::kDeviceUserAllowlist, str_list);
    writer.WriteToFile(gpo_path);

    validate_device_policy_ = [str_list](
                                  const em::ChromeDeviceSettingsProto& policy) {
      EXPECT_EQ(kPolicyBool, policy.guest_mode_enabled().guest_mode_enabled());
      EXPECT_EQ(
          kPolicyInt,
          policy.device_policy_refresh_rate().device_policy_refresh_rate());
      EXPECT_EQ(kPolicyStr, policy.system_timezone().timezone());
      const em::UserAllowlistProto& str_list_proto = policy.user_allowlist();
      EXPECT_EQ(str_list_proto.user_allowlist_size(),
                static_cast<int>(str_list.size()));
      for (int n = 0; n < str_list_proto.user_allowlist_size(); ++n)
        EXPECT_EQ(str_list_proto.user_allowlist(n), str_list.at(n));
    };
  }

  // Writes a device policy file to |policy_path|. The file can be read with
  // libpolicy.
  void WriteDevicePolicyFile(const base::FilePath& policy_path,
                             const em::ChromeDeviceSettingsProto& policy) {
    em::PolicyData policy_data;
    policy_data.set_policy_value(policy.SerializeAsString());
    em::PolicyFetchResponse policy_fetch_response;
    policy_fetch_response.set_policy_data(policy_data.SerializeAsString());
    std::string policy_blob = policy_fetch_response.SerializeAsString();
    brillo::WriteStringToFile(policy_path, policy_blob);
  }

  // Writes |device_policy| to a file, points samba() to it and reinitializes
  // samba(). This simulates a restart of authpolicyd with given device policy.
  void WritePolicyAndRestartAuthpolicy(
      const em::ChromeDeviceSettingsProto& device_policy) {
    const base::FilePath policy_path = base_path_.Append("policy");
    WriteDevicePolicyFile(policy_path, device_policy);

    // Set up a device policy instance that reads from our fake file.
    // Verification has to be disabled since MarkDeviceAsLocked() applies to
    // authpolicy only, but doesn't actually set the real install attributes
    // read by the impl.
    auto policy_impl = std::make_unique<policy::DevicePolicyImpl>();
    policy_impl->set_policy_path_for_testing(policy_path);
    policy_impl->set_verify_policy_for_testing(false);

    // Initialize again. This should load the device policy file.
    samba().ResetForTesting();
    samba().SetDevicePolicyImplForTesting(std::move(policy_impl));
    EXPECT_EQ(ERROR_NONE, samba().Initialize(true /* expect_config */));
  }

  // Returns the modification time of the file at |path|.
  base::Time GetLastModified(const base::FilePath& path) {
    base::File::Info file_info;
    EXPECT_TRUE(GetFileInfo(path, &file_info));
    return file_info.last_modified;
  }

  // Returns the modification time of the file at |path|.
  base::Time GetLastModified(Path path) {
    return GetLastModified(base::FilePath(paths_->Get(path)));
  }

  void SetLastModified(Path path, const base::Time& last_modified) {
    const base::FilePath filepath(paths_->Get(path));
    base::File::Info file_info;
    EXPECT_TRUE(GetFileInfo(filepath, &file_info));
    EXPECT_TRUE(
        base::TouchFile(filepath, file_info.last_accessed, last_modified));
  }

  // Returns the contents of the file at |path|.
  std::string ReadFile(Path path) {
    std::string str;
    EXPECT_TRUE(
        base::ReadFileToString(base::FilePath(paths_->Get(path)), &str));
    return str;
  }

  // Sends the session started signal to authpolicyd.
  void NotifySessionStarted() {
    // Tell authpolicyd that the session started.
    dbus::Signal signal(login_manager::kSessionManagerInterface,
                        login_manager::kSessionStateChangedSignal);
    dbus::MessageWriter writer(&signal);
    writer.AppendString("started");
    session_state_changed_callback_.Run(&signal);
  }

  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};

  scoped_refptr<MockBus> mock_bus_ = new MockBus(dbus::Bus::Options());
  scoped_refptr<MockExportedObject> mock_exported_object_;
  scoped_refptr<MockObjectProxy> mock_session_manager_proxy_;
  org::chromium::CryptohomeMiscInterfaceProxyMock* cryptohome_misc_proxy_;
  user_data_auth::GetSanitizedUsernameReply sanitized_username_reply_;

  // Notifies authpolicy that the session state changed (e.g. "started").
  base::RepeatingCallback<void(dbus::Signal* signal)>
      session_state_changed_callback_;

  // Keep this order! |authpolicy_| must be last as it depends on the other two.
  std::unique_ptr<TestMetrics> metrics_;
  std::unique_ptr<TestPathService> paths_;
  std::unique_ptr<AuthPolicy> authpolicy_;

  base::FilePath base_path_;
  base::FilePath stub_gpo1_path_;
  base::FilePath stub_gpo2_path_;
  base::FilePath user_daemon_store_path_;
  base::FilePath backup_path_;

  // Markers to check whether various callbacks are actually called.
  bool store_policy_called_ = false;      // StubCallStorePolicyMethod()
  bool user_policy_validated_ = false;    // Policy validation
  bool device_policy_validated_ = false;  //   callbacks below.

  // IDs of extensions for which policy was validated.
  std::multiset<std::string> validated_extension_ids_;
  // IDs of extensions for which policy was deleted.
  std::multiset<std::string> deleted_extension_ids_;
  // IDs returned from the stub Session Manager for ListStoredComponentPolicies.
  std::vector<std::string> stored_extension_ids_;

  // Set by ValidatePolicy during user policy validation if the affiliation
  // marker is set.
  bool user_affiliation_marker_set_ = false;

  // How often the UserKerberosFilesChanged signal was fired.
  int user_kerberos_files_changed_count_ = 0;

  // Must be set in unit tests to validate policy protos which authpolicy_ sends
  // to Session Manager via D-Bus (resp. to StubCallStorePolicyMethod() in these
  // tests).
  std::function<void(const em::CloudPolicySettings&)> validate_user_policy_;
  std::function<void(const em::ChromeDeviceSettingsProto&)>
      validate_device_policy_;
  std::function<void(const std::string&, const std::string&)>
      validate_extension_policy_;

 private:
  void HandleUserKerberosFilesChanged(dbus::Signal* signal) {
    EXPECT_EQ(signal->GetInterface(), "org.chromium.AuthPolicy");
    EXPECT_EQ(signal->GetMember(), "UserKerberosFilesChanged");
    user_kerberos_files_changed_count_++;
  }

  // Expected calls of metrics reporting functions, set and checked internally.
  std::map<ErrorMetricType, int> expected_error_reports;
};

// Can't fetch user policy if the user is not logged in.
TEST_F(AuthPolicyTest, UserPolicyFailsNotLoggedIn) {
  FetchAndValidateUserPolicy("account_id", ERROR_NOT_LOGGED_IN);
}

// Can't fetch device policy if the device is not joined.
TEST_F(AuthPolicyTest, DevicePolicyFailsNotJoined) {
  FetchAndValidateDevicePolicy(ERROR_NOT_JOINED);
}

// Authentication fails if the machine is not joined.
TEST_F(AuthPolicyTest, AuthFailsNotJoined) {
  EXPECT_EQ(ERROR_NOT_JOINED, Auth(kUserPrincipal, "", MakePasswordFd()));
}

// Successful domain join. The machine should join the user's domain since
// Join() doesn't specify machine domain.
TEST_F(AuthPolicyTest, JoinSucceeds) {
  JoinDomainRequest request;
  request.set_machine_name(kMachineName);
  request.set_user_principal_name(kUserPrincipal);
  std::string joined_realm;
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd(), &joined_realm));
  SmbConf conf;
  ReadSmbConf(paths_->Get(Path::DEVICE_SMB_CONF), &conf);
  EXPECT_EQ(base::ToUpperASCII(kMachineName), conf.machine_name);
  EXPECT_EQ(kUserRealm, conf.realm);
  EXPECT_EQ(kUserRealm, joined_realm);
  EXPECT_EQ(kEncTypesStrong, conf.kerberos_encryption_types);
}

// Successful domain join with separate machine domain specified.
TEST_F(AuthPolicyTest, JoinSucceedsWithDifferentDomain) {
  JoinDomainRequest request;
  request.set_machine_name(kMachineName);
  request.set_machine_domain(kMachineRealm);
  request.set_user_principal_name(kUserPrincipal);
  std::string joined_realm;
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd(), &joined_realm));
  SmbConf conf;
  ReadSmbConf(paths_->Get(Path::DEVICE_SMB_CONF), &conf);
  EXPECT_EQ(base::ToUpperASCII(kMachineName), conf.machine_name);
  EXPECT_EQ(kMachineRealm, conf.realm);
  EXPECT_EQ(kMachineRealm, joined_realm);
}

// Successful domain join with organizational unit (OU).
TEST_F(AuthPolicyTest, JoinSucceedsWithOrganizationalUnit) {
  JoinDomainRequest request;
  request.set_machine_name(kMachineName);
  request.set_user_principal_name(kExpectOuUserPrincipal);
  for (size_t n = 0; n < kExpectedOuPartsSize; ++n)
    *request.add_machine_ou() = kExpectedOuParts[n];
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));
  // Note: We can't test directly whether the computer was put into the right OU
  // because there's no state for that in authpolicy. The only indicator is the
  // 'createcomputer' parameter to net ads join, but that can only be tested in
  // stub_net, see kExpectOuUserPrincipal.
}

// Encryption types are written properly to smb.conf.
TEST_F(AuthPolicyTest, JoinSetsProperEncTypes) {
  std::pair<KerberosEncryptionTypes, const char*> enc_types_list[] = {
      {ENC_TYPES_ALL, kEncTypesAll},
      {ENC_TYPES_STRONG, kEncTypesStrong},
      {ENC_TYPES_LEGACY, kEncTypesLegacy}};

  for (const auto& enc_types : enc_types_list) {
    JoinDomainRequest request;
    request.set_machine_name(kMachineName);
    request.set_user_principal_name(kUserPrincipal);
    request.set_kerberos_encryption_types(enc_types.first);
    EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));
    CheckSmbEncTypes(paths_->Get(Path::DEVICE_SMB_CONF), enc_types.second);
    EXPECT_TRUE(MakeConfigWriteable());
    samba().ResetForTesting();
  }
}

// The encryption types reset to strong after device policy fetch.
TEST_F(AuthPolicyTest, EncTypesResetAfterDevicePolicyFetch) {
  // Disable machine password change, because the password check runs
  // immediately and wipes smb.conf (to get server time) with ENC_TYPES_STRONG,
  // so the check below for kEncTypesAll fails.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendInteger(policy::key::kDeviceMachinePasswordChangeRate, 0);
  writer.WriteToFile(stub_gpo1_path_);

  JoinDomainRequest request;
  request.set_machine_name(kOneGpoMachineName);
  request.set_user_principal_name(kUserPrincipal);
  request.set_kerberos_encryption_types(ENC_TYPES_ALL);
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));
  MarkDeviceAsLocked();

  // After the first device policy fetch, the enc types should be 'strong'
  // internally, but the conf files used should still contain 'all' types.
  validate_device_policy_ = &DontValidateDevicePolicy;
  FetchAndValidateDevicePolicy(ERROR_NONE);
  CheckSmbEncTypes(paths_->Get(Path::DEVICE_SMB_CONF), kEncTypesAll);
  CheckKrb5EncTypes(paths_->Get(Path::DEVICE_KRB5_CONF), kKrb5EncTypesAll);

  // After the second device policy fetch, the conf files should contain
  // 'strong' enc types.
  FetchAndValidateDevicePolicy(ERROR_NONE);
  CheckSmbEncTypes(paths_->Get(Path::DEVICE_SMB_CONF), kEncTypesStrong);
  CheckKrb5EncTypes(paths_->Get(Path::DEVICE_KRB5_CONF), kKrb5EncTypesStrong);

  // Likewise, auth should only use 'strong' types.
  validate_user_policy_ = &CheckUserPolicyEmpty;
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  CheckSmbEncTypes(paths_->Get(Path::USER_SMB_CONF), kEncTypesStrong);
  CheckKrb5EncTypes(paths_->Get(Path::USER_KRB5_CONF), kKrb5EncTypesStrong);
}

// If The encryption types reset to strong after device policy fetch.
TEST_F(AuthPolicyTest, LoadsDevicePolicyOnStartup) {
  // Join to bootstrap a config file.
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();

  // Set a device policy file with Kerberos encryption types set to 'all' and
  // restart authpolicy, so that it loads this file on startup.
  em::ChromeDeviceSettingsProto device_policy;
  device_policy.mutable_device_kerberos_encryption_types()->set_types(
      em::DeviceKerberosEncryptionTypesProto::ENC_TYPES_ALL);
  WritePolicyAndRestartAuthpolicy(device_policy);

  // Now an auth operation should use the loaded encryption types.
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  CheckKrb5EncTypes(paths_->Get(Path::USER_KRB5_CONF), kKrb5EncTypesAll);
}

// Both Samba commands (smb) and kinit (krb5) use the encryption types from the
// previous device policy fetch.
TEST_F(AuthPolicyTest, UsesEncTypesFromDevicePolicy) {
  // Write a GPO with DeviceKerberosEncryptionTypes set to 'all'.
  auto enc_types_all = em::DeviceKerberosEncryptionTypesProto::ENC_TYPES_ALL;
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendInteger(policy::key::kDeviceKerberosEncryptionTypes,
                       enc_types_all);
  writer.WriteToFile(stub_gpo1_path_);
  validate_device_policy_ = &DontValidateDevicePolicy;

  // Join and fetch device policy. This should set encryption types to 'all' in
  // Samba.
  EXPECT_EQ(ERROR_NONE,
            Join(kOneGpoMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();
  FetchAndValidateDevicePolicy(ERROR_NONE);

  // Now subsequent calls should use encryption types 'all', both for stuff
  // using smb.conf (policy fetch) as well as stuff using Kerberos tickets (user
  // auth, device policy fetch).
  validate_user_policy_ = &CheckUserPolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);

  // User and device smb.conf has enc types 'all'.
  CheckSmbEncTypes(paths_->Get(Path::USER_SMB_CONF), kEncTypesAll);
  CheckSmbEncTypes(paths_->Get(Path::DEVICE_SMB_CONF), kEncTypesAll);

  // User and device krb5.conf has aes_* + rc4_hmac enc types.
  CheckKrb5EncTypes(paths_->Get(Path::USER_KRB5_CONF), kKrb5EncTypesAll);
  CheckKrb5EncTypes(paths_->Get(Path::DEVICE_KRB5_CONF), kKrb5EncTypesAll);
}

// By default, the user's and device's krb5.conf files only have strong crypto.
TEST_F(AuthPolicyTest, TgtsUseStrongEncTypesByDefault) {
  JoinAndFetchDevicePolicy(kMachineName);
  validate_user_policy_ = &CheckUserPolicyEmpty;
  CheckKrb5EncTypes(paths_->Get(Path::DEVICE_KRB5_CONF), kKrb5EncTypesStrong);
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  CheckKrb5EncTypes(paths_->Get(Path::USER_KRB5_CONF), kKrb5EncTypesStrong);
}

// The password check runs when device policy is fetched.
TEST_F(AuthPolicyTest, ChecksMachinePasswordOnDevicePolicyFetch) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_FALSE(samba().DidPasswordChangeCheckRunForTesting());
  MarkDeviceAsLocked();
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_TRUE(samba().DidPasswordChangeCheckRunForTesting());
}

// The password check can be toggled by fetched device policy.
TEST_F(AuthPolicyTest, FetchedPolicyTogglesMachinePassword) {
  // Join domain.
  EXPECT_EQ(ERROR_NONE,
            Join(kOneGpoMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();
  validate_device_policy_ = &DontValidateDevicePolicy;

  // Turn off password change in policy.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendInteger(policy::key::kDeviceMachinePasswordChangeRate, 0);
  writer.WriteToFile(stub_gpo1_path_);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_FALSE(samba().DidPasswordChangeCheckRunForTesting());

  // Turn password change back on in policy.
  policy::PRegUserDevicePolicyWriter writer2;
  writer2.AppendInteger(policy::key::kDeviceMachinePasswordChangeRate, 1);
  writer2.WriteToFile(stub_gpo1_path_);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_TRUE(samba().DidPasswordChangeCheckRunForTesting());
}

// The password check can be toggled by device policy loaded from disk.
TEST_F(AuthPolicyTest, PolicyOnDiskTogglesMachinePasswordChangeCheck) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();

  // Write a policy to disk that turns off password change and restart.
  em::ChromeDeviceSettingsProto device_policy;
  device_policy.mutable_device_machine_password_change_rate()->set_rate_days(0);
  WritePolicyAndRestartAuthpolicy(device_policy);
  EXPECT_FALSE(samba().DidPasswordChangeCheckRunForTesting());

  // Write a policy to disk that turns password change back on and restart.
  device_policy.mutable_device_machine_password_change_rate()->set_rate_days(1);
  WritePolicyAndRestartAuthpolicy(device_policy);
  EXPECT_TRUE(samba().DidPasswordChangeCheckRunForTesting());
}

// The password actually gets reset once it exceeds the max age.
TEST_F(AuthPolicyTest, MachinePasswordChangesWhenMaxAgeIsReached) {
  EXPECT_EQ(ERROR_NONE,
            Join(kChangePasswordMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();

  // Device policy fetch should trigger a password age check.
  // kChangePasswordMachineName should trigger a server time that's bigger than
  // initial_password_time + 30 days, so that the password should change.
  const std::string initial_password = ReadFile(Path::MACHINE_PASS);
  const base::Time initial_password_time = GetLastModified(Path::MACHINE_PASS);
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);
  const std::string current_password = ReadFile(Path::MACHINE_PASS);
  const base::Time current_password_time = GetLastModified(Path::MACHINE_PASS);
  EXPECT_NE(initial_password, current_password);
  EXPECT_NE(initial_password_time, current_password_time);
  EXPECT_GE(current_password_time - initial_password_time,
            kDefaultMachinePasswordChangeRate);

  // Authpolicy should also keep the prev password around.
  const std::string previous_password = ReadFile(Path::PREV_MACHINE_PASS);
  const base::Time previous_password_time =
      GetLastModified(Path::PREV_MACHINE_PASS);
  EXPECT_EQ(initial_password, previous_password);
  EXPECT_EQ(initial_password_time, previous_password_time);
}

// If the current machine password has just been changed, it might not have
// propagated through Active Directory yet. In that case, kinit should fail and
// authpolicy should retry with the previous machine password.
TEST_F(AuthPolicyTest, DevicePolicyFetchUsesPrevMachinePassword) {
  JoinAndFetchDevicePolicy(kMachineName);

  // Create an expected password. stub_kinit will compare the expected password
  // with the actual password and cause device policy fetch to fail.
  const base::FilePath prev_password_path(paths_->Get(Path::PREV_MACHINE_PASS));
  const base::FilePath expected_password_path =
      base::FilePath(paths_->Get(Path::DEVICE_KRB5_CONF))
          .DirName()
          .Append(kExpectedMachinePassFilename);
  const std::string expected_password = GenerateRandomMachinePassword();
  brillo::WriteStringToFile(expected_password_path, expected_password);
  EXPECT_FALSE(base::PathExists(prev_password_path));
  FetchAndValidateDevicePolicy(ERROR_BAD_PASSWORD);

  // Write the expected password at PREV_MACHINE_PASS and verify fetch works.
  brillo::WriteStringToFile(prev_password_path, expected_password);
  FetchAndValidateDevicePolicy(ERROR_NONE);

  // kinit should be called 1x from 1st fetch, 1x from 2nd fetch and 2x from 3rd
  // fetch (for current and prev machine password).
  EXPECT_EQ(4, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
}

// The password check runs on startup on an enrolled device.
TEST_F(AuthPolicyTest, ChecksMachinePasswordOnStartup) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_FALSE(samba().DidPasswordChangeCheckRunForTesting());

  // Make password old enough for a password change.
  SetLastModified(Path::MACHINE_PASS, base::Time());

  // Restart with empty device policy. This should trigger it as well.
  samba().ResetForTesting();
  EXPECT_FALSE(samba().DidPasswordChangeCheckRunForTesting());
  EXPECT_EQ(ERROR_NONE, samba().Initialize(true /* expect_config */));
  EXPECT_TRUE(samba().DidPasswordChangeCheckRunForTesting());

  // Check that SMB conf contains KDC IP (regression test for crbug.com/815139).
  Krb5Conf conf;
  ReadKrb5Conf(paths_->Get(Path::DEVICE_KRB5_CONF), &conf);
  EXPECT_FALSE(conf.kdc.empty());
}

// Successful user authentication.
TEST_F(AuthPolicyTest, AuthSucceeds) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
}

// Successful user authentication with given account id.
TEST_F(AuthPolicyTest, AuthSucceedsWithKnownAccountId) {
  ActiveDirectoryAccountInfo account_info;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE,
            Auth(kUserPrincipal, kAccountId, MakePasswordFd(), &account_info));
  EXPECT_EQ(kAccountId, account_info.account_id());
}

// Program should die if trying to auth with different account ids.
TEST_F(AuthPolicyTest, AuthFailsDifferentAccountIds) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, kAccountId, MakePasswordFd()));
  EXPECT_DEATH((void)Auth(kUserPrincipal, kAltAccountId, MakePasswordFd()),
               kMultiUserNotSupported);
}

// User authentication fails with bad (non-existent) account id.
TEST_F(AuthPolicyTest, AuthFailsWithBadAccountId) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_BAD_USER_NAME,
            Auth(kUserPrincipal, kBadAccountId, MakePasswordFd()));
}

// Successful user authentication.
TEST_F(AuthPolicyTest, AuthSetsAccountInfo) {
  ActiveDirectoryAccountInfo account_info;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE,
            Auth(kUserPrincipal, "", MakePasswordFd(), &account_info));
  EXPECT_EQ(kAccountId, account_info.account_id());
  EXPECT_EQ(kDisplayName, account_info.display_name());
  EXPECT_EQ(kGivenName, account_info.given_name());
  EXPECT_EQ(kUserName, account_info.sam_account_name());
  EXPECT_EQ(kCommonName, account_info.common_name());
  EXPECT_EQ(kPwdLastSet, account_info.pwd_last_set());
  EXPECT_EQ(kUserAccountControl, account_info.user_account_control());
}

// Authentication fails for badly formatted user principal name.
TEST_F(AuthPolicyTest, AuthFailsInvalidUpn) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_PARSE_UPN_FAILED,
            Auth(kInvalidUserPrincipal, "", MakePasswordFd()));
}

// Authentication fails for non-existing user principal name.
TEST_F(AuthPolicyTest, AuthFailsBadUpn) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_BAD_USER_NAME,
            Auth(kNonExistingUserPrincipal, "", MakePasswordFd()));
}

// Authentication fails for wrong password.
TEST_F(AuthPolicyTest, AuthFailsBadPassword) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_BAD_PASSWORD,
            Auth(kUserPrincipal, "", MakeFileDescriptor(kWrongPassword)));
  // During PODs auth it is possible that the user gets into a session despite
  // the ERROR_BAD_PASSWORD error. This must mean that the password changed on
  // the server and the user entered the old password, which successfully
  // unlocked Cryptohome.
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, GetUserStatus(kUserPrincipal, kAccountId, &status));
  EXPECT_EQ(ActiveDirectoryUserStatus::PASSWORD_CHANGED,
            status.password_status());
}

// Authentication fails for expired password.
TEST_F(AuthPolicyTest, AuthFailsExpiredPassword) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_PASSWORD_EXPIRED,
            Auth(kUserPrincipal, "", MakeFileDescriptor(kExpiredPassword)));
}

// Authentication fails for rejected password.
TEST_F(AuthPolicyTest, AuthFailsRejectedPassword) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_PASSWORD_REJECTED,
            Auth(kUserPrincipal, "", MakeFileDescriptor(kRejectedPassword)));
}

// Authentication succeeds if the "password will expire" warning is shown.
TEST_F(AuthPolicyTest, AuthSucceedsPasswordWillExpire) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE,
            Auth(kUserPrincipal, "", MakeFileDescriptor(kWillExpirePassword)));
}

// Authentication fails if there's a network issue.
TEST_F(AuthPolicyTest, AuthFailsNetworkProblem) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NETWORK_PROBLEM,
            Auth(kNetworkErrorUserPrincipal, "", MakePasswordFd()));
}

// Authentication fails with unsupported encryption type.
TEST_F(AuthPolicyTest, AuthFailsEncTypeNotSupported) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE,
            Auth(kEncTypeNotSupportedUserPrincipal, "", MakePasswordFd()));
}

// Authentication retries without KDC if it fails the first time.
TEST_F(AuthPolicyTest, AuthSucceedsKdcRetry) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kKdcRetryUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(2, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
}

// Can't get user status before domain join.
TEST_F(AuthPolicyTest, GetUserStatusFailsNotJoined) {
  EXPECT_EQ(ERROR_NOT_JOINED, GetUserStatus(kUserPrincipal, kAccountId));
  EXPECT_EQ(0, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
}

// Program should die if trying to get user status with different account ids
// than what was used for auth.
TEST_F(AuthPolicyTest, GetUserStatusFailsDifferentAccountId) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, kAccountId, MakePasswordFd()));
  EXPECT_DEATH((void)GetUserStatus(kUserPrincipal, kAltAccountId),
               kMultiUserNotSupported);
}

// GetUserStatus succeeds without auth, reporting TGT_NOT_FOUND and lacking
// account info and password status.
TEST_F(AuthPolicyTest, GetUserStatusSucceedsTgtNotFound) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, GetUserStatus(kUserPrincipal, kAccountId, &status));
  EXPECT_EQ(ActiveDirectoryUserStatus::TGT_NOT_FOUND, status.tgt_status());
  EXPECT_FALSE(status.has_account_info());
  EXPECT_FALSE(status.has_password_status());
}

// GetUserStatus succeeds with join and auth, but with an expired TGT and
// available server.
TEST_F(AuthPolicyTest, GetUserStatusSucceedsTgtExpiredServerAvailable) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kExpiredTgtUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, GetUserStatus(kUserPrincipal, kAccountId, &status));
  EXPECT_EQ(ActiveDirectoryUserStatus::TGT_EXPIRED, status.tgt_status());
}

// GetUserStatus succeeds with join and auth, but with an expired TGT and
// unavailable server.
TEST_F(AuthPolicyTest, GetUserStatusFailsTgtExpiredServerUnavailable) {
  EXPECT_EQ(ERROR_NONE,
            Join(kPingServerFailMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kExpiredTgtUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(ERROR_NETWORK_PROBLEM, GetUserStatus(kUserPrincipal, kAccountId));
}

// GetUserStatus succeeds with join and auth.
TEST_F(AuthPolicyTest, GetUserStatusSucceeds) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  EXPECT_TRUE(authpolicy_->IsUserTgtAutoRenewalEnabledForTesting());
  EXPECT_EQ(ERROR_NONE, GetUserStatus(kUserPrincipal, kAccountId, &status));

  ActiveDirectoryUserStatus expected_status;
  ActiveDirectoryAccountInfo& expected_account_info =
      *expected_status.mutable_account_info();
  expected_account_info.set_account_id(kAccountId);
  expected_account_info.set_display_name(kDisplayName);
  expected_account_info.set_given_name(kGivenName);
  expected_account_info.set_sam_account_name(kUserName);
  expected_account_info.set_common_name(kCommonName);
  expected_account_info.set_pwd_last_set(kPwdLastSet);
  expected_account_info.set_user_account_control(kUserAccountControl);
  expected_status.set_tgt_status(ActiveDirectoryUserStatus::TGT_VALID);
  expected_status.set_password_status(
      ActiveDirectoryUserStatus::PASSWORD_VALID);

  // Note that protobuf equality comparison is not supported.
  std::string status_blob, expected_status_blob;
  EXPECT_TRUE(status.SerializeToString(&status_blob));
  EXPECT_TRUE(expected_status.SerializeToString(&expected_status_blob));
  EXPECT_EQ(expected_status_blob, status_blob);

  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
}

// GetUserStatus actually contains the last auth error.
TEST_F(AuthPolicyTest, GetUserStatusReportsLastAuthError) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_PASSWORD_EXPIRED,
            Auth(kUserPrincipal, "", MakeFileDescriptor(kExpiredPassword)));
  EXPECT_EQ(ERROR_NONE, GetUserStatus(kUserPrincipal, kAccountId, &status));
  EXPECT_EQ(ActiveDirectoryUserStatus::PASSWORD_EXPIRED,
            status.password_status());
}

// GetUserStatus reports to expire the password.
TEST_F(AuthPolicyTest, GetUserStatusReportsExpiredPasswords) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE,
            Auth(kUserPrincipal, kExpiredPasswordAccountId, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE,
            GetUserStatus(kUserPrincipal, kExpiredPasswordAccountId, &status));
  EXPECT_EQ(ActiveDirectoryUserStatus::PASSWORD_EXPIRED,
            status.password_status());
}

// GetUserStatus does not report expired passwords if UF_DONT_EXPIRE_PASSWD is
// set.
TEST_F(AuthPolicyTest, GetUserStatusDontReportNeverExpirePasswords) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, kNeverExpirePasswordAccountId,
                             MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, GetUserStatus(kUserPrincipal,
                                      kNeverExpirePasswordAccountId, &status));
  EXPECT_EQ(ActiveDirectoryUserStatus::PASSWORD_VALID,
            status.password_status());
}

// GetUserStatus reports password changes.
TEST_F(AuthPolicyTest, GetUserStatusReportChangedPasswords) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE,
            Auth(kPasswordChangedUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE,
            GetUserStatus(kUserPrincipal, kPasswordChangedAccountId, &status));
  EXPECT_EQ(ActiveDirectoryUserStatus::PASSWORD_CHANGED,
            status.password_status());
}

// GetUserStatus reports valid password if the LDAP attributes pwdLastSet or
// userAccountControl are missing for some reason.
TEST_F(AuthPolicyTest, GetUserStatusReportValidPasswordsWithoutPwdFields) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kNoPwdFieldsUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE,
            GetUserStatus(kUserPrincipal, kNoPwdFieldsAccountId, &status));
  EXPECT_EQ(ActiveDirectoryUserStatus::PASSWORD_VALID,
            status.password_status());
  EXPECT_FALSE(status.account_info().has_pwd_last_set());
  EXPECT_FALSE(status.account_info().has_user_account_control());
  EXPECT_FALSE(authpolicy_->IsUserTgtAutoRenewalEnabledForTesting());
}

// GetUserKerberosFiles succeeds with empty files if not joined.
TEST_F(AuthPolicyTest, GetUserKerberosFilesEmptyNotJoined) {
  KerberosFiles files;
  EXPECT_EQ(ERROR_NONE, GetUserKerberosFiles(kAccountId, &files));
  EXPECT_EQ(0, user_kerberos_files_changed_count_);
  EXPECT_FALSE(files.has_krb5cc());
  EXPECT_FALSE(files.has_krb5conf());
}

// GetUserKerberosFiles succeeds with empty files if not logged in.
TEST_F(AuthPolicyTest, GetUserKerberosFilesEmptyNotLoggedIn) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  KerberosFiles files;
  EXPECT_EQ(ERROR_NONE, GetUserKerberosFiles(kAccountId, &files));
  EXPECT_EQ(0, user_kerberos_files_changed_count_);
  EXPECT_FALSE(files.has_krb5cc());
  EXPECT_FALSE(files.has_krb5conf());
}

// Authenticating with different id after GetUserKerberosFiles dies.
TEST_F(AuthPolicyTest, GetUserKerberosFilesBeforeAuthWithAltIdDies) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, GetUserKerberosFiles(kAccountId));
  EXPECT_DEATH((void)Auth(kUserPrincipal, kAltAccountId, MakePasswordFd()),
               kMultiUserNotSupported);
}

// GetUserKerberosFiles succeeds with actual files if logged in.
TEST_F(AuthPolicyTest, GetUserKerberosFilesSucceeds) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  KerberosFiles files;
  EXPECT_EQ(ERROR_NONE, GetUserKerberosFiles(kAccountId, &files));
  EXPECT_EQ(1, user_kerberos_files_changed_count_);
  EXPECT_TRUE(files.has_krb5cc());
  EXPECT_TRUE(files.has_krb5conf());
  EXPECT_EQ(kValidKrb5CCData, files.krb5cc());
  EXPECT_NE(std::string::npos, files.krb5conf().find("allow_weak_crypto"));
}

// Changes of krb5.conf should trigger the UserKerberosFilesChanged signal. This
// is tested by retrying kinit without kdc ip causes a config change and should
// result in a UserKerberosFilesChanged signal.
TEST_F(AuthPolicyTest, ConfigChangeTriggersFilesChangedSignal) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  // Do a normal auth first to bootstrap Kerberos files, but generate an expired
  // TGT, so that the last step won't change the TGT.
  EXPECT_EQ(ERROR_NONE, Auth(kExpiredTgtUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(1, user_kerberos_files_changed_count_);
  // 1x user TGT.
  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));

  // Try to auth again, but trigger a KDC retry to change JUST the config.
  EXPECT_EQ(ERROR_CONTACTING_KDC_FAILED,
            Auth(kKdcRetryFailsUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(2, user_kerberos_files_changed_count_);
  // 2x user TGT because of KDC retry.
  EXPECT_EQ(2, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));

  // Once the config is changed, it shouldn't change again.
  EXPECT_EQ(ERROR_KERBEROS_TICKET_EXPIRED, samba().RenewUserTgtForTesting());
  EXPECT_EQ(2, user_kerberos_files_changed_count_);
  // 1x user TGT.
  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
}

// TGT renewal should trigger a KerberosFilesChanged signal.
TEST_F(AuthPolicyTest, RenewTriggersFilesChangedSignal) {
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  EXPECT_EQ(1, user_kerberos_files_changed_count_);
  EXPECT_EQ(ERROR_NONE, samba().RenewUserTgtForTesting());
  EXPECT_EQ(2, user_kerberos_files_changed_count_);
}

// Join fails if there's a network issue.
TEST_F(AuthPolicyTest, JoinFailsNetworkProblem) {
  EXPECT_EQ(ERROR_NETWORK_PROBLEM,
            Join(kMachineName, kNetworkErrorUserPrincipal, MakePasswordFd()));
}

// Join fails for badly formatted user principal name.
TEST_F(AuthPolicyTest, JoinFailsInvalidUpn) {
  EXPECT_EQ(ERROR_PARSE_UPN_FAILED,
            Join(kMachineName, kInvalidUserPrincipal, MakePasswordFd()));
}

// Join fails for non-existing user principal name, but the error message is the
// same as for wrong password.
TEST_F(AuthPolicyTest, JoinFailsBadUpn) {
  EXPECT_EQ(ERROR_BAD_PASSWORD,
            Join(kMachineName, kNonExistingUserPrincipal, MakePasswordFd()));
}

// Join fails for wrong password.
TEST_F(AuthPolicyTest, JoinFailsBadPassword) {
  EXPECT_EQ(ERROR_BAD_PASSWORD, Join(kMachineName, kUserPrincipal,
                                     MakeFileDescriptor(kWrongPassword)));
}

// Join fails with expired password.
TEST_F(AuthPolicyTest, JoinFailsPasswordExpired) {
  EXPECT_EQ(ERROR_PASSWORD_EXPIRED, Join(kMachineName, kUserPrincipal,
                                         MakeFileDescriptor(kExpiredPassword)));
}

// Join fails if user can't join a machine to the domain.
TEST_F(AuthPolicyTest, JoinFailsAccessDenied) {
  EXPECT_EQ(ERROR_JOIN_ACCESS_DENIED,
            Join(kMachineName, kAccessDeniedUserPrincipal, MakePasswordFd()));
}

// Join fails if the machine name is too long.
TEST_F(AuthPolicyTest, JoinFailsMachineNameTooLong) {
  EXPECT_EQ(ERROR_MACHINE_NAME_TOO_LONG,
            Join(kTooLongMachineName, kUserPrincipal, MakePasswordFd()));
}

// Join fails if the machine name contains invalid characters.
TEST_F(AuthPolicyTest, JoinFailsInvalidMachineName) {
  EXPECT_EQ(ERROR_INVALID_MACHINE_NAME,
            Join(kInvalidMachineName, kUserPrincipal, MakePasswordFd()));
}

// Join fails if the user can't join additional machines.
TEST_F(AuthPolicyTest, JoinFailsInsufficientQuota) {
  EXPECT_EQ(
      ERROR_USER_HIT_JOIN_QUOTA,
      Join(kMachineName, kInsufficientQuotaUserPrincipal, MakePasswordFd()));
}

// Join fails with unsupported encryption type.
TEST_F(AuthPolicyTest, JoinFailsEncTypeNotSupported) {
  EXPECT_EQ(
      ERROR_KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE,
      Join(kMachineName, kEncTypeNotSupportedUserPrincipal, MakePasswordFd()));
}

// A second domain join is blocked.
TEST_F(AuthPolicyTest, JoinFailsAlreadyJoined) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_ALREADY_JOINED,
            Join(kMachineName, kUserPrincipal, MakePasswordFd()));
}

// Successful user policy fetch with empty policy.
TEST_F(AuthPolicyTest, UserPolicyFetchSucceeds) {
  validate_user_policy_ = &CheckUserPolicyEmpty;
  JoinAndFetchDevicePolicy(kMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  EXPECT_EQ(2, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
  EXPECT_EQ(2, metrics_->GetNumMetricReports(METRIC_DOWNLOAD_GPO_COUNT));
}

// For affiliated users, the affiliation marker should be set during user policy
// fetch.
TEST_F(AuthPolicyTest, AffiliationMarkerSetForAffiliatedUsers) {
  validate_user_policy_ = &CheckUserPolicyEmpty;
  JoinAndFetchDevicePolicy(kMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  EXPECT_TRUE(user_affiliation_marker_set_);
}

// For unaffiliated users, the affiliation marker should not be set during user
// policy fetch.
TEST_F(AuthPolicyTest, AffiliationMarkerNotSetForUnaffiliatedUsers) {
  // Users in the same realm as the device are always affiliated, so pick a
  // different realm.
  JoinDomainRequest request;
  request.set_machine_name(kUnaffiliatedMachineName);
  request.set_machine_domain(kMachineRealm);
  request.set_user_principal_name(kUserPrincipal);
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));
  MarkDeviceAsLocked();
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);

  validate_user_policy_ = &CheckUserPolicyEmpty;
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  EXPECT_FALSE(user_affiliation_marker_set_);
}

// Successful device and user policy fetch with empty policy for different
// workgroups.
TEST_F(AuthPolicyTest, DeviceAndUserPolicyFetchDifferentWorkgroupsSucceeds) {
  // The workgroup is associated with the realm. Pass secondary workgroup realm,
  // so `HandleWorkgroup()` imitating "net ads workgroup" in stub will fetch the
  // secondary workgroup associated with it.
  JoinDomainRequest request;
  request.set_machine_name(kMachineName);
  request.set_machine_domain(kSecondaryWorkgroupRealm);
  request.set_user_principal_name(kUserPrincipal);
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));
  MarkDeviceAsLocked();
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);

  // Validate device workgroup.
  SmbConf device_smb_conf;
  ReadSmbConf(paths_->Get(Path::DEVICE_SMB_CONF), &device_smb_conf);
  EXPECT_EQ(kSecondaryWorkgroup, device_smb_conf.workgroup);

  validate_user_policy_ = &CheckUserPolicyEmpty;
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);

  // Validate user workgroup.
  SmbConf user_smb_conf;
  ReadSmbConf(paths_->Get(Path::USER_SMB_CONF), &user_smb_conf);
  EXPECT_EQ(kDefaultWorkgroup, user_smb_conf.workgroup);
}

// Successful user policy fetch with actual data.
TEST_F(AuthPolicyTest, UserPolicyFetchSucceedsWithData) {
  // Write a preg file with all basic data types. The file is picked up by
  // stub_net and "downloaded" by stub_smbclient.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(policy::key::kSearchSuggestEnabled, kPolicyBool);
  writer.AppendInteger(policy::key::kPolicyRefreshRate, kPolicyInt);
  writer.AppendString(policy::key::kHomepageLocation, kPolicyStr);
  const std::vector<std::string> apps = {"App1", "App2"};
  writer.AppendStringList(policy::key::kPinnedLauncherApps, apps);
  writer.WriteToFile(stub_gpo1_path_);

  // Validate that the protobufs sent from authpolicy to Session Manager
  // actually contain the policies set above. This validator is called by
  // FetchAndValidateUserPolicy below.
  validate_user_policy_ = [apps](const em::CloudPolicySettings& policy) {
    EXPECT_EQ(kPolicyBool, policy.searchsuggestenabled().value());
    EXPECT_EQ(kPolicyInt, policy.policyrefreshrate().value());
    EXPECT_EQ(kPolicyStr, policy.homepagelocation().value());
    const em::StringList& apps_proto = policy.pinnedlauncherapps().value();
    EXPECT_EQ(apps_proto.entries_size(), static_cast<int>(apps.size()));
    for (int n = 0; n < apps_proto.entries_size(); ++n)
      EXPECT_EQ(apps_proto.entries(n), apps.at(n));
  };
  JoinAndFetchDevicePolicy(kOneGpoMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  EXPECT_EQ(2,
            metrics_->GetNumMetricReports(METRIC_SMBCLIENT_FAILED_TRY_COUNT));
}

// Successful user policy fetch that also contains extension policy.
TEST_F(AuthPolicyTest, UserPolicyFetchSucceedsWithDataAndExtensions) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  policy::PRegPolicyWriter writer;
  writer.SetKeysForUserDevicePolicy();
  writer.AppendBoolean(policy::key::kSearchSuggestEnabled, kPolicyBool);
  WriteDefaultExtensionPolicy(&writer);
  writer.WriteToFile(stub_gpo1_path_);

  validate_user_policy_ = [](const em::CloudPolicySettings& policy) {
    EXPECT_EQ(kPolicyBool, policy.searchsuggestenabled().value());
  };
  validate_extension_policy_ = &CheckDefaultExtensionPolicy;
  JoinAndFetchDevicePolicy(kOneGpoMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  EXPECT_EQ(2, validated_extension_ids_.size());
}

// Successful user policy fetch that also contains extension policy.
TEST_F(AuthPolicyTest, StaleExtensionPoliciesAreDeleted) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  policy::PRegPolicyWriter writer;
  writer.SetKeysForExtensionPolicy(kExtensionId);
  writer.AppendString(kExtensionPolicy1, kPolicyStr);
  writer.WriteToFile(stub_gpo1_path_);

  // Pretend that Session Manager has stored policy for these two extensions.
  stored_extension_ids_.push_back(kExtensionId);
  stored_extension_ids_.push_back(kOtherExtensionId);

  // Fetch and validate. This should trigger policy kOtherExtensionId to be
  // deleted because the GPO only contains kExtensionId.
  validate_user_policy_ = &CheckUserPolicyEmpty;
  validate_extension_policy_ = &CheckDefaultExtensionPolicy;
  JoinAndFetchDevicePolicy(kOneGpoMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  EXPECT_EQ(validated_extension_ids_,
            std::multiset<std::string>({kExtensionId}));
  EXPECT_EQ(deleted_extension_ids_,
            std::multiset<std::string>({kOtherExtensionId}));
}

// Verify that PolicyLevel is encoded properly.
TEST_F(AuthPolicyTest, UserPolicyFetchSucceedsWithPolicyLevel) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(policy::key::kSearchSuggestEnabled, kPolicyBool,
                       policy::POLICY_LEVEL_RECOMMENDED);
  writer.AppendInteger(policy::key::kPolicyRefreshRate, kPolicyInt);
  writer.WriteToFile(stub_gpo1_path_);

  validate_user_policy_ = [](const em::CloudPolicySettings& policy) {
    EXPECT_TRUE(policy.searchsuggestenabled().has_policy_options());
    EXPECT_EQ(em::PolicyOptions_PolicyMode_RECOMMENDED,
              policy.searchsuggestenabled().policy_options().mode());

    EXPECT_TRUE(policy.policyrefreshrate().has_policy_options());
    EXPECT_EQ(em::PolicyOptions_PolicyMode_MANDATORY,
              policy.policyrefreshrate().policy_options().mode());
  };
  JoinAndFetchDevicePolicy(kOneGpoMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
}

// Verifies that a POLICY_LEVEL_MANDATORY policy is not overwritten by a
// POLICY_LEVEL_RECOMMENDED policy.
TEST_F(AuthPolicyTest, UserPolicyFetchMandatoryTakesPreference) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  policy::PRegUserDevicePolicyWriter writer1;
  writer1.AppendBoolean(policy::key::kSearchSuggestEnabled, kPolicyBool,
                        policy::POLICY_LEVEL_MANDATORY);
  writer1.WriteToFile(stub_gpo1_path_);

  // Normally, the latter GPO file overrides the former
  // (DevicePolicyFetchGposOverride), but POLICY_LEVEL_RECOMMENDED does not
  // beat POLICY_LEVEL_MANDATORY.
  policy::PRegUserDevicePolicyWriter writer2;
  writer2.AppendBoolean(policy::key::kSearchSuggestEnabled, kOtherPolicyBool,
                        policy::POLICY_LEVEL_RECOMMENDED);
  writer2.WriteToFile(stub_gpo2_path_);

  validate_user_policy_ = [](const em::CloudPolicySettings& policy) {
    EXPECT_TRUE(policy.searchsuggestenabled().has_value());
    EXPECT_EQ(kPolicyBool, policy.searchsuggestenabled().value());
    EXPECT_TRUE(policy.searchsuggestenabled().has_policy_options());
    EXPECT_EQ(em::PolicyOptions_PolicyMode_MANDATORY,
              policy.searchsuggestenabled().policy_options().mode());
  };
  JoinAndFetchDevicePolicy(kTwoGposMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
}

// Verify that GPO containing policies with the wrong data type are not set.
// An exception is bool and int. Internally, bools are handled like ints with
// value {0,1}, so that setting kPolicyRefreshRate to true is actually
// interpreted as int 1.
TEST_F(AuthPolicyTest, UserPolicyFetchIgnoreBadDataType) {
  // Set policies with wrong data type, e.g. kPinnedLauncherApps is a string
  // list, but it is set as a string. See UserPolicyFetchSucceedsWithData for
  // the logic of policy testing.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(policy::key::kPolicyRefreshRate, kPolicyBool);
  writer.AppendInteger(policy::key::kHomepageLocation, kPolicyInt);
  writer.AppendString(policy::key::kPinnedLauncherApps, kPolicyStr);
  const std::vector<std::string> apps = {"App1", "App2"};
  writer.AppendStringList(policy::key::kSearchSuggestEnabled, apps);
  writer.WriteToFile(stub_gpo1_path_);

  validate_user_policy_ = [](const em::CloudPolicySettings& policy) {
    EXPECT_FALSE(policy.has_searchsuggestenabled());
    EXPECT_FALSE(policy.has_pinnedlauncherapps());
    EXPECT_FALSE(policy.has_homepagelocation());
    EXPECT_TRUE(policy.has_policyrefreshrate());  // Interpreted as int 1.
  };
  JoinAndFetchDevicePolicy(kOneGpoMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
}

// GPOs with version 0 should be ignored.
TEST_F(AuthPolicyTest, UserPolicyFetchIgnoreZeroVersion) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(policy::key::kSearchSuggestEnabled, kPolicyBool);
  writer.WriteToFile(stub_gpo1_path_);

  validate_user_policy_ = [](const em::CloudPolicySettings& policy) {
    EXPECT_FALSE(policy.has_searchsuggestenabled());
  };
  JoinAndFetchDevicePolicy(kZeroUserVersionMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);

  // Validate the validation. GPO is actually taken if user version is > 0.
  validate_user_policy_ = [](const em::CloudPolicySettings& policy) {
    EXPECT_TRUE(policy.has_searchsuggestenabled());
  };
  EXPECT_TRUE(MakeConfigWriteable());
  samba().ResetForTesting();
  JoinAndFetchDevicePolicy(kOneGpoMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
}

// GPOs with an ignore flag set should be ignored. Sounds reasonable, hmm?
TEST_F(AuthPolicyTest, UserPolicyFetchIgnoreFlagSet) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(policy::key::kSearchSuggestEnabled, kPolicyBool);
  writer.WriteToFile(stub_gpo1_path_);

  validate_user_policy_ = [](const em::CloudPolicySettings& policy) {
    EXPECT_FALSE(policy.has_searchsuggestenabled());
  };
  JoinAndFetchDevicePolicy(kDisableUserFlagMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);

  // Validate the validation. GPO is taken if the ignore flag is not set.
  validate_user_policy_ = [](const em::CloudPolicySettings& policy) {
    EXPECT_TRUE(policy.has_searchsuggestenabled());
  };
  EXPECT_TRUE(MakeConfigWriteable());
  samba().ResetForTesting();
  JoinAndFetchDevicePolicy(kOneGpoMachineName);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
}

// User policy fetch fails if there's no device policy (since the way user
// policy is fetched depends on device policy).
TEST_F(AuthPolicyTest, UserPolicyFetchFailsNoDevicePolicy) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NO_DEVICE_POLICY);
}

// User policy fetch works properly with loopback processing.
TEST_F(AuthPolicyTest, UserPolicyFetchObeysLoopbackProcessing) {
  // Write 2 GPO files with 2 policies each:
  //
  //   GPO  Policy 1 2 3
  //   GPO1        x y
  //   GPO2        A   B
  //
  // 'x' is the value of policy 1 in GPO1 etc. Now for the test,
  //   GPO1 is used as user GPO and
  //   GPO2 is used as device GPO.
  //
  // Depending on the loopback processing mode, this should result in
  //
  //   Mode    Policy 1 2 3
  //   Default        x y    <-- Only take user GPO1
  //   Merge          A y B  <-- Merge device GPO2 on top of user GPO1
  //   Replace        A   B  <-- Only take device GPO2

  const char* policy1 = policy::key::kSearchSuggestEnabled;
  const char* policy2 = policy::key::kPolicyRefreshRate;
  const char* policy3 = policy::key::kHomepageLocation;

  const bool value_x = kPolicyBool;
  const int value_y = kPolicyInt;
  const bool value_A = kOtherPolicyBool;
  const char* value_B = kOtherPolicyStr;

  policy::PRegUserDevicePolicyWriter writer1;
  writer1.AppendBoolean(policy1, value_x);
  writer1.AppendInteger(policy2, value_y);
  writer1.WriteToFile(stub_gpo1_path_);

  policy::PRegUserDevicePolicyWriter writer2;
  writer2.AppendBoolean(policy1, value_A);
  writer2.AppendString(policy3, value_B);
  writer2.WriteToFile(stub_gpo2_path_);

  // |kLoopbackGpoMachineName| triggers stub_net to
  //   - return GPO1 for net ads gpo list <user_principal> and
  //   - return GPO2 for net ads gpo list <device_principal>.
  JoinAndFetchDevicePolicy(kLoopbackGpoMachineName);

  const int mode_min =
      em::DeviceUserPolicyLoopbackProcessingModeProto::Mode_MIN;
  const int mode_max =
      em::DeviceUserPolicyLoopbackProcessingModeProto::Mode_MAX;
  for (int int_mode = mode_min; int_mode <= mode_max; ++int_mode) {
    const auto mode =
        static_cast<em::DeviceUserPolicyLoopbackProcessingModeProto::Mode>(
            int_mode);
    samba().SetUserPolicyModeForTesting(mode);

    validate_user_policy_ = [value_x, value_y, value_A, value_B,
                             mode](const em::CloudPolicySettings& policy) {
      const bool has_policy1 = policy.has_searchsuggestenabled();
      const bool has_policy2 = policy.has_policyrefreshrate();
      const bool has_policy3 = policy.has_homepagelocation();

      const bool policy1_value = policy.searchsuggestenabled().value();
      const int policy2_value = policy.policyrefreshrate().value();
      const std::string& policy3_value = policy.homepagelocation().value();

      EXPECT_TRUE(has_policy1);
      switch (mode) {
        case em::DeviceUserPolicyLoopbackProcessingModeProto::
            USER_POLICY_MODE_DEFAULT:
          EXPECT_TRUE(has_policy2);
          EXPECT_FALSE(has_policy3);
          EXPECT_EQ(value_x, policy1_value);
          EXPECT_EQ(value_y, policy2_value);
          break;

        case em::DeviceUserPolicyLoopbackProcessingModeProto::
            USER_POLICY_MODE_MERGE:
          EXPECT_TRUE(has_policy2);
          EXPECT_TRUE(has_policy3);
          EXPECT_EQ(value_A, policy1_value);
          EXPECT_EQ(value_y, policy2_value);
          EXPECT_EQ(value_B, policy3_value);
          break;

        case em::DeviceUserPolicyLoopbackProcessingModeProto::
            USER_POLICY_MODE_REPLACE:
          EXPECT_FALSE(has_policy2);
          EXPECT_TRUE(has_policy3);
          EXPECT_EQ(value_A, policy1_value);
          EXPECT_EQ(value_B, policy3_value);
          break;
      }
    };
    FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  }
  // 3x for user TGT during auth, 1 for device policy fetch, 2x for device TGT
  // for MERGE and REPLACE.
  EXPECT_EQ(6, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
  // 1x for device policy fetch, 1x for DEFAULT, 2x for MERGE, 1x for REPLACE.
  EXPECT_EQ(5,
            metrics_->GetNumMetricReports(METRIC_SMBCLIENT_FAILED_TRY_COUNT));
  // 1x for device policy fetch, 1x for DEFAULT, 2x for MERGE, 1x for REPLACE.
  EXPECT_EQ(5, metrics_->GetNumMetricReports(METRIC_DOWNLOAD_GPO_COUNT));
}

// Successful device policy fetch with empty policy.
TEST_F(AuthPolicyTest, DevicePolicyFetchSucceeds) {
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_DOWNLOAD_GPO_COUNT));
}

// Device policy fetch fails if the machine account doesn't exist.
TEST_F(AuthPolicyTest, DevicePolicyFetchFailsBadMachineName) {
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  EXPECT_EQ(ERROR_NONE,
            Join(kNonExistingMachineName, kUserPrincipal, MakePasswordFd()));
  FetchAndValidateDevicePolicy(ERROR_BAD_MACHINE_NAME);
  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
  EXPECT_EQ(0, metrics_->GetNumMetricReports(METRIC_DOWNLOAD_GPO_COUNT));
}

// Policy fetch should ignore GPO files that are missing on the server. This
// test looks for stub_gpo1_path_ and won't find it because we don't create it.
TEST_F(AuthPolicyTest, DevicePolicyFetchSucceedsMissingFile) {
  validate_user_policy_ = &CheckUserPolicyEmpty;
  JoinAndFetchDevicePolicy(kOneGpoMachineName);
}

// Successful device policy fetch with keytab file. This tests backwards
// compatibility with old clients that used a keytab file instead of a password.
TEST_F(AuthPolicyTest, DevicePolicyFetchSucceedsWithKeytab) {
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  EXPECT_EQ(ERROR_NONE,
            Join(kExpectKeytabMachineName, kUserPrincipal, MakePasswordFd()));

  // Replace the machine password by a keytab file. Authpolicy should use that
  // instead.
  const base::FilePath password_path(paths_->Get(Path::MACHINE_PASS));
  const base::FilePath keytab_path(paths_->Get(Path::MACHINE_KEYTAB));
  EXPECT_TRUE(base::Move(password_path, keytab_path));

  MarkDeviceAsLocked();
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_KINIT_FAILED_TRY_COUNT));
  EXPECT_EQ(1, metrics_->GetNumMetricReports(METRIC_DOWNLOAD_GPO_COUNT));
}

// Policy fetch fails if a file fails to download (unless it's missing, see
// DevicePolicyFetchSucceedsMissingFile).
TEST_F(AuthPolicyTest, DevicePolicyFetchFailsDownloadError) {
  EXPECT_EQ(ERROR_NONE, Join(kGpoDownloadErrorMachineName, kUserPrincipal,
                             MakePasswordFd()));
  FetchAndValidateDevicePolicy(ERROR_SMBCLIENT_FAILED);
}

// Successful device policy fetch with a few kinit retries because the machine
// account hasn't propagated yet.
TEST_F(AuthPolicyTest, DevicePolicyFetchSucceedsPropagationRetry) {
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  EXPECT_EQ(ERROR_NONE, Join(kPropagationRetryMachineName, kUserPrincipal,
                             MakePasswordFd()));
  MarkDeviceAsLocked();
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(kNumPropagationRetries,
            metrics_->GetLastMetricSample(METRIC_KINIT_FAILED_TRY_COUNT));
}

// Successful device policy fetch with actual data.
TEST_F(AuthPolicyTest, DevicePolicyFetchSucceedsWithData) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  SetupDeviceOneGpo(stub_gpo1_path_);
  EXPECT_EQ(ERROR_NONE,
            Join(kOneGpoMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();
  FetchAndValidateDevicePolicy(ERROR_NONE);
}

// Authpolicy caches device policy when device is not locked.
TEST_F(AuthPolicyTest, CachesDevicePolicyWhenDeviceIsNotLocked) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  SetupDeviceOneGpo(stub_gpo1_path_);
  EXPECT_EQ(ERROR_NONE,
            Join(kOneGpoMachineName, kUserPrincipal, MakePasswordFd()));
  FetchAndValidateDevicePolicy(ERROR_DEVICE_POLICY_CACHED_BUT_NOT_SENT);
  EXPECT_TRUE(base::DeleteFile(stub_gpo1_path_));
  MarkDeviceAsLocked();
  FetchAndValidateDevicePolicy(ERROR_NONE);
}

// Successful device policy fetch that also contains extension policy.
TEST_F(AuthPolicyTest, DevicePolicyFetchSucceedsWithDataAndExtensions) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  policy::PRegPolicyWriter writer;
  writer.SetKeysForUserDevicePolicy();
  writer.AppendBoolean(policy::key::kDeviceGuestModeEnabled, kPolicyBool);
  WriteDefaultExtensionPolicy(&writer);
  writer.WriteToFile(stub_gpo1_path_);

  validate_device_policy_ = [](const em::ChromeDeviceSettingsProto& policy) {
    EXPECT_EQ(kPolicyBool, policy.guest_mode_enabled().guest_mode_enabled());
  };
  validate_extension_policy_ = &CheckDefaultExtensionPolicy;
  EXPECT_EQ(ERROR_NONE,
            Join(kOneGpoMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(2, validated_extension_ids_.size());
}

// Completely empty GPO list fails. GPO lists should always contain at least
// a "local policy" created by the Samba tool, independently of the server.
TEST_F(AuthPolicyTest, DevicePolicyFetchFailsEmptyGpoList) {
  EXPECT_EQ(ERROR_NONE,
            Join(kEmptyGpoMachineName, kUserPrincipal, MakePasswordFd()));
  FetchAndValidateDevicePolicy(ERROR_PARSE_FAILED);
}

// A GPO later in the list overrides prior GPOs.
TEST_F(AuthPolicyTest, DevicePolicyFetchGposOverride) {
  // See UserPolicyFetchSucceedsWithData for the logic of policy testing.
  policy::PRegUserDevicePolicyWriter writer1;
  writer1.AppendBoolean(policy::key::kDeviceGuestModeEnabled, kOtherPolicyBool);
  writer1.AppendInteger(policy::key::kDevicePolicyRefreshRate, kPolicyInt);
  writer1.AppendString(policy::key::kSystemTimezone, kPolicyStr);
  const std::vector<std::string> str_list1 = {"str1", "str2", "str3"};
  writer1.AppendStringList(policy::key::kDeviceUserAllowlist, str_list1);
  writer1.WriteToFile(stub_gpo1_path_);

  policy::PRegUserDevicePolicyWriter writer2;
  writer2.AppendBoolean(policy::key::kDeviceGuestModeEnabled, kPolicyBool);
  writer2.AppendInteger(policy::key::kDevicePolicyRefreshRate, kOtherPolicyInt);
  writer2.AppendString(policy::key::kSystemTimezone, kOtherPolicyStr);
  const std::vector<std::string> str_list2 = {"str4", "str5"};
  writer2.AppendStringList(policy::key::kDeviceUserAllowlist, str_list2);
  writer2.WriteToFile(stub_gpo2_path_);

  validate_device_policy_ = [str_list2](
                                const em::ChromeDeviceSettingsProto& policy) {
    EXPECT_EQ(kPolicyBool, policy.guest_mode_enabled().guest_mode_enabled());
    EXPECT_EQ(kOtherPolicyInt,
              policy.device_policy_refresh_rate().device_policy_refresh_rate());
    EXPECT_EQ(kOtherPolicyStr, policy.system_timezone().timezone());
    const em::UserAllowlistProto& str_list_proto = policy.user_allowlist();
    EXPECT_EQ(str_list_proto.user_allowlist_size(),
              static_cast<int>(str_list2.size()));
    for (int n = 0; n < str_list_proto.user_allowlist_size(); ++n)
      EXPECT_EQ(str_list_proto.user_allowlist(n), str_list2.at(n));
  };
  EXPECT_EQ(ERROR_NONE,
            Join(kTwoGposMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();
  FetchAndValidateDevicePolicy(ERROR_NONE);
}

// Make sure cleaning state works.
TEST_F(AuthPolicyTest, CleanStateDir) {
  const base::FilePath state_path =
      base::FilePath(paths_->Get(Path::STATE_DIR));
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  EXPECT_FALSE(base::IsDirectoryEmpty(state_path));
  EXPECT_TRUE(AuthPolicy::CleanState(paths_.get()));
  EXPECT_TRUE(base::IsDirectoryEmpty(state_path));
}

// Authentication doesn't back up auth state if Cryptohome is not mounted.
TEST_F(AuthPolicyTest, DoesNotBackUpOnAuthIfCryptohomeIsNotMounted) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  EXPECT_FALSE(base::PathExists(backup_path_));
}

// Authentication backs up auth state if Cryptohome is already mounted.
TEST_F(AuthPolicyTest, BacksUpOnAuthIfCryptohomeIsMounted) {
  samba().OnSessionStateChanged(kSessionStarted);
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_FALSE(base::PathExists(backup_path_));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  EXPECT_TRUE(base::PathExists(backup_path_));
}

// The session state change signal handler triggers a backup of user auth state.
TEST_F(AuthPolicyTest, BacksUpOnSessionStarted) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  EXPECT_FALSE(base::PathExists(backup_path_));
  NotifySessionStarted();
  EXPECT_TRUE(base::PathExists(backup_path_));
}

// Kerberos ticket renewal triggers a backup of user auth state.
TEST_F(AuthPolicyTest, BacksUpOnTgtAutoRenewal) {
  // Join and authenticate with Cryptohome mounted, so that a backup is written.
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  NotifySessionStarted();

  // Trigger TGT renewal and check if the backup file got re-written.
  // Modify timestamps of the existing backup file to detect overwrite.
  base::Time impossible_time = base::Time();
  ASSERT_TRUE(base::TouchFile(backup_path_, impossible_time, impossible_time));
  EXPECT_EQ(ERROR_NONE, samba().RenewUserTgtForTesting());
  base::Time backup_time = GetLastModified(backup_path_);
  EXPECT_LT(impossible_time, backup_time);
}

// Restarting authpolicy reloads the backup data and user-specific calls work
// without another AuthenticateUser() call.
TEST_F(AuthPolicyTest, LoadsBackupAndRestoresState) {
  // Join and authenticate with Cryptohome mounted, so that a backup is written.
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  NotifySessionStarted();
  EXPECT_TRUE(base::PathExists(backup_path_));

  // Restart authpolicyd.
  samba().ResetForTesting();
  EXPECT_EQ(ERROR_NONE, samba().Initialize(true /* expect_config */));

  // GetUserKerberosFiles should restore the backup including the Kerberos
  // ticket, so the Kerberos files changed signal should be called.
  KerberosFiles files;
  EXPECT_EQ(1, user_kerberos_files_changed_count_);
  EXPECT_EQ(ERROR_NONE, GetUserKerberosFiles(kAccountId, &files));
  EXPECT_EQ(2, user_kerberos_files_changed_count_);
  EXPECT_TRUE(files.has_krb5cc());
  EXPECT_TRUE(files.has_krb5conf());
  EXPECT_FALSE(files.krb5cc().empty());
  EXPECT_FALSE(files.krb5conf().empty());

  // The state should look like as if the user was logged in with valid TGT.
  ActiveDirectoryUserStatus status;
  EXPECT_EQ(ERROR_NONE, GetUserStatus(kUserPrincipal, kAccountId, &status));
  EXPECT_TRUE(status.has_tgt_status());
  EXPECT_EQ(ActiveDirectoryUserStatus::TGT_VALID, status.tgt_status());
  EXPECT_TRUE(status.has_password_status());
  EXPECT_EQ(ActiveDirectoryUserStatus::PASSWORD_VALID,
            status.password_status());
  EXPECT_TRUE(status.has_account_info());
  EXPECT_TRUE(status.account_info().has_pwd_last_set());
  EXPECT_TRUE(status.account_info().has_user_account_control());

  // TGT renewal still works. Do this before auth to check all state for renewal
  // got properly restored (auth overrides this).
  EXPECT_EQ(ERROR_NONE, samba().RenewUserTgtForTesting());

  // User policy fetch still works and that the affiliation state has been
  // properly restored from backup.
  validate_user_policy_ = &CheckUserPolicyEmpty;
  EXPECT_FALSE(user_affiliation_marker_set_);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);
  EXPECT_TRUE(user_affiliation_marker_set_);

  // Can also authenticate again to fetch a new TGT.
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, kAccountId, MakePasswordFd()));
}

// Policy fetch after a restart recovers successfully from backup (see
// https://crbug.com/908772).
TEST_F(AuthPolicyTest, LoadsBackupOnPolicyFetch) {
  // Join and authenticate with Cryptohome mounted, so that a backup is written.
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  NotifySessionStarted();

  // Restart authpolicyd.
  samba().ResetForTesting();
  EXPECT_EQ(ERROR_NONE, samba().Initialize(true /* expect_config */));

  // User policy fetch still works, even without auth.
  validate_user_policy_ = &CheckUserPolicyEmpty;
  FetchAndValidateUserPolicy(kAccountId, ERROR_NONE);
}

// By default, nothing should call the (expensive) anonymizer since no sensitive
// data is logged. Only if logging is enabled it should be called.
TEST_F(AuthPolicyTest, AnonymizerNotCalledWithoutLogging) {
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();

  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);

  validate_user_policy_ = &CheckUserPolicyEmpty;
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_NONE);

  EXPECT_FALSE(samba().GetAnonymizerForTesting()->process_called_for_testing());
}

// If log output is requested, the logs should be anonymized.
TEST_F(AuthPolicyTest, AnonymizerCalledWithLogging) {
  // Turn on max logging and trigger an error. This triggers debug logging
  // which should be anonymized.
  samba().SetDefaultLogLevel(AuthPolicyFlags::kMaxLevel);
  EXPECT_EQ(ERROR_MACHINE_NAME_TOO_LONG,
            Join(kTooLongMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_TRUE(samba().GetAnonymizerForTesting()->process_called_for_testing());
}

// Disable SeccompFiltersEnabled under ASAN. Minijail does not enable seccomp
// filtering when running under ASAN, so the test fails.
// https://crbug.com/908140
#ifndef BRILLO_ASAN_BUILD

// TODO(https://crbug.com/994814): This is currently broken under llvm-next
// since unexpected parts of the code trigger seccomp failures. The fix could be
// to refactor the code so that seccomp filtering is only enabled for the one
// process that is expected to trigger a seccomp failure. For example, if
// ERROR_NET_FAILED is expected, JailHelper::SetupJailAndRun should only enable
// seccomp filtering if |seccomp_path_key| is NET_ADS_SECCOMP etc.

// Re-enable seccomp filters and check that they are actually in effect.
TEST_F(AuthPolicyTest, DISABLED_SeccompFiltersEnabled) {
  // Re-enable seccomp filtering and trigger it in net ads join.
  samba().DisableSeccompForTesting(false);
  EXPECT_EQ(ERROR_NET_FAILED,
            Join(kSeccompMachineName, kUserPrincipal, MakePasswordFd()));

  // Disable seccomp filtering again, make sure net ads join works this time.
  samba().DisableSeccompForTesting(true);
  EXPECT_EQ(ERROR_NONE,
            Join(kSeccompMachineName, kUserPrincipal, MakePasswordFd()));

  MarkDeviceAsLocked();

  // Same with kinit. Check whether kinit can trigger seccomp failures.
  samba().DisableSeccompForTesting(false);
  EXPECT_EQ(ERROR_KINIT_FAILED,
            Auth(kSeccompUserPrincipal, "", MakePasswordFd()));
  samba().DisableSeccompForTesting(true);
  EXPECT_EQ(ERROR_NONE, Auth(kSeccompUserPrincipal, "", MakePasswordFd()));

  // Finally, check whether smbclient can trigger seccomp failures.
  samba().DisableSeccompForTesting(false);
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_SMBCLIENT_FAILED);
  samba().DisableSeccompForTesting(true);
  FetchAndValidateDevicePolicy(ERROR_NONE);
}

#endif  // #ifndef BRILLO_ASAN_BUILD

// GPO files are cached and not re-downloaded if the version didn't change.
TEST_F(AuthPolicyTest, UsesCachedGposForSameVersion) {
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(policy::key::kDeviceGuestModeEnabled, kPolicyBool);
  writer.WriteToFile(stub_gpo1_path_);

  validate_device_policy_ = [](const em::ChromeDeviceSettingsProto& policy) {
    EXPECT_EQ(kPolicyBool, policy.guest_mode_enabled().guest_mode_enabled());
  };

  const GpoVersionCache* cache = samba().GetGpoVersionCacheForTesting();

  // Join domain. |kOneGpoKeepVersionMachineName| freezes the GPO version at 1.
  EXPECT_EQ(ERROR_NONE, Join(kOneGpoKeepVersionMachineName, kUserPrincipal,
                             MakePasswordFd()));
  MarkDeviceAsLocked();

  // First policy fetch should be a cache miss with expected version 1.
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(1, cache->cache_misses_for_testing());
  EXPECT_EQ(0, cache->cache_hits_for_testing());

  // Next time should be a cache hit since the version is still 1.
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(1, cache->cache_misses_for_testing());
  EXPECT_EQ(1, cache->cache_hits_for_testing());
}

// GPO files are re-downloaded if the version changed.
TEST_F(AuthPolicyTest, DoesNotUseCachedGposForDifferentVersion) {
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendBoolean(policy::key::kDeviceGuestModeEnabled, kPolicyBool);
  writer.WriteToFile(stub_gpo1_path_);

  validate_device_policy_ = [](const em::ChromeDeviceSettingsProto& policy) {
    EXPECT_EQ(kPolicyBool, policy.guest_mode_enabled().guest_mode_enabled());
  };

  GpoVersionCache* cache = samba().GetGpoVersionCacheForTesting();

  // Join domain.
  EXPECT_EQ(ERROR_NONE,
            Join(kOneGpoMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();

  // First policy fetch should be a cache miss with expected version 1.
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(1, cache->cache_misses_for_testing());
  EXPECT_EQ(0, cache->cache_hits_for_testing());

  // Next time should be a cache miss again since |kOneGpoMachineName| caused
  // the version to increase on every FetchAndValidateDevicePolicy() call.
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(2, cache->cache_misses_for_testing());
  EXPECT_EQ(0, cache->cache_hits_for_testing());
}

// Caching should not complain about GPOs with missing files.
TEST_F(AuthPolicyTest, CachesGposWithMissingFile) {
  const GpoVersionCache* cache = samba().GetGpoVersionCacheForTesting();

  // Write file 1, but omit file 2.
  policy::PRegUserDevicePolicyWriter writer;
  writer.WriteToFile(stub_gpo1_path_);
  EXPECT_FALSE(base::PathExists(stub_gpo2_path_));

  // First time should be a cache miss for both.
  // Note that with each FetchAndValidateDevicePolicy() call, the effect of
  // |kTwoGposKeepVersionMachineName| is
  // - an increase of the version of the first GPO, so that the download code is
  //   triggered, but
  // - a freeze of the version of the second GPO, so that it's cached.

  // First time should be a cache miss.
  JoinAndFetchDevicePolicy(kTwoGposKeepVersionMachineName);
  EXPECT_EQ(2, cache->cache_misses_for_testing());
  EXPECT_EQ(0, cache->cache_hits_for_testing());

  // Second time should be a cache miss for the first file (since its version
  // increased) and a cache hit for the missing second file.
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(3, cache->cache_misses_for_testing());
  EXPECT_EQ(1, cache->cache_hits_for_testing());
}

// The GPO cache is purged occasionally.
TEST_F(AuthPolicyTest, PurgesGpoCacheOccasionally) {
  // Set a testing clock to stub out cache TTL.
  GpoVersionCache* cache = samba().GetGpoVersionCacheForTesting();
  auto clock_ptr = std::make_unique<base::SimpleTestClock>();
  base::SimpleTestClock* clock = clock_ptr.get();
  cache->SetClockForTesting(std::move(clock_ptr));

  // Pick delta so that one Advance() call won't purge the cache, but two will.
  const base::TimeDelta delta =
      samba().GetGpoVersionCacheTTLForTesting() * 2 / 3;

  JoinAndFetchDevicePolicy(kOneGpoKeepVersionMachineName);
  EXPECT_EQ(1, cache->cache_misses_for_testing());
  EXPECT_EQ(0, cache->cache_hits_for_testing());

  // First Advance() should NOT cause a cache purge, so we get a cache hit.
  clock->Advance(delta);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(1, cache->cache_misses_for_testing());
  EXPECT_EQ(1, cache->cache_hits_for_testing());

  // Second Advance() should cause a cache purge, so we get a cache miss.
  clock->Advance(delta);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_EQ(2, cache->cache_misses_for_testing());
  EXPECT_EQ(1, cache->cache_hits_for_testing());
}

// The lifetime of the GPO cache can be changed by the DeviceGpoCacheLifetime
// policy. It can also be turned off by that policy.
TEST_F(AuthPolicyTest, GpoCacheTTLCanBeSetByPolicy) {
  // Join domain.
  EXPECT_EQ(ERROR_NONE, Join(kOneGpoKeepVersionMachineName, kUserPrincipal,
                             MakePasswordFd()));
  MarkDeviceAsLocked();
  validate_device_policy_ = &DontValidateDevicePolicy;
  EXPECT_TRUE(samba().GetGpoVersionCacheForTesting()->IsEnabled());

  // Setting the policy to 0 should turn the cache off and set the TTL to 0.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendInteger(policy::key::kDeviceGpoCacheLifetime, kZeroHours);
  writer.WriteToFile(stub_gpo1_path_);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_FALSE(samba().GetGpoVersionCacheForTesting()->IsEnabled());
  EXPECT_EQ(base::Hours(kZeroHours), samba().GetGpoVersionCacheTTLForTesting());

  // Setting the policy to > 0 should turn the cache on again and set the TTL.
  // Note that this part would fail (policy wouldn't reload) if the cache was
  // still on, see below.
  policy::PRegUserDevicePolicyWriter writer2;
  writer2.AppendInteger(policy::key::kDeviceGpoCacheLifetime, kNonZeroHours);
  writer2.WriteToFile(stub_gpo1_path_);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_TRUE(samba().GetGpoVersionCacheForTesting()->IsEnabled());
  EXPECT_EQ(base::Hours(kNonZeroHours),
            samba().GetGpoVersionCacheTTLForTesting());

  // Fetch again to fill the cache.
  FetchAndValidateDevicePolicy(ERROR_NONE);

  // Rewriting the policy should be ignored now since a cached version is used.
  // (A rewrite in this test doesn't change the GPO version since we're using
  // kOneGpoKeepVersionMachineName).
  policy::PRegUserDevicePolicyWriter writer3;
  writer3.AppendInteger(policy::key::kDeviceGpoCacheLifetime, kZeroHours);
  writer3.WriteToFile(stub_gpo1_path_);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_TRUE(samba().GetGpoVersionCacheForTesting()->IsEnabled());
}

// Authpolicyd writes an auth data cache file on domain join and after auth.
TEST_F(AuthPolicyTest, AuthDataCacheWrittenOnJoinAndAuth) {
  base::FilePath cache_path(paths_->Get(Path::AUTH_DATA_CACHE));

  // Cache file should be written after domain join.
  EXPECT_FALSE(base::PathExists(cache_path));
  EXPECT_EQ(ERROR_NONE, Join(kMachineName, kUserPrincipal, MakePasswordFd()));
  EXPECT_TRUE(base::PathExists(cache_path));

  // Cache file should be written by user auth as well.
  EXPECT_TRUE(base::DeleteFile(cache_path));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));
  EXPECT_TRUE(base::PathExists(cache_path));

  // The file should NOT be written on failed auth (because at the point of
  // failure we don't know yet whether the realm is affiliated or not).
  EXPECT_TRUE(base::DeleteFile(cache_path));
  EXPECT_EQ(ERROR_PARSE_UPN_FAILED,
            Auth(kInvalidUserPrincipal, "", MakePasswordFd()));
  EXPECT_FALSE(base::PathExists(cache_path));
}

// Checks whether the auth data cache contains all the data that we'd expect.
TEST_F(AuthPolicyTest, AuthDataCacheContainsExpectedData) {
  // Join domain with machine domain != user domain.
  JoinDomainRequest request;
  request.set_machine_name(kMachineName);
  request.set_machine_domain(kMachineRealm);
  request.set_user_principal_name(kUserPrincipal);
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));

  // Load the cache and check values.
  AuthDataCache* cache = samba().GetAuthDataCacheForTesting();

  ASSERT_TRUE(cache->GetWorkgroup(kMachineRealm));
  ASSERT_TRUE(cache->GetKdcIp(kMachineRealm));
  ASSERT_TRUE(cache->GetDcName(kMachineRealm));
  ASSERT_TRUE(cache->GetIsAffiliated(kMachineRealm));

  EXPECT_EQ(kDefaultWorkgroup, *cache->GetWorkgroup(kMachineRealm));
  EXPECT_EQ(kDefaultKdcIp, *cache->GetKdcIp(kMachineRealm));
  EXPECT_EQ(kDefaultDcName, *cache->GetDcName(kMachineRealm));
  // The machine realm is always affiliated with itself!
  EXPECT_TRUE(*cache->GetIsAffiliated(kMachineRealm));

  EXPECT_FALSE(cache->GetWorkgroup(kUserRealm));
  EXPECT_FALSE(cache->GetKdcIp(kUserRealm));
  EXPECT_FALSE(cache->GetDcName(kUserRealm));
  EXPECT_FALSE(cache->GetIsAffiliated(kUserRealm));

  // Auth should fill the user realm data.
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));

  ASSERT_TRUE(cache->GetWorkgroup(kUserRealm));
  ASSERT_TRUE(cache->GetKdcIp(kUserRealm));
  ASSERT_TRUE(cache->GetDcName(kUserRealm));
  ASSERT_TRUE(cache->GetIsAffiliated(kUserRealm));

  EXPECT_EQ(kDefaultWorkgroup, *cache->GetWorkgroup(kUserRealm));
  EXPECT_EQ(kDefaultKdcIp, *cache->GetKdcIp(kUserRealm));
  EXPECT_EQ(kDefaultDcName, *cache->GetDcName(kUserRealm));
  EXPECT_TRUE(*cache->GetIsAffiliated(kUserRealm));
}

// Authpolicyd loads auth data cache on startup and uses the data for workgroup
// and KDC IP.
TEST_F(AuthPolicyTest, AuthDataCacheLoadsAndWorksForWorkgroupAndKdcIp) {
  // Join domain, so that a config file is written. Authpolicyd only loads a
  // auth data cache file if a config is expected.
  JoinDomainRequest request;
  request.set_machine_name(kMachineName);
  request.set_machine_domain(kMachineRealm);
  request.set_user_principal_name(kUserPrincipal);
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));
  MarkDeviceAsLocked();
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);

  // Create a cache file with stub workgroup and KDC IP data. Note that machine
  // KDC IP is not checked. The cached KDC IP is overwritten during the machine
  // password check, which happens immediately on startup. The check needs the
  // server time and the KDC IP is fetched along with it, immediately
  // overwriting the cached value.
  protos::DebugFlags flags;
  AuthDataCache cache(&flags);
  cache.SetWorkgroup(kUserRealm, kCacheTestUserWorkgroup);
  cache.SetKdcIp(kUserRealm, kCacheTestUserKdcIp);
  cache.SetWorkgroup(kMachineRealm, kCacheTestMachineWorkgroup);
  base::FilePath cache_path(paths_->Get(Path::AUTH_DATA_CACHE));
  EXPECT_TRUE(cache.Save(cache_path));

  // Restart authpolicyd. That should load the cache file.
  samba().ResetForTesting();
  EXPECT_EQ(ERROR_NONE, samba().Initialize(true /* expect_config */));
  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));

  // Check that the device smb.conf contains the workgroup from the cache.
  SmbConf device_smb_conf;
  ReadSmbConf(paths_->Get(Path::DEVICE_SMB_CONF), &device_smb_conf);
  EXPECT_EQ(kCacheTestMachineWorkgroup, device_smb_conf.workgroup);

  // Check that the user smb.conf contains the workgroup from the cache.
  SmbConf user_smb_conf;
  ReadSmbConf(paths_->Get(Path::USER_SMB_CONF), &user_smb_conf);
  EXPECT_EQ(kCacheTestUserWorkgroup, user_smb_conf.workgroup);

  // Check that the user krb5.conf contains the KDC IP from the cache.
  Krb5Conf user_krb5_conf;
  ReadKrb5Conf(paths_->Get(Path::USER_KRB5_CONF), &user_krb5_conf);
  EXPECT_EQ(EmbraceIp(kCacheTestUserKdcIp), user_krb5_conf.kdc);
}

// Authpolicyd loads auth data cache on startup and uses the data for DC name.
TEST_F(AuthPolicyTest, AuthDataCacheWorksForDcName) {
  // Join domain, so that a config file is written. Authpolicyd only loads a
  // auth data cache file if a config is expected.
  // Note that |kOneGpoMachineName| is used here. This makes sure that
  // stub_smbclient is called with the DC name in the URL of the GPO to
  // download. Since stub_smbclient doesn't accept the DC name we set here
  // (|kCacheTest*DcName|, see |kHostAndShare|), it should respond  with a
  // failed connection error and we should see ERROR_SMBCLIENT_FAILED as a
  // result. There's no other artifact of DC name that could be tested.
  JoinDomainRequest request;
  request.set_machine_name(kOneGpoMachineName);
  request.set_machine_domain(kMachineRealm);
  request.set_user_principal_name(kUserPrincipal);
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));
  MarkDeviceAsLocked();
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);

  // Create a cache file with stub DC name.
  protos::DebugFlags flags;
  AuthDataCache cache(&flags);
  cache.SetDcName(kUserRealm, kCacheTestUserDcName);
  cache.SetDcName(kMachineRealm, kCacheTestMachineDcName);
  base::FilePath cache_path(paths_->Get(Path::AUTH_DATA_CACHE));
  EXPECT_TRUE(cache.Save(cache_path));

  // Restart authpolicyd, so that the cache file gets loaded.
  samba().ResetForTesting();
  EXPECT_EQ(ERROR_NONE, samba().Initialize(true /* expect_config */));

  // Since stub_smbclient doesn't accept the DC names from the cache, we should
  // get an error here (best we can do to verify cached DC name was used).
  FetchAndValidateDevicePolicy(ERROR_SMBCLIENT_FAILED);
  FetchAndValidateUserPolicy(DefaultAuth(), ERROR_SMBCLIENT_FAILED);
}

// Authpolicyd loads auth data cache on startup and uses the data for DC name.
TEST_F(AuthPolicyTest, AuthDataCacheDiesForUnaffiliatedUsers) {
  JoinAndFetchDevicePolicy(kMachineName);

  // Set affiliation flag to false for the user realm. Note that this shouldn't
  // be possible, authpolicy shouldn't cache any data for unaffiliated realms.
  // See AuthDataCacheTurnedOffForUnaffiliatedUsers.
  samba().GetAuthDataCacheForTesting()->SetIsAffiliated(kUserRealm, false);

  // SambaInterface::IsUserAffiliated() should bail on Auth() because data for
  // an unaffiliated realm is cached.
  EXPECT_DEATH((void)Auth(kUserPrincipal, "", MakePasswordFd()),
               "Caching for unaffiliated realms not supported");
}

// Authpolicyd loads auth data cache on startup and uses the data for DC name.
TEST_F(AuthPolicyTest, AuthDataCacheTurnedOffForUnaffiliatedUsers) {
  // |kUnaffiliatedMachineName| causes the user realm to be unaffiliated.
  JoinDomainRequest request;
  request.set_machine_name(kUnaffiliatedMachineName);
  request.set_machine_domain(kMachineRealm);
  request.set_user_principal_name(kUserPrincipal);
  EXPECT_EQ(ERROR_NONE, JoinEx(request, MakePasswordFd()));
  MarkDeviceAsLocked();
  validate_device_policy_ = &CheckDevicePolicyEmpty;
  FetchAndValidateDevicePolicy(ERROR_NONE);

  EXPECT_EQ(ERROR_NONE, Auth(kUserPrincipal, "", MakePasswordFd()));

  // The cache should still exist from domain join, but it shouldn't contain the
  // user realm.
  AuthDataCache* cache = samba().GetAuthDataCacheForTesting();
  EXPECT_FALSE(cache->GetWorkgroup(kUserRealm));
  EXPECT_FALSE(cache->GetKdcIp(kUserRealm));
  EXPECT_FALSE(cache->GetDcName(kUserRealm));
  EXPECT_FALSE(cache->GetIsAffiliated(kUserRealm));
}

// The auth data cache cache is purged occasionally.
TEST_F(AuthPolicyTest, PurgesAuthDataCacheOccasionally) {
  // Set a testing clock to stub out cache TTL.
  auto clock_ptr = std::make_unique<base::SimpleTestClock>();
  base::SimpleTestClock* clock = clock_ptr.get();
  samba().GetAuthDataCacheForTesting()->SetClockForTesting(
      std::move(clock_ptr));

  JoinAndFetchDevicePolicy(kMachineName);

  // Save a cache file that contains a different workgroup.
  protos::DebugFlags flags;
  AuthDataCache cache(&flags);
  cache.SetClockForTesting(std::make_unique<base::SimpleTestClock>());
  cache.SetWorkgroup(kUserRealm, kCacheTestUserWorkgroup);
  base::FilePath cache_path(paths_->Get(Path::AUTH_DATA_CACHE));
  EXPECT_TRUE(cache.Save(cache_path));

  // Restart authpolicy to make sure that the cached workgroup is used.
  samba().ResetForTesting();
  EXPECT_EQ(ERROR_NONE, samba().Initialize(true /* expect_config */));
  DefaultAuth();
  SmbConf user_smb_conf;
  ReadSmbConf(paths_->Get(Path::USER_SMB_CONF), &user_smb_conf);
  EXPECT_EQ(kCacheTestUserWorkgroup, user_smb_conf.workgroup);

  // Restart authpolicy again and call auth, but this time advance the clock
  // enough to clear the cache, so that the default workgroup is used.
  samba().ResetForTesting();
  EXPECT_EQ(ERROR_NONE, samba().Initialize(true /* expect_config */));
  clock->Advance(samba().GetAuthDataCacheTTLForTesting() * 2);
  DefaultAuth();
  ReadSmbConf(paths_->Get(Path::USER_SMB_CONF), &user_smb_conf);
  EXPECT_EQ(kDefaultWorkgroup, user_smb_conf.workgroup);
}

// The lifetime of the auth data cache can be changed by the
// DeviceAuthDataCacheLifetime policy. It can also be turned off by that policy.
TEST_F(AuthPolicyTest, AuthDataCacheTTLCanBeSetByPolicy) {
  base::FilePath cache_path(paths_->Get(Path::AUTH_DATA_CACHE));

  // Join domain.
  EXPECT_EQ(ERROR_NONE,
            Join(kOneGpoMachineName, kUserPrincipal, MakePasswordFd()));
  MarkDeviceAsLocked();
  validate_device_policy_ = &DontValidateDevicePolicy;
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_TRUE(base::PathExists(cache_path));

  // Setting the policy to 0 should turn the cache off, clear the file and set
  // the TTL to 0.
  policy::PRegUserDevicePolicyWriter writer;
  writer.AppendInteger(policy::key::kDeviceAuthDataCacheLifetime, kZeroHours);
  writer.WriteToFile(stub_gpo1_path_);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_FALSE(samba().GetAuthDataCacheForTesting()->IsEnabled());
  EXPECT_EQ(base::Hours(kZeroHours), samba().GetAuthDataCacheTTLForTesting());
  EXPECT_FALSE(base::PathExists(cache_path));

  // Setting the policy to > 0 should turn the cache on again and set the TTL.
  policy::PRegUserDevicePolicyWriter writer2;
  writer2.AppendInteger(policy::key::kDeviceAuthDataCacheLifetime,
                        kNonZeroHours);
  writer2.WriteToFile(stub_gpo1_path_);
  FetchAndValidateDevicePolicy(ERROR_NONE);
  EXPECT_TRUE(samba().GetAuthDataCacheForTesting()->IsEnabled());
  EXPECT_EQ(base::Hours(kNonZeroHours),
            samba().GetAuthDataCacheTTLForTesting());
  EXPECT_FALSE(base::PathExists(cache_path));
}

}  // namespace authpolicy
