// 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.

// Stub implementation of Samba net. Does not talk to server, but simply returns
// fixed responses to predefined input.

#include <inttypes.h>
#include <string>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <base/strings/strcat.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include "authpolicy/constants.h"
#include "authpolicy/platform_helper.h"
#include "authpolicy/samba_helper.h"
#include "authpolicy/stub_common.h"

namespace authpolicy {
namespace {

const char kSmbConfDevice[] = "smb_device.conf";
const char kSmbConfUser[] = "smb_user.conf";
const char kMachinePass[] = "machine_pass";
const char kStateDir[] = "state";
const char kSambaDir[] = "samba";
const char kKrb5CCUser[] = "krb5cc_user";

// Prefix for the fake domain sid marker file "fake_domain_sid_<workgroup>".
const char kFakeDomainSidMarkerPrefix[] = "fake_domain_sid_";

// Various stub error messages.
const char kSmbConfArgMissingError[] =
    "Can't load /etc/samba/smb.conf - run testparm to debug it";
const char kNetworkError[] = "No logon servers";
const char kWrongPasswordError[] =
    "Failed to join domain: failed to lookup DC info for domain "
    "'REALM.EXAMPLE.COM' over rpc: Logon failure";
const char kExpiredPasswordError[] =
    "Enter user@REALM.EXAMPLE.COM's password:\n"
    "Failed to join domain: failed to lookup DC info for domain "
    "'REALM.EXAMPLE.COM' over rpc: Must change password";
const char kJoinAccessDeniedError[] =
    "Failed to join domain: Failed to set account flags for machine account "
    "(NT_STATUS_ACCESS_DENIED)";
const char kMachineNameTooLongError[] =
    "Our netbios name can be at most %zd chars long, \"%s\" is %zd chars long\n"
    "Failed to join domain: The format of the specified computer name is "
    "invalid.";
const char kInvalidMachineNameError[] =
    "Failed to join domain: failed to join domain 'REALM.EXAMPLE.COM' over "
    "rpc: Improperly formed account name";
const char kInsufficientQuotaError[] =
    "Insufficient quota exists to complete the operation";
const char kEncTypeNotSupportedError[] =
    "Failed to join domain: failed to connect to AD: KDC has no support for "
    "encryption type";

// Size limit for machine name.
const size_t kMaxMachineNameSize = 15;

// Stub net ads info response.
const char kStubInfo[] = R"!!!(LDAP server: 111.222.33.1
LDAP server name: LDAPNAME.example.com
Realm: REALM.EXAMPLE.COM
Bind Path: dc=REALM,dc=EXAMPLE,dc=COM
LDAP port: 389
Server time: %s
KDC server: 111.222.33.2
Server time offset: -91
Last machine account password change:
Wed, 31 Dec 1969 16:00:00 PST)!!!";

constexpr char kDefaultServerTime[] = "Fri, 03 Feb 2017 05:24:05 PST";

// Stub net ads info response.
const char kStubLookup[] = R"!!!(Information for Domain Controller: 111.222.33.3
Response Type: LOGON_SAM_LOGON_RESPONSE_EX
GUID: fca78f31-bf15-4ca3-b730-fbe619e937b2
Flags:
    Is a PDC:                                   yes
    Is a GC of the forest:                      yes
    Is an LDAP server:                          yes
    Supports DS:                                yes
    Is running a KDC:                           yes
    Is running time services:                   yes
    Is the closest DC:                          no
    Is writable:                                yes
    Has a hardware clock:                       yes
    Is a non-domain NC serviced by LDAP server: no
    Is NT6 DC that has some secrets:            no
    Is NT6 DC that has all secrets:             yes
    Runs Active Directory Web Services:         yes
    Runs on Windows 2012 or later:              yes
Forest:             FOREST.EXAMPLE.COM
Domain:             REALM.EXAMPLE.COM
Domain Controller:  DCNAME.EXAMPLE.COM
Pre-Win2k Domain:   REALM
Pre-Win2k Hostname: DCNAME
Server Site Name :  SITE
Client Site Name :  SITE
NT Version: 5
LMNT Token: ffff
LM20 Token: ffff)!!!";

// Stub net ads gpo list response.
const char kStubLocalGpo[] = R"!!!(---------------------
name:   Local Policy
displayname:  Local Policy
version:  0 (0x00000000)
version_user:  0 (0x0000)
version_machine: 0 (0x0000)
filesyspath:  (null)
dspath:  (null)
options:  0 GPFLAGS_ALL_ENABLED
link:   (null)
link_type:  5 machine_extensions: (null)
user_extensions: (null)
)!!!";

const char kStubRemoteGpo[] = R"!!!(---------------------
name:   %s
displayname:  test-user-policy
version:  %u (0x%04x%04x)
version_user:  %u (0x%04x)
version_machine: %u (0x%04x)
filesyspath:  \\realm.example.com\SysVol\realm.example.com\Policies\%s
dspath:  cn=%s,cn=policies,cn=system,DC=realm,DC=example,DC=com
options:  %s
link:   OU=test-ou,DC=realm,DC=example,DC=com
link_type:  4 GP_LINK_OU
machine_extensions: (null)
user_extensions: [{D02B1F73-3407-48AE-BA88-E8213C6761F1}]
)!!!";

// Stub net ads search response.
const char kStubSearchFormat[] = R"!!!(Got 1 replies
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: %s
sn: Doe
givenName: %s
initials: JD
distinguishedName: CN=%s,OU=test-ou,DC=realm,DC=example,DC=com
instanceType: 4
whenCreated: 20161018155136.0Z
whenChanged: 20170217134227.0Z
displayName: %s
uSNCreated: 287406
uSNChanged: 307152
name: John Doe
objectGUID: %s
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 131309487458845506
lastLogoff: 0
lastLogon: 131320568639495686
primaryGroupID: 513
objectSid: S-1-5-21-250062649-3667841115-373469193-1134
accountExpires: 9223372036854775807
logonCount: 1453
sAMAccountName: %s
sAMAccountType: 805306368
userPrincipalName: jdoe@realm.example.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=realm,DC=example,DC=com
dSCorePropagationData: 20161024075536.0Z
dSCorePropagationData: 20161024075311.0Z
dSCorePropagationData: 20161019075502.0Z
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 131318125471489990
msDS-SupportedEncryptionTypes: 0)!!!";

// Password related fields in search response.
const char kStubSearchPwdFormat[] = R"!!!(
pwdLastSet: %)!!!" PRIu64 R"!!!(
userAccountControl: %)!!!" PRIu32;

// Search that doesn't find anything.
const char kStubBadSearch[] = "Got 0 replies";

// Builder for custom search results (without having a 7-line base::StringPrintf
// every time). Usage:
//   search_result = SearchBuilder().SetDisplayName("John Doe").GetResult();
class SearchBuilder {
 public:
  // Prints out a stub net ads search result with the set parameters.
  std::string GetResult() {
    std::string result = base::StringPrintf(
        kStubSearchFormat, common_name_.c_str(), given_name_.c_str(),
        common_name_.c_str(), display_name_.c_str(), object_guid_.c_str(),
        sam_account_name_.c_str());

    if (output_pwd_fields) {
      result += base::StringPrintf(kStubSearchPwdFormat, pwd_last_set_,
                                   user_account_control_);
    }

    return result;
  }

  // Sets the value of the givenName key.
  SearchBuilder& SetGivenName(const std::string& value) {
    given_name_ = value;
    return *this;
  }

  // Sets the value of the displayName key.
  SearchBuilder& SetDisplayName(const std::string& value) {
    display_name_ = value;
    return *this;
  }

  // Sets the value of the objectUID key.
  SearchBuilder& SetObjectGuid(const std::string& value) {
    object_guid_ = value;
    return *this;
  }

  // Sets the value of the sAMAccountName key.
  SearchBuilder& SetSAMAccountName(const std::string& value) {
    sam_account_name_ = value;
    return *this;
  }

  // Sets the value of the common name key.
  SearchBuilder& SetCommonName(const std::string& value) {
    common_name_ = value;
    return *this;
  }

  // Sets the value of the userAccountControl key.
  SearchBuilder& SetUserAccountControl(const uint32_t value) {
    user_account_control_ = value;
    return *this;
  }

  // Sets the value of the pwdLastSet key.
  SearchBuilder& SetPwdLastSet(const uint64_t value) {
    pwd_last_set_ = value;
    return *this;
  }

  // Prevents output of pwdLastSet and userAccountControl fields.
  SearchBuilder& NoPwdFields() {
    output_pwd_fields = false;
    return *this;
  }

 private:
  std::string given_name_ = kGivenName;
  std::string display_name_ = kDisplayName;
  std::string object_guid_ = kAccountId;
  std::string sam_account_name_ = kUserName;
  std::string common_name_ = kCommonName;
  uint32_t user_account_control_ = kUserAccountControl;
  uint64_t pwd_last_set_ = kPwdLastSet;
  bool output_pwd_fields = true;
};

// Searches |str| for (|searchKey|=value) and returns value. Returns an empty
// string if the key could not be found or if the value is empty.
std::string FindSearchValue(const std::string& str, const char* search_key) {
  const std::string full_key = base::StringPrintf("(%s=", search_key);
  size_t idx1 = str.find(full_key);
  if (idx1 == std::string::npos)
    return "";
  const size_t idx2 = str.find(")", idx1 + full_key.size());
  if (idx2 == std::string::npos)
    return "";
  idx1 += full_key.size();
  return str.substr(idx1, idx2 - idx1);
}

// Prints custom stub net ads gpo list output corresponding to one remote GPO
// with the given properties. For |gpflags| see kGpFlag*.
std::string PrintGpo(const char* guid,
                     uint32_t version_user,
                     uint32_t version_machine,
                     int gpflags) {
  DCHECK(gpflags >= 0 && gpflags < kGpFlagCount);
  return base::StringPrintf(
      kStubRemoteGpo, guid, (version_user << 16) | version_machine,
      version_user, version_machine, version_user, version_user,
      version_machine, version_machine, guid, guid, kGpFlagsStr[gpflags]);
}

// Reads the machine and user passwords from stdin.
// Expected format is:machine_pass + "\n" + user_pass.
bool GetNetAdsJoinPasswords(std::string* user_password,
                            std::string* machine_password) {
  std::string passwords_str;
  if (!ReadPipeToString(STDIN_FILENO, &passwords_str))
    return false;
  std::vector<std::string> passwords = base::SplitString(
      passwords_str, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  if (passwords.size() != 2)
    return false;
  *machine_password = std::move(passwords[0]);
  *user_password = std::move(passwords[1]);
  return true;
}

// Reads the contents of the (stub) user Kerberos credentials cache. Returns an
// empty string if the file does not exist.
std::string GetUserKrb5CCData(const std::string& smb_conf_path) {
  // Note: Can't use GetKrb5CCFilePath() here since the env var is not defined,
  // so figure it out from |smb_conf_path|.
  // smb.conf is at <basepath>/temp/smb_*.conf.
  // krb5cc   is at <basepath>/temp/samba/krb5cc_user.
  const base::FilePath krb5cc_path = base::FilePath(smb_conf_path)
                                         .DirName()
                                         .Append(kSambaDir)
                                         .Append(kKrb5CCUser);
  std::string krb5cc_data;
  if (!base::PathExists(krb5cc_path))
    return std::string();
  CHECK(base::ReadFileToString(krb5cc_path, &krb5cc_data));
  return krb5cc_data;
}

// Reads the smb.conf file at |smb_conf_path| and extracts the string value
// associated with given |setting|.
std::string GetStringValueFromSmbConf(const std::string& smb_conf_path,
                                      const std::string& setting) {
  std::string smb_conf;
  CHECK(base::ReadFileToString(base::FilePath(smb_conf_path), &smb_conf));
  std::string value;
  CHECK(FindToken(smb_conf, '=', setting, &value));
  return value;
}

// Reads the smb.conf file at |smb_conf_path| and extracts the netbios name.
std::string GetMachineNameFromSmbConf(const std::string& smb_conf_path) {
  // We need the device smb.conf here, the user smb.conf doesn't contain the
  // netbios name.
  std::string device_smb_conf_path = smb_conf_path;
  base::ReplaceFirstSubstringAfterOffset(&device_smb_conf_path, 0, kSmbConfUser,
                                         kSmbConfDevice);
  return GetStringValueFromSmbConf(device_smb_conf_path, "netbios name");
}

// Returns different stub net ads search results depending on |object_guid|.
std::string GetSearchResultFromObjectGUID(const std::string& object_guid) {
  SearchBuilder search_builder;
  search_builder.SetObjectGuid(object_guid);

  // Valid account id, return valid search result for the default user.
  if (object_guid == kAccountId)
    return search_builder.GetResult();

  // Invalid account id, return bad "nothing found" search result.
  if (object_guid == kBadAccountId)
    return kStubBadSearch;

  // Pretend that the password expired.
  if (object_guid == kExpiredPasswordAccountId)
    return search_builder.SetPwdLastSet(0).GetResult();

  // Pretend that the password never expires.
  if (object_guid == kNeverExpirePasswordAccountId) {
    return search_builder.SetPwdLastSet(0)
        .SetUserAccountControl(UF_DONT_EXPIRE_PASSWD)
        .GetResult();
  }

  // Pretend that the password changed on the server.
  if (object_guid == kPasswordChangedAccountId)
    return search_builder.SetPwdLastSet(kPwdLastSet + 1).GetResult();

  // Pretend missing pwdLastSet and userAccountControl fields.
  if (object_guid == kNoPwdFieldsAccountId)
    return search_builder.NoPwdFields().GetResult();

  NOTREACHED() << "UNHANDLED OBJECT GUID " << object_guid;
  return std::string();
}

// Returns different stub net ads search results depending on
// |sam_account_name|.
std::string GetSearchResultFromSAMAccountName(
    const std::string& sam_account_name) {
  SearchBuilder search_builder;
  search_builder.SetSAMAccountName(sam_account_name);

  // Set special account ids, required during auth for tests that use the ids in
  // GetUserStatus().
  if (sam_account_name == kPasswordChangedUserName)
    return search_builder.SetObjectGuid(kPasswordChangedAccountId).GetResult();
  if (sam_account_name == kNoPwdFieldsUserName) {
    return search_builder.SetObjectGuid(kNoPwdFieldsAccountId)
        .NoPwdFields()
        .GetResult();
  }

  // In all cases, just return a search result with the proper sAMAccountName.
  return search_builder.GetResult();
}

// Formats time according to "Fri, 03 Feb 2017 05:24:05 UTC".
std::string FormatServerTime(const base::Time& time) {
  time_t utime = time.ToTimeT();
  struct tm tm;
  gmtime_r(&utime, &tm);
  char str[64];
  CHECK(strftime(str, sizeof(str), "%a, %d %b %Y %H:%M:%S UTC", &tm));
  return std::string(str);
}

// Returns the path of a marker file to check whether "net setdomainsid" has
// been called for a given workgroup stored in a config file at |smb_conf_path|.
base::FilePath GetDomainSidMarkerPath(const std::string& smb_conf_path) {
  return base::FilePath(smb_conf_path)
      .DirName()
      .Append(kFakeDomainSidMarkerPrefix +
              GetStringValueFromSmbConf(smb_conf_path, "workgroup"));
}

// Fakes setting a "net setdomainsid" call by writing a marker file.
void SetFakeDomainSid(const std::string& smb_conf_path) {
  char c = 0;
  CHECK_EQ(base::WriteFile(GetDomainSidMarkerPath(smb_conf_path), &c, 1), 1);
}

// Checks whether "net setdomainsid" has been called before by checking the
// marker file.
bool IsFakeDomainSidSet(const std::string& smb_conf_path) {
  return base::PathExists(GetDomainSidMarkerPath(smb_conf_path));
}

// Handles a stub 'net ads workgroup' call. Different behavior is triggered by
// passing different machine names (in smb.conf) and user credential caches.
int HandleWorkgroup(const std::string& smb_conf_path) {
  // Read machine name from smb.conf.
  const std::string machine_name = GetMachineNameFromSmbConf(smb_conf_path);

  // Stub server ping error when the TGT is expired (to get certain behavior in
  // GetUserStatus()). Note that SambaInterface::PingServer currently calls net
  // ads workgroup to check if the server is available.
  if (machine_name == base::ToUpperASCII(kPingServerFailMachineName) &&
      GetUserKrb5CCData(smb_conf_path) == kExpiredKrb5CCData) {
    WriteOutput("", kNetworkError);
    return kExitCodeError;
  }

  // Select workgroup based on realm.
  std::string workgroup = (GetStringValueFromSmbConf(smb_conf_path, "realm") ==
                           kSecondaryWorkgroupRealm)
                              ? kSecondaryWorkgroup
                              : kDefaultWorkgroup;

  WriteOutput(base::StrCat({"Workgroup: ", workgroup}), "");
  return kExitCodeOk;
}

// Handles a stub 'net ads join' call. Different behavior is triggered by
// passing different user principals, passwords and machine names (in smb.conf).
int HandleJoin(const std::string& command_line,
               const std::string& smb_conf_path) {
  // Read the passwords from stdin (should be machine_pass + "\n" + user_pass).
  std::string user_password, machine_password;
  if (!GetNetAdsJoinPasswords(&user_password, &machine_password)) {
    LOG(ERROR) << "Failed to read passwords";
    return kExitCodeError;
  }
  CheckMachinePassword(machine_password);

  const std::string kUserFlag(std::string(kUserParam) + " ");

  // Read machine name from smb.conf.
  const std::string machine_name = GetMachineNameFromSmbConf(smb_conf_path);

  // Stub too long machine name error.
  if (machine_name.size() > kMaxMachineNameSize) {
    WriteOutput(
        base::StringPrintf(kMachineNameTooLongError, kMaxMachineNameSize,
                           machine_name.c_str(), machine_name.size()),
        "");
    return kExitCodeError;
  }

  // Stub bad machine name error.
  if (machine_name == base::ToUpperASCII(kInvalidMachineName)) {
    WriteOutput(kInvalidMachineNameError, "");
    return kExitCodeError;
  }

  // Stub seccomp failure.
  if (machine_name == base::ToUpperASCII(kSeccompMachineName)) {
    TriggerSeccompFailure();
    return kExitCodeOk;
  }

  // Stub insufficient quota error.
  if (Contains(command_line, kUserFlag + kInsufficientQuotaUserPrincipal)) {
    WriteOutput(kInsufficientQuotaError, "");
    return kExitCodeError;
  }

  // Stub non-existing account error (same error as 'wrong password' error).
  if (Contains(command_line, kUserFlag + kNonExistingUserPrincipal)) {
    WriteOutput(kWrongPasswordError, "");
    return kExitCodeError;
  }

  // Stub network error.
  if (Contains(command_line, kUserFlag + kNetworkErrorUserPrincipal)) {
    WriteOutput("", kNetworkError);
    return kExitCodeError;
  }

  // Stub access denied error.
  if (Contains(command_line, kUserFlag + kAccessDeniedUserPrincipal)) {
    WriteOutput(kJoinAccessDeniedError, "");
    return kExitCodeError;
  }

  // Stub encryption type not supported error.
  if (Contains(command_line, kUserFlag + kEncTypeNotSupportedUserPrincipal)) {
    WriteOutput(kEncTypeNotSupportedError, "");
    return kExitCodeError;
  }

  // Check whether createcomputer argument matches the expected one.
  if (Contains(command_line, kUserFlag + kExpectOuUserPrincipal)) {
    CHECK(Contains(command_line, std::string(kCreatecomputerParam) +
                                     kExpectedOuCreatecomputer))
        << "Bad createcomputer arg in command line " << command_line
        << ". Expected: " << kExpectedOuCreatecomputer;
    return kExitCodeOk;
  }

  // Stub valid user principal. Switch behavior based on password.
  if (Contains(command_line, kUserFlag + kUserPrincipal)) {
    // Stub wrong password.
    if (user_password == kWrongPassword) {
      WriteOutput(kWrongPasswordError, "");
      return kExitCodeError;
    }
    // Stub expired password.
    if (user_password == kExpiredPassword) {
      WriteOutput(kExpiredPasswordError, "");
      return kExitCodeError;
    }
    // Stub valid password.
    if (user_password == kPassword)
      return kExitCodeOk;

    NOTREACHED() << "UNHANDLED PASSWORD " << user_password;
    return kExitCodeError;
  }

  NOTREACHED() << "UNHANDLED COMMAND LINE " << command_line;
  return kExitCodeError;
}

// Handles a stub 'net ads info' call. Just returns stub information.
int HandleInfo(const std::string& smb_conf_path) {
  // Read machine name from smb.conf.
  const std::string machine_name = GetMachineNameFromSmbConf(smb_conf_path);

  if (machine_name == base::ToUpperASCII(kChangePasswordMachineName)) {
    // Figure out the machine pass last modified time.
    // smb.conf is at <basepath>/temp/smb_*.conf, the
    // password is at <basepath>/state/machine_pass.
    const base::FilePath password_path = base::FilePath(smb_conf_path)
                                             .DirName()
                                             .DirName()
                                             .Append(kStateDir)
                                             .Append(kMachinePass);
    base::File::Info file_info;
    if (GetFileInfo(password_path, &file_info)) {
      const base::Time password_time = file_info.last_modified;
      const base::Time server_time = password_time +
                                     kDefaultMachinePasswordChangeRate +
                                     base::TimeDelta::FromDays(1);
      const std::string server_time_str = FormatServerTime(server_time);
      WriteOutput(base::StringPrintf(kStubInfo, server_time_str.c_str()), "");
      return kExitCodeOk;
    }
  }

  WriteOutput(base::StringPrintf(kStubInfo, kDefaultServerTime), "");
  return kExitCodeOk;
}

// Handles a stub 'net ads lookup' call. Just returns stub information.
int HandleLookup() {
  WriteOutput(kStubLookup, "");
  return kExitCodeOk;
}

// Handles a stub 'net ads gpo list' call. Different behavior is triggered by
// passing different machine names (in smb.conf).
int HandleGpoList(const std::string& smb_conf_path) {
  // Read machine name from smb.conf.
  const std::string machine_name = GetMachineNameFromSmbConf(smb_conf_path);

  // Stub empty GPO list.
  if (machine_name == base::ToUpperASCII(kEmptyGpoMachineName))
    return kExitCodeOk;

  // Samba 4.10.7 requires a domain sid for this command.
  if (!IsFakeDomainSidSet(smb_conf_path))
    return kExitCodeError;

  // All other GPO lists use the local GPO.
  std::string gpos = kStubLocalGpo;

  // Increase the version by default, so that GPOs will always reload properly
  // (prevents nasty surprises in tests). The version is only frozen for GPO
  // cache tests.
  const auto test_dir = base::FilePath(smb_conf_path).DirName();
  const int version = 1 + PostIncTestCounter(test_dir);

  if (machine_name == base::ToUpperASCII(kGpoDownloadErrorMachineName)) {
    // Stub GPO list that triggers a download error in smbclient.
    gpos += PrintGpo(kErrorGpoGuid, version, version, kGpFlagAllEnabled);
  } else if (machine_name == base::ToUpperASCII(kSeccompMachineName)) {
    // Stub GPO list that triggers a seccomp failure in smbclient.
    gpos += PrintGpo(kSeccompGpoGuid, version, version, kGpFlagAllEnabled);
  } else if (machine_name == base::ToUpperASCII(kOneGpoMachineName)) {
    // Stub GPO list that downloads one GPO if present.
    gpos += PrintGpo(kGpo1Guid, version, version, kGpFlagAllEnabled);
  } else if (machine_name == base::ToUpperASCII(kTwoGposMachineName)) {
    // Stub GPO list that downloads two GPOs if present.
    gpos += PrintGpo(kGpo1Guid, version, version, kGpFlagAllEnabled);
    gpos += PrintGpo(kGpo2Guid, version, version, kGpFlagAllEnabled);
  } else if (machine_name ==
             base::ToUpperASCII(kOneGpoKeepVersionMachineName)) {
    // Stub GPO list with two GPOs and frozen version.
    gpos += PrintGpo(kGpo1Guid, 1, 1, kGpFlagAllEnabled);
  } else if (machine_name ==
             base::ToUpperASCII(kTwoGposKeepVersionMachineName)) {
    // Stub GPO list with two GPOs and freezing the version of the second.
    gpos += PrintGpo(kGpo1Guid, version, version, kGpFlagAllEnabled);
    gpos += PrintGpo(kGpo2Guid, 1, 1, kGpFlagAllEnabled);
  } else if (machine_name == base::ToUpperASCII(kZeroUserVersionMachineName)) {
    // Stub GPO list that contains a GPO with version_user == 0 (should be
    // ignored during user policy fetch).
    gpos += PrintGpo(kGpo1Guid, 0, version, kGpFlagAllEnabled);
  } else if (machine_name == base::ToUpperASCII(kDisableUserFlagMachineName)) {
    // Stub GPO list that contains a GPO with kGpFlagUserDisabled set (should be
    // ignored during user policy fetch).
    gpos += PrintGpo(kGpo1Guid, version, version, kGpFlagUserDisabled);
  } else if (machine_name == base::ToUpperASCII(kLoopbackGpoMachineName)) {
    // Stub GPO list that contains
    //   - GPO1 when querying GPOs for the user account and
    //   - GPO2 when querying GPOs for the device account.
    bool requesting_user_gpos = Contains(smb_conf_path, kSmbConfUser);
    const char* gpo_guid = requesting_user_gpos ? kGpo1Guid : kGpo2Guid;
    gpos += PrintGpo(gpo_guid, version, version, kGpFlagAllEnabled);
  }

  WriteOutput(smb_conf_path, gpos);
  return kExitCodeOk;
}

// Handles a stub 'net ads search' call. Different behavior is triggered by
// passing different sAMAccountNames or objectGUIDs as search term.
int HandleSearch(const std::string& command_line) {
  std::string sam_account_name =
      FindSearchValue(command_line, kSearchSAMAccountName);
  std::string object_guid_octet =
      FindSearchValue(command_line, kSearchObjectGUID);

  // Handle the net ads search command to detect unaffiliated users.
  if (sam_account_name == base::ToUpperASCII(kUnaffiliatedMachineName) + "$")
    return kExitCodeUnspecifiedError;

  std::string search_result;
  if (!object_guid_octet.empty()) {
    // Search by objectGUID aka account id.
    std::string object_guid = OctetStringToGuidForTesting(object_guid_octet);
    search_result = GetSearchResultFromObjectGUID(object_guid);
  } else if (!sam_account_name.empty()) {
    // Search by sAMAccountName.
    search_result = GetSearchResultFromSAMAccountName(sam_account_name);
  } else {
    LOG(ERROR) << "SEARCH TERM NOT RECOGNIZED IN COMMAND LINE " << command_line;
  }

  WriteOutput(search_result, "");
  return kExitCodeOk;
}

// Handles a stub 'net setdomainsid' call. Writes out a marker file to indicate
// that the domain sid has been set. This is checked in 'net ads gpo list'. This
// fakes the behavior of Samba 4.10.7, which requires the domain sid to be set
// for that command.
int HandleSetDomainSid(const std::string& smb_conf_path) {
  // net setdomainsid should be called at most once for the same workgroup.
  if (IsFakeDomainSidSet(smb_conf_path))
    return kExitCodeError;
  SetFakeDomainSid(smb_conf_path);
  return kExitCodeOk;
}

int HandleCommandLine(const std::string& command_line,
                      const std::string& smb_conf_path) {
  // Make sure the caller adds the debug level.
  CHECK(Contains(command_line, kDebugParam));

  // Stub net ads workgroup.
  if (StartsWithCaseSensitive(command_line, "ads workgroup"))
    return HandleWorkgroup(smb_conf_path);

  // Stub net ads join.
  if (StartsWithCaseSensitive(command_line, "ads join"))
    return HandleJoin(command_line, smb_conf_path);

  // Stub net ads info.
  if (StartsWithCaseSensitive(command_line, "ads info"))
    return HandleInfo(smb_conf_path);

  // Stub net ads lookup.
  if (StartsWithCaseSensitive(command_line, "ads lookup"))
    return HandleLookup();

  // Stub net ads gpo list.
  if (StartsWithCaseSensitive(command_line, "ads gpo list"))
    return HandleGpoList(smb_conf_path);

  // Stub net ads search.
  if (StartsWithCaseSensitive(command_line, "ads search"))
    return HandleSearch(command_line);

  // Stub net setdomainsid.
  if (StartsWithCaseSensitive(command_line, "setdomainsid"))
    return HandleSetDomainSid(smb_conf_path);

  NOTREACHED() << "UNHANDLED COMMAND LINE " << command_line;
  return kExitCodeError;
}

}  // namespace
}  // namespace authpolicy

int main(int argc, char* argv[]) {
  // Find Samba configuration path ("-s" argument).
  const std::string smb_conf_path =
      authpolicy::GetArgValue(argc, argv, authpolicy::kConfigParam);
  if (smb_conf_path.empty()) {
    authpolicy::WriteOutput("", authpolicy::kSmbConfArgMissingError);
    return authpolicy::kExitCodeError;
  }

  const std::string command_line = authpolicy::GetCommandLine(argc, argv);
  return authpolicy::HandleCommandLine(command_line, smb_conf_path);
}
