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

#include <memory>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/time/default_tick_clock.h>
#include <brillo/daemons/dbus_daemon.h>
#include <brillo/syslog_logging.h>
#include <install_attributes/libinstallattributes.h>

#include "smbprovider/authpolicy_kerberos_artifact_client.h"
#include "smbprovider/constants.h"
#include "smbprovider/kerberos_artifact_synchronizer.h"
#include "smbprovider/kerberos_kerberos_artifact_client.h"
#include "smbprovider/mount_manager.h"
#include "smbprovider/samba_interface_impl.h"
#include "smbprovider/smbprovider.h"

namespace smbprovider {

namespace {

constexpr char kDaemonStoreRoot[] = "/run/daemon-store/smbproviderd";

// Helper method to set $HOME variable to a temporary path that only
// smbproviderd user can access.
bool SetHomeEnvironmentVariable() {
  if (setenv(kHomeEnvironmentVariable, kSmbProviderHome, 1 /* overwrite */) !=
      0) {
    PLOG(ERROR) << "Failed to set $HOME variable";
    return false;
  }
  return true;
}

std::string GetKrb5ConfLocation() {
  return std::string(kSmbProviderHome) + kKrb5ConfLocation;
}

std::string GetCCacheLocation() {
  return std::string(kSmbProviderHome) + kCCacheLocation;
}

std::string GetKrb5TraceLocation() {
  return std::string(kSmbProviderHome) + kKrbTraceLocation;
}

std::string GetKrb5ConfPath() {
  return GetKrb5ConfLocation() + kKrb5ConfFile;
}

std::string GetCCachePath() {
  return GetCCacheLocation() + kCCacheFile;
}

std::string GetKrb5TracePath() {
  return GetKrb5TraceLocation() + kKrbTraceFile;
}

bool SetKrb5ConfigEnviornmentVariable() {
  if (setenv(kKrb5ConfigEnvironmentVariable, GetKrb5ConfPath().c_str(),
             1 /* overwrite */) != 0) {
    PLOG(ERROR) << "Failed to set $KRB5_CONFIG variable";
    return false;
  }
  return true;
}

bool SetKrb5CCNameEnvironmentVariable() {
  if (setenv(kKrb5CCNameEnvironmentVariable, GetCCachePath().c_str(),
             1 /* overwrite */) != 0) {
    PLOG(ERROR) << "Failed to set $KRB5CCNAME variable";
    return false;
  }
  return true;
}

bool SetKrb5TraceEnvironmentVariable() {
  if (setenv(kKrb5TraceEnvironmentVariable, GetKrb5TracePath().c_str(),
             1 /* overwrite */) != 0) {
    PLOG(ERROR) << "Failed to set $KRB5_TRACE variable";
    return false;
  }
  return true;
}

bool SetKerberosEnvironmentVariables() {
  return SetKrb5ConfigEnviornmentVariable() &&
         SetKrb5CCNameEnvironmentVariable() &&
         SetKrb5TraceEnvironmentVariable();
}

// Creates a directory at |path|. Logs and returns an error on failure.
bool CreateDirectory(const std::string& path) {
  base::File::Error ferror;
  if (!base::CreateDirectoryAndGetError(base::FilePath(path), &ferror)) {
    LOG(ERROR) << "Failed to create directory '" << path
               << "': " << base::File::ErrorToString(ferror);
    return false;
  }
  return true;
}

bool CreateKerberosDirectories() {
  return CreateDirectory(GetKrb5ConfLocation()) &&
         CreateDirectory(GetCCacheLocation()) &&
         CreateDirectory(GetKrb5TraceLocation());
}

void InitLog() {
  brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);
  logging::SetLogItems(true /* enable_process_id */,
                       true /* enable_thread_id */, true /* enable_timestamp */,
                       true /* enable_tickcount */);
}

// Creates smb configuration file in $HOME/.smb/smb.conf.
bool CreateSmbConfFile() {
  const std::string smb_conf_directory(std::string(kSmbProviderHome) +
                                       kSmbConfLocation);
  if (!CreateDirectory(smb_conf_directory)) {
    return false;
  }

  const int data_size = strlen(kSmbConfData);
  return base::WriteFile(base::FilePath(smb_conf_directory + kSmbConfFile),
                         kSmbConfData, data_size) == data_size;
}

std::unique_ptr<SambaInterface> SambaInterfaceFactoryFunction(
    MountManager* mount_manager, const MountConfig& mount_config) {
  return SambaInterfaceImpl::Create(
      base::Bind(base::IgnoreResult(&MountManager::GetAuthentication),
                 mount_manager->AsWeakPtr()),
      mount_config);
}

}  // namespace

class SmbProviderDaemon : public brillo::DBusServiceDaemon {
 public:
  SmbProviderDaemon() : DBusServiceDaemon(kSmbProviderServiceName) {}
  SmbProviderDaemon(const SmbProviderDaemon&) = delete;
  SmbProviderDaemon& operator=(const SmbProviderDaemon&) = delete;

 protected:
  void RegisterDBusObjectsAsync(
      brillo::dbus_utils::AsyncEventSequencer* sequencer) override {
    auto dbus_object = std::make_unique<brillo::dbus_utils::DBusObject>(
        nullptr, bus_, org::chromium::SmbProviderAdaptor::GetObjectPath());

    // Check if this is Active Directory managed devices.
    const bool is_active_directory =
        InstallAttributesReader().GetAttribute(
            InstallAttributesReader::kAttrMode) ==
        InstallAttributesReader::kDeviceModeEnterpriseAD;

    // If this is Active Directory managed devices, Kerberos artifact
    // synchronizing happens between SmbProvider and AuthPolicy daemeon using
    // AuthPolicyKerberosArtifactClient, otherwise with Kerberos daemon using
    // KerberosKerberosArtifactClient.
    // Note that, we allow to update credentials for Kerberos daemon if
    // !is_active_directory.
    auto kerberos_artifact_client =
        is_active_directory
            ? std::unique_ptr<KerberosArtifactClientInterface>(
                  std::make_unique<AuthPolicyKerberosArtifactClient>(bus_))
            : std::unique_ptr<KerberosArtifactClientInterface>(
                  std::make_unique<KerberosKerberosArtifactClient>(bus_));
    auto kerberos_artifact_synchronizer =
        std::make_unique<KerberosArtifactSynchronizer>(
            GetKrb5ConfPath(), GetCCachePath(),
            std::move(kerberos_artifact_client), !is_active_directory);

    auto tick_clock = std::make_unique<base::DefaultTickClock>();

    auto mount_tracker = std::make_unique<MountTracker>(
        std::move(tick_clock), true /* enable_metadata_cache*/);

    auto samba_interface_factory = base::Bind(&SambaInterfaceFactoryFunction);

    auto mount_manager = std::make_unique<MountManager>(
        std::move(mount_tracker), std::move(samba_interface_factory));

    smb_provider_ = std::make_unique<SmbProvider>(
        std::move(dbus_object), std::move(mount_manager),
        std::move(kerberos_artifact_synchronizer),
        base::FilePath(kDaemonStoreRoot));
    smb_provider_->RegisterAsync(
        sequencer->GetHandler("SmbProvider.RegisterAsync() failed.", true));
  }

  void OnShutdown(int* return_code) override {
    DBusServiceDaemon::OnShutdown(return_code);
    smb_provider_.reset();
  }

 private:
  std::unique_ptr<SmbProvider> smb_provider_;
};

// Runs SmbProviderDaemon.
int RunDaemon() {
  SmbProviderDaemon daemon;
  int res = daemon.Run();
  LOG(INFO) << "smbproviderd stopping with exit code " << res;
  return res;
}

}  // namespace smbprovider

int main(int argc, char* argv[]) {
  smbprovider::InitLog();
  // Smb configuration file must be written before the daemon is started because
  // the check for smb.conf happens when the context is set.
  if (!(smbprovider::SetHomeEnvironmentVariable() &&
        smbprovider::SetKerberosEnvironmentVariables() &&
        smbprovider::CreateSmbConfFile() &&
        smbprovider::CreateKerberosDirectories())) {
    LOG(ERROR) << "Failed to set configuration files, exiting";
    return EXIT_FAILURE;
  }
  return smbprovider::RunDaemon();
}
