1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/acl.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,122 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "sandbox/win/src/acl.h" 1.9 + 1.10 +#include <aclapi.h> 1.11 +#include <sddl.h> 1.12 + 1.13 +#include "base/logging.h" 1.14 + 1.15 +namespace sandbox { 1.16 + 1.17 +bool GetDefaultDacl(HANDLE token, 1.18 + scoped_ptr_malloc<TOKEN_DEFAULT_DACL>* default_dacl) { 1.19 + if (token == NULL) 1.20 + return false; 1.21 + 1.22 + DCHECK(default_dacl != NULL); 1.23 + 1.24 + unsigned long length = 0; 1.25 + ::GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &length); 1.26 + if (length == 0) { 1.27 + NOTREACHED(); 1.28 + return false; 1.29 + } 1.30 + 1.31 + TOKEN_DEFAULT_DACL* acl = 1.32 + reinterpret_cast<TOKEN_DEFAULT_DACL*>(malloc(length)); 1.33 + default_dacl->reset(acl); 1.34 + 1.35 + if (!::GetTokenInformation(token, TokenDefaultDacl, default_dacl->get(), 1.36 + length, &length)) 1.37 + return false; 1.38 + 1.39 + return true; 1.40 +} 1.41 + 1.42 +bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MASK access, 1.43 + ACL** new_dacl) { 1.44 + EXPLICIT_ACCESS new_access = {0}; 1.45 + new_access.grfAccessMode = GRANT_ACCESS; 1.46 + new_access.grfAccessPermissions = access; 1.47 + new_access.grfInheritance = NO_INHERITANCE; 1.48 + 1.49 + new_access.Trustee.pMultipleTrustee = NULL; 1.50 + new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 1.51 + new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID; 1.52 + new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>( 1.53 + const_cast<SID*>(sid.GetPSID())); 1.54 + 1.55 + if (ERROR_SUCCESS != ::SetEntriesInAcl(1, &new_access, old_dacl, new_dacl)) 1.56 + return false; 1.57 + 1.58 + return true; 1.59 +} 1.60 + 1.61 +bool AddSidToDefaultDacl(HANDLE token, const Sid& sid, ACCESS_MASK access) { 1.62 + if (token == NULL) 1.63 + return false; 1.64 + 1.65 + scoped_ptr_malloc<TOKEN_DEFAULT_DACL> default_dacl; 1.66 + if (!GetDefaultDacl(token, &default_dacl)) 1.67 + return false; 1.68 + 1.69 + ACL* new_dacl = NULL; 1.70 + if (!AddSidToDacl(sid, default_dacl->DefaultDacl, access, &new_dacl)) 1.71 + return false; 1.72 + 1.73 + TOKEN_DEFAULT_DACL new_token_dacl = {0}; 1.74 + new_token_dacl.DefaultDacl = new_dacl; 1.75 + 1.76 + BOOL ret = ::SetTokenInformation(token, TokenDefaultDacl, &new_token_dacl, 1.77 + sizeof(new_token_dacl)); 1.78 + ::LocalFree(new_dacl); 1.79 + return (TRUE == ret); 1.80 +} 1.81 + 1.82 +bool AddUserSidToDefaultDacl(HANDLE token, ACCESS_MASK access) { 1.83 + DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; 1.84 + TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(malloc(size)); 1.85 + 1.86 + scoped_ptr_malloc<TOKEN_USER> token_user_ptr(token_user); 1.87 + 1.88 + if (!::GetTokenInformation(token, TokenUser, token_user, size, &size)) 1.89 + return false; 1.90 + 1.91 + return AddSidToDefaultDacl(token, 1.92 + reinterpret_cast<SID*>(token_user->User.Sid), 1.93 + access); 1.94 +} 1.95 + 1.96 +bool AddKnownSidToKernelObject(HANDLE object, const Sid& sid, 1.97 + ACCESS_MASK access) { 1.98 + PSECURITY_DESCRIPTOR descriptor = NULL; 1.99 + PACL old_dacl = NULL; 1.100 + PACL new_dacl = NULL; 1.101 + 1.102 + if (ERROR_SUCCESS != ::GetSecurityInfo(object, SE_KERNEL_OBJECT, 1.103 + DACL_SECURITY_INFORMATION, NULL, NULL, 1.104 + &old_dacl, NULL, &descriptor)) 1.105 + return false; 1.106 + 1.107 + if (!AddSidToDacl(sid.GetPSID(), old_dacl, access, &new_dacl)) { 1.108 + ::LocalFree(descriptor); 1.109 + return false; 1.110 + } 1.111 + 1.112 + DWORD result = ::SetSecurityInfo(object, SE_KERNEL_OBJECT, 1.113 + DACL_SECURITY_INFORMATION, NULL, NULL, 1.114 + new_dacl, NULL); 1.115 + 1.116 + ::LocalFree(new_dacl); 1.117 + ::LocalFree(descriptor); 1.118 + 1.119 + if (ERROR_SUCCESS != result) 1.120 + return false; 1.121 + 1.122 + return true; 1.123 +} 1.124 + 1.125 +} // namespace sandbox