Sdílet prostřednictvím


Provádění kontrol přístupu

Kontrola přístupu určuje, zda popisovač zabezpečení uděluje zadanou sadu přístupových práv klientovi nebo vláknu identifikovanému přístupovým tokenem. Funkci zabezpečení můžete volat AccessCheck z klientských aplikací nebo poskytovatelů WMI napsaných v C++ nebo C#. Skripty a aplikace jazyka Visual Basic nemůžou provádět kontroly přístupu pomocí metody popsané zde.

Klientské aplikace by měly provést kontrolu přístupu k určení identity zpětného volání při vrácení výsledků do jímky poskytované asynchronním voláním klienta.

Pokud zprostředkovatelé nemohou zosobnit klientskou aplikaci nebo skript, který požaduje data, měli by provést kontroly přístupu v následujících situacích:

  • Při přístupu k prostředkům, které nejsou chráněny seznamy řízení přístupu (ACL).
  • Když se klient připojí na úrovni zosobnění RPC_C_LEVEL_IDENTIFY.

Poznámka

Aplikace C++ a C# můžou řídit, jestli se kontroly přístupu provádějí samostatným procesem. Skripty a aplikace jazyka Visual Basic mohou číst nebo měnit klíč registru, aby bylo zajištěno, že rozhraní WMI provádí kontroly přístupu. Další informace naleznete v tématu Nastavení zabezpečení asynchronního volání.

 

Příklad kódu v tomto tématu vyžaduje, aby byly správně kompilovány následující odkazy a příkazy #include.

#include <lmcons.h>
#define _WIN32_DCOM
#define SECURITY_WIN32
#include <wbemidl.h>
#include <security.h>
#include <safestr.h>
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "Secur32.lib")

Následující příklad kódu ukazuje, jak zkontrolovat, že token zabezpečení vlákna klientské aplikace obsahuje oprávnění odpovídající zadanému popisovači zabezpečení. Funkce vezme řetězec "domain\user" a vrátí identifikátor SID. Pokud volání selže, vrátí funkce NULL, jinak volající musí uvolnit vrácený ukazatel.

BYTE * GetSid(LPWSTR pwcUserName)
{
    DWORD dwSidSize = 0, dwDomainSize = 0;
    SID_NAME_USE use;

    // first call is to get the size
    BOOL bRet = LookupAccountNameW(

      NULL,            // system name
      pwcUserName,     // account name
      NULL,            // security identifier
      &dwSidSize,      // size of security identifier
      NULL,            // domain name
      &dwDomainSize,   // size of domain name
      &use             // SID-type indicator
      );    

    if(bRet == FALSE && ERROR_INSUFFICIENT_BUFFER 
        != GetLastError())\
        return NULL;

    BYTE * buff = new BYTE[dwSidSize];

    if(buff == NULL)
        return NULL;

    WCHAR * pwcDomain = new WCHAR[dwDomainSize];

    if(pwcDomain == NULL)

    {
        delete [] buff;
        return FALSE;
    }

    // Call to LookupAccountNameW actually gets the SID
    bRet = LookupAccountNameW(

      NULL,           // system name
      pwcUserName,    // account name
      buff,           // security identifier
      &dwSidSize,     // size of security identifier
      pwcDomain,      // domain name
      &dwDomainSize,  // size of domain name
      &use            // SID-type indicator
      );    

    delete [] pwcDomain;

    if(bRet == FALSE)
    {
        delete [] buff;
        return NULL;
    }

    return buff;
}

// This returns true if the caller is coming 
//   from the expected computer in the expected domain.

BOOL IsAllowed(LPWSTR pwsExpectedDomain, 
   LPWSTR pwsExpectedMachine)
{

    WCHAR wCallerName[UNLEN + 1];
    DWORD nSize = UNLEN + 1;

// Impersonate the caller and get its name

    HRESULT hr = CoImpersonateClient();
    if(FAILED(hr))

        return FALSE;

    BOOL bRet = GetUserNameExW(NameSamCompatible, 
       wCallerName, &nSize);

    CoRevertToSelf();

    if(bRet == FALSE)

        return FALSE;


    // take the expected domain and lan manager 
    //   style name and create a SID.  In actual
    // production code, it would be more efficient 
    //   to do this only when necessary

    WCHAR wExpectedName[UNLEN + 1];

    HRESULT hrCopyCat;
    hrCopyCat = StringCchCopy(wExpectedName,
        sizeof(pwsExpectedDomain)*sizeof(WCHAR)+1, 
        pwsExpectedDomain);
    if (FAILED(hrCopyCat))
    {
        return FALSE;
    }
    hrCopyCat = 
        StringCchCat(wExpectedName,sizeof(wExpectedName)
        + 2*sizeof(WCHAR)+1, L"\\");
    if (FAILED(hrCopyCat))
    {
        return FALSE;
    }
    hrCopyCat = StringCchCat(wExpectedName,sizeof(wExpectedName)
        + sizeof(pwsExpectedMachine)*sizeof(WCHAR)+1, 
        pwsExpectedMachine);
    if (FAILED(hrCopyCat))
    {
        return FALSE;
    }
    hrCopyCat = StringCchCat(wExpectedName,sizeof(wExpectedName)
        + sizeof(WCHAR)+1, L"$");
    if (FAILED(hrCopyCat))
    {
        return FALSE;
    }
  

    // convert the two names to SIDs and compare.  
    // Note that SIDs are used since 
    //   the format of the names might vary.  

    BYTE * pCaller = GetSid(wCallerName);

    if(pCaller == NULL)

        return FALSE;

    BYTE * pExpected = GetSid(wExpectedName);

    if(pExpected == NULL)
    {
        delete [] pCaller;

        return FALSE;
    }

    bRet = EqualSid((PSID)pCaller, (PSID)pExpected);

    delete [] pCaller;
    delete [] pExpected;

    return bRet;
}

Výběr správné registrace

Udržování zabezpečení WMI

Zabezpečení vašeho poskytovatele

Přístup k názvovým oborům rozhraní WMI