1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
6 
7 #include "WinTokenUtils.h"
8 #include "nsWindowsHelpers.h"
9 
10 using namespace mozilla;
11 
12 // If |aToken| is nullptr, CheckTokenMembership uses the calling thread's
13 // primary token to check membership for.
IsMemberOfAdministrators(const nsAutoHandle & aToken)14 static LauncherResult<bool> IsMemberOfAdministrators(
15     const nsAutoHandle& aToken) {
16   BYTE adminsGroupSid[SECURITY_MAX_SID_SIZE];
17   DWORD adminsGroupSidSize = sizeof(adminsGroupSid);
18   if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, nullptr, adminsGroupSid,
19                           &adminsGroupSidSize)) {
20     return LAUNCHER_ERROR_FROM_LAST();
21   }
22 
23   BOOL isMember;
24   if (!CheckTokenMembership(aToken, adminsGroupSid, &isMember)) {
25     return LAUNCHER_ERROR_FROM_LAST();
26   }
27   return !!isMember;
28 }
29 
IsUacEnabled()30 static LauncherResult<bool> IsUacEnabled() {
31   DWORD len = sizeof(DWORD);
32   DWORD value;
33   LSTATUS status = RegGetValueW(
34       HKEY_LOCAL_MACHINE,
35       L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
36       L"EnableLUA", RRF_RT_DWORD, nullptr, &value, &len);
37   if (status != ERROR_SUCCESS) {
38     return LAUNCHER_ERROR_FROM_WIN32(status);
39   }
40 
41   // UAC is disabled only when EnableLUA is 0.
42   return (value != 0);
43 }
44 
45 namespace mozilla {
46 
IsAdminWithoutUac()47 LauncherResult<bool> IsAdminWithoutUac() {
48   // To check whether the process was launched with Administrator priviledges
49   // or not, we cannot simply check the integrity level of the current process
50   // because the launcher process spawns the browser process with the medium
51   // integrity level even though the launcher process is high integrity level.
52   // We check whether the thread's token contains Administratos SID or not
53   // instead.
54   LauncherResult<bool> containsAdminGroup =
55       IsMemberOfAdministrators(nsAutoHandle());
56   if (containsAdminGroup.isErr()) {
57     return containsAdminGroup.propagateErr();
58   }
59 
60   if (!containsAdminGroup.unwrap()) {
61     return false;
62   }
63 
64   LauncherResult<bool> isUacEnabled = IsUacEnabled();
65   if (isUacEnabled.isErr()) {
66     return isUacEnabled.propagateErr();
67   }
68 
69   return !isUacEnabled.unwrap();
70 }
71 
72 }  // namespace mozilla
73