1bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/policy/configuration_policy_provider_mac.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/file_util.h"
8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/logging.h"
9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/mac/scoped_cftyperef.h"
10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/path_service.h"
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/sys_string_conversions.h"
12513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/common/chrome_paths.h"
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace policy {
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
16513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstatic FilePath GetManagedPolicyPath() {
17513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // This constructs the path to the plist file in which Mac OS X stores the
18513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // managed preference for the application. This is undocumented and therefore
19513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // fragile, but if it doesn't work out, FileBasedPolicyLoader has a task that
20513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // polls periodically in order to reload managed preferences later even if we
21513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // missed the change.
22513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  FilePath path;
23513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!PathService::Get(chrome::DIR_MANAGED_PREFS, &path))
24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return FilePath();
25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  CFBundleRef bundle(CFBundleGetMainBundle());
27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!bundle)
28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return FilePath();
29513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
30513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  CFStringRef bundle_id = CFBundleGetIdentifier(bundle);
31513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!bundle_id)
32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return FilePath();
33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
34513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return path.Append(base::SysCFStringRefToUTF8(bundle_id) + ".plist");
35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenMacPreferencesPolicyProviderDelegate::MacPreferencesPolicyProviderDelegate(
38513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    MacPreferences* preferences,
39513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list)
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    : FileBasedPolicyProvider::ProviderDelegate(GetManagedPolicyPath()),
41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      policy_list_(policy_list),
42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      preferences_(preferences) {
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
45dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenMacPreferencesPolicyProviderDelegate::~MacPreferencesPolicyProviderDelegate() {}
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenDictionaryValue* MacPreferencesPolicyProviderDelegate::Load() {
48513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  preferences_->AppSynchronize(kCFPreferencesCurrentApplication);
49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DictionaryValue* policy = new DictionaryValue;
50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current;
52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  for (current = policy_list_->begin; current != policy_list_->end; ++current) {
53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base::mac::ScopedCFTypeRef<CFStringRef> name(
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        base::SysUTF8ToCFStringRef(current->name));
55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base::mac::ScopedCFTypeRef<CFPropertyListRef> value(
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        preferences_->CopyAppValue(name, kCFPreferencesCurrentApplication));
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!value.get())
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      continue;
59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!preferences_->AppValueIsForced(name, kCFPreferencesCurrentApplication))
60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      continue;
61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    switch (current->value_type) {
63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      case Value::TYPE_STRING:
64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (CFGetTypeID(value) == CFStringGetTypeID()) {
65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          std::string string_value =
66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen              base::SysCFStringRefToUTF8((CFStringRef)value.get());
67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          policy->SetString(current->name, string_value);
68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        break;
70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      case Value::TYPE_BOOLEAN:
71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (CFGetTypeID(value) == CFBooleanGetTypeID()) {
72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          bool bool_value = CFBooleanGetValue((CFBooleanRef)value.get());
73513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          policy->SetBoolean(current->name, bool_value);
74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        break;
76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      case Value::TYPE_INTEGER:
77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (CFGetTypeID(value) == CFNumberGetTypeID()) {
78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          int int_value;
79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          bool cast = CFNumberGetValue((CFNumberRef)value.get(),
80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                       kCFNumberIntType,
81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                       &int_value);
82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          if (cast)
83513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            policy->SetInteger(current->name, int_value);
84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        break;
86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      case Value::TYPE_LIST:
87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (CFGetTypeID(value) == CFArrayGetTypeID()) {
88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          scoped_ptr<ListValue> list_value(new ListValue);
89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          bool valid_array = true;
90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          CFArrayRef array_value = (CFArrayRef)value.get();
91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          for (CFIndex i = 0; i < CFArrayGetCount(array_value); ++i) {
92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            // For now we assume that all values are strings.
93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            CFStringRef array_string =
94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                (CFStringRef)CFArrayGetValueAtIndex(array_value, i);
95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            if (CFGetTypeID(array_string) == CFStringGetTypeID()) {
96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen              std::string array_string_value =
97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                  base::SysCFStringRefToUTF8(array_string);
98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen              list_value->Append(Value::CreateStringValue(array_string_value));
99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            } else {
100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen              valid_array = false;
101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            }
102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          }
103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          if (valid_array)
104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            policy->Set(current->name, list_value.release());
105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        break;
107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      default:
108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        NOTREACHED();
109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return policy;
113513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbase::Time MacPreferencesPolicyProviderDelegate::GetLastModification() {
116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  base::PlatformFileInfo file_info;
117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!file_util::GetFileInfo(config_file_path(), &file_info) ||
118513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      file_info.is_directory) {
119513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return base::Time();
120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
121513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
122513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return file_info.last_modified;
123513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
124513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
125513209b27ff55e2841eac0e4120199c23acce758Ben MurdochConfigurationPolicyProviderMac::ConfigurationPolicyProviderMac(
126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list)
127513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    : FileBasedPolicyProvider(policy_list,
12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          new MacPreferencesPolicyProviderDelegate(new MacPreferences,
12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                   policy_list)) {
130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
132513209b27ff55e2841eac0e4120199c23acce758Ben MurdochConfigurationPolicyProviderMac::ConfigurationPolicyProviderMac(
133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list,
134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    MacPreferences* preferences)
135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    : FileBasedPolicyProvider(policy_list,
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          new MacPreferencesPolicyProviderDelegate(preferences,
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                   policy_list)) {
138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace policy
141