UAC References

References

This section includes a virtualization reference and a security settings reference.

Virtualization Reference

File Virtualization

  • Virtualize (%SYSTEMROOT%, %PROGRAMDATA%,%PROGRAMFILES%\(Subdirectories)

  • Redirect to: %LOCALAPPDATA%\VirtualStore

  • Excluded binary executables: .exe, .dll, .sys

Registry Virtualization

  • Virtualize (HKEY_LOCAL_MACHINE\SOFTWARE)

  • Redirect to: HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE\<Application Registry Keys>

  • Keys excluded from virtualization

  • HKEY_LOCAL_MACHINE\Software\Classes

  • HKEY_LOCAL_MACHINE \Software\Microsoft\Windows

  • HKEY_LOCAL_MACHINE \Software\Microsoft\Windows NT

Applicability

  • Virtual stores do not roam

  • Corresponding global objects would not roam

  • Enabled only for interactive standard users

  • Disabled for non-interactive processes

  • Disabled for 64-bit executables

  • Disabled for executables that request an execution level (requestedExecutionLevel) in their application manifest, the model for separation

  • Disabled for kernel mode and impersonated callers

  • ·Only administrator writeable registry keys and files are virtualized

UAC Security Settings Reference

This reference details the security settings available to administer UAC with Group Policy or the computer's local security policy.

Note

The procedures presented in this section are intended for administering unmanaged computers. To use Group Policy to administer the settings centrally in a managed environment, use Active Directory Users and Computers (dsa.msc) instead of local Security Policy Manager snap-in (secpol.msc).

Configuring UAC Security Settings

The following procedure details how to configure the UAC security settings with the Security Policy Manager. The procedure details the default user experience for an administrator in Admin Approval Mode.

To view or set the UAC security settings with Security Policy Manager

  1. Click the Start button, type secpol.msc into the search box, and then press Enter.

  2. At the User Account Control consent prompt, click Continue.

  3. In Local Security Settings, expand Local Policies, and then click Security Options.

  4. Right-click the security setting that you would like to change and select Properties.

The following procedure details how to configure the UAC security settings with the Group Policy. The procedure details the default user experience for an administrator in Admin Approval Mode.

To view or set the UAC security settings with the Group Policy Object Editor

  1. Click the Start button, type gpedit.msc into the search box, and then press Enter.

  2. At the User Account Control consent prompt, click Continue.

  3. In Group Policy, expand User Configuration, and then expand Security Options.

  4. Right-click the security setting that you would like to change and select Properties.

UAC Security Settings

The following table lists the configurable UAC security settings. These settings can be configured with the Security Policy Manager (secpol.msc) or managed centrally with Group Policy (gpedit.msc).

Setting

Description

Default value

User Account Control: Admin Approval Mode for the Built-in Administrator account

There are two possible settings:

  • Enabled—the built-in Administrator will be run as an administrator in Admin Approval Mode.

  • Disabled—the administrator runs with a full administrator access token.

  • Disabled for new installations and for upgrades where the built-in Administrator is NOT the only local active administrator on the computer. The built-in Administrator account is disabled by default for installations and upgrades on domain-joined computers.

  • Enabled for upgrades when Windows Vista® determines that the built-in Administrator account is the only active local administrator on the computer. If Windows Vista determines this, the built-in Administrator account is also kept enabled following the upgrade. The built-in Administrator account is disabled by default for installations and upgrades on domain-joined computers.

User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode

There are three possible values:

  • No prompt—the elevation occurs automatically and silently. This option allows an administrator in Admin Approval Mode to perform an operation that requires elevation without consent or credentials. Note: this scenario should only be used in the most constrained environments and is NOT recommended.

  • Prompt for consent—an operation that requires a full administrator access token will prompt the administrator in Admin Approval Mode to select either Continue or Cancel. If the administrator clicks Continue, the operation will continue with their highest available privilege.

  • Prompt for credentials—an operation that requires a full administrator access token will prompt an administrator in Admin Approval Mode to enter an administrator user name and password. If the user enters valid credentials, the operation will continue with the applicable privilege.

Prompt for consent

User Account Control: Behavior of the elevation prompt for standard users

There are two possible values:

  • No prompt—no elevation prompt is presented and the user cannot perform administrative tasks without using Run as administrator or by logging on with an administrator account. Most enterprises running desktops as standard user will configure the "No prompt" policy to reduce help desk calls.

  • Prompt for credentials—an operation that requires a full administrator access token will prompt the user to enter an administrative user name and password. If the user enters valid credentials the operation will continue with the applicable privilege.

  • Home: Prompt for credentials

  • Enterprise: No prompt

User Account Control: Detect application installations and prompt for elevation

There are two possible values:

  • Enabled—the user is prompted for consent or credentials when Windows Vista detects an installer.

  • Disabled—application installations will silently fail or fail in a non-deterministic manner. Enterprises running standard users desktops that leverage delegated installation technologies like GPSI or SMS will disable this feature. In this case, installer detection is unnecessary and therefore not required.

Enabled

User Account Control: Only elevate executables that are signed and validated

There are two possible values:

  • Enabled—only signed executable files will run. This policy will enforce PKI signature checks on any interactive application that requests elevation. Enterprise administrators can control the administrative application allowed list through the population of certificates in the local computers Trusted Publisher Store.

  • Disabled—both signed and unsigned code will be run.

Disabled

User Account Control: Only elevate UIAccess applications that are installed in secure locations

There are two possible values:

  • The system will only give UIAccess privileges and user rights to executables that are launched from under %ProgramFiles% or %windir%. The ACLs on these directories ensure that the executable is not user-modifiable (which would otherwise allow elevation of privilege). UIAccess executables launched from other locations will launch without additional privileges (i.e. they will run "asInvoker").

  • Disabled—the location checks are not done, so all UIAccess applications will be launched with the user's full access token upon user approval.

Enabled

User Account Control: Run all administrators in Admin Approval Mode

There are two possible values:

  • Enabled—both administrators and standard users will be prompted when attempting to perform administrative operations. The prompt style is dependent on policy.

  • Disabled—UAC is essentially "turned off" and the AIS service is disabled from automatically starting. The Windows Security Center will also notify the logged on user that the overall security of the operating system has been reduced and will give the user the ability to self- enable UAC.

Note: Changing this setting will require a system reboot.

Enabled

User Account Control: Switch to the secure desktop when prompting for elevation

There are two possible values:

  • Enabled—displays the UAC elevation prompt on the secure desktop. The secure desktop can only receive messages from Windows processes, which eliminates messages from malicious software.

  • Disabled—the UAC elevation prompt is displayed on the interactive (user) desktop.

Enabled

User Account Control: Virtualize file and registry write failures to per-user locations

There are two possible values:

  • Enabled—this policy enables the redirection of pre-Windows Vista application write failures to defined locations in both the registry and file system. This feature mitigates those applications that historically ran as administrator and wrote runtime application data back to %ProgramFiles%; %Windir%; %Windir%\system32; or HKLM\Software\.... This setting should be kept enabled in environments that utilize non-UAC compliant software. Applications that lack an application compatibility database entry or a requested execution level marking in the application manifest are not UAC compliant.

  • Disabled—virtualization facilitates the running of pre-Windows Vista (legacy) applications that historically failed to run as a standard user. An administrator running only Windows Vista compliant applications may choose to disable this feature as it is unnecessary. Non-UAC compliant applications that attempt to write %ProgramFiles%; %Windir%; %Windir%\system32; or HKLM\Software\.... will silently fail if this setting is disabled.

Enabled

Note

Modifying the User Account control: Run all administrators in Admin Approval Mode setting will require a computer restart before the setting becomes effective. All other UAC Group Policy settings are dynamic and do not require a reboot.

Task Scheduler Code Sample

The following C++ code sample illustrates how to use Task Scheduler to run an un-elevated application as the currently logged on desktop user from an elevated process. This method works for both the consent prompt and the credential prompt.

//---------------------------------------------------------------------
//  This file is part of the Microsoft .NET Framework SDK Code Samples.
// 
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// 
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation.  See these other
//materials for detailed information regarding Microsoft code samples.
// 
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------

/**********************************************************************
* Main.cpp - Sample application for Task Scheduler V2 COMAPI                * Component: Task Scheduler                          
* Copyright (c) 2002 - 2003, Microsoft Corporation 
* This sample creates a task to that launches as the currently logged
* on deskup user. The task launches as soon as it is registered.
**********************************************************************/
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <comdef.h>
#include <comutil.h>
//Include Task header files - Included in Windows Vista Beta-2 SDK from //MSDN
#include <taskschd.h>
#include <conio.h>
#include <iostream>
#include <time.h>

using namespace std;

#define CLEANUP \
pRootFolder->Release();\
        pTask->Release();\
        CoUninitialize();

HRESULT CreateMyTask(LPCWSTR, wstring);

void __cdecl wmain(int argc, wchar_t** argv)
{
wstring wstrExecutablePath;
WCHAR taskName[20];
HRESULT result;

if( argc < 2 )
{
printf("\nUsage: LaunchApp yourapp.exe" );
return;
}

// Pick random number for task name
srand((unsigned int) time(NULL));
wsprintf((LPWSTR)taskName, L"Launch %d", rand());

wstrExecutablePath = argv[1];

result = CreateMyTask(taskName, wstrExecutablePath);
printf("\nReturn status:%d\n", result);

}
HRESULT CreateMyTask(LPCWSTR wszTaskName, wstring wstrExecutablePath)
{
    //  ------------------------------------------------------
    //  Initialize COM.
TASK_STATE taskState;
int i;
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if( FAILED(hr) )
    {
        printf("\nCoInitializeEx failed: %x", hr );
        return 1;
    }

    //  Set general COM security levels.
    hr = CoInitializeSecurity(
        NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        0,
        NULL);

    if( FAILED(hr) )
    {
        printf("\nCoInitializeSecurity failed: %x", hr );
        CoUninitialize();
        return 1;
    }

    //  ------------------------------------------------------
    //  Create an instance of the Task Service. 
    ITaskService *pService = NULL;
    hr = CoCreateInstance( CLSID_TaskScheduler,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ITaskService,
                           (void**)&pService );  
    if (FAILED(hr))
    {
        printf("Failed to CoCreate an instance of the TaskService  
                class: %x", hr);
        CoUninitialize();
        return 1;
    }
        
    //  Connect to the task service.
    hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(),  
         _variant_t());
    if( FAILED(hr) )
    {
        printf("ITaskService::Connect failed: %x", hr );
        pService->Release();
        CoUninitialize();
        return 1;
    }

    //  ------------------------------------------------------
    //  Get the pointer to the root task folder.  This folder will hold 
    //  the new task that is registered.
    ITaskFolder *pRootFolder = NULL;
    hr = pService->GetFolder( _bstr_t( L"\\") , &pRootFolder );
    if( FAILED(hr) )
    {
        printf("Cannot get Root Folder pointer: %x", hr );
        pService->Release();
        CoUninitialize();
        return 1;
    }
    
    //  Check if the same task already exists. If the same task exists,    
   //  remove it.
    hr = pRootFolder->DeleteTask( _bstr_t( wszTaskName), 0  );
    
    //  Create the task builder object to create the task.
    ITaskDefinition *pTask = NULL;
    hr = pService->NewTask( 0, &pTask );

    pService->Release();  // COM clean up.  Pointer is no longer used.
    if (FAILED(hr))
    {
        printf("Failed to CoCreate an instance of the TaskService   
               class: %x", hr);
        pRootFolder->Release();
        CoUninitialize();
        return 1;
    }
        

    //  ------------------------------------------------------
    //  Get the trigger collection to insert the registration trigger.
    ITriggerCollection *pTriggerCollection = NULL;
    hr = pTask->get_Triggers( &pTriggerCollection );
    if( FAILED(hr) )
    {
        printf("\nCannot get trigger collection: %x", hr );
  CLEANUP
        return 1;
    }
  
    //  Add the registration trigger to the task.
    ITrigger *pTrigger = NULL;
    
    hr = pTriggerCollection->Create( TASK_TRIGGER_REGISTRATION,  
                                     &pTrigger );     
    pTriggerCollection->Release();  
// COM clean up.  Pointer is no longer used.
    if( FAILED(hr) )
    {
       printf("\nCannot add registration trigger to the Task %x", hr );
       CLEANUP
       return 1;
    }
    pTrigger->Release();

    //  ------------------------------------------------------
    //  Add an Action to the task.     
    IExecAction *pExecAction = NULL;
    IActionCollection *pActionCollection = NULL;

    //  Get the task action collection pointer.
    hr = pTask->get_Actions( &pActionCollection );
    if( FAILED(hr) )
    {
        printf("\nCannot get Task collection pointer: %x", hr );
        CLEANUP
        return 1;
    }
    
    //  Create the action, specifying that it is an executable action.
    IAction *pAction = NULL;
    hr = pActionCollection->Create( TASK_ACTION_EXEC, &pAction );
    pActionCollection->Release();  
   // COM clean up.  Pointer is no longer used.
    if( FAILED(hr) )
    {
        printf("\npActionCollection->Create failed: %x", hr );
        CLEANUP
        return 1;
    }

    hr = pAction->QueryInterface( IID_IExecAction, (void**)   
                                  &pExecAction );
    pAction->Release();
    if( FAILED(hr) )
    {
        printf("\npAction->QueryInterface failed: %x", hr );
        CLEANUP
        return 1;
    }

    //  Set the path of the executable to the user supplied executable.
   hr = pExecAction->put_Path( _bstr_t( wstrExecutablePath.c_str() ) );  

    if( FAILED(hr) )
    {
        printf("\nCannot set path of executable: %x", hr );
        pExecAction->Release();
        CLEANUP
        return 1;
    }
    hr = pExecAction->put_Arguments( _bstr_t( L"" ) );  
  
   if( FAILED(hr) )
    {
        printf("\nCannot set arguments of executable: %x", hr );
        pExecAction->Release();
        CLEANUP
        return 1;
    }
    
    //  ------------------------------------------------------
    //  Save the task in the root folder.
    IRegisteredTask *pRegisteredTask = NULL;
    hr = pRootFolder->RegisterTaskDefinition(
            _bstr_t( wszTaskName ),
            pTask,
      TASK_CREATE, 
_variant_t(_bstr_t( L"S-1-5-32-545")),//Well Known SID for \\Builtin\Users group
_variant_t(), 
TASK_LOGON_GROUP,
            _variant_t(L""),
            &pRegisteredTask);
    if( FAILED(hr) )
    {
        printf("\nError saving the Task : %x", hr );
        CLEANUP
        return 1;
    }
    printf("\n Success! Task successfully registered. " );
    for (i=0; i<100; i++)//give 10 seconds for the task to start
{
pRegisteredTask->get_State(&taskState);
if (taskState == TASK_STATE_RUNNING)
{
printf("\nTask is running\n");
break;
}
Sleep(100);
}
if (i>= 100) printf("Task didn't start\n");

    //Delete the task when done
    hr = pRootFolder->DeleteTask(
            _bstr_t( wszTaskName ),
            NULL);
    if( FAILED(hr) )
    {
        printf("\nError deleting the Task : %x", hr );
        CLEANUP
        return 1;
    }

    printf("\n Success! Task successfully deleted. " );

//  Clean up.
    CLEANUP
    CoUninitialize();
    return 0;
}