// Copyright 2016 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 <memory>

#include <base/check.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/memory/weak_ptr.h>
#include <brillo/daemons/dbus_daemon.h>
#include <brillo/syslog_logging.h>
#include <brillo/userdb_utils.h>
#include <install_attributes/libinstallattributes.h>

#include "authpolicy/authpolicy.h"
#include "authpolicy/constants.h"
#include "authpolicy/path_service.h"
#include "authpolicy/platform_helper.h"

namespace {

const char kObjectServicePath[] = "/org/chromium/AuthPolicy/ObjectManager";
const char kAuthPolicydUser[] = "authpolicyd";
const char kAuthPolicydExecUser[] = "authpolicyd-exec";

const int kExitCodeStartupFailure = 175;  // This number is hex AF.

}  // namespace

namespace authpolicy {

class Daemon : public brillo::DBusServiceDaemon {
 public:
  explicit Daemon(bool device_is_locked)
      : DBusServiceDaemon(kAuthPolicyServiceName, kObjectServicePath),
        device_is_locked_(device_is_locked),
        weak_ptr_factory_(this) {}
  Daemon(const Daemon&) = delete;
  Daemon& operator=(const Daemon&) = delete;

  // Cleans the authpolicy daemon state directory. Returns true if all files
  // were cleared.
  static bool CleanState() {
    PathService path_service;
    return AuthPolicy::CleanState(&path_service);
  }

 protected:
  void RegisterDBusObjectsAsync(
      brillo::dbus_utils::AsyncEventSequencer* sequencer) override {
    brillo::dbus_utils::AsyncEventSequencer::Handler handler =
        sequencer->GetHandler("AuthPolicy.RegisterAsync() failed.", true);
    authpolicy_.RegisterAsync(
        AuthPolicy::GetDBusObject(object_manager_.get()),
        base::Bind(&Daemon::OnAuthPolicyRegistered,
                   weak_ptr_factory_.GetWeakPtr(), handler));
  }

 private:
  void OnAuthPolicyRegistered(
      const brillo::dbus_utils::AsyncEventSequencer::Handler& handler,
      bool success) {
    // If it wasn't successful, the sequencer handler should print an error and
    // exit.
    handler.Run(success);
    CHECK(success);
    LOG(INFO) << "authpolicyd started";

    // Initialize authpolicy here, so that stuff like the machine password check
    // happens after the daemon is registered.
    ErrorType error = authpolicy_.Initialize(device_is_locked_);
    if (error != ERROR_NONE) {
      LOG(ERROR) << "SambaInterface failed to initialize with error code "
                 << error;
      exit(kExitCodeStartupFailure);
    }
  }

  bool device_is_locked_;

  // Keep this order! |authpolicy_| must be last as it depends on the other two.
  AuthPolicyMetrics metrics_;
  PathService path_service_;
  AuthPolicy authpolicy_{&metrics_, &path_service_};

  base::WeakPtrFactory<Daemon> weak_ptr_factory_;
};

}  // namespace authpolicy

int main(int /* argc */, char* /* argv */[]) {
  brillo::OpenLog("authpolicyd", true);
  brillo::InitLog(brillo::kLogToSyslog);

  // Verify we're running as authpolicyd user.
  uid_t authpolicyd_uid;
  CHECK(
      brillo::userdb::GetUserInfo(kAuthPolicydUser, &authpolicyd_uid, nullptr));
  if (authpolicyd_uid != authpolicy::GetEffectiveUserId()) {
    LOG(ERROR) << "Failed to verify effective UID (must run as authpolicyd).";
    exit(kExitCodeStartupFailure);
  }

  // Make it possible to switch to authpolicyd-exec without caps and drop caps.
  uid_t authpolicyd_exec_uid;
  CHECK(brillo::userdb::GetUserInfo(kAuthPolicydExecUser, &authpolicyd_exec_uid,
                                    nullptr));
  if (!authpolicy::SetSavedUserAndDropCaps(authpolicyd_exec_uid)) {
    LOG(ERROR) << "Failed to establish user ids and drop caps.";
    exit(kExitCodeStartupFailure);
  }

  // Safety check to ensure that authpolicyd cannot run after the device has
  // been locked to a mode other than enterprise_ad.  (The lifetime management
  // of authpolicyd happens through upstart, this check only serves as a second
  // line of defense.)
  bool device_is_locked = false;
  InstallAttributesReader install_attributes_reader;
  if (install_attributes_reader.IsLocked()) {
    const std::string& mode = install_attributes_reader.GetAttribute(
        InstallAttributesReader::kAttrMode);
    if (mode != InstallAttributesReader::kDeviceModeEnterpriseAD) {
      LOG(ERROR) << "OOBE completed but device not in Active Directory "
                    "management mode. Cleaning state and exiting.";
      CHECK(authpolicy::Daemon::CleanState());
      exit(kExitCodeStartupFailure);
    } else {
      LOG(INFO) << "Install attributes locked to Active Directory mode.";

      // A configuration file should be present in this case.
      device_is_locked = true;
    }
  } else {
    LOG(INFO) << "No install attributes found. Cleaning state.";
    CHECK(authpolicy::Daemon::CleanState());
  }

  // Run daemon.
  LOG(INFO) << "authpolicyd starting";
  authpolicy::Daemon daemon(device_is_locked);
  int res = daemon.Run();
  LOG(INFO) << "authpolicyd stopping with exit code " << res;

  return res;
}
