, COM . COM : (launch permissions) (access permissions). , , SCM. , , . DCOMCNFG.EXE, ( , , ). SCM .
SCM , , NT SECURITY_DESCRIPTOR, , . SCM AppID . NT, LaunchPermission AppID:
[HKCR\AppID\{27EE6A4D-DF65-11d0-8C5F-0080C73925BA}] LaunchPermission=<serialized NT security descriptor>
, SCM :
[HKEY_LOCAL_MACHINE\Software\Microsoft\OLE] DefaultLaunchPermission=<serialized NT security descriptor>
DCOMCNFG.EXE. , COM . SECURITY_DESCRIPTOR , SCM ( actiuator) DACL (Discretionary Access Control List), , , . , HRESULT E_ACCESSDENIED, . SCM .
, . SCM , . , . COM , . API- CoIntializeSecurity.
, , CoInitializeSecurity, , AppID :
[HKCR\AppIO\{27EE6A4D-DF65-11d0-8C5F-0080C73925BA}] AccessPermission=<serialized NT security descriptor>
, , COM , , , SYSTEM.
, CoInitializeSecurity, , , . CoIntializeSecurity SECURITY_DESCRIPTOR NT. , COM . . , RPC_C_AUTHN_LEVEL_NONE, COM , . , COM DACL , . SDK (COM_RIGHTS_EXECUTE), DACL .
API- Win32 SECURITY_DESCRIPTOR CoInitializeSecurity, , API- Win32. COM COM Windows NT 4.0 Service Pack 2 COM, . COM CoInitializeSecurity IAccessControl:
[object, uuid(EEDD23EO-8410-11CE-A1C3-08002B2B8D8F)] interface IAccessControl : IUnknown { // add access allowed rights for a list of users // HRESULT GrantAccessRights([in] PACTRL_ACCESSW pAccessList); // explicitly set the access rights for a list of users // HRESULT SetAccessRights([in] PACTRL_ACCESSW pAccessList // users+rights // + ); // set the owner/group IDs of the descriptor // / HRESULT Set0wner( [in] PTRUSTEEW pOwner, // owner ID // ID [in] PTRUSTEEW pGroup // group ID // ID ); // remove access rights for a list of users // HRESULT RevokeAccessRights( [in] LPWSTR lpProperty, // not used // [in] ULONG cTrustees, // how many users // [in, size_is(cTrustees)] TRUSTEEW prgTrustees[] // users // ); // get list of users and their rights // HRESULT GetAllAccessRights( [in] LPWSTR lpProperty, // not used // [out] PACTRL_ACCESSW *ppAccessList, // users+rights // + [out] PTRUSTEEW *ppOwner, // owner ID // ID [out] PTRUSTEEW *ppGroup // group ID // ID ); // called by COM to allow/deny access to an object // COM / HRESULT IsAccessAllowed( [in] PTRUSTEEW pTrustee, // caller's ID // ID [in] LPWSTR lpProperty, // not used // [in] ACCESS_RIGHTS Rights, // COM_RIGHTS_EXECUTE [out] BOOL *pbAllowed // yes/no! // / ! ); }
, , . Windows NT 4.0 API (trustee), , . , API, TRUSTEE:
typedef struct _TRUSTEE_W { struct _TRUSTEE_W *pMultipleTrustee; MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation; TRUSTEE_FORM TrusteeForm; TRUSTEE_TYPE TrusteeType; switch_is(TrusteeForm)] union { [case(TRUSTEE_IS_NAME)] LPWSTR ptstrName; [case(TRUSTEE_IS_SID)] SID *pSid; }; } TRUSTEE_W, *PTRUSTEE_W, TRUSTEEW, *PTRUSTEEW;
. , pMultipleTrustee MultipleTrusteeOperation, (logins ) . , ptstrName/pSid, NT (security identifier SID), , . , TrusteeForm, , (union member) . , TrusteeType, , .
, , Win32 API ACTRL_ACCESS_ENTRY:
typedef struct _ACTRL_ACCESS_ENTRYW { TRUSTEE_W Trustee; // who? // ? ULONG fAccessFlags; // allowed/denied? // / ? ACCESSRIGHTS Access;// which rights? // ? ACCESSRIGHTS ProvSpecificAccess; // not used by COM // COM INHERIT_FLAGS Inheritance; // not used by COM // COM LPWSTR lpInheritProperty; // not used by COM // COM } ACTRL_ACCESS_ENTRYW, *PACTRL_ACCESS_ENTRYW;
/ :
typedef struct _ACTRL_ACCESS_ENTRY_LISTW { ULONG cEntries; [size_is(cEntries)] ACTRL_ACCESS_ENTRYW *pAccessList; } ACTRL_ACCESS_ENTRY_LISTW, *PACTRL_ACCESS_ENTRY_LISTW;
, Win32 , .
typedef struct _ACTRL_PROPERTY_ENTRYW { LPWSTR lpProperty; // not used by COM // COM ACTRL_ACCESS_ENTRY_LISW *pAccessEntryList; ULONG fListFlags; // not used by COM // COM } ACTRL_PROPERTY_ENTRYW, *PACTRL_PROPERTY_ENTRYW; typedef struct _ACTRL_ALISTW { ULONG cEntries; [size_is(cEntries)] ACTRL_PROPERTY_ENTRYW *pPropertyAccessList; } ACTRL_ACCESSW, *PACTRL_ACCESSW;
COM , , ACTRL_ACCESSW IAccessControl . , Windows NT 5.0, .
COM IAccessControl (CLSID_DCOMAccessControl), , NT 4.01. , SYSTEM Sales\Managers, Sales\Bob:
HRESULT CreateAccessControl(IAccessControl * &rpac) { rpac = 0; // create default access control object // HRESULT hr = CoCreateInstance(CLSID_DCOMAccessControl, 0, CLSCTX_ALL, IID_IaccessControl, (void**)&rpac); if (SUCCEEDED(hr)) { // build list of users/rights using NT4 security data types // / , NT4 ACTRL_ACCESS_ENTRYW rgaae[] = { { { 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, L"Sales\\Bob" }, ACTRL_ACCESS_DENIED, COM_RIGHTS_EXECUTE, 0, NO_INHERITANCE, 0 }, { { 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_GROUP, L"Sales\\Managers" }, ACTRL_ACCESS_ALLOWED, COM_RIGHTS_EXECUTE, 0, NO_INHERITANCE, 0 }, { { 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, L"NT AUTHORITY\\SYSTEM" }, ACTRL_ACCESS_ALLOWED, COM_RIGHTS_EXECUTE, 0, NO_INHERITANCE, 0 } }; ACTRL_ACCESS_ENTRY_LISTW aael = { sizeof(rgaae)/sizeof(*rgaae), rgaae }; ACTRL_PROPERTY_ENTRYW ape = { 0, &aael, 0 }; ACTRL_ACCESSW aa = { 1, &ape }; // present list of users+rights to Access Control object // + hr = rpac->SetAccessRights(&aa); } return hr; }
, :
IAccessControl *pac = 0; HRESULT hr = CreateAccessControl(pac); assert(SUCCEEDED(hr)); hr = CoInitializeSecurity(pac, -1, 0, 0, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IDENTIFY, 0, EOAC_ACCESS_CONTROL, // use IAccessControl // IAccessControl 0); assert(SUCCEEDED(hr)); pac->Release(); // COM holds reference until last CoUninitialize // COM CoUninitialize
EOAC_ACCESS_CONTROL , InitializeSecurity IAccessControl, SECURITY_DESCRIPTOR NT. COM IsAccessAllowed , . , COM, CoCreateInstance IAccessControl , COM .
, (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.
1 IPersistStream. SCM AccessPermission .