Delen via


De COM-verhogingsmoniker

Met de COM-elevatie moniker kunnen toepassingen die worden uitgevoerd onder gebruikersaccount-beheer (UAC) COM-klassen met verhoogde bevoegdheden activeren. Zie Focus op Minimale bevoegdhedenvoor meer informatie.

Wanneer gebruikt u de hoogte-moniker

De elevatie-moniker wordt gebruikt om een COM-klasse te activeren om een specifieke en beperkte functie uit te voeren waarvoor verhoogde rechten zijn vereist, zoals het wijzigen van de systeemdatum en -tijd.

Verhoging vereist deelname van zowel een COM-klasse als de client. De COM-klasse moet worden geconfigureerd om privilegeverhoging te ondersteunen door de registervermelding te annoteren, zoals beschreven in de sectie 'Vereisten'. De COM-client moet verhoogde bevoegdheden aanvragen met behulp van de elevatiemoniker.

De verhogingsmoniker is niet bedoeld om toepassingscompatibiliteit te bieden. Als u bijvoorbeeld een verouderde COM-toepassing zoals WinWord als een verhoogde beheerder wilt uitvoeren, moet u het uitvoerbare COM-clientbestand zo configureren dat verhoging van bevoegdheden vereist is, in plaats van de klasse van de verouderde toepassing te activeren met de elevatie-moniker. Wanneer de COM-client met verhoogde bevoegdheid CoCreateInstance aanroept met de CLSID van de verouderde applicatie, zal de verhoogde status van de client naar het serverproces worden doorgegeven.

Niet alle COM-functionaliteit is compatibel met verhoging. De functionaliteit die niet werkt, omvat:

  • Verhoging van bevoegdheden wordt niet doorgegeven van een client naar een externe COM-server. Als een client een externe COM-server activeert met de elevation moniker, wordt de server niet verhoogd in rechten, zelfs niet als deze het verhogen van rechten ondersteunt.
  • Als een COM-klasse met verhoogde bevoegdheden imitatie gebruikt tijdens een COM-aanroep, verliest deze mogelijk de verhoogde bevoegdheden tijdens de imitatie.
  • Als een COM-server met verhoogde bevoegdheid een klasse registreert in de actieve objecttabel (ROT), is de klasse niet beschikbaar voor niet-verhoogde clients.
  • Een proces verhoogd met behulp van het UAC-mechanisme laadt niet de per-gebruiker klassen tijdens de COM-activeringen. Voor COM-toepassingen betekent dit dat de COM-klassen van de toepassing moeten worden geïnstalleerd in de HKEY_LOCAL_MACHINE register hive als de toepassing moet worden gebruikt door niet-bevoegde en bevoegde accounts. De COM-klassen van de toepassing hoeven alleen te worden geïnstalleerd in de HKEY_USERS hive als de toepassing nooit wordt gebruikt door bevoegde accounts.
  • Slepen en neerzetten is niet toegestaan van niet-verhoogde naar verhoogde toepassingen.

Eisen

Als u de elevatie-moniker wilt gebruiken om een COM-klasse te activeren, moet de klasse worden geconfigureerd om te worden uitgevoerd als de gebruiker die het heeft gestart of de toepassingsidentiteit 'Activeren als Activator'. Als de klasse is geconfigureerd voor uitvoering onder een andere identiteit, retourneert de activering de fout CO_E_RUNAS_VALUE_MUST_BE_AAA.

De klasse moet ook worden geannoteerd met een 'beschrijvende' weergavenaam die compatibel is met een meertalige gebruikersinterface (MUI). Hiervoor is de volgende registervermelding vereist:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
   {CLSID}
      LocalizedString = displayName

Als deze vermelding ontbreekt, retourneert de activering de fout CO_E_MISSING_DISPLAYNAME. Als het MUI-bestand ontbreekt, wordt de foutcode van de RegLoadMUIStringW--functie geretourneerd.

Als u desgewenst een toepassingspictogram wilt opgeven dat moet worden weergegeven door de gebruikersinterface van UAC, voegt u de volgende registersleutel toe:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
   {CLSID}
      Elevation
         IconReference = applicationIcon

IconReference gebruikt dezelfde indeling als LocalizedString:

@ pathtobinary,-resourcenummer

Daarnaast moet het COM-onderdeel zijn ondertekend om het pictogram weer te geven.

De COM-klasse moet ook worden geannoteerd als LUA-ingeschakeld. Hiervoor is de volgende registervermelding vereist:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
   {CLSID}
      Elevation
         Enabled = 1

Als deze vermelding ontbreekt, retourneert de activering de fout CO_E_ELEVATION_DISABLED.

Houd er rekening mee dat deze vermeldingen moeten bestaan in de HKEY_LOCAL_MACHINE hive, niet de HKEY_CURRENT_USER of HKEY_USERS hive. Dit voorkomt dat gebruikers COM-klassen verhogen die ze niet ook de bevoegdheden hebben om zich te registreren.

De Elevatie-moniker en de Elevatie-gebruikersinterface

Als de client al is verhoogd, zorgt het gebruik van de elevatie moniker er niet voor dat de Elevatie-gebruikersinterface wordt weergegeven.

"De elevatiemoniker gebruiken"

De verhogingsmoniker is een standaard COM-moniker, vergelijkbaar met de sessie, partitie of wachtrij monikers. Het stuurt een activeringsaanvraag naar een opgegeven server met het opgegeven uitbreidingsniveau. De CLSID die moet worden geactiveerd, wordt weergegeven in de monikertekenreeks.

De uitbreidings moniker ondersteunt de volgende tokens op runniveau:

  1. Administrateur
  2. Hoogst

De syntaxis hiervoor is als volgt:

Elevation:Administrator!new:{guid}
Elevation:Highest!new:{guid}

In de voorgaande syntaxis wordt de nieuwe moniker gebruikt om een exemplaar van de COM-klasse terug te geven dat is opgegeven door guid. De 'nieuwe' moniker maakt intern gebruik van de IClassFactory--interface om een klasseobject te verkrijgen en roept vervolgens IClassFactory::CreateInstance erop aan.

De elevation moniker kan ook worden gebruikt om een klasseobject te verkrijgen, waarmee IClassFactorywordt geïmplementeerd. De aanroeper roept vervolgens aan via CreateInstance om een objectexemplaar te verkrijgen. De syntaxis hiervoor is als volgt:

Elevation:Administrator!clsid:{guid}

Voorbeeldcode

In het volgende codevoorbeeld wordt getoond hoe u de elevatie moniker gebruikt. Hierbij wordt ervan uitgegaan dat u COM al hebt geïnitialiseerd op de huidige thread.

HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
    BIND_OPTS3 bo;
    WCHAR  wszCLSID[50];
    WCHAR  wszMonikerName[300];

    StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0])); 
    HRESULT hr = StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);
    if (FAILED(hr))
        return hr;
    memset(&bo, 0, sizeof(bo));
    bo.cbStruct = sizeof(bo);
    bo.hwnd = hwnd;
    bo.dwClassContext  = CLSCTX_LOCAL_SERVER;
    return CoGetObject(wszMonikerName, &bo, riid, ppv);
}

BIND_OPTS3 is nieuw in Windows Vista. Het is afgeleid van BIND_OPTS2.

De enige toevoeging is een HWND veld, hwnd. Deze hendel vertegenwoordigt een venster dat, indien van toepassing, de eigenaar wordt van de elevatie-UI.

Als hwndNULLis, roept COM GetActiveWindow op om een vensterhandle te vinden die gekoppeld is aan de huidige thread. Dit kan gebeuren als de client een script is, dat geen BIND_OPTS3 structuur kan invullen. In dit geval probeert COM het venster te gebruiken dat is gekoppeld aan de scriptthread.

Over-The-Shoulder (OTS) Verhoging

Bij over-the-shoulder (OTS)-verhoging gaat het om het scenario waarin een client een COM-server uitvoert met de inloggegevens van een beheerder in plaats van zijn of haar eigen. (De term 'over de schouder' betekent dat de beheerder over de schouder van de cliënt meekijkt terwijl de cliënt de server beheert.)

Dit scenario kan een probleem veroorzaken voor COM-aanroepen naar de server, omdat de server mogelijk niet CoInitializeSecurity expliciet (programmatisch) of impliciet (dat wil gezegd, declaratief, met behulp van het register). Voor dergelijke servers berekent COM een beveiligingsdescriptor waarmee alleen SELF, SYSTEM en Builtin\Administrators COM-aanroepen naar de server kunnen uitvoeren. Deze regeling werkt niet in OTS-scenario's. In plaats daarvan moet de server CoInitializeSecurityaanroepen, expliciet of impliciet, en een ACL opgeven die de INTERACTIEVE groeps-SID en SYSTEM bevat.

In het volgende codevoorbeeld ziet u hoe u een beveiligingsdescriptor (SD) maakt met de SID van de INTERACTIEVE groep.

BOOL GetAccessPermissionsForLUAServer(SECURITY_DESCRIPTOR **ppSD)
{
// Local call permissions to IU, SY
    LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)";
    SECURITY_DESCRIPTOR *pSD;
    *ppSD = NULL;

    if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))
    {
        *ppSD = pSD;
        return TRUE;
    }

    return FALSE;
}

In het volgende codevoorbeeld ziet u hoe u CoInitializeSecurity- impliciet aanroept met de SD uit het vorige codevoorbeeld:

// hKey is the HKCR\AppID\{GUID} key
BOOL SetAccessPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
{
    BOOL bResult = FALSE;
    DWORD dwLen = GetSecurityDescriptorLength(pSD);
    LONG lResult;
    lResult = RegSetValueExA(hkey, 
        "AccessPermission",
        0,
        REG_BINARY,
        (BYTE*)pSD,
        dwLen);
    if (lResult != ERROR_SUCCESS) goto done;
    bResult = TRUE;
done:
    return bResult;
}

In het volgende codevoorbeeld ziet u hoe u CoInitializeSecurity- expliciet aanroept met de bovenstaande SD:

// Absolute SD values
PSECURITY_DESCRIPTOR pAbsSD = NULL;
DWORD AbsSdSize = 0;
PACL  pAbsAcl = NULL;
DWORD AbsAclSize = 0;
PACL  pAbsSacl = NULL;
DWORD AbsSaclSize = 0;
PSID  pAbsOwner = NULL;
DWORD AbsOwnerSize = 0;
PSID  pAbsGroup = NULL;
DWORD AbsGroupSize = 0;

MakeAbsoluteSD (
    pSD,
    pAbsSD,
    &AbsSdSize,
    pAbsAcl,
    &AbsAclSize,
    pAbsSacl,
    &AbsSaclSize,
    pAbsOwner,
    &AbsOwnerSize,
    pAbsGroup,
    &AbsGroupSize
);

if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
    pAbsSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, AbsSdSize);
    pAbsAcl = (PACL)LocalAlloc(LMEM_FIXED, AbsAclSize);
    pAbsSacl = (PACL)LocalAlloc(LMEM_FIXED, AbsSaclSize);
    pAbsOwner = (PSID)LocalAlloc(LMEM_FIXED, AbsOwnerSize);
    pAbsGroup = (PSID)LocalAlloc(LMEM_FIXED, AbsGroupSize);

    if ( ! (pAbsSD && pAbsAcl && pAbsSacl && pAbsOwner && pAbsGroup))
    {
        hr = E_OUTOFMEMORY;
        goto Cleanup;
    }
    if ( ! MakeAbsoluteSD(
        pSD,
        pAbsSD,
        &AbsSdSize,
        pAbsAcl,
        &AbsAclSize,
        pAbsSacl,
        &AbsSaclSize,
        pAbsOwner,
        &AbsOwnerSize,
        pAbsGroup,
        &AbsGroupSize
        ))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Cleanup;
    }
}
else
{
    hr = HRESULT_FROM_WIN32(GetLastError());
    goto Cleanup;
}

// Call CoInitializeSecurity .

COM-machtigingen en verplichte toegangslabels

Windows Vista introduceert het begrip verplichte toegangslabels in beveiligingsdescriptors. Het label bepaalt of clients toegang kunnen krijgen tot een COM-object. Het label wordt opgegeven in het sacl-gedeelte (system access control list) van de beveiligingsdescriptor. In Windows Vista ondersteunt COM het SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP label. SACL's in de COM-machtigingen worden genegeerd op besturingssystemen vóór Windows Vista.

Vanaf Windows Vista biedt dcomcnfg.exe geen ondersteuning voor het wijzigen van het integriteitsniveau (IL) in COM-machtigingen. Het moet programmatisch worden ingesteld.

In het volgende codevoorbeeld ziet u hoe u een COM-beveiligingsdescriptor maakt met een label waarmee aanvragen voor het starten/activeren van alle LOW IL-clients zijn toegestaan. Houd er rekening mee dat de labels geldig zijn voor start-/activerings- en oproepmachtigingen. Het is dus mogelijk om een COM-server te schrijven die het starten, activeren of aanroepen van clients met een bepaalde IL niet toekent. Zie voor meer informatie over integriteitsniveaus de sectie "Begrijpen van de integriteitsmechanismen van Windows Vista" in Understanding and Working in Protected Mode Internet Explorer.

BOOL GetLaunchActPermissionsWithIL (SECURITY_DESCRIPTOR **ppSD)
{
// Allow World Local Launch/Activation permissions. Label the SD for LOW IL Execute UP
    LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)";
    if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))
    {
        *ppSD = pSD;
        return TRUE;
    }
}

BOOL SetLaunchActPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
{
    
    BOOL bResult = FALSE;
    DWORD dwLen = GetSecurityDescriptorLength(pSD);
    LONG lResult;
    lResult = RegSetValueExA(hkey, 
        "LaunchPermission",
        0,
        REG_BINARY,
        (BYTE*)pSD,
        dwLen);
    if (lResult != ERROR_SUCCESS) goto done;
    bResult = TRUE;
done:
    return bResult;
};

CoCreateInstance en integriteitsniveaus

Het gedrag van CoCreateInstance is gewijzigd in Windows Vista, om te voorkomen dat lage IL-clients standaard worden gebonden aan COM-servers. De server moet dergelijke bindingen expliciet toestaan door de SACL op te geven. De wijzigingen in CoCreateInstance zijn als volgt:

  1. Bij het starten van een COM-serverproces wordt het IL in het serverprocestoken ingesteld op de client of servertoken IL, afhankelijk van wat lager is.
  2. Standaard voorkomt COM dat clients met lage IL-verbindingen worden gebonden aan actieve exemplaren van COM-servers. Als u de binding wilt toestaan, moet de securitydescriptor launch/activation van een COM-server een SACL bevatten waarmee het label Low IL wordt opgegeven (zie de vorige sectie voor de voorbeeldcode om een dergelijke beveiligingsdescriptor te maken).

Verhoogde servers en ROT-registraties

Als een COM-server zich wil registreren in de actieve objecttabel (ROT) en elke client toegang wil geven tot de registratie, moet deze de vlag ROTFLAGS_ALLOWANYCLIENT gebruiken. Een 'Activate As Activator' COM-server kan geen ROTFLAGS_ALLOWANYCLIENT opgeven, omdat de DCOM-servicecontrolbeheerder (DCOMSCM) een spoof-controle uitvoert tegen deze vlag. Daarom voegt COM in Windows Vista ondersteuning toe voor een nieuwe registervermelding waarmee de server kan bepalen dat de ROT-registraties beschikbaar worden gesteld aan elke client:

HKEY_LOCAL_MACHINE\Software\Classes\AppID
   {APPID}
      ROTFlags

De enige geldige waarde voor deze REG_DWORD vermelding is:

ROTREGFLAGS_ALLOWANYCLIENT 0x1

De vermelding moet aanwezig zijn in de HKEY_LOCAL_MACHINE hive.

Deze vermelding biedt een "Activate As Activator" -server met dezelfde functionaliteit die ROTFLAGS_ALLOWANYCLIENT biedt voor een RunAs-server.

Beveiliging in COM

Informatie over en werken in de beveiligde modus Internet Explorer