1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SANDBOX_SRC_RESTRICTED_TOKEN_H__
#define SANDBOX_SRC_RESTRICTED_TOKEN_H__
#include <windows.h>
#include <vector>
#include "base/basictypes.h"
#include "sandbox/src/restricted_token_utils.h"
#include "sandbox/src/security_level.h"
#include "sandbox/src/sid.h"
// Flags present in the Group SID list. These 2 flags are new in Windows Vista
#ifndef SE_GROUP_INTEGRITY
#define SE_GROUP_INTEGRITY (0x00000020L)
#endif
#ifndef SE_GROUP_INTEGRITY_ENABLED
#define SE_GROUP_INTEGRITY_ENABLED (0x00000040L)
#endif
namespace sandbox {
// Handles the creation of a restricted token using the effective token or
// any token handle.
// Sample usage:
// RestrictedToken restricted_token;
// unsigned err_code = restricted_token.Init(NULL); // Use the current
// // effective token
// if (ERROR_SUCCESS != err_code) {
// // handle error.
// }
//
// restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID());
// HANDLE token_handle;
// err_code = restricted_token.GetRestrictedTokenHandle(&token_handle);
// if (ERROR_SUCCESS != err_code) {
// // handle error.
// }
// [...]
// CloseHandle(token_handle);
class RestrictedToken {
public:
// Init() has to be called before calling any other method in the class.
RestrictedToken()
: init_(false), effective_token_(NULL),
integrity_level_(INTEGRITY_LEVEL_LAST) { }
~RestrictedToken() {
if (effective_token_)
CloseHandle(effective_token_);
}
// Initializes the RestrictedToken object with effective_token.
// If effective_token is NULL, it initializes the RestrictedToken object with
// the effective token of the current process.
unsigned Init(HANDLE effective_token);
// Creates a restricted token and returns its handle using the token_handle
// output parameter. This handle has to be closed by the caller.
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
unsigned GetRestrictedTokenHandle(HANDLE *token_handle) const;
// Creates a restricted token and uses this new token to create a new token
// for impersonation. Returns the handle of this impersonation token using
// the token_handle output parameter. This handle has to be closed by
// the caller.
//
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
//
// The sample usage is the same as the GetRestrictedTokenHandle function.
unsigned GetRestrictedTokenHandleForImpersonation(HANDLE *token_handle) const;
// Lists all sids in the token and mark them as Deny Only except for those
// present in the exceptions parameter. If there is no exception needed,
// the caller can pass an empty list or NULL for the exceptions
// parameter.
//
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
//
// Sample usage:
// std::vector<Sid> sid_exceptions;
// sid_exceptions.push_back(ATL::Sids::Users().GetPSID());
// sid_exceptions.push_back(ATL::Sids::World().GetPSID());
// restricted_token.AddAllSidsForDenyOnly(&sid_exceptions);
// Note: A Sid marked for Deny Only in a token cannot be used to grant
// access to any resource. It can only be used to deny access.
unsigned AddAllSidsForDenyOnly(std::vector<Sid> *exceptions);
// Adds a user or group SID for Deny Only in the restricted token.
// Parameter: sid is the SID to add in the Deny Only list.
// The return value is always ERROR_SUCCESS.
//
// Sample Usage:
// restricted_token.AddSidForDenyOnly(ATL::Sids::Admins().GetPSID());
unsigned AddSidForDenyOnly(const Sid &sid);
// Adds the user sid of the token for Deny Only in the restricted token.
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
unsigned AddUserSidForDenyOnly();
// Lists all privileges in the token and add them to the list of privileges
// to remove except for those present in the exceptions parameter. If
// there is no exception needed, the caller can pass an empty list or NULL
// for the exceptions parameter.
//
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
//
// Sample usage:
// std::vector<std::wstring> privilege_exceptions;
// privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
// restricted_token.DeleteAllPrivileges(&privilege_exceptions);
unsigned DeleteAllPrivileges(
const std::vector<std::wstring> *exceptions);
// Adds a privilege to the list of privileges to remove in the restricted
// token.
// Parameter: privilege is the privilege name to remove. This is the string
// representing the privilege. (e.g. "SeChangeNotifyPrivilege").
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
//
// Sample usage:
// restricted_token.DeletePrivilege(SE_LOAD_DRIVER_NAME);
unsigned DeletePrivilege(const wchar_t *privilege);
// Adds a SID to the list of restricting sids in the restricted token.
// Parameter: sid is the sid to add to the list restricting sids.
// The return value is always ERROR_SUCCESS.
//
// Sample usage:
// restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID());
// Note: The list of restricting is used to force Windows to perform all
// access checks twice. The first time using your user SID and your groups,
// and the second time using your list of restricting sids. The access has
// to be granted in both places to get access to the resource requested.
unsigned AddRestrictingSid(const Sid &sid);
// Adds the logon sid of the token in the list of restricting sids for the
// restricted token.
//
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
unsigned AddRestrictingSidLogonSession();
// Adds the owner sid of the token in the list of restricting sids for the
// restricted token.
//
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
unsigned AddRestrictingSidCurrentUser();
// Adds all group sids and the user sid to the restricting sids list.
//
// If the function succeeds, the return value is ERROR_SUCCESS. If the
// function fails, the return value is the win32 error code corresponding to
// the error.
unsigned AddRestrictingSidAllSids();
// Sets the token integrity level. This is only valid on Vista. The integrity
// level cannot be higher than your current integrity level.
unsigned SetIntegrityLevel(IntegrityLevel integrity_level);
private:
// The list of restricting sids in the restricted token.
std::vector<Sid> sids_to_restrict_;
// The list of privileges to remove in the restricted token.
std::vector<LUID> privileges_to_disable_;
// The list of sids to mark as Deny Only in the restricted token.
std::vector<Sid> sids_for_deny_only_;
// The token to restrict. Can only be set in a constructor.
HANDLE effective_token_;
// The token integrity level. Only valid on Vista.
IntegrityLevel integrity_level_;
// Tells if the object is initialized or not (if Init() has been called)
bool init_;
DISALLOW_EVIL_CONSTRUCTORS(RestrictedToken);
};
} // namespace sandbox
#endif // SANDBOX_SRC_RESTRICTED_TOKEN_H__
|