Dizyatec  
home Home
sitemap Sitemap contact Contact
Dizyatec Solutions - IT Services
Engineering Services
Task Schedular


In the whitepaper Launch your application from session 0 to session 1 using a service helper application” an application was launched by the service which had the privileges of the local system account. The advantage of such an approach was the ability to use an UI to perform high privilege tasks across any user account. It also facilitated writing to the HKLM section of the registry which could be read across all user accounts. This can also be done by designing an application which can communicate with a service through RPC to achieve the desired result.

Title: Using a task schedular to run administrative tasks on demand.
OS: Microsoft Vista
Language: VC++


Introduction

In the whitepaper Launch your application from session 0 to session 1 using a service helper application” an application was launched by the service which had the privileges of the local system account. The advantage of such an approach was the ability to use an UI to perform high privilege tasks across any user account. It also facilitated writing to the HKLM section of the registry which could be read across all user accounts. This can also be done by designing an application which can communicate with a service through RPC to achieve the desired result.


This article focuses on the Administrator account of Vista for administrative applications. It shows how to launch an application into session 1 under the Administrator role with full privileges effectively bypassing the UAC prompt. Windows tasks scheduler is used for this purpose. The approach may be useful for some automated tasks which need to run under the administrator account.


The article will be expanded further to show how RPC can be implemented effectively to run administrative applications.


Background

The concept used is very straightforward. A normal user mode application is developed which communicates with a service through custom messages. On receiving the custom message, the service will register a task in the task scheduler. Depending on the attributes assigned, the task is run on demand with the highest privileges of that account. At the end the task is deleted from the task scheduler.


Using the code

First let us review the file CustomMessageSender.cpp. This is the user-mode application which communicates with the service. This application can be any normal application without any special privileges.

#define SERVICE_NAME _T ("CustomSvc" )

#defineSERVICE_CONTROL_CUSTOM_MESSAGE 0x0085
int _tmain(int argc, _TCHAR* argv[])
{
SC_HANDLE hMyService,hSCM;
BOOL bSuccess;
SERVICE_STATUS status;
hSCM = OpenSCManager(0,0,SC_MANAGER_CONNECT);
if(!hSCM)
{
printf("Open SCM failed with error %u",GetLastError());
}
hMyService =
OpenService(hSCM,SERVICE_NAME,SERVICE_USER_DEFINED_CONTROL);
if(!hMyService)
{
printf("Open SCM failed with error %u",GetLastError());
}
bSuccess =
ControlService(hMyService,SERVICE_CONTROL_CUSTOM_MESSAGE,&status);
if(!bSuccess)
{ printf("Control Service failed with error %u",GetLastError());
}
CloseServiceHandle(hMyService);
CloseServiceHandle(hSCM);
return 0;
}

The code above is very simple and straightforward. SERVICE_USER_DEFINED_CONTROL and SC_MANAGER_CONNECT access permission is used because any user mode applications can connect to the service to send custom messages to it. No admin privileges are required. So this application sends the SERVICE_CONTROL_CUSTOM_MESSAGE to the service. Once the message is sent to the service it will register a task under the current user account which can be run at normal or highest privileges under that account.

Most of the code for registering the task in the task scheduler is taking from the Windows Whitepaper on UAC. I have added a section on the IPrincipal interface to set the highest privileges attribute.

The code snippet shows that first COM and its security attributes are initialized. Then we create an instance of the Task Service.

{
// ------------------------------------------------------
// Initialize COM.
LPCWSTR wszTaskName = L"Dizyatec Task";
wstring wstrExecutablePath = L"C:\\SessionLauncher\\debug\\a.exe";
// 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;
}
Once the task service is initialized, we connect to the service and perform the following steps:
1) Get a pointer to the tasks root folder
2) Use the ITaskDefinition interface to create a new task definition
3) Register the trigger
4) Define the action to be executed.

These are the general steps to be followed. Once this is done we need to get a interface pointer to the IPrincipal interface and define the runLevel which is TASK_RUNLEVEL_HIGHEST. The Code snippet below shows the same:

IPrincipal *pPrincipal = NULL;
hr = pTask->get_Principal(&pPrincipal);
if( FAILED(hr) )
{
printf("\nPointer to principal: %x", hr );
CLEANUP
return 1;
}
printf("\nDone : %x" ), hr;
hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST);
printf("\nDone : %x", hr );
if( FAILED(hr) )
{
printf(nCould not get principal : %x", hr );
CLEANUP
return 1;
}
pPrincipal->Release();
// ------------------------------------------------------

Once this done we save the task in the root folder to run under the current user account.

// Save the task in the root folder.
IRegisteredTask *pRegisteredTask = NULL;
hr = pRootFolder->RegisterTaskDefinition(
_bstr_t( wszTaskName ),
pTask,
TASK_CREATE_OR_UPDATE,
_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
return1;
}
printf("\n Success! Task successfully registered. " );


The task is then started, run and deleted.
This is all needed to run the task under the administrative account under highest privileges.

I will be further extending this article to demonstrate an example of the service broker model where the a normal user application communicates with a service through RPC, which is one of the methods recommended by Microsoft to run administrative applications.

Click Here to download source code Task Schedular

About the Author
R.Jaisvar,Technical Consultant
Dizyatec Solutions
top_navigation
© 2011 Dizyatec Solutions Pte Ltd |Disclaimer