Dela via


Utföra åtkomstkontroller

En åtkomstkontroll avgör om en säkerhetsbeskrivning ger en angiven uppsättning åtkomsträttigheter till klienten eller tråden som identifieras av en åtkomsttoken. Du kan anropa säkerhetsfunktionen AccessCheck från WMI-klientprogram eller leverantörer som skrivits i C++ eller C#. Skript och Visual Basic-program kan inte utföra åtkomstkontroller med hjälp av metoden som beskrivs här.

Klientapplikationer bör göra en åtkomstkontroll för att fastställa identiteten för återanropet när resultaten returneras till mottagaren som tillhandahålls av klientens asynkrona anrop.

När leverantörer inte kan personifiera klientprogrammet eller skriptet som begär data bör de utföra åtkomstkontroller för följande situationer:

  • Vid åtkomst till resurser som inte skyddas av åtkomstkontrollistor (ACL).
  • När klienten har anslutit på RPC_C_LEVEL_IDENTIFY personifieringsnivå.

Obs

C++ och C#-program kan styra om åtkomstkontroller utförs av en separat process. Skript och Visual Basic-program kan läsa eller ändra en registernyckel för att säkerställa att WMI utför åtkomstkontroller. Mer information finns i Ställa in säkerhet på ett asynkront anrop.

 

Kodexemplet i det här avsnittet kräver följande referenser och #include-instruktioner för att kompilera korrekt.

#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")

I följande kodexempel visas hur du kontrollerar att säkerhetstoken för en klientprogramtråd innehåller behörigheter som är lämpliga för en angiven säkerhetsbeskrivning. Funktionen tar strängen "domain\user" och returnerar SID. Om anropet misslyckas returnerar funktionen NULL-, annars måste anroparen frigöra den returnerade pekaren.

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älja rätt registrering

Upprätthållande av WMI-säkerhet

Skydda din provider

åtkomst till WMI-namnområden