15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/registry_policy.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/ipc_tags.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_opcodes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_params.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_utils.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_types.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/win_utils.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const DWORD kAllowedRegFlags = KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS |
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      KEY_NOTIFY | KEY_READ | GENERIC_READ |
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      GENERIC_EXECUTE | READ_CONTROL;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opens the key referenced by |obj_attributes| with |access| and
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// checks what permission was given. Remove the WRITE flags and update
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |access| with the new value.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS TranslateMaximumAllowed(OBJECT_ATTRIBUTES* obj_attributes,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 DWORD* access) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NtOpenKeyFunction NtOpenKey = NULL;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResolveNTFunctionPtr("NtOpenKey", &NtOpenKey);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NtCloseFunction NtClose = NULL;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResolveNTFunctionPtr("NtClose", &NtClose);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NtQueryObjectFunction NtQueryObject = NULL;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open the key.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE handle;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = NtOpenKey(&handle, *access, obj_attributes);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!NT_SUCCESS(status))
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OBJECT_BASIC_INFORMATION info = {0};
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  status = NtQueryObject(handle, ObjectBasicInformation, &info, sizeof(info),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         NULL);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NtClose(handle);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!NT_SUCCESS(status))
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *access = info.GrantedAccess & kAllowedRegFlags;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return STATUS_SUCCESS;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS NtCreateKeyInTarget(HANDLE* target_key_handle,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ACCESS_MASK desired_access,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             OBJECT_ATTRIBUTES* obj_attributes,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ULONG title_index,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             UNICODE_STRING* class_name,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ULONG create_options,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ULONG* disposition,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HANDLE target_process) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NtCreateKeyFunction NtCreateKey = NULL;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResolveNTFunctionPtr("NtCreateKey", &NtCreateKey);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MAXIMUM_ALLOWED & desired_access) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NTSTATUS status = TranslateMaximumAllowed(obj_attributes, &desired_access);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(status))
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return STATUS_ACCESS_DENIED;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE local_handle = INVALID_HANDLE_VALUE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = NtCreateKey(&local_handle, desired_access, obj_attributes,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                title_index, class_name, create_options,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                disposition);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!NT_SUCCESS(status))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         target_process, target_key_handle, 0, FALSE,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return STATUS_ACCESS_DENIED;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return STATUS_SUCCESS;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS NtOpenKeyInTarget(HANDLE* target_key_handle,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ACCESS_MASK desired_access,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           OBJECT_ATTRIBUTES* obj_attributes,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           HANDLE target_process) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NtOpenKeyFunction NtOpenKey = NULL;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResolveNTFunctionPtr("NtOpenKey", &NtOpenKey);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MAXIMUM_ALLOWED & desired_access) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NTSTATUS status = TranslateMaximumAllowed(obj_attributes, &desired_access);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!NT_SUCCESS(status))
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return STATUS_ACCESS_DENIED;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE local_handle = INVALID_HANDLE_VALUE;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = NtOpenKey(&local_handle, desired_access, obj_attributes);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!NT_SUCCESS(status))
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         target_process, target_key_handle, 0, FALSE,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return STATUS_ACCESS_DENIED;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return STATUS_SUCCESS;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RegistryPolicy::GenerateRules(const wchar_t* name,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   TargetPolicy::Semantics semantics,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   LowLevelPolicy* policy) {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 resovled_name(name);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resovled_name.empty()) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ResolveRegistryName(resovled_name, &resovled_name))
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name = resovled_name.c_str();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EvalResult result = ASK_BROKER;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyRule open(result);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyRule create(result);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (semantics) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TargetPolicy::REG_ALLOW_READONLY: {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We consider all flags that are not known to be readonly as potentially
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // used for write. Here we also support MAXIMUM_ALLOWED, but we are going
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // to expand it to read-only before the call.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DWORD restricted_flags = ~(kAllowedRegFlags | MAXIMUM_ALLOWED);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      open.AddNumberMatch(IF_NOT, OpenKey::ACCESS, restricted_flags, AND);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      create.AddNumberMatch(IF_NOT, OpenKey::ACCESS, restricted_flags, AND);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TargetPolicy::REG_ALLOW_ANY: {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default: {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!create.AddStringMatch(IF, OpenKey::NAME, name, CASE_INSENSITIVE) ||
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy->AddRule(IPC_NTCREATEKEY_TAG, &create)) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!open.AddStringMatch(IF, OpenKey::NAME, name, CASE_INSENSITIVE) ||
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !policy->AddRule(IPC_NTOPENKEY_TAG, &open)) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RegistryPolicy::CreateKeyAction(EvalResult eval_result,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const ClientInfo& client_info,
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     const base::string16 &key,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     uint32 attributes,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     HANDLE root_directory,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     uint32 desired_access,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     uint32 title_index,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     uint32 create_options,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     HANDLE* handle,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     NTSTATUS* nt_status,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     ULONG* disposition) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The only action supported is ASK_BROKER which means create the requested
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file as specified.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ASK_BROKER != eval_result) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *nt_status = STATUS_ACCESS_DENIED;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't support creating link keys, volatile keys or backup/restore.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (create_options) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *nt_status = STATUS_ACCESS_DENIED;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNICODE_STRING uni_name = {0};
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OBJECT_ATTRIBUTES obj_attributes = {0};
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitObjectAttribs(key, attributes, root_directory, &obj_attributes,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &uni_name);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *nt_status = NtCreateKeyInTarget(handle, desired_access, &obj_attributes,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   title_index, NULL, create_options,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   disposition, client_info.process);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RegistryPolicy::OpenKeyAction(EvalResult eval_result,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const ClientInfo& client_info,
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   const base::string16 &key,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   uint32 attributes,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   HANDLE root_directory,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   uint32 desired_access,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   HANDLE* handle,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   NTSTATUS* nt_status) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The only action supported is ASK_BROKER which means open the requested
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file as specified.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ASK_BROKER != eval_result) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *nt_status = STATUS_ACCESS_DENIED;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNICODE_STRING uni_name = {0};
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OBJECT_ATTRIBUTES obj_attributes = {0};
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitObjectAttribs(key, attributes, root_directory, &obj_attributes,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    &uni_name);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *nt_status = NtOpenKeyInTarget(handle, desired_access, &obj_attributes,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                client_info.process);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace sandbox
226