Сущность технологии СОМ. Библиотека программиста

ОглавлениеДобавить в закладки К обложке

Если список авторизованных пользователей не может быть известен во время запуска процесса, то можно зарегистрировать специальную (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.


Логин
Пароль
Запомнить меня