| OLD | NEW |
| (Empty) |
| 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 #include "base/memory/free_deleter.h" | |
| 12 | |
| 13 namespace sandbox { | |
| 14 | |
| 15 bool GetDefaultDacl( | |
| 16 HANDLE token, | |
| 17 scoped_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter>* default_dacl) { | |
| 18 if (token == NULL) | |
| 19 return false; | |
| 20 | |
| 21 DCHECK(default_dacl != NULL); | |
| 22 | |
| 23 unsigned long length = 0; | |
| 24 ::GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &length); | |
| 25 if (length == 0) { | |
| 26 NOTREACHED(); | |
| 27 return false; | |
| 28 } | |
| 29 | |
| 30 TOKEN_DEFAULT_DACL* acl = | |
| 31 reinterpret_cast<TOKEN_DEFAULT_DACL*>(malloc(length)); | |
| 32 default_dacl->reset(acl); | |
| 33 | |
| 34 if (!::GetTokenInformation(token, TokenDefaultDacl, default_dacl->get(), | |
| 35 length, &length)) | |
| 36 return false; | |
| 37 | |
| 38 return true; | |
| 39 } | |
| 40 | |
| 41 bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MODE access_mode, | |
| 42 ACCESS_MASK access, ACL** new_dacl) { | |
| 43 EXPLICIT_ACCESS new_access = {0}; | |
| 44 new_access.grfAccessMode = access_mode; | |
| 45 new_access.grfAccessPermissions = access; | |
| 46 new_access.grfInheritance = NO_INHERITANCE; | |
| 47 | |
| 48 new_access.Trustee.pMultipleTrustee = NULL; | |
| 49 new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; | |
| 50 new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID; | |
| 51 new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>( | |
| 52 const_cast<SID*>(sid.GetPSID())); | |
| 53 | |
| 54 if (ERROR_SUCCESS != ::SetEntriesInAcl(1, &new_access, old_dacl, new_dacl)) | |
| 55 return false; | |
| 56 | |
| 57 return true; | |
| 58 } | |
| 59 | |
| 60 bool AddSidToDefaultDacl(HANDLE token, | |
| 61 const Sid& sid, | |
| 62 ACCESS_MODE access_mode, | |
| 63 ACCESS_MASK access) { | |
| 64 if (token == NULL) | |
| 65 return false; | |
| 66 | |
| 67 scoped_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter> default_dacl; | |
| 68 if (!GetDefaultDacl(token, &default_dacl)) | |
| 69 return false; | |
| 70 | |
| 71 ACL* new_dacl = NULL; | |
| 72 if (!AddSidToDacl(sid, default_dacl->DefaultDacl, access_mode, access, | |
| 73 &new_dacl)) | |
| 74 return false; | |
| 75 | |
| 76 TOKEN_DEFAULT_DACL new_token_dacl = {0}; | |
| 77 new_token_dacl.DefaultDacl = new_dacl; | |
| 78 | |
| 79 BOOL ret = ::SetTokenInformation(token, TokenDefaultDacl, &new_token_dacl, | |
| 80 sizeof(new_token_dacl)); | |
| 81 ::LocalFree(new_dacl); | |
| 82 return (TRUE == ret); | |
| 83 } | |
| 84 | |
| 85 bool RevokeLogonSidFromDefaultDacl(HANDLE token) { | |
| 86 DWORD size = sizeof(TOKEN_GROUPS) + SECURITY_MAX_SID_SIZE; | |
| 87 TOKEN_GROUPS* logon_sid = reinterpret_cast<TOKEN_GROUPS*>(malloc(size)); | |
| 88 | |
| 89 scoped_ptr<TOKEN_GROUPS, base::FreeDeleter> logon_sid_ptr(logon_sid); | |
| 90 | |
| 91 if (!::GetTokenInformation(token, TokenLogonSid, logon_sid, size, &size)) | |
| 92 return false; | |
| 93 if (logon_sid->GroupCount < 1) { | |
| 94 ::SetLastError(ERROR_INVALID_TOKEN); | |
| 95 return false; | |
| 96 } | |
| 97 return AddSidToDefaultDacl(token, | |
| 98 reinterpret_cast<SID*>(logon_sid->Groups[0].Sid), | |
| 99 REVOKE_ACCESS, 0); | |
| 100 } | |
| 101 | |
| 102 bool AddUserSidToDefaultDacl(HANDLE token, ACCESS_MASK access) { | |
| 103 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; | |
| 104 TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(malloc(size)); | |
| 105 | |
| 106 scoped_ptr<TOKEN_USER, base::FreeDeleter> token_user_ptr(token_user); | |
| 107 | |
| 108 if (!::GetTokenInformation(token, TokenUser, token_user, size, &size)) | |
| 109 return false; | |
| 110 | |
| 111 return AddSidToDefaultDacl(token, | |
| 112 reinterpret_cast<SID*>(token_user->User.Sid), | |
| 113 GRANT_ACCESS, access); | |
| 114 } | |
| 115 | |
| 116 bool AddKnownSidToObject(HANDLE object, SE_OBJECT_TYPE object_type, | |
| 117 const Sid& sid, ACCESS_MODE access_mode, | |
| 118 ACCESS_MASK access) { | |
| 119 PSECURITY_DESCRIPTOR descriptor = NULL; | |
| 120 PACL old_dacl = NULL; | |
| 121 PACL new_dacl = NULL; | |
| 122 | |
| 123 if (ERROR_SUCCESS != ::GetSecurityInfo(object, object_type, | |
| 124 DACL_SECURITY_INFORMATION, NULL, NULL, | |
| 125 &old_dacl, NULL, &descriptor)) | |
| 126 return false; | |
| 127 | |
| 128 if (!AddSidToDacl(sid.GetPSID(), old_dacl, access_mode, access, &new_dacl)) { | |
| 129 ::LocalFree(descriptor); | |
| 130 return false; | |
| 131 } | |
| 132 | |
| 133 DWORD result = ::SetSecurityInfo(object, object_type, | |
| 134 DACL_SECURITY_INFORMATION, NULL, NULL, | |
| 135 new_dacl, NULL); | |
| 136 | |
| 137 ::LocalFree(new_dacl); | |
| 138 ::LocalFree(descriptor); | |
| 139 | |
| 140 if (ERROR_SUCCESS != result) | |
| 141 return false; | |
| 142 | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 } // namespace sandbox | |
| OLD | NEW |