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