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

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.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";

// 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: %lu
userAccountControl: %u)!!!";

// 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 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);
  std::string smb_conf;
  CHECK(
      base::ReadFileToString(base::FilePath(device_smb_conf_path), &smb_conf));
  std::string machine_name;
  CHECK(FindToken(smb_conf, '=', "netbios name", &machine_name));
  return machine_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);
}

// 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;
  }

  WriteOutput("Workgroup: WOKGROUP", "");
  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;

  // 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;
}

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);

  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);
}
