Bug 1463895 - Allow some policies to be machine-only. r=mkaply
authorFelipe Gomes <felipc@gmail.com>
Mon, 28 May 2018 18:35:15 -0300
changeset 421832 5c20da9b09875a22bfde156ebd5e372a0de8d0d1
parent 421831 6a6e61fb16661ee52992f0171e5d84d82986918f
child 421833 7143eb15fac9e6b8545d12e17bc0b62997a61cf4
push id104125
push useraciure@mozilla.com
push dateThu, 07 Jun 2018 21:57:03 +0000
treeherdermozilla-inbound@38c222c1bf73 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkaply
bugs1463895
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1463895 - Allow some policies to be machine-only. r=mkaply Machine-only policies can only be triggered from sources that require user privileges to make machine-wide changes. Currently, that means the policies.json file in the installation folder, or the HKEY_LOCAL_MACHINE registry root. In other words, it currently excludes the HKEY_CURRENT_USER registry root MozReview-Commit-ID: G9wxEM19yVb
browser/components/enterprisepolicies/EnterprisePolicies.js
browser/components/enterprisepolicies/WindowsGPOParser.jsm
--- a/browser/components/enterprisepolicies/EnterprisePolicies.js
+++ b/browser/components/enterprisepolicies/EnterprisePolicies.js
@@ -419,46 +419,39 @@ class JSONPoliciesProvider {
   }
 }
 
 class GPOPoliciesProvider {
   constructor() {
     this._policies = null;
 
     let wrk = Cc["@mozilla.org/windows-registry-key;1"].createInstance(Ci.nsIWindowsRegKey);
+
     // Machine policies override user policies, so we read
     // user policies first and then replace them if necessary.
-    wrk.open(wrk.ROOT_KEY_CURRENT_USER,
-             "SOFTWARE\\Policies",
-             wrk.ACCESS_READ);
-    if (wrk.hasChild("Mozilla\\Firefox")) {
-      this._readData(wrk);
-    }
-    wrk.close();
-
-    wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
-             "SOFTWARE\\Policies",
-             wrk.ACCESS_READ);
-    if (wrk.hasChild("Mozilla\\Firefox")) {
-      this._readData(wrk);
-    }
-    wrk.close();
+    this._readData(wrk, wrk.ROOT_KEY_CURRENT_USER);
+    this._readData(wrk, wrk.ROOT_KEY_LOCAL_MACHINE);
   }
 
   get hasPolicies() {
     return this._policies !== null;
   }
 
   get policies() {
     return this._policies;
   }
 
   get failed() {
     return this._failed;
   }
 
-  _readData(wrk) {
-    this._policies = WindowsGPOParser.readPolicies(wrk, this._policies);
+  _readData(wrk, root) {
+    wrk.open(root, "SOFTWARE\\Policies", wrk.ACCESS_READ);
+    if (wrk.hasChild("Mozilla\\Firefox")) {
+      let isMachineRoot = (root == wrk.ROOT_KEY_LOCAL_MACHINE);
+      this._policies = WindowsGPOParser.readPolicies(wrk, this._policies, isMachineRoot);
+    }
+    wrk.close();
   }
 }
 
 var components = [EnterprisePoliciesManager];
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/browser/components/enterprisepolicies/WindowsGPOParser.jsm
+++ b/browser/components/enterprisepolicies/WindowsGPOParser.jsm
@@ -14,57 +14,70 @@ XPCOMUtils.defineLazyGetter(this, "log",
     prefix: "GPOParser.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,
   });
 });
 
+XPCOMUtils.defineLazyModuleGetters(this, {
+  schema: "resource:///modules/policies/schema.jsm",
+});
+
 var EXPORTED_SYMBOLS = ["WindowsGPOParser"];
 
 var WindowsGPOParser = {
-  readPolicies(wrk, policies) {
+  readPolicies(wrk, policies, isMachineRoot) {
     let childWrk = wrk.openChild("Mozilla\\Firefox", wrk.ACCESS_READ);
     if (!policies) {
       policies = {};
     }
     try {
-      policies = registryToObject(childWrk, policies);
+      policies = registryToObject(childWrk, policies, isMachineRoot);
     } catch (e) {
       log.error(e);
     } finally {
       childWrk.close();
     }
     // Need an extra check here so we don't
     // JSON.stringify if we aren't in debug mode
     if (log._maxLogLevel == "debug") {
+      log.debug("root = " + isMachineRoot ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER");
       log.debug(JSON.stringify(policies, null, 2));
     }
     return policies;
   }
 };
 
-function registryToObject(wrk, policies) {
+function registryToObject(wrk, policies, isMachineRoot) {
   if (!policies) {
     policies = {};
   }
   if (wrk.valueCount > 0) {
     if (wrk.getValueName(0) == "1") {
       // If the first item is 1, just assume it is an array
       let array = [];
       for (let i = 0; i < wrk.valueCount; i++) {
         array.push(readRegistryValue(wrk, wrk.getValueName(i)));
       }
       // If it's an array, it shouldn't have any children
       return array;
     }
     for (let i = 0; i < wrk.valueCount; i++) {
       let name = wrk.getValueName(i);
       let value = readRegistryValue(wrk, name);
+
+      if (!isMachineRoot &&
+          schema.properties[name] &&
+          schema.properties[name].machine_only) {
+        log.error(`Policy ${name} is only allowed under the HKEY_LOCAL_MACHINE root`);
+        continue;
+      }
+
       policies[name] = value;
     }
   }
   if (wrk.childCount > 0) {
     if (wrk.getChildName(0) == "1") {
       // If the first item is 1, it's an array of objects
       let array = [];
       for (let i = 0; i < wrk.childCount; i++) {