Home | History | Annotate | Download | only in users
      1 // Copyright 2014 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/chromeos/login/users/supervised_user_manager_impl.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/files/file_path.h"
      9 #include "base/prefs/pref_registry_simple.h"
     10 #include "base/prefs/pref_service.h"
     11 #include "base/prefs/scoped_user_pref_update.h"
     12 #include "base/strings/string_util.h"
     13 #include "base/strings/stringprintf.h"
     14 #include "base/strings/utf_string_conversions.h"
     15 #include "base/threading/sequenced_worker_pool.h"
     16 #include "base/values.h"
     17 #include "chrome/browser/browser_process.h"
     18 #include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h"
     19 #include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
     20 #include "chrome/browser/chromeos/login/users/user_manager_impl.h"
     21 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     22 #include "chrome/browser/supervised_user/supervised_user_service.h"
     23 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
     24 #include "chromeos/settings/cros_settings_names.h"
     25 #include "content/public/browser/browser_thread.h"
     26 #include "google_apis/gaia/gaia_auth_util.h"
     27 
     28 using content::BrowserThread;
     29 
     30 namespace {
     31 
     32 // Names for pref keys in Local State.
     33 // A map from locally managed user local user id to sync user id.
     34 const char kSupervisedUserSyncId[] =
     35     "ManagedUserSyncId";
     36 
     37 // A map from locally managed user id to manager user id.
     38 const char kSupervisedUserManagers[] =
     39     "ManagedUserManagers";
     40 
     41 // A map from locally managed user id to manager display name.
     42 const char kSupervisedUserManagerNames[] =
     43     "ManagedUserManagerNames";
     44 
     45 // A map from locally managed user id to manager display e-mail.
     46 const char kSupervisedUserManagerDisplayEmails[] =
     47     "ManagedUserManagerDisplayEmails";
     48 
     49 // A vector pref of the locally managed accounts defined on this device, that
     50 // had not logged in yet.
     51 const char kLocallyManagedUsersFirstRun[] = "LocallyManagedUsersFirstRun";
     52 
     53 // A pref of the next id for locally managed users generation.
     54 const char kLocallyManagedUsersNextId[] =
     55     "LocallyManagedUsersNextId";
     56 
     57 // A pref of the next id for locally managed users generation.
     58 const char kLocallyManagedUserCreationTransactionDisplayName[] =
     59     "LocallyManagedUserCreationTransactionDisplayName";
     60 
     61 // A pref of the next id for locally managed users generation.
     62 const char kLocallyManagedUserCreationTransactionUserId[] =
     63     "LocallyManagedUserCreationTransactionUserId";
     64 
     65 // A map from user id to password schema id.
     66 const char kSupervisedUserPasswordSchema[] =
     67     "SupervisedUserPasswordSchema";
     68 
     69 // A map from user id to password salt.
     70 const char kSupervisedUserPasswordSalt[] =
     71     "SupervisedUserPasswordSalt";
     72 
     73 // A map from user id to password revision.
     74 const char kSupervisedUserPasswordRevision[] =
     75     "SupervisedUserPasswordRevision";
     76 
     77 // A map from user id to flag indicating if password should be updated upon
     78 // signin.
     79 const char kSupervisedUserNeedPasswordUpdate[] =
     80     "SupervisedUserNeedPasswordUpdate";
     81 
     82 // A map from user id to flag indicating if cryptohome does not have signature
     83 // key.
     84 const char kSupervisedUserIncompleteKey[] = "SupervisedUserHasIncompleteKey";
     85 
     86 std::string LoadSyncToken(base::FilePath profile_dir) {
     87   std::string token;
     88   base::FilePath token_file =
     89       profile_dir.Append(chromeos::kSupervisedUserTokenFilename);
     90   VLOG(1) << "Loading" << token_file.value();
     91   if (!base::ReadFileToString(token_file, &token))
     92     return std::string();
     93   return token;
     94 }
     95 
     96 } // namespace
     97 
     98 namespace chromeos {
     99 
    100 const char kSchemaVersion[] = "SchemaVersion";
    101 const char kPasswordRevision[] = "PasswordRevision";
    102 const char kSalt[] = "PasswordSalt";
    103 const char kPasswordSignature[] = "PasswordSignature";
    104 const char kEncryptedPassword[] = "EncryptedPassword";
    105 const char kRequirePasswordUpdate[] = "RequirePasswordUpdate";
    106 const char kHasIncompleteKey[] = "HasIncompleteKey";
    107 const char kPasswordEncryptionKey[] = "password.hmac.encryption";
    108 const char kPasswordSignatureKey[] = "password.hmac.signature";
    109 
    110 const char kPasswordUpdateFile[] = "password.update";
    111 const int kMinPasswordRevision = 1;
    112 
    113 // static
    114 void SupervisedUserManager::RegisterPrefs(PrefRegistrySimple* registry) {
    115   registry->RegisterListPref(kLocallyManagedUsersFirstRun);
    116   registry->RegisterIntegerPref(kLocallyManagedUsersNextId, 0);
    117   registry->RegisterStringPref(
    118       kLocallyManagedUserCreationTransactionDisplayName, "");
    119   registry->RegisterStringPref(
    120       kLocallyManagedUserCreationTransactionUserId, "");
    121   registry->RegisterDictionaryPref(kSupervisedUserSyncId);
    122   registry->RegisterDictionaryPref(kSupervisedUserManagers);
    123   registry->RegisterDictionaryPref(kSupervisedUserManagerNames);
    124   registry->RegisterDictionaryPref(kSupervisedUserManagerDisplayEmails);
    125 
    126   registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
    127   registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
    128   registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
    129 
    130   registry->RegisterDictionaryPref(kSupervisedUserNeedPasswordUpdate);
    131   registry->RegisterDictionaryPref(kSupervisedUserIncompleteKey);
    132 }
    133 
    134 SupervisedUserManagerImpl::SupervisedUserManagerImpl(UserManagerImpl* owner)
    135     : owner_(owner),
    136       cros_settings_(CrosSettings::Get()) {
    137   // SupervisedUserManager instance should be used only on UI thread.
    138   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    139   authentication_.reset(new SupervisedUserAuthentication(this));
    140 }
    141 
    142 SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
    143 }
    144 
    145 std::string SupervisedUserManagerImpl::GenerateUserId() {
    146   int counter = g_browser_process->local_state()->
    147       GetInteger(kLocallyManagedUsersNextId);
    148   std::string id;
    149   bool user_exists;
    150   do {
    151     id = base::StringPrintf("%d@%s", counter,
    152         UserManager::kLocallyManagedUserDomain);
    153     counter++;
    154     user_exists = (NULL != owner_->FindUser(id));
    155     DCHECK(!user_exists);
    156     if (user_exists) {
    157       LOG(ERROR) << "Supervised user with id " << id << " already exists.";
    158     }
    159   } while (user_exists);
    160 
    161   g_browser_process->local_state()->
    162       SetInteger(kLocallyManagedUsersNextId, counter);
    163 
    164   g_browser_process->local_state()->CommitPendingWrite();
    165   return id;
    166 }
    167 
    168 bool SupervisedUserManagerImpl::HasSupervisedUsers(
    169       const std::string& manager_id) const {
    170   const UserList& users = owner_->GetUsers();
    171   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
    172     if ((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
    173       if (manager_id == GetManagerUserId((*it)->email()))
    174         return true;
    175     }
    176   }
    177   return false;
    178 }
    179 
    180 const User* SupervisedUserManagerImpl::CreateUserRecord(
    181       const std::string& manager_id,
    182       const std::string& local_user_id,
    183       const std::string& sync_user_id,
    184       const base::string16& display_name) {
    185   const User* user = FindByDisplayName(display_name);
    186   DCHECK(!user);
    187   if (user)
    188     return user;
    189   const User* manager = owner_->FindUser(manager_id);
    190   CHECK(manager);
    191 
    192   PrefService* local_state = g_browser_process->local_state();
    193 
    194   User* new_user = User::CreateLocallyManagedUser(local_user_id);
    195 
    196   owner_->AddUserRecord(new_user);
    197 
    198   ListPrefUpdate prefs_new_users_update(local_state,
    199                                         kLocallyManagedUsersFirstRun);
    200   DictionaryPrefUpdate sync_id_update(local_state, kSupervisedUserSyncId);
    201   DictionaryPrefUpdate manager_update(local_state, kSupervisedUserManagers);
    202   DictionaryPrefUpdate manager_name_update(local_state,
    203                                            kSupervisedUserManagerNames);
    204   DictionaryPrefUpdate manager_email_update(
    205       local_state,
    206       kSupervisedUserManagerDisplayEmails);
    207 
    208   prefs_new_users_update->Insert(0, new base::StringValue(local_user_id));
    209 
    210   sync_id_update->SetWithoutPathExpansion(local_user_id,
    211       new base::StringValue(sync_user_id));
    212   manager_update->SetWithoutPathExpansion(local_user_id,
    213       new base::StringValue(manager->email()));
    214   manager_name_update->SetWithoutPathExpansion(local_user_id,
    215       new base::StringValue(manager->GetDisplayName()));
    216   manager_email_update->SetWithoutPathExpansion(local_user_id,
    217       new base::StringValue(manager->display_email()));
    218 
    219   owner_->SaveUserDisplayName(local_user_id, display_name);
    220 
    221   g_browser_process->local_state()->CommitPendingWrite();
    222   return new_user;
    223 }
    224 
    225 std::string SupervisedUserManagerImpl::GetUserSyncId(const std::string& user_id)
    226     const {
    227   std::string result;
    228   GetUserStringValue(user_id, kSupervisedUserSyncId, &result);
    229   return result;
    230 }
    231 
    232 base::string16 SupervisedUserManagerImpl::GetManagerDisplayName(
    233     const std::string& user_id) const {
    234   PrefService* local_state = g_browser_process->local_state();
    235   const base::DictionaryValue* manager_names =
    236       local_state->GetDictionary(kSupervisedUserManagerNames);
    237   base::string16 result;
    238   if (manager_names->GetStringWithoutPathExpansion(user_id, &result) &&
    239       !result.empty())
    240     return result;
    241   return base::UTF8ToUTF16(GetManagerDisplayEmail(user_id));
    242 }
    243 
    244 std::string SupervisedUserManagerImpl::GetManagerUserId(
    245       const std::string& user_id) const {
    246   std::string result;
    247   GetUserStringValue(user_id, kSupervisedUserManagers, &result);
    248   return result;
    249 }
    250 
    251 std::string SupervisedUserManagerImpl::GetManagerDisplayEmail(
    252       const std::string& user_id) const {
    253   std::string result;
    254   if (GetUserStringValue(user_id,
    255                          kSupervisedUserManagerDisplayEmails,
    256                          &result) &&
    257       !result.empty())
    258     return result;
    259   return GetManagerUserId(user_id);
    260 }
    261 
    262 void SupervisedUserManagerImpl::GetPasswordInformation(
    263     const std::string& user_id,
    264     base::DictionaryValue* result) {
    265   int value;
    266   if (GetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, &value))
    267     result->SetIntegerWithoutPathExpansion(kSchemaVersion, value);
    268   if (GetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, &value))
    269     result->SetIntegerWithoutPathExpansion(kPasswordRevision, value);
    270 
    271   bool flag;
    272   if (GetUserBooleanValue(user_id, kSupervisedUserNeedPasswordUpdate, &flag))
    273     result->SetBooleanWithoutPathExpansion(kRequirePasswordUpdate, flag);
    274   if (GetUserBooleanValue(user_id, kSupervisedUserIncompleteKey, &flag))
    275     result->SetBooleanWithoutPathExpansion(kHasIncompleteKey, flag);
    276 
    277   std::string salt;
    278   if (GetUserStringValue(user_id, kSupervisedUserPasswordSalt, &salt))
    279     result->SetStringWithoutPathExpansion(kSalt, salt);
    280 }
    281 
    282 void SupervisedUserManagerImpl::SetPasswordInformation(
    283       const std::string& user_id,
    284       const base::DictionaryValue* password_info) {
    285   int value;
    286   if (password_info->GetIntegerWithoutPathExpansion(kSchemaVersion, &value))
    287     SetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, value);
    288   if (password_info->GetIntegerWithoutPathExpansion(kPasswordRevision, &value))
    289     SetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, value);
    290 
    291   bool flag;
    292   if (password_info->GetBooleanWithoutPathExpansion(kRequirePasswordUpdate,
    293                                                     &flag)) {
    294     SetUserBooleanValue(user_id, kSupervisedUserNeedPasswordUpdate, flag);
    295   }
    296   if (password_info->GetBooleanWithoutPathExpansion(kHasIncompleteKey, &flag))
    297     SetUserBooleanValue(user_id, kSupervisedUserIncompleteKey, flag);
    298 
    299   std::string salt;
    300   if (password_info->GetStringWithoutPathExpansion(kSalt, &salt))
    301     SetUserStringValue(user_id, kSupervisedUserPasswordSalt, salt);
    302   g_browser_process->local_state()->CommitPendingWrite();
    303 }
    304 
    305 bool SupervisedUserManagerImpl::GetUserStringValue(
    306     const std::string& user_id,
    307     const char* key,
    308     std::string* out_value) const {
    309   PrefService* local_state = g_browser_process->local_state();
    310   const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
    311   return dictionary->GetStringWithoutPathExpansion(user_id, out_value);
    312 }
    313 
    314 bool SupervisedUserManagerImpl::GetUserIntegerValue(
    315     const std::string& user_id,
    316     const char* key,
    317     int* out_value) const {
    318   PrefService* local_state = g_browser_process->local_state();
    319   const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
    320   return dictionary->GetIntegerWithoutPathExpansion(user_id, out_value);
    321 }
    322 
    323 bool SupervisedUserManagerImpl::GetUserBooleanValue(const std::string& user_id,
    324                                                     const char* key,
    325                                                     bool* out_value) const {
    326   PrefService* local_state = g_browser_process->local_state();
    327   const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
    328   return dictionary->GetBooleanWithoutPathExpansion(user_id, out_value);
    329 }
    330 
    331 void SupervisedUserManagerImpl::SetUserStringValue(
    332     const std::string& user_id,
    333     const char* key,
    334     const std::string& value) {
    335   PrefService* local_state = g_browser_process->local_state();
    336   DictionaryPrefUpdate update(local_state, key);
    337   update->SetStringWithoutPathExpansion(user_id, value);
    338 }
    339 
    340 void SupervisedUserManagerImpl::SetUserIntegerValue(
    341     const std::string& user_id,
    342     const char* key,
    343     const int value) {
    344   PrefService* local_state = g_browser_process->local_state();
    345   DictionaryPrefUpdate update(local_state, key);
    346   update->SetIntegerWithoutPathExpansion(user_id, value);
    347 }
    348 
    349 void SupervisedUserManagerImpl::SetUserBooleanValue(const std::string& user_id,
    350                                                     const char* key,
    351                                                     const bool value) {
    352   PrefService* local_state = g_browser_process->local_state();
    353   DictionaryPrefUpdate update(local_state, key);
    354   update->SetBooleanWithoutPathExpansion(user_id, value);
    355 }
    356 
    357 const User* SupervisedUserManagerImpl::FindByDisplayName(
    358     const base::string16& display_name) const {
    359   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    360   const UserList& users = owner_->GetUsers();
    361   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
    362     if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
    363         ((*it)->display_name() == display_name)) {
    364       return *it;
    365     }
    366   }
    367   return NULL;
    368 }
    369 
    370 const User* SupervisedUserManagerImpl::FindBySyncId(
    371     const std::string& sync_id) const {
    372   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    373   const UserList& users = owner_->GetUsers();
    374   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
    375     if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
    376         (GetUserSyncId((*it)->email()) == sync_id)) {
    377       return *it;
    378     }
    379   }
    380   return NULL;
    381 }
    382 
    383 void SupervisedUserManagerImpl::StartCreationTransaction(
    384       const base::string16& display_name) {
    385   g_browser_process->local_state()->
    386       SetString(kLocallyManagedUserCreationTransactionDisplayName,
    387                 base::UTF16ToASCII(display_name));
    388   g_browser_process->local_state()->CommitPendingWrite();
    389 }
    390 
    391 void SupervisedUserManagerImpl::SetCreationTransactionUserId(
    392       const std::string& email) {
    393   g_browser_process->local_state()->
    394       SetString(kLocallyManagedUserCreationTransactionUserId,
    395                 email);
    396   g_browser_process->local_state()->CommitPendingWrite();
    397 }
    398 
    399 void SupervisedUserManagerImpl::CommitCreationTransaction() {
    400   g_browser_process->local_state()->
    401       ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
    402   g_browser_process->local_state()->
    403       ClearPref(kLocallyManagedUserCreationTransactionUserId);
    404   g_browser_process->local_state()->CommitPendingWrite();
    405 }
    406 
    407 bool SupervisedUserManagerImpl::HasFailedUserCreationTransaction() {
    408   return !(g_browser_process->local_state()->
    409                GetString(kLocallyManagedUserCreationTransactionDisplayName).
    410                    empty());
    411 }
    412 
    413 void SupervisedUserManagerImpl::RollbackUserCreationTransaction() {
    414   PrefService* prefs = g_browser_process->local_state();
    415 
    416   std::string display_name = prefs->
    417       GetString(kLocallyManagedUserCreationTransactionDisplayName);
    418   std::string user_id = prefs->
    419       GetString(kLocallyManagedUserCreationTransactionUserId);
    420 
    421   LOG(WARNING) << "Cleaning up transaction for "
    422                << display_name << "/" << user_id;
    423 
    424   if (user_id.empty()) {
    425     // Not much to do - just remove transaction.
    426     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
    427     prefs->CommitPendingWrite();
    428     return;
    429   }
    430 
    431   if (gaia::ExtractDomainName(user_id) !=
    432           UserManager::kLocallyManagedUserDomain) {
    433     LOG(WARNING) << "Clean up transaction for  non-locally managed user found :"
    434                  << user_id << ", will not remove data";
    435     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
    436     prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
    437     prefs->CommitPendingWrite();
    438     return;
    439   }
    440   owner_->RemoveNonOwnerUserInternal(user_id, NULL);
    441 
    442   prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
    443   prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
    444   prefs->CommitPendingWrite();
    445 }
    446 
    447 void SupervisedUserManagerImpl::RemoveNonCryptohomeData(
    448     const std::string& user_id) {
    449   PrefService* prefs = g_browser_process->local_state();
    450   ListPrefUpdate prefs_new_users_update(prefs, kLocallyManagedUsersFirstRun);
    451   prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
    452 
    453   CleanPref(user_id, kSupervisedUserSyncId);
    454   CleanPref(user_id, kSupervisedUserManagers);
    455   CleanPref(user_id, kSupervisedUserManagerNames);
    456   CleanPref(user_id, kSupervisedUserManagerDisplayEmails);
    457   CleanPref(user_id, kSupervisedUserPasswordSalt);
    458   CleanPref(user_id, kSupervisedUserPasswordSchema);
    459   CleanPref(user_id, kSupervisedUserPasswordRevision);
    460   CleanPref(user_id, kSupervisedUserNeedPasswordUpdate);
    461   CleanPref(user_id, kSupervisedUserIncompleteKey);
    462 }
    463 
    464 void SupervisedUserManagerImpl::CleanPref(const std::string& user_id,
    465                                           const char* key) {
    466   PrefService* prefs = g_browser_process->local_state();
    467   DictionaryPrefUpdate dict_update(prefs, key);
    468   dict_update->RemoveWithoutPathExpansion(user_id, NULL);
    469 }
    470 
    471 bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
    472   ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
    473                                         kLocallyManagedUsersFirstRun);
    474   return prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
    475 }
    476 
    477 void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
    478     const base::string16& new_display_name) {
    479   PrefService* local_state = g_browser_process->local_state();
    480 
    481   const base::DictionaryValue* manager_ids =
    482       local_state->GetDictionary(kSupervisedUserManagers);
    483 
    484   DictionaryPrefUpdate manager_name_update(local_state,
    485                                            kSupervisedUserManagerNames);
    486   for (base::DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
    487       it.Advance()) {
    488     std::string user_id;
    489     bool has_manager_id = it.value().GetAsString(&user_id);
    490     DCHECK(has_manager_id);
    491     if (user_id == manager_id) {
    492       manager_name_update->SetWithoutPathExpansion(
    493           it.key(),
    494           new base::StringValue(new_display_name));
    495     }
    496   }
    497 }
    498 
    499 SupervisedUserAuthentication* SupervisedUserManagerImpl::GetAuthentication() {
    500   return authentication_.get();
    501 }
    502 
    503 void SupervisedUserManagerImpl::LoadSupervisedUserToken(
    504     Profile* profile,
    505     const LoadTokenCallback& callback) {
    506   // TODO(antrim): use profile->GetPath() once we sure it is safe.
    507   base::FilePath profile_dir = ProfileHelper::GetProfilePathByUserIdHash(
    508       UserManager::Get()->GetUserByProfile(profile)->username_hash());
    509   PostTaskAndReplyWithResult(
    510       content::BrowserThread::GetBlockingPool(),
    511       FROM_HERE,
    512       base::Bind(&LoadSyncToken, profile_dir),
    513       callback);
    514 }
    515 
    516 void SupervisedUserManagerImpl::ConfigureSyncWithToken(
    517     Profile* profile,
    518     const std::string& token) {
    519   if (!token.empty())
    520     SupervisedUserServiceFactory::GetForProfile(profile)->InitSync(token);
    521 }
    522 
    523 }  // namespace chromeos
    524