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/policy/chrome_browser_policy_connector.h"
6
7#include <string>
8
9#include "base/callback.h"
10#include "base/command_line.h"
11#include "base/files/file_path.h"
12#include "base/logging.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/path_service.h"
15#include "base/strings/sys_string_conversions.h"
16#include "chrome/browser/policy/configuration_policy_handler_list_factory.h"
17#include "chrome/browser/policy/device_management_service_configuration.h"
18#include "chrome/common/chrome_paths.h"
19#include "components/policy/core/common/async_policy_provider.h"
20#include "components/policy/core/common/cloud/device_management_service.h"
21#include "components/policy/core/common/configuration_policy_provider.h"
22#include "components/policy/core/common/policy_map.h"
23#include "components/policy/core/common/policy_namespace.h"
24#include "components/policy/core/common/policy_service.h"
25#include "components/policy/core/common/policy_types.h"
26#include "components/signin/core/common/signin_switches.h"
27#include "content/public/browser/browser_thread.h"
28#include "net/url_request/url_request_context_getter.h"
29#include "policy/policy_constants.h"
30
31#if defined(OS_WIN)
32#include "components/policy/core/common/policy_loader_win.h"
33#elif defined(OS_MACOSX)
34#include <CoreFoundation/CoreFoundation.h>
35#include "components/policy/core/common/policy_loader_mac.h"
36#include "components/policy/core/common/preferences_mac.h"
37#elif defined(OS_POSIX) && !defined(OS_ANDROID)
38#include "components/policy/core/common/config_dir_policy_loader.h"
39#elif defined(OS_ANDROID)
40#include "components/policy/core/common/policy_provider_android.h"
41#endif
42
43using content::BrowserThread;
44
45namespace policy {
46
47namespace {
48
49#if defined(OS_MACOSX)
50base::FilePath GetManagedPolicyPath() {
51  // This constructs the path to the plist file in which Mac OS X stores the
52  // managed preference for the application. This is undocumented and therefore
53  // fragile, but if it doesn't work out, AsyncPolicyLoader has a task that
54  // polls periodically in order to reload managed preferences later even if we
55  // missed the change.
56  base::FilePath path;
57  if (!PathService::Get(chrome::DIR_MANAGED_PREFS, &path))
58    return base::FilePath();
59
60  CFBundleRef bundle(CFBundleGetMainBundle());
61  if (!bundle)
62    return base::FilePath();
63
64  CFStringRef bundle_id = CFBundleGetIdentifier(bundle);
65  if (!bundle_id)
66    return base::FilePath();
67
68  return path.Append(base::SysCFStringRefToUTF8(bundle_id) + ".plist");
69}
70#endif  // defined(OS_MACOSX)
71
72}  // namespace
73
74ChromeBrowserPolicyConnector::ChromeBrowserPolicyConnector()
75    : BrowserPolicyConnector(base::Bind(&BuildHandlerList)) {
76  ConfigurationPolicyProvider* platform_provider = CreatePlatformProvider();
77  if (platform_provider)
78    SetPlatformPolicyProvider(make_scoped_ptr(platform_provider));
79}
80
81ChromeBrowserPolicyConnector::~ChromeBrowserPolicyConnector() {}
82
83void ChromeBrowserPolicyConnector::Init(
84    PrefService* local_state,
85    scoped_refptr<net::URLRequestContextGetter> request_context) {
86  // Initialization of some of the providers requires the FILE thread; make
87  // sure that threading is ready at this point.
88  DCHECK(BrowserThread::IsThreadInitialized(BrowserThread::FILE));
89
90  scoped_ptr<DeviceManagementService::Configuration> configuration(
91      new DeviceManagementServiceConfiguration(
92          BrowserPolicyConnector::GetDeviceManagementUrl()));
93  scoped_ptr<DeviceManagementService> device_management_service(
94      new DeviceManagementService(configuration.Pass()));
95  device_management_service->ScheduleInitialization(
96      kServiceInitializationStartupDelay);
97
98  BrowserPolicyConnector::Init(
99      local_state, request_context, device_management_service.Pass());
100
101  AppendExtraFlagPerPolicy();
102}
103
104ConfigurationPolicyProvider*
105    ChromeBrowserPolicyConnector::CreatePlatformProvider() {
106#if defined(OS_WIN)
107  scoped_ptr<AsyncPolicyLoader> loader(PolicyLoaderWin::Create(
108      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
109      kRegistryChromePolicyKey));
110  return new AsyncPolicyProvider(GetSchemaRegistry(), loader.Pass());
111#elif defined(OS_MACOSX)
112  scoped_ptr<AsyncPolicyLoader> loader(new PolicyLoaderMac(
113      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
114      GetManagedPolicyPath(),
115      new MacPreferences()));
116  return new AsyncPolicyProvider(GetSchemaRegistry(), loader.Pass());
117#elif defined(OS_POSIX) && !defined(OS_ANDROID)
118  base::FilePath config_dir_path;
119  if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) {
120    scoped_ptr<AsyncPolicyLoader> loader(new ConfigDirPolicyLoader(
121        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
122        config_dir_path,
123        POLICY_SCOPE_MACHINE));
124    return new AsyncPolicyProvider(GetSchemaRegistry(), loader.Pass());
125  } else {
126    return NULL;
127  }
128#elif defined(OS_ANDROID)
129  return new PolicyProviderAndroid();
130#else
131  return NULL;
132#endif
133}
134
135void ChromeBrowserPolicyConnector::AppendExtraFlagPerPolicy() {
136  PolicyService* policy_service = GetPolicyService();
137  PolicyNamespace chrome_ns = PolicyNamespace(POLICY_DOMAIN_CHROME, "");
138  const PolicyMap& chrome_policy = policy_service->GetPolicies(chrome_ns);
139  const base::Value* policy_value =
140      chrome_policy.GetValue(key::kEnableWebBasedSignin);
141  bool enabled = false;
142  CommandLine* command_line = CommandLine::ForCurrentProcess();
143  if (policy_value && policy_value->GetAsBoolean(&enabled) && enabled &&
144      !command_line->HasSwitch(switches::kEnableWebBasedSignin)) {
145    command_line->AppendSwitch(switches::kEnableWebBasedSignin);
146  }
147}
148
149}  // namespace policy
150