Home | History | Annotate | Download | only in src
      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.
     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