// 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/files/scoped_file.h>
#include <base/logging.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 kStubKeytab[] = "Stub keytab file";

// 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.COM' "
    "over rpc: Logon failure";
const char kExpiredPasswordError[] =
    "Enter user@REALM.COM's password:\n"
    "Failed to join domain: failed to lookup DC info for domain 'REALM.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.COM' over rpc: "
    "Improperly formed account name";
const char kInsufficientQuotaError[] =
    "Insufficient quota exists to complete the operation";

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

// Stub net ads info response.
const char kStubInfo[] = R"!!!(LDAP server: 111.222.33.44
LDAP server name: dcname.realm.com
Realm: REALM.COM
Bind Path: dc=REALM,dc=COM
LDAP port: 389
Server time: Fri, 03 Feb 2017 05:24:05 PST
KDC server: 111.222.33.44
Server time offset: -91
Last machine account password change:
Wed, 31 Dec 1969 16:00:00 PST)!!!";

// 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.com\SysVol\realm.com\Policies\%s
dspath:  cn=%s,cn=policies,cn=system,DC=chrome,DC=lan
options:  %s
link:   OU=test-ou,DC=chrome,DC=lan
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=some-ou,DC=realm,DC=com
instanceType: 4
whenCreated: 20161018155136.0Z
whenChanged: 20170217134227.0Z
displayName: %s
uSNCreated: 287406
uSNChanged: 307152
name: John Doe
objectGUID: %s
userAccountControl: %u
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 131309487458845506
lastLogoff: 0
lastLogon: 131320568639495686
pwdLastSet: %lu
primaryGroupID: 513
objectSid: S-1-5-21-250062649-3667841115-373469193-1134
accountExpires: 9223372036854775807
logonCount: 1453
sAMAccountName: %s
sAMAccountType: 805306368
userPrincipalName: jdoe@realm.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=chrome,DC=lan
dSCorePropagationData: 20161024075536.0Z
dSCorePropagationData: 20161024075311.0Z
dSCorePropagationData: 20161019075502.0Z
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 131318125471489990
msDS-SupportedEncryptionTypes: 0)!!!";

// 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() {
    return base::StringPrintf(
        kStubSearchFormat, common_name_.c_str(), given_name_.c_str(),
        common_name_.c_str(), display_name_.c_str(), object_guid_.c_str(),
        user_account_control_, pwd_last_set_, sam_account_name_.c_str());
  }

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

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

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

// Writes a fake keytab file.
void WriteKeytabFile() {
  std::string keytab_path = GetKeytabFilePath();
  CHECK(!keytab_path.empty());
  // Note: base::WriteFile triggers a seccomp failure, so do it old-school.
  base::ScopedFILE kt_file(fopen(keytab_path.c_str(), "w"));
  CHECK(kt_file);
  CHECK_EQ(1U, fwrite(kStubKeytab, strlen(kStubKeytab), 1, kt_file.get()));
}

// Reads the smb.conf file at |smb_conf_path| and extracts the netbios name.
std::string GetMachineNameFromSmbConf(const std::string& smb_conf_path) {
  std::string smb_conf;
  CHECK(base::ReadFileToString(base::FilePath(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();

  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 a special |kPasswordChangedAccountId|, required during auth for a
  // test that uses that id in GetUserStatus().
  if (sam_account_name == kPasswordChangedUserName)
    return search_builder.SetObjectGuid(kPasswordChangedAccountId).GetResult();

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

// Handles a stub 'net ads workgroup' call. Just returns a fake workgroup.
int HandleWorkgroup() {
  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 password from stdin.
  std::string password;
  if (!ReadPipeToString(STDIN_FILENO, &password)) {
    LOG(ERROR) << "Failed to read password";
    return kExitCodeError;
  }
  const std::string kUserFlag = "-U ";

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

  // 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 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 valid user principal. Switch behavior based on password.
  if (Contains(command_line, kUserFlag + kUserPrincipal)) {
    // Stub wrong password.
    if (password == kWrongPassword) {
      WriteOutput(kWrongPasswordError, "");
      return kExitCodeError;
    }
    // Stub expired password.
    if (password == kExpiredPassword) {
      WriteOutput(kExpiredPasswordError, "");
      return kExitCodeError;
    }
    // Stub valid password.
    if (password == kPassword) {
      WriteKeytabFile();
      return kExitCodeOk;
    }
    NOTREACHED() << "UNHANDLED PASSWORD " << password;
    return kExitCodeError;
  }

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

// Handles a stub 'net ads info' call. Just returns stub information.
int HandleInfo() {
  WriteOutput(kStubInfo, "");
  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);
  CHECK(!machine_name.empty());

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

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

  if (machine_name == base::ToUpperASCII(kGpoDownloadErrorMachineName)) {
    // Stub GPO list that triggers a download error in smbclient.
    gpos += PrintGpo(kErrorGpoGuid, 1, 1, kGpFlagAllEnabled);
  } else if (machine_name == base::ToUpperASCII(kOneGpoMachineName)) {
    // Stub GPO list that downloads one GPO if present.
    gpos += PrintGpo(kGpo1Guid, 1, 1, kGpFlagAllEnabled);
  } else if (machine_name == base::ToUpperASCII(kTwoGposMachineName)) {
    // Stub GPO list that downloads two GPOs if present.
    gpos += PrintGpo(kGpo1Guid, 1, 1, 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, 1, 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, 1, 1, kGpFlagUserDisabled);
  }

  WriteOutput("", 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);
  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, " -d "));

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

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

  // 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, "-s");
  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);
}
