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 |