1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "sandbox/win/src/acl.h" 6 7 #include <aclapi.h> 8 #include <sddl.h> 9 10 #include "base/logging.h" 11 12 namespace sandbox { 13 14 bool GetDefaultDacl(HANDLE token, 15 scoped_ptr_malloc<TOKEN_DEFAULT_DACL>* default_dacl) { 16 if (token == NULL) 17 return false; 18 19 DCHECK(default_dacl != NULL); 20 21 unsigned long length = 0; 22 ::GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &length); 23 if (length == 0) { 24 NOTREACHED(); 25 return false; 26 } 27 28 TOKEN_DEFAULT_DACL* acl = 29 reinterpret_cast<TOKEN_DEFAULT_DACL*>(malloc(length)); 30 default_dacl->reset(acl); 31 32 if (!::GetTokenInformation(token, TokenDefaultDacl, default_dacl->get(), 33 length, &length)) 34 return false; 35 36 return true; 37 } 38 39 bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MODE access_mode, 40 ACCESS_MASK access, ACL** new_dacl) { 41 EXPLICIT_ACCESS new_access = {0}; 42 new_access.grfAccessMode = access_mode; 43 new_access.grfAccessPermissions = access; 44 new_access.grfInheritance = NO_INHERITANCE; 45 46 new_access.Trustee.pMultipleTrustee = NULL; 47 new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 48 new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID; 49 new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>( 50 const_cast<SID*>(sid.GetPSID())); 51 52 if (ERROR_SUCCESS != ::SetEntriesInAcl(1, &new_access, old_dacl, new_dacl)) 53 return false; 54 55 return true; 56 } 57 58 bool AddSidToDefaultDacl(HANDLE token, const Sid& sid, ACCESS_MASK access) { 59 if (token == NULL) 60 return false; 61 62 scoped_ptr_malloc<TOKEN_DEFAULT_DACL> default_dacl; 63 if (!GetDefaultDacl(token, &default_dacl)) 64 return false; 65 66 ACL* new_dacl = NULL; 67 if (!AddSidToDacl(sid, default_dacl->DefaultDacl, GRANT_ACCESS, access, 68 &new_dacl)) 69 return false; 70 71 TOKEN_DEFAULT_DACL new_token_dacl = {0}; 72 new_token_dacl.DefaultDacl = new_dacl; 73 74 BOOL ret = ::SetTokenInformation(token, TokenDefaultDacl, &new_token_dacl, 75 sizeof(new_token_dacl)); 76 ::LocalFree(new_dacl); 77 return (TRUE == ret); 78 } 79 80 bool AddUserSidToDefaultDacl(HANDLE token, ACCESS_MASK access) { 81 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; 82 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(malloc(size)); 83 84 scoped_ptr_malloc<TOKEN_USER> token_user_ptr(token_user); 85 86 if (!::GetTokenInformation(token, TokenUser, token_user, size, &size)) 87 return false; 88 89 return AddSidToDefaultDacl(token, 90 reinterpret_cast<SID*>(token_user->User.Sid), 91 access); 92 } 93 94 bool AddKnownSidToObject(HANDLE object, SE_OBJECT_TYPE object_type, 95 const Sid& sid, ACCESS_MODE access_mode, 96 ACCESS_MASK access) { 97 PSECURITY_DESCRIPTOR descriptor = NULL; 98 PACL old_dacl = NULL; 99 PACL new_dacl = NULL; 100 101 if (ERROR_SUCCESS != ::GetSecurityInfo(object, object_type, 102 DACL_SECURITY_INFORMATION, NULL, NULL, 103 &old_dacl, NULL, &descriptor)) 104 return false; 105 106 if (!AddSidToDacl(sid.GetPSID(), old_dacl, access_mode, access, &new_dacl)) { 107 ::LocalFree(descriptor); 108 return false; 109 } 110 111 DWORD result = ::SetSecurityInfo(object, object_type, 112 DACL_SECURITY_INFORMATION, NULL, NULL, 113 new_dacl, NULL); 114 115 ::LocalFree(new_dacl); 116 ::LocalFree(descriptor); 117 118 if (ERROR_SUCCESS != result) 119 return false; 120 121 return true; 122 } 123 124 } // namespace sandbox 125