Commit 59c61c81 authored by dzhioev@chromium.org's avatar dzhioev@chromium.org

Added policy for disabling locally managed users.

By default LMU disabled for managed devices.

Also added support of new policy in ChromeOS part.

BUG=229298

Review URL: https://chromiumcodereview.appspot.com/17546004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207978 0039d316-1c4b-4281-b951-d872f2087c98
parent b5b9ff44
......@@ -112,7 +112,7 @@
# persistent IDs for all fields (but not for groups!) are needed. These are
# specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
# because doing so would break the deployed wire format!
# For your editing convenience: highest ID currently used: 218
# For your editing convenience: highest ID currently used: 219
#
# Placeholders:
# The following placeholder strings are automatically substituted:
......@@ -4982,6 +4982,24 @@
This policy is for internal use by Chrome itself.''',
},
{
'name': 'SupervisedUsersEnabled',
'type': 'main',
'schema': { 'type': 'boolean' },
'supported_on': ['chrome_os:29-'],
'device_only': True,
'features': {
'dynamic_refresh': False,
},
'example_value': True,
'id': 219,
'caption': '''Enable supervised users.''',
'desc': '''If set to true, it is possible to create and log in as a supervised user.
If set to false or not configured, supervised users creation and login will be disabled. All existing supervised users will be hidden.
NOTE: The default behavior for consumer and enterprise devices differs: on consumer devices supervised users are enabled by default, but on enterprice devices they aren't.'''
},
],
},
],
......
......@@ -181,8 +181,13 @@ void ExistingUserController::UpdateLoginDisplay(const UserList& users) {
if (show_users_on_signin) {
for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
// TODO(xiyuan): Clean user profile whose email is not in whitelist.
if (LoginUtils::IsWhitelisted((*it)->email()) ||
(*it)->GetType() != User::USER_TYPE_REGULAR) {
bool meets_locally_managed_requirements =
(*it)->GetType() != User::USER_TYPE_LOCALLY_MANAGED ||
UserManager::Get()->AreLocallyManagedUsersAllowed();
bool meets_whitelist_requirements =
LoginUtils::IsWhitelisted((*it)->email()) ||
(*it)->GetType() != User::USER_TYPE_REGULAR;
if (meets_locally_managed_requirements && meets_whitelist_requirements) {
filtered_users.push_back(*it);
}
}
......@@ -438,6 +443,11 @@ void ExistingUserController::PerformLogin(
is_login_in_progress_ = true;
if (gaia::ExtractDomainName(user_context.username) ==
UserManager::kLocallyManagedUserDomain) {
if (!UserManager::Get()->AreLocallyManagedUsersAllowed()) {
LOG(ERROR) << "Login attempt of locally managed user detected.";
login_display_->SetUIEnabled(true);
return;
}
login_performer_->LoginAsLocallyManagedUser(
UserContext(user_context.username,
user_context.password,
......
......@@ -95,6 +95,7 @@ class MockUserManager : public UserManager {
std::string*));
MOCK_METHOD2(SetAppModeChromeClientOAuthInfo, void(const std::string&,
const std::string&));
MOCK_CONST_METHOD0(AreLocallyManagedUsersAllowed, bool(void));
// You can't mock these functions easily because nobody can create
// User objects but the UserManagerImpl and us.
......
......@@ -349,6 +349,9 @@ class UserManager {
virtual void NotifyLocalStateChanged() = 0;
// Returns true if locally managed users allowed.
virtual bool AreLocallyManagedUsersAllowed() const = 0;
private:
friend class ScopedUserManagerEnabler;
......
......@@ -35,6 +35,7 @@
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/session_length_limiter.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile_manager.h"
......@@ -205,6 +206,7 @@ UserManagerImpl::UserManagerImpl()
is_current_user_new_(false),
is_current_user_ephemeral_regular_user_(false),
ephemeral_users_enabled_(false),
locally_managed_users_enabled_by_policy_(false),
merge_session_state_(MERGE_STATUS_NOT_STARTED),
observed_sync_service_(NULL),
user_image_manager_(new UserImageManagerImpl) {
......@@ -215,6 +217,10 @@ UserManagerImpl::UserManagerImpl()
registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
content::NotificationService::AllSources());
RetrieveTrustedDevicePolicies();
cros_settings_->AddSettingsObserver(kAccountsPrefDeviceLocalAccounts,
this);
cros_settings_->AddSettingsObserver(kAccountsPrefSupervisedUsersEnabled,
this);
UpdateLoginState();
}
......@@ -237,6 +243,9 @@ void UserManagerImpl::Shutdown() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
cros_settings_->RemoveSettingsObserver(kAccountsPrefDeviceLocalAccounts,
this);
cros_settings_->RemoveSettingsObserver(
kAccountsPrefSupervisedUsersEnabled,
this);
// Stop the session length limiter.
session_length_limiter_.reset();
......@@ -713,11 +722,14 @@ void UserManagerImpl::Observe(int type,
}
}
break;
case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED:
DCHECK_EQ(*content::Details<const std::string>(details).ptr(),
kAccountsPrefDeviceLocalAccounts);
case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED: {
std::string changed_setting =
*content::Details<const std::string>(details).ptr();
DCHECK(changed_setting == kAccountsPrefDeviceLocalAccounts ||
changed_setting == kAccountsPrefSupervisedUsersEnabled);
RetrieveTrustedDevicePolicies();
break;
}
default:
NOTREACHED();
}
......@@ -1010,6 +1022,7 @@ void UserManagerImpl::EnsureUsersLoaded() {
void UserManagerImpl::RetrieveTrustedDevicePolicies() {
ephemeral_users_enabled_ = false;
locally_managed_users_enabled_by_policy_ = false;
owner_email_ = "";
// Schedule a callback if device policy has not yet been verified.
......@@ -1021,6 +1034,8 @@ void UserManagerImpl::RetrieveTrustedDevicePolicies() {
cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
&ephemeral_users_enabled_);
cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
&locally_managed_users_enabled_by_policy_);
cros_settings_->GetString(kDeviceOwner, &owner_email_);
EnsureUsersLoaded();
......@@ -1052,9 +1067,6 @@ void UserManagerImpl::RetrieveTrustedDevicePolicies() {
if (changed)
NotifyUserListChanged();
cros_settings_->AddSettingsObserver(kAccountsPrefDeviceLocalAccounts,
this);
}
bool UserManagerImpl::AreEphemeralUsersEnabled() const {
......@@ -1586,6 +1598,12 @@ void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
chrome_client_secret_ = chrome_client_secret;
}
bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
return ManagedUserService::AreManagedUsersEnabled() &&
(locally_managed_users_enabled_by_policy_ ||
!g_browser_process->browser_policy_connector()->IsEnterpriseManaged());
}
UserFlow* UserManagerImpl::GetDefaultUserFlow() const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!default_flow_.get())
......
......@@ -134,6 +134,7 @@ class UserManagerImpl
virtual void SetAppModeChromeClientOAuthInfo(
const std::string& chrome_client_id,
const std::string& chrome_client_secret) OVERRIDE;
virtual bool AreLocallyManagedUsersAllowed() const OVERRIDE;
// content::NotificationObserver implementation.
virtual void Observe(int type,
......@@ -357,6 +358,11 @@ class UserManagerImpl
// policy yet.
bool ephemeral_users_enabled_;
// Cached flag indicating whether the locally managed users are enabled by
// policy. Defaults to |false| if the value has not been read from trusted
// device policy yet.
bool locally_managed_users_enabled_by_policy_;
// Merge session state (cookie restore process state).
MergeSessionState merge_session_state_;
......
......@@ -47,12 +47,11 @@ class UserManagerTest : public testing::Test {
cros_settings_->AddSettingsProvider(&stub_settings_provider_);
// Populate the stub DeviceSettingsProvider with valid values.
SetDeviceSettings(false, "");
SetDeviceSettings(false, "", false);
// Register an in-memory local settings instance.
local_state_.reset(new TestingPrefServiceSimple);
reinterpret_cast<TestingBrowserProcess*>(g_browser_process)
->SetLocalState(local_state_.get());
TestingBrowserProcess::GetGlobal()->SetLocalState(local_state_.get());
UserManager::RegisterPrefs(local_state_->registry());
// Wallpaper manager and user image managers prefs will be accessed by the
// unit-test as well.
......@@ -64,8 +63,7 @@ class UserManagerTest : public testing::Test {
virtual void TearDown() OVERRIDE {
// Unregister the in-memory local settings instance.
reinterpret_cast<TestingBrowserProcess*>(g_browser_process)
->SetLocalState(0);
TestingBrowserProcess::GetGlobal()->SetLocalState(0);
// Restore the real DeviceSettingsProvider.
EXPECT_TRUE(
......@@ -78,24 +76,28 @@ class UserManagerTest : public testing::Test {
base::RunLoop().RunUntilIdle();
}
UserManagerImpl* GetUserManagerImpl() const {
return static_cast<UserManagerImpl*>(UserManager::Get());
}
bool GetUserManagerEphemeralUsersEnabled() const {
return reinterpret_cast<UserManagerImpl*>(UserManager::Get())->
ephemeral_users_enabled_;
return GetUserManagerImpl()->ephemeral_users_enabled_;
}
bool GetUserManagerLocallyManagedUsersEnabledByPolicy() const {
return GetUserManagerImpl()->locally_managed_users_enabled_by_policy_;
}
void SetUserManagerEphemeralUsersEnabled(bool ephemeral_users_enabled) {
reinterpret_cast<UserManagerImpl*>(UserManager::Get())->
ephemeral_users_enabled_ = ephemeral_users_enabled;
GetUserManagerImpl()->ephemeral_users_enabled_ = ephemeral_users_enabled;
}
const std::string& GetUserManagerOwnerEmail() const {
return reinterpret_cast<UserManagerImpl*>(UserManager::Get())->
owner_email_;
return GetUserManagerImpl()-> owner_email_;
}
void SetUserManagerOwnerEmail(const std::string& owner_email) {
reinterpret_cast<UserManagerImpl*>(UserManager::Get())->
owner_email_ = owner_email;
GetUserManagerImpl()->owner_email_ = owner_email;
}
void ResetUserManager() {
......@@ -107,18 +109,20 @@ class UserManagerTest : public testing::Test {
}
void SetDeviceSettings(bool ephemeral_users_enabled,
const std::string &owner) {
const std::string &owner,
bool locally_managed_users_enabled) {
base::FundamentalValue
ephemeral_users_enabled_value(ephemeral_users_enabled);
stub_settings_provider_.Set(kAccountsPrefEphemeralUsersEnabled,
ephemeral_users_enabled_value);
base::StringValue owner_value(owner);
stub_settings_provider_.Set(kDeviceOwner, owner_value);
stub_settings_provider_.Set(kAccountsPrefSupervisedUsersEnabled,
base::FundamentalValue(locally_managed_users_enabled));
}
void RetrieveTrustedDevicePolicies() {
reinterpret_cast<UserManagerImpl*>(UserManager::Get())->
RetrieveTrustedDevicePolicies();
GetUserManagerImpl()->RetrieveTrustedDevicePolicies();
}
protected:
......@@ -142,7 +146,7 @@ TEST_F(UserManagerTest, RetrieveTrustedDevicePolicies) {
SetUserManagerEphemeralUsersEnabled(true);
SetUserManagerOwnerEmail("");
SetDeviceSettings(false, "owner@invalid.domain");
SetDeviceSettings(false, "owner@invalid.domain", false);
RetrieveTrustedDevicePolicies();
EXPECT_FALSE(GetUserManagerEphemeralUsersEnabled());
......@@ -166,7 +170,7 @@ TEST_F(UserManagerTest, RemoveAllExceptOwnerFromList) {
EXPECT_EQ((*users)[1]->email(), "user0@invalid.domain");
EXPECT_EQ((*users)[2]->email(), "owner@invalid.domain");
SetDeviceSettings(true, "owner@invalid.domain");
SetDeviceSettings(true, "owner@invalid.domain", false);
RetrieveTrustedDevicePolicies();
users = &UserManager::Get()->GetUsers();
......@@ -175,7 +179,7 @@ TEST_F(UserManagerTest, RemoveAllExceptOwnerFromList) {
}
TEST_F(UserManagerTest, RegularUserLoggedInAsEphemeral) {
SetDeviceSettings(true, "owner@invalid.domain");
SetDeviceSettings(true, "owner@invalid.domain", false);
RetrieveTrustedDevicePolicies();
UserManager::Get()->UserLoggedIn(
......@@ -190,4 +194,13 @@ TEST_F(UserManagerTest, RegularUserLoggedInAsEphemeral) {
EXPECT_EQ((*users)[0]->email(), "owner@invalid.domain");
}
TEST_F(UserManagerTest, DisablingLMUByDeviceSettings) {
SetDeviceSettings(false, "owner@invalid.domain", false);
RetrieveTrustedDevicePolicies();
EXPECT_EQ(GetUserManagerLocallyManagedUsersEnabledByPolicy(), false);
SetDeviceSettings(false, "owner@invalid.domain", true);
RetrieveTrustedDevicePolicies();
EXPECT_EQ(GetUserManagerLocallyManagedUsersEnabledByPolicy(), true);
}
} // namespace chromeos
......@@ -177,6 +177,19 @@ void DecodeLoginPolicies(const em::ChromeDeviceSettingsProto& policy,
container.enable_auto_login_bailout()));
}
}
if (policy.has_supervised_users_settings()) {
const em::SupervisedUsersSettingsProto& container =
policy.supervised_users_settings();
if (container.has_supervised_users_enabled()) {
Value* value = Value::CreateBooleanValue(
container.supervised_users_enabled());
policies->Set(key::kSupervisedUsersEnabled,
POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_MACHINE,
value);
}
}
}
void DecodeKioskPolicies(const em::ChromeDeviceSettingsProto& policy,
......
......@@ -32,6 +32,8 @@ const char kAccountsPrefDeviceLocalAccountAutoLoginDelay[] =
"cros.accounts.deviceLocalAccountAutoLoginDelay";
const char kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled[] =
"cros.accounts.deviceLocalAccountAutoLoginBailoutEnabled";
const char kAccountsPrefSupervisedUsersEnabled[] =
"cros.accounts.supervisedUsersEnabled";
// All cros.signed.* settings are stored in SignedSettings.
const char kSignedDataRoamingEnabled[] = "cros.signed.data_roaming_enabled";
......
......@@ -22,6 +22,7 @@ extern const char kAccountsPrefDeviceLocalAccountsKeyKioskAppUpdateURL[];
extern const char kAccountsPrefDeviceLocalAccountAutoLoginId[];
extern const char kAccountsPrefDeviceLocalAccountAutoLoginDelay[];
extern const char kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled[];
extern const char kAccountsPrefSupervisedUsersEnabled[];
extern const char kSignedDataRoamingEnabled[];
......
......@@ -47,6 +47,7 @@ const char* kKnownSettings[] = {
kAccountsPrefDeviceLocalAccountAutoLoginId,
kAccountsPrefEphemeralUsersEnabled,
kAccountsPrefShowUserNamesOnSignIn,
kAccountsPrefSupervisedUsersEnabled,
kAccountsPrefUsers,
kAllowRedeemChromeOsRegistrationOffers,
kAllowedConnectionTypesForUpdate,
......@@ -366,16 +367,17 @@ void DeviceSettingsProvider::SetInPolicy() {
} else {
// The remaining settings don't support Set(), since they are not
// intended to be customizable by the user:
// kAccountsPrefSupervisedUsersEnabled
// kAppPack
// kDeviceAttestationEnabled
// kDeviceOwner
// kIdleLogoutTimeout
// kIdleLogoutWarningDuration
// kReleaseChannelDelegated
// kReportDeviceVersionInfo
// kReportDeviceActivityTimes
// kReportDeviceBootMode
// kReportDeviceLocation
// kReportDeviceVersionInfo
// kScreenSaverExtensionId
// kScreenSaverTimeout
// kStartUpUrls
......@@ -448,6 +450,11 @@ void DeviceSettingsProvider::DecodeLoginPolicies(
policy.ephemeral_users_enabled().has_ephemeral_users_enabled() &&
policy.ephemeral_users_enabled().ephemeral_users_enabled());
new_values_cache->SetBoolean(
kAccountsPrefSupervisedUsersEnabled,
policy.has_supervised_users_settings() &&
policy.supervised_users_settings().supervised_users_enabled());
base::ListValue* list = new base::ListValue();
const em::UserWhitelistProto& whitelist_proto = policy.user_whitelist();
const RepeatedPtrField<std::string>& whitelist =
......
......@@ -408,6 +408,11 @@ message AccessibilitySettingsProto {
optional ScreenMagnifierType login_screen_default_screen_magnifier_type = 4;
}
message SupervisedUsersSettingsProto {
// Defines whether supervised users can be created on the device.
optional bool supervised_users_enabled = 1;
}
message ChromeDeviceSettingsProto {
optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1;
optional UserWhitelistProto user_whitelist = 2;
......@@ -436,4 +441,5 @@ message ChromeDeviceSettingsProto {
optional VariationsParameterProto variations_parameter = 25;
optional AttestationSettingsProto attestation_settings = 26;
optional AccessibilitySettingsProto accessibility_settings = 27;
optional SupervisedUsersSettingsProto supervised_users_settings = 28;
}
......@@ -29,7 +29,6 @@
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/io_thread.h"
#include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chromeos/login/error_screen_handler.h"
......@@ -1005,11 +1004,12 @@ void SigninScreenHandler::UpdateAuthParams(DictionaryValue* params) {
// bool single_user = users.size() == 1;
// chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
bool managed_users_enabled = ManagedUserService::AreManagedUsersEnabled();
bool managed_users_allowed =
UserManager::Get()->AreLocallyManagedUsersAllowed();
bool managed_users_can_create = false;
if (managed_users_enabled)
if (managed_users_allowed)
managed_users_can_create = delegate_->GetUsers().size() > 0;
params->SetBoolean("managedUsersEnabled", managed_users_enabled);
params->SetBoolean("managedUsersEnabled", managed_users_allowed);
params->SetBoolean("managedUsersCanCreate", managed_users_can_create);
}
......@@ -1128,8 +1128,8 @@ void SigninScreenHandler::HandleLaunchIncognito() {
}
void SigninScreenHandler::HandleShowLocallyManagedUserCreationScreen() {
if (!ManagedUserService::AreManagedUsersEnabled()) {
LOG(ERROR) << "Managed users disabled.";
if (!UserManager::Get()->AreLocallyManagedUsersAllowed()) {
LOG(ERROR) << "Managed users not allowed.";
return;
}
scoped_ptr<DictionaryValue> params(new DictionaryValue());
......
......@@ -1954,6 +1954,9 @@
"AttestationEnabledForDevice": {
},
"SupervisedUsersEnabled": {
},
"----- Chrome Frame policies -------------------------------------------": {},
"ChromeFrameRendererSettings": {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment