• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
25 namespace 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);
45 class RestrictedToken {
46  public:
47   // Init() has to be called before calling any other method in the class.
RestrictedToken()48   RestrictedToken()
49       : init_(false), effective_token_(NULL),
50         integrity_level_(INTEGRITY_LEVEL_LAST) { }
51 
~RestrictedToken()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