1// Copyright (c) 2010 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#ifndef SANDBOX_SRC_RESTRICTED_TOKEN_H_
6#define SANDBOX_SRC_RESTRICTED_TOKEN_H_
7
8#include <windows.h>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/strings/string16.h"
13#include "sandbox/win/src/restricted_token_utils.h"
14#include "sandbox/win/src/security_level.h"
15#include "sandbox/win/src/sid.h"
16
17// Flags present in the Group SID list. These 2 flags are new in Windows Vista
18#ifndef SE_GROUP_INTEGRITY
19#define SE_GROUP_INTEGRITY (0x00000020L)
20#endif
21#ifndef SE_GROUP_INTEGRITY_ENABLED
22#define SE_GROUP_INTEGRITY_ENABLED (0x00000040L)
23#endif
24
25namespace sandbox {
26
27// Handles the creation of a restricted token using the effective token or
28// any token handle.
29// Sample usage:
30//    RestrictedToken restricted_token;
31//    unsigned err_code = restricted_token.Init(NULL);  // Use the current
32//                                                      // effective token
33//    if (ERROR_SUCCESS != err_code) {
34//      // handle error.
35//    }
36//
37//    restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID());
38//    HANDLE token_handle;
39//    err_code = restricted_token.GetRestrictedTokenHandle(&token_handle);
40//    if (ERROR_SUCCESS != err_code) {
41//      // handle error.
42//    }
43//    [...]
44//    CloseHandle(token_handle);
45class RestrictedToken {
46 public:
47  // Init() has to be called before calling any other method in the class.
48  RestrictedToken()
49      : init_(false), effective_token_(NULL),
50        integrity_level_(INTEGRITY_LEVEL_LAST) { }
51
52  ~RestrictedToken() {
53    if (effective_token_)
54      CloseHandle(effective_token_);
55  }
56
57  // Initializes the RestrictedToken object with effective_token.
58  // If effective_token is NULL, it initializes the RestrictedToken object with
59  // the effective token of the current process.
60  unsigned Init(HANDLE effective_token);
61
62  // Creates a restricted token and returns its handle using the token_handle
63  // output parameter. This handle has to be closed by the caller.
64  // If the function succeeds, the return value is ERROR_SUCCESS. If the
65  // function fails, the return value is the win32 error code corresponding to
66  // the error.
67  unsigned GetRestrictedTokenHandle(HANDLE *token_handle) const;
68
69  // Creates a restricted token and uses this new token to create a new token
70  // for impersonation. Returns the handle of this impersonation token using
71  // the token_handle output parameter. This handle has to be closed by
72  // the caller.
73  //
74  // If the function succeeds, the return value is ERROR_SUCCESS. If the
75  // function fails, the return value is the win32 error code corresponding to
76  // the error.
77  //
78  // The sample usage is the same as the GetRestrictedTokenHandle function.
79  unsigned GetRestrictedTokenHandleForImpersonation(HANDLE *token_handle) const;
80
81  // Lists all sids in the token and mark them as Deny Only except for those
82  // present in the exceptions parameter. If there is no exception needed,
83  // the caller can pass an empty list or NULL for the exceptions
84  // parameter.
85  //
86  // If the function succeeds, the return value is ERROR_SUCCESS. If the
87  // function fails, the return value is the win32 error code corresponding to
88  // the error.
89  //
90  // Sample usage:
91  //    std::vector<Sid> sid_exceptions;
92  //    sid_exceptions.push_back(ATL::Sids::Users().GetPSID());
93  //    sid_exceptions.push_back(ATL::Sids::World().GetPSID());
94  //    restricted_token.AddAllSidsForDenyOnly(&sid_exceptions);
95  // Note: A Sid marked for Deny Only in a token cannot be used to grant
96  // access to any resource. It can only be used to deny access.
97  unsigned AddAllSidsForDenyOnly(std::vector<Sid> *exceptions);
98
99  // Adds a user or group SID for Deny Only in the restricted token.
100  // Parameter: sid is the SID to add in the Deny Only list.
101  // The return value is always ERROR_SUCCESS.
102  //
103  // Sample Usage:
104  //    restricted_token.AddSidForDenyOnly(ATL::Sids::Admins().GetPSID());
105  unsigned AddSidForDenyOnly(const Sid &sid);
106
107  // Adds the user sid of the token for Deny Only in the restricted token.
108  // If the function succeeds, the return value is ERROR_SUCCESS. If the
109  // function fails, the return value is the win32 error code corresponding to
110  // the error.
111  unsigned AddUserSidForDenyOnly();
112
113  // Lists all privileges in the token and add them to the list of privileges
114  // to remove except for those present in the exceptions parameter. If
115  // there is no exception needed, the caller can pass an empty list or NULL
116  // for the exceptions parameter.
117  //
118  // If the function succeeds, the return value is ERROR_SUCCESS. If the
119  // function fails, the return value is the win32 error code corresponding to
120  // the error.
121  //
122  // Sample usage:
123  //    std::vector<base::string16> privilege_exceptions;
124  //    privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
125  //    restricted_token.DeleteAllPrivileges(&privilege_exceptions);
126  unsigned DeleteAllPrivileges(
127      const std::vector<base::string16> *exceptions);
128
129  // Adds a privilege to the list of privileges to remove in the restricted
130  // token.
131  // Parameter: privilege is the privilege name to remove. This is the string
132  // representing the privilege. (e.g. "SeChangeNotifyPrivilege").
133  // If the function succeeds, the return value is ERROR_SUCCESS. If the
134  // function fails, the return value is the win32 error code corresponding to
135  // the error.
136  //
137  // Sample usage:
138  //    restricted_token.DeletePrivilege(SE_LOAD_DRIVER_NAME);
139  unsigned DeletePrivilege(const wchar_t *privilege);
140
141  // Adds a SID to the list of restricting sids in the restricted token.
142  // Parameter: sid is the sid to add to the list restricting sids.
143  // The return value is always ERROR_SUCCESS.
144  //
145  // Sample usage:
146  //    restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID());
147  // Note: The list of restricting is used to force Windows to perform all
148  // access checks twice. The first time using your user SID and your groups,
149  // and the second time using your list of restricting sids. The access has
150  // to be granted in both places to get access to the resource requested.
151  unsigned AddRestrictingSid(const Sid &sid);
152
153  // Adds the logon sid of the token in the list of restricting sids for the
154  // restricted token.
155  //
156  // If the function succeeds, the return value is ERROR_SUCCESS. If the
157  // function fails, the return value is the win32 error code corresponding to
158  // the error.
159  unsigned AddRestrictingSidLogonSession();
160
161  // Adds the owner sid of the token in the list of restricting sids for the
162  // restricted token.
163  //
164  // If the function succeeds, the return value is ERROR_SUCCESS. If the
165  // function fails, the return value is the win32 error code corresponding to
166  // the error.
167  unsigned AddRestrictingSidCurrentUser();
168
169  // Adds all group sids and the user sid to the restricting sids list.
170  //
171  // If the function succeeds, the return value is ERROR_SUCCESS. If the
172  // function fails, the return value is the win32 error code corresponding to
173  // the error.
174  unsigned AddRestrictingSidAllSids();
175
176  // Sets the token integrity level. This is only valid on Vista. The integrity
177  // level cannot be higher than your current integrity level.
178  unsigned SetIntegrityLevel(IntegrityLevel integrity_level);
179
180 private:
181  // The list of restricting sids in the restricted token.
182  std::vector<Sid> sids_to_restrict_;
183  // The list of privileges to remove in the restricted token.
184  std::vector<LUID> privileges_to_disable_;
185  // The list of sids to mark as Deny Only in the restricted token.
186  std::vector<Sid> sids_for_deny_only_;
187  // The token to restrict. Can only be set in a constructor.
188  HANDLE effective_token_;
189  // The token integrity level. Only valid on Vista.
190  IntegrityLevel integrity_level_;
191  // Tells if the object is initialized or not (if Init() has been called)
192  bool init_;
193
194  DISALLOW_COPY_AND_ASSIGN(RestrictedToken);
195};
196
197}  // namespace sandbox
198
199#endif  // SANDBOX_SRC_RESTRICTED_TOKEN_H_
200