Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π‘ΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ БОМ. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 73

Автор Π”ΠΎΠ½Π°Π»ΡŒΠ΄ Бокс

Если список Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ извСстСн Π²ΠΎ врСмя запуска процСсса, Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ (custom) Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ IAccessControl, которая выполняСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ€ΠΎΠ΄Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ доступа Π²ΠΎ врСмя выполнСния Π² своСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° IsAccessAllowed. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ сама COM ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ IsAccessAllowed, Ρ‚ΠΎ такая ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ рСализация ΠΌΠΎΠ³Π»Π° Π±Ρ‹ Π±Π΅Π·ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ E_NOTIMPL для всСх Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² IAccessControl. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° простая рСализация IAccessControl, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π°Ρ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ процСсса Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ с символом "x" Π² ΠΈΠΌΠ΅Π½Π°Ρ… своих ΡƒΡ‡Π΅Ρ‚Π½Ρ‹Ρ… записСй:

class XOnly : public IAccessControl {

// Unknown methods

// ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ IUnknown

STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {

if (riid == IID_IAccessControl || riid == IID_IUnknown)

*ppv = static_cast<IAccessControl*>(this);

else

return (*ppv = 0), E_NOINTERFACE;

((IUnknown*)*ppv)->AddRef();

return S_OK;

}

STDMETHODIMP_(ULONG) AddRef(void) { return 2; }

STDMETHODIMP_(ULONG) Release(void) { return 1; }

// IAccessControl methods

// ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ IAccessControl

STDMETHODIMP GrantAccessRights(ACTRL_ACCESSW *)

{ return E_NOTIMPL; }

STDMETHODIMP SetAccessRights(ACTRL_ACCESSW *)

{ return E_NOTIMPL; }

STDMETHODIMP SetOwner(PTRUSTEEW, PTRUSTEEW)

{ return E_NOTIMPL; }

STDMETHODIMP RevokeAccessRights(LPWSTR, ULONG, TRUSTEEW[])

{ return E_NOTIMPL; }

STDMETHODIMP GetAllAccessRights(LPWSTR, PACTRL_ACCESSW_ALLOCATE_ALL_NODES *,

PTRUSTEEW *, PTRUSTEEW *)

{ return E_NOTIMPL; }

// this is the only IAccessControl method called by COM

// это СдинствСнный ΠΌΠ΅Ρ‚ΠΎΠ΄ IAccessControl, Π²Ρ‹Π·Π²Π°Π½Π½Ρ‹ΠΉ COM

STDMETHODIMP IsAccessAllowed(

PTRUSTEEW pTrustee,

LPWSTR lpProperty,

ACCESS_RIGHTS AccessRights,

BOOL *pbIsAllowed)

{

// verify that trustee contains a string

// удостовСряСмся, Ρ‡Ρ‚ΠΎ ΠΎΠΏΠ΅ΠΊΡƒΠ½ содСрТит строку

if (pTrustee == 0 || pTrustee->TrusteeForm != TRUSTEE_IS_NAME)

return E_UNEXPECTED;

// look for X or x and grant/deny based on presence

// ΠΈΡ‰Π΅ΠΌ "X" ΠΈΠ»ΠΈ "x" ΠΈ Π² зависимости ΠΎΡ‚ Π΅Π³ΠΎ наличия

// прСдоставляСм ΠΈΠ»ΠΈ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅ΠΌ

*pbIsAllowed = wcsstr(pTrustee->ptstrName, L"x") != 0 ||

wcsstr(pTrustee->ptstrName, L"X") != 0;

return S_OK;

}

}

Если экзСмпляр Π²Ρ‹ΡˆΠ΅ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ класса C++ зарСгистрирован c CoInitializeSecurity:

XOnly xo;

// declare an instance of the C++ class

// объявляСм экзСмпляр класса C++

hr = CoInitializeSecurity(static_cast<IAccessControl*>(&xo),

–1, 0, 0, RPC_C_AUTHN_LEVEL_PKT,

RPC_C_IMP_LEVEL_IDENTIFY, 0,

EOAC_ACCESS_CONTROL,

// use IAccessControl

// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ IAccessControl

0);

assert(SUCCEEDED(hr));

Ρ‚ΠΎ ΠΎΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ… "x" Π² ΠΈΠΌΠ΅Π½Π°Ρ… своих ΡƒΡ‡Π΅Ρ‚Π½Ρ‹Ρ… записСй, Π½ΠΈΠΊΠ°ΠΊΠΈΠ΅ ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΠ΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ приняты. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ имя ΠΎΠΏΠ΅ΠΊΡƒΠ½Π° содСрТит Π² качСствС прСфикса имя Π΄ΠΎΠΌΠ΅Π½Π°, этот простой тСст Ρ‚Π°ΠΊΠΆΠ΅ прСдоставит доступ ΡƒΡ‡Π΅Ρ‚Π½Ρ‹ΠΌ записям ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΡ… ΠΊ Π΄ΠΎΠΌΠ΅Π½Π°ΠΌ, содСрТащим "x" Π² своих ΠΈΠΌΠ΅Π½Π°Ρ…. Π₯отя этот тСст доступа вряд Π»ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ слишком ΠΏΠΎΠ»Π΅Π·Π΅Π½, ΠΎΠ½ дСмонстрируСт Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡŽ использования ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° IAccessControl с CoInitializeSecurity.


Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π°ΠΌΠΈ

Под Windows NT ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ процСсс ΠΈΠΌΠ΅Π΅Ρ‚ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ доступа (access token), ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ полномочия ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°Π»Π° Π·Π°Ρ‰ΠΈΡ‚Ρ‹. Π­Ρ‚ΠΎΡ‚ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ доступа создаСтся Π²ΠΎ врСмя ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ процСсса ΠΈ содСрТит Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Π²ΠΈΠ΄Ρ‹ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅, Π² Ρ‚ΠΎΠΌ числС Π΅Π³ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ NT (SID), список Π³Ρ€ΡƒΠΏΠΏ, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ, Π° Ρ‚Π°ΠΊΠΆΠ΅ список ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΎΠ½ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΌΠΎΠΆΠ΅Ρ‚ Π»ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ систСмы, ΠΌΠΎΠΆΠ΅Ρ‚ Π»ΠΈ ΠΎΠ½ ΠΌΠ΅Π½ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ систСмных часов). Когда процСсс пытаСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ рСсурсам ядра бСзопасности (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊ Ρ„Π°ΠΉΠ»Π°ΠΌ, ΠΊΠ»ΡŽΡ‡Π°ΠΌ рССстра, сСмафорам), ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ NT (SRM – Security Reference Monitor) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² цСлях Π°ΡƒΠ΄ΠΈΡ‚Π° (отслСТивания дСйствий ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΏΡƒΡ‚Π΅ΠΌ записи Π² ΠΆΡƒΡ€Π½Π°Π» бСзопасности Π²Ρ‹Π±Ρ€Π°Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² событий бСзопасности) ΠΈ контроля доступа.

Когда Π² процСсс поступаСт сообщСниС ΠΎΠ± ORPC-запросС, COM ΠΎΡ€Π³Π°Π½ΠΈΠ·ΡƒΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π²Ρ‹Π·ΠΎΠ²Π° ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΠ»ΠΈ Π² RPC-ΠΏΠΎΡ‚ΠΎΠΊΠ΅ (Π² случаС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², располоТСнных Π² МВА), ΠΈΠ»ΠΈ Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅, созданном ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ (Π² случаС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², располоТСнных Π² STA). Π’ любом случаС ΠΌΠ΅Ρ‚ΠΎΠ΄ выполняСтся с использованиСм ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° доступа, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ Π΄Π°Π½Π½ΠΎΠΌΡƒ процСссу. Π’ Ρ†Π΅Π»ΠΎΠΌ этого достаточно, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ это позволяСт Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΡ€ΠΎΠ³Π½ΠΎΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΈ ΠΈ ΠΏΡ€Π°Π²Π° Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, нСзависимо ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊΠΎΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ осущСствляСт запрос. Π’ Ρ‚ΠΎ ΠΆΠ΅ врСмя ΠΈΠ½ΠΎΠ³Π΄Π° Π±Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄ выполнялся с использованиСм ΠΏΡ€Π°Π² доступа ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄; Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π»ΠΈΠ±ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ, Π»ΠΈΠ±ΠΎ ΡƒΡΠΈΠ»ΠΈΡ‚ΡŒ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ ΠΏΡ€Π°Π²Π° ΠΈ ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Ρ‚Π°ΠΊΠΎΠ³ΠΎ стиля программирования Π² Windows NT допускаСтся присвоСниС ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ΠΎΠ² Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ. Если ΠΏΠΎΡ‚ΠΎΠΊ ΠΈΠΌΠ΅Π΅Ρ‚ свой собствСнный ΠΌΠ°Ρ€ΠΊΠ΅Ρ€, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ процСсса. ВмСсто Π½Π΅Π³ΠΎ для выполнСния Π°ΡƒΠ΄ΠΈΡ‚Π° ΠΈ контроля доступа ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€, присвоСнный ΠΏΠΎΡ‚ΠΎΠΊΡƒ. Π₯отя Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Ρ‹ ΠΈ ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°Ρ‚ΡŒ ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ, Π² COM прСдусмотрСн Π³ΠΎΡ€Π°Π·Π΄ΠΎ Π±ΠΎΠ»Π΅Π΅ прямой ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ создания ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° Π½Π° основС ORPC-запроса, обслуТиваСмого Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ. Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ раскрываСтся Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° посрСдством контСкстного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π²Ρ‹Π·ΠΎΠ²Π°, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΌ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ сСрвСрного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

НапоминаСм, Ρ‡Ρ‚ΠΎ контСкстный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π²Ρ‹Π·ΠΎΠ²Π° сопоставляСтся с ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, ΠΊΠΎΠ³Π΄Π° ORPC-запрос направляСтся Π½Π° ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡΠ½ΡƒΡŽ Π·Π°Π³Π»ΡƒΡˆΠΊΡƒ. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ доступ ΠΊ контСксту Π²Ρ‹Π·ΠΎΠ²Π° Ρ‡Π΅Ρ€Π΅Π· API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ CoGetCallContext. ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π²Ρ‹Π·ΠΎΠ²Π° Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ интСрфСйс IServerSecurity:

[local, object, uuid(0000013E-0000-0000-C000-000000000046)]

interface IServerSecurity : IUnknown {

// get caller's security settings

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ установки Π·Π°Ρ‰ΠΈΡ‚Ρ‹ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ HRESULT

QueryBlanket(

[out] DWORD *pAuthnSvc, // authentication pkg

// ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ

[out] DWORD *pAuthzSvc, // authorization pkg

// ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ

[out] OLECHAR **pServerName, // server principal

// сСрвСрный ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°Π»

[out] DWORD *pAuthnLevel, // authentication level

// ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ

[out] DWORD *pImpLevel, // impersonation level

// ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ заимствования ΠΏΡ€Π°Π²

[out] void **pPrivs, // client principal

// клиСнтский ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°Π»

[out] DWORD *pCaps // EOAC flags

// Ρ„Π»Π°Π³ΠΈ EOAC

);

// start running with credentials of caller

// Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ с полномочиями Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

HRESULT ImpersonateClient(void);

// stop running with credentials of caller

// Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ с полномочиями Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

HRESULT RevertToSelf(void);

// test for impersonation

// ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° заимствования ΠΏΡ€Π°Π²

BOOL IsImpersonating(void);

}

Π’ ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Ρ€Π°Π·Π΄Π΅Π»ΠΎΠ² этой Π³Π»Π°Π²Ρ‹ ΡƒΠΆΠ΅ рассматривался ΠΌΠ΅Ρ‚ΠΎΠ΄ QueryBlanket. ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для управлСния ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π°ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π²ΠΎ врСмя выполнСния ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. ΠœΠ΅Ρ‚ΠΎΠ΄ ImpersonateClient создаСт ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ доступа, основанный Π½Π° полномочиях ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΈ присваиваСт этот ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ возвращаСтся IServerSecurity::ImpersonateClient, всС ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ доступа ΠΊ рСсурсам ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Ρ‚ΡŒΡΡ ΠΈΠ»ΠΈ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Ρ‚ΡŒΡΡ Π² соотвСтствии с полномочиями ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π° Π½Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. ΠœΠ΅Ρ‚ΠΎΠ΄ RevertToSelf заставляСт Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ процСсс Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΊ использованию ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° доступа, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰Π΅Π³ΠΎ процСссу. Если Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ Π²ΠΎ врСмя Ρ€Π΅ΠΆΠΈΠΌΠ° заимствования ΠΏΡ€Π°Π², Ρ‚ΠΎ COM нСявно Π²Π΅Ρ€Π½Π΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊ ΠΊ использованию ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° процСсса. И Π½Π°ΠΊΠΎΠ½Π΅Ρ†, ΠΌΠ΅Ρ‚ΠΎΠ΄ IServerSecurity::IsImpersonating ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ: полномочия ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈΠ»ΠΈ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ процСсса ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Подобно ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ QueryBlanket, Π΄Π²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° IServerSecurity Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΡƒΠ΄ΠΎΠ±Π½Ρ‹Π΅ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ CoGetCallContext ΠΈΠ·Π½ΡƒΡ‚Ρ€ΠΈ ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄:

HRESULT CoImpersonateClient(void);

HRESULT CoRevertToSelf(void);

Π’ ΠΎΠ±Ρ‰Π΅ΠΌ случаС, Ссли Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° IServerSecurity, Ρ‚ΠΎ эффСктивнСС Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ CoGetCallContext ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, Π° для Π²Ρ‹Π·ΠΎΠ²Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ интСрфСйс IServerSecurity.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ дСмонстрируСт использованиС контСкстного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π²Ρ‹Π·ΠΎΠ²Π° для выполнСния части ΠΊΠΎΠ΄Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° с полномочиями ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:

STDMETHODIMP MyClass::ReadWrite(DWORD dwNew, DWORD *pdw0ld)

{

// execute using server's token to let anyone read the value

// выполняСм с использованиСм ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° сСрвСра, Ρ‡Ρ‚ΠΎΠ±Ρ‹

// всС ΠΌΠΎΠ³Π»ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΄Π°Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅

ULONG cb;

HANDLE hfile = CreateFile(Β«C:\\file1.binΒ», GENERIC_READ,

0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if (hfile == INVALID_HANDLE_VALUE)

return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());

ReadFile(hfile, pdwOld, sizeof(DWORD), &cb, 0);

CloseHandle(hfile);

// get call context object

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ контСкстный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π²Ρ‹Π·ΠΎΠ²Π°

IServerSecurlty *pss = 0;

HRESULT hr = CoGetCallContext(IID_IServerSecurity, (void**)&pss);

if (FAILED(hr)) return hr;

// set thread token to use caller's credentials

// устанавливаСм ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ ΠΏΠΎΡ‚ΠΎΠΊΠ° для использования

// ΠΏΠΎΠ»Π½ΠΎΠΌΠΎΡ‡ΠΈΠΉ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹

hr = pss->ImpersonateClient();

assert(SUCCEEDED(hr));

// execute using client's token to let only users that can

// write to the file change the value

// выполняСм с использованиСм ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹

// ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠ³Π»ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ,

// ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΏΡ€Π°Π²ΠΎ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π² Ρ„Π°ΠΉΠ»

hfile = CreateFile(Β«C:\\file2.binΒ»,

GENERIC_READ | GENERIC_WRITE, 0, 0,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if (hfile == INVALID_HANDLE_VALUE)

hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());

else {

WriteFile(hfile, &dwNew, sizeof(DWORD), &cb, 0);

CloseHandle(hfile);

}

// restore thread to use process-level token

// восстанавливаСм Ρ€Π΅ΠΆΠΈΠΌ использования ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° процСсса

pss->RevertToSelf();

// release call context

// освобоТдаСм контСкст Π²Ρ‹Π·ΠΎΠ²Π°

pss->Release();

return hr;

}

ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² CreateFile выполняСтся с использованиСм ΠΏΠΎΠ»Π½ΠΎΠΌΠΎΡ‡ΠΈΠΉ процСсса ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹Π·ΠΎΠ² – с полномочиями ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Если ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΡ€Π°Π²Π° доступа для чтСния/записи Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ„Π°ΠΉΠ», Ρ‚ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° CreateFile ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹ΠΌ, Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ процСсс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ доступа ΠΊ этому Ρ„Π°ΠΉΠ»Ρƒ.