1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/policy/enterprise_install_attributes.h"
6
7#include "base/logging.h"
8#include "chrome/browser/chromeos/cros/cryptohome_library.h"
9
10static const char kAttrEnterpriseOwned[] = "enterprise.owned";
11static const char kAttrEnterpriseUser[] = "enterprise.user";
12
13namespace policy {
14
15EnterpriseInstallAttributes::EnterpriseInstallAttributes(
16    chromeos::CryptohomeLibrary* cryptohome)
17    : cryptohome_(cryptohome),
18      device_locked_(false) {}
19
20EnterpriseInstallAttributes::LockResult EnterpriseInstallAttributes::LockDevice(
21    const std::string& user) {
22  // Check for existing lock first.
23  if (device_locked_) {
24    return !registration_user_.empty() && user == registration_user_ ?
25        LOCK_SUCCESS : LOCK_WRONG_USER;
26  }
27
28  if (!cryptohome_->InstallAttributesIsReady())
29    return LOCK_NOT_READY;
30
31  // Clearing the TPM password seems to be always a good deal.
32  if (cryptohome_->TpmIsEnabled() &&
33      !cryptohome_->TpmIsBeingOwned() &&
34      cryptohome_->TpmIsOwned()) {
35    cryptohome_->TpmClearStoredPassword();
36  }
37
38  // Make sure we really have a working InstallAttrs.
39  if (cryptohome_->InstallAttributesIsInvalid()) {
40    LOG(ERROR) << "Install attributes invalid.";
41    return LOCK_BACKEND_ERROR;
42  }
43
44  if (!cryptohome_->InstallAttributesIsFirstInstall())
45    return LOCK_WRONG_USER;
46
47  // Set values in the InstallAttrs and lock it.
48  if (!cryptohome_->InstallAttributesSet(kAttrEnterpriseOwned, "true") ||
49      !cryptohome_->InstallAttributesSet(kAttrEnterpriseUser, user)) {
50    LOG(ERROR) << "Failed writing attributes";
51    return LOCK_BACKEND_ERROR;
52  }
53
54  if (!cryptohome_->InstallAttributesFinalize() ||
55      cryptohome_->InstallAttributesIsFirstInstall() ||
56      GetRegistrationUser() != user) {
57    LOG(ERROR) << "Failed locking.";
58    return LOCK_BACKEND_ERROR;
59  }
60
61  return LOCK_SUCCESS;
62}
63
64bool EnterpriseInstallAttributes::IsEnterpriseDevice() {
65  ReadImmutableAttributes();
66  return device_locked_ && !registration_user_.empty();
67}
68
69std::string EnterpriseInstallAttributes::GetRegistrationUser() {
70  ReadImmutableAttributes();
71
72  if (!device_locked_)
73    return std::string();
74
75  return registration_user_;
76}
77
78std::string EnterpriseInstallAttributes::GetDomain() {
79  if (!IsEnterpriseDevice())
80    return std::string();
81
82  std::string domain;
83  size_t pos = registration_user_.find('@');
84  if (pos != std::string::npos)
85    domain = registration_user_.substr(pos + 1);
86
87  return domain;
88}
89
90void EnterpriseInstallAttributes::ReadImmutableAttributes() {
91  if (device_locked_)
92    return;
93
94  if (cryptohome_ &&
95      cryptohome_->InstallAttributesIsReady() &&
96      !cryptohome_->InstallAttributesIsInvalid() &&
97      !cryptohome_->InstallAttributesIsFirstInstall()) {
98    device_locked_ = true;
99    std::string enterprise_owned;
100    std::string enterprise_user;
101    if (cryptohome_->InstallAttributesGet(kAttrEnterpriseOwned,
102                                          &enterprise_owned) &&
103        cryptohome_->InstallAttributesGet(kAttrEnterpriseUser,
104                                          &enterprise_user) &&
105        enterprise_owned == "true" &&
106        !enterprise_user.empty()) {
107      registration_user_ = enterprise_user;
108    }
109  }
110}
111
112}  // namespace policy
113