// 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/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) {}

  // 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);
    auth_policy_.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 = auth_policy_.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! auth_policy_ must be last as it depends on the other two.
  AuthPolicyMetrics metrics_;
  PathService path_service_;
  AuthPolicy auth_policy_{&metrics_, &path_service_};

  base::WeakPtrFactory<Daemon> weak_ptr_factory_;
  DISALLOW_COPY_AND_ASSIGN(Daemon);
};

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