Policies.jsm 9.2 KB
Newer Older
1
2
3
4
5
6
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

7
8
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
9
10
11
XPCOMUtils.defineLazyServiceGetter(this, "gXulStore",
                                   "@mozilla.org/xul/xulstore;1",
                                   "nsIXULStore");
12

13
14
15
16
XPCOMUtils.defineLazyModuleGetters(this, {
  BookmarksPolicies: "resource:///modules/policies/BookmarksPolicies.jsm",
});

17
const PREF_LOGLEVEL           = "browser.policies.loglevel";
18
const BROWSER_DOCUMENT_URL    = "chrome://browser/content/browser.xul";
19
20

XPCOMUtils.defineLazyGetter(this, "log", () => {
21
  let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
22
23
24
25
26
27
28
29
30
  return new ConsoleAPI({
    prefix: "Policies.jsm",
    // tip: set maxLogLevel to "debug" and use log.debug() to create detailed
    // messages during development. See LOG_LEVELS in Console.jsm for details.
    maxLogLevel: "error",
    maxLogLevelPref: PREF_LOGLEVEL,
  });
});

31
var EXPORTED_SYMBOLS = ["Policies"];
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
 * ============================
 * = POLICIES IMPLEMENTATIONS =
 * ============================
 *
 * The Policies object below is where the implementation for each policy
 * happens. An object for each policy should be defined, containing
 * callback functions that will be called by the engine.
 *
 * See the _callbacks object in EnterprisePolicies.js for the list of
 * possible callbacks and an explanation of each.
 *
 * Each callback will be called with two parameters:
 * - manager
 *   This is the EnterprisePoliciesManager singleton object from
 *   EnterprisePolicies.js
 *
 * - param
 *   The parameter defined for this policy in policies-schema.json.
 *   It will be different for each policy. It could be a boolean,
 *   a string, an array or a complex object. All parameters have
 *   been validated according to the schema, and no unknown
 *   properties will be present on them.
 *
 * The callbacks will be bound to their parent policy object.
 */
59
var Policies = {
60
61
62
63
64
65
66
67
  "BlockAboutAddons": {
    onBeforeUIStartup(manager, param) {
      if (param) {
        manager.disallowFeature("about:addons", true);
      }
    }
  },

68
  "BlockAboutConfig": {
69
    onBeforeUIStartup(manager, param) {
70
      if (param) {
71
        manager.disallowFeature("about:config", true);
72
        setAndLockPref("devtools.chrome.enabled", false);
73
74
75
      }
    }
  },
76

77
78
79
80
81
82
83
84
  "BlockAboutProfiles": {
    onBeforeUIStartup(manager, param) {
      if (param) {
        manager.disallowFeature("about:profiles", true);
      }
    }
  },

85
86
87
88
89
90
91
92
  "BlockAboutSupport": {
    onBeforeUIStartup(manager, param) {
      if (param) {
        manager.disallowFeature("about:support", true);
      }
    }
  },

93
  "BlockSetDesktopBackground": {
94
    onBeforeUIStartup(manager, param) {
95
      if (param) {
96
        manager.disallowFeature("setDesktopBackground", true);
97
98
99
100
      }
    }
  },

101
102
103
104
105
106
  "Bookmarks": {
    onAllWindowsRestored(manager, param) {
      BookmarksPolicies.processBookmarks(param);
    }
  },

107
  "Cookies": {
108
    onBeforeUIStartup(manager, param) {
109
      addAllowDenyPermissions("cookie", param.Allow, param.Block);
110
111
112
    }
  },

113
  "CreateMasterPassword": {
114
    onBeforeUIStartup(manager, param) {
115
116
      if (!param) {
        manager.disallowFeature("createMasterPassword");
117
118
119
120
      }
    }
  },

121
122
123
124
  "DisableAppUpdate": {
    onBeforeAddons(manager, param) {
      if (param) {
        manager.disallowFeature("appUpdate");
125
126
127
128
      }
    }
  },

129
130
131
132
133
134
135
136
137
138
139
140
141
142
  "DisableDeveloperTools": {
    onBeforeAddons(manager, param) {
      if (param) {
        setAndLockPref("devtools.policy.disabled", true);
        setAndLockPref("devtools.chrome.enabled", false);

        manager.disallowFeature("devtools");
        manager.disallowFeature("about:devtools");
        manager.disallowFeature("about:debugging");
        manager.disallowFeature("about:devtools-toolbox");
      }
    }
  },

143
144
  "DisableFirefoxScreenshots": {
    onBeforeAddons(manager, param) {
145
      if (param) {
146
147
148
149
150
        setAndLockPref("extensions.screenshots.disabled", true);
      }
    }
  },

151
152
  "DisableFirefoxStudies": {
    onBeforeAddons(manager, param) {
153
      if (param) {
154
155
156
157
158
        manager.disallowFeature("Shield");
      }
    }
  },

159
160
  "DisableFormHistory": {
    onBeforeUIStartup(manager, param) {
161
      if (param) {
162
163
164
165
166
        setAndLockPref("browser.formfill.enable", false);
      }
    }
  },

167
168
169
170
171
172
173
174
  "DisablePocket": {
    onBeforeAddons(manager, param) {
      if (param) {
        setAndLockPref("extensions.pocket.enabled", false);
      }
    }
  },

175
176
177
178
179
180
181
182
183
184
185
  "DisablePrivateBrowsing": {
    onBeforeAddons(manager, param) {
      if (param) {
        manager.disallowFeature("privatebrowsing");
        manager.disallowFeature("about:privatebrowsing", true);
        setAndLockPref("browser.privatebrowsing.autostart", false);
      }
    }
  },


186
  "DisplayBookmarksToolbar": {
187
    onBeforeUIStartup(manager, param) {
188
189
190
191
      if (param) {
        // This policy is meant to change the default behavior, not to force it.
        // If this policy was alreay applied and the user chose to re-hide the
        // bookmarks toolbar, do not show it again.
192
        runOnce("displayBookmarksToolbar", () => {
193
          gXulStore.setValue(BROWSER_DOCUMENT_URL, "PersonalToolbar", "collapsed", "false");
194
        });
195
      }
196
    }
197
198
  },

199
  "DisplayMenuBar": {
200
    onBeforeUIStartup(manager, param) {
201
202
203
204
      if (param) {
        // This policy is meant to change the default behavior, not to force it.
        // If this policy was alreay applied and the user chose to re-hide the
        // menu bar, do not show it again.
205
        runOnce("displayMenuBar", () => {
206
          gXulStore.setValue(BROWSER_DOCUMENT_URL, "toolbar-menubar", "autohide", "false");
207
        });
208
      }
209
210
211
    }
  },

212
  "DontCheckDefaultBrowser": {
213
    onBeforeUIStartup(manager, param) {
214
      setAndLockPref("browser.shell.checkDefaultBrowser", false);
215
216
217
    }
  },

218
  "FlashPlugin": {
219
    onBeforeUIStartup(manager, param) {
220
      addAllowDenyPermissions("plugin:flash", param.Allow, param.Block);
221
222
223
    }
  },

224
  "InstallAddons": {
225
    onBeforeUIStartup(manager, param) {
226
      addAllowDenyPermissions("install", param.Allow, null);
227
228
229
    }
  },

230
  "Popups": {
231
    onBeforeUIStartup(manager, param) {
232
      addAllowDenyPermissions("popup", param.Allow, null);
233
234
235
236
237
238
    }
  },

  "RememberPasswords": {
    onBeforeUIStartup(manager, param) {
      setAndLockPref("signon.rememberSignons", param);
239
240
    }
  },
241
};
242
243
244
245
246
247
248
249
250

/*
 * ====================
 * = HELPER FUNCTIONS =
 * ====================
 *
 * The functions below are helpers to be used by several policies.
 */

251
252
253
254
255
256
257
258
259
260
261
262
263
/**
 * setAndLockPref
 *
 * Sets the _default_ value of a pref, and locks it (meaning that
 * the default value will always be returned, independent from what
 * is stored as the user value).
 * The value is only changed in memory, and not stored to disk.
 *
 * @param {string} prefName
 *        The pref to be changed
 * @param {boolean,number,string} prefValue
 *        The value to set and lock
 */
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
function setAndLockPref(prefName, prefValue) {
  if (Services.prefs.prefIsLocked(prefName)) {
    Services.prefs.unlockPref(prefName);
  }

  let defaults = Services.prefs.getDefaultBranch("");

  switch (typeof(prefValue)) {
    case "boolean":
      defaults.setBoolPref(prefName, prefValue);
      break;

    case "number":
      if (!Number.isInteger(prefValue)) {
        throw new Error(`Non-integer value for ${prefName}`);
      }

      defaults.setIntPref(prefName, prefValue);
      break;

    case "string":
      defaults.setStringPref(prefName, prefValue);
      break;
  }

  Services.prefs.lockPref(prefName);
}
291

292
293
294
295
296
297
298
299
300
301
302
303
304
/**
 * addAllowDenyPermissions
 *
 * Helper function to call the permissions manager (Services.perms.add)
 * for two arrays of URLs.
 *
 * @param {string} permissionName
 *        The name of the permission to change
 * @param {array} allowList
 *        The list of URLs to be set as ALLOW_ACTION for the chosen permission.
 * @param {array} blockList
 *        The list of URLs to be set as DENY_ACTION for the chosen permission.
 */
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
function addAllowDenyPermissions(permissionName, allowList, blockList) {
  allowList = allowList || [];
  blockList = blockList || [];

  for (let origin of allowList) {
    Services.perms.add(origin,
                       permissionName,
                       Ci.nsIPermissionManager.ALLOW_ACTION,
                       Ci.nsIPermissionManager.EXPIRE_POLICY);
  }

  for (let origin of blockList) {
    Services.perms.add(origin,
                       permissionName,
                       Ci.nsIPermissionManager.DENY_ACTION,
                       Ci.nsIPermissionManager.EXPIRE_POLICY);
  }
}
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342

/**
 * runOnce
 *
 * Helper function to run a callback only once per policy.
 *
 * @param {string} actionName
 *        A given name which will be used to track if this callback has run.
 * @param {Functon} callback
 *        The callback to run only once.
 */
function runOnce(actionName, callback) {
  let prefName = `browser.policies.runonce.${actionName}`;
  if (Services.prefs.getBoolPref(prefName, false)) {
    log.debug(`Not running action ${actionName} again because it has already run.`);
    return;
  }
  callback();
  Services.prefs.setBoolPref(prefName, true);
}