Topic Options
#1382 - 07/16/03 07:17 PM Chapter 03 – Running Programs "As User"
Luke Tomasello Administrator Offline
Member

Registered: 09/17/00
Posts: 740
Loc: San Jose, CA., USA
Chapter 03 – Running Programs "As User", Part I

How to run a program as another user.

It is often a requirement for task scheduling that the task—or program—be run as another user. That is, using the security credentials of another user.

This is the case when, for example, you need to run a disk defragmenter or disk backup utility, yet the logged in user hasn’t the appropriate access privileges. Or maybe nobody is even logged in at all.

In these cases you need to impersonate the appropriate user, usually a user that belongs to the Administrator group.

In this chapter we will talk about impersonation and how to use it to accomplish system automation.

The function used to accomplish impersonation of a another user and run a programs using their security credentials, is the CreateProcessAsUser () function.

It should be noted that running a process “As User” is far less complicated when done from the LocalSystem account. I.e., when TaskGhost is run as a system service.

The remainder of Part I of this chapter assumes you have TaskGhost installed as an interactive system service . In Part II of this chapter we will discuss the special limitations of user impersonation when running TaskGhost as an application and the workarounds that can be employed.

If TaskGhost is not currently started, start it by Control Panel/Administrative Tools/Services, select TaskGhost and press Start.

Lets open TaskGhost\Sample Scripts\CreateProcessAsUser.vbs in a text editor and have a look:
Code:
Sub main(commandline)

	Dim user
	Dim domain
	Dim password
	
	'' set these in your environment, or here in the script
	''	If you're running as a service, you will need to set these
	''	as SYSTEM variables
	user = TGCtrl.GetEnvironmentVariable (ENV_PERSISTENT, "USER")
	domain = TGCtrl.GetEnvironmentVariable (ENV_PERSISTENT, "DOMAIN")
	password = TGCtrl.GetEnvironmentVariable (ENV_PERSISTENT Or ENV_CRYPTO, "PASSWORD")
	
	Dim exit_code
	exit_code = TGCtrl.CreateProcessAsUser(0,user,domain,password,commandline)
	
	If exit_code = -1 Then 
		TGCtrl.Print(commandline & " failed to start!") 
	Else 
		TGCtrl.Print(commandline & " returned " & exit_code)
	End If
	
End Sub
As usual, the script is really simple. We’ll make it even simpler by getting rid of the reliance on encrypted environment variables for the password and other information as we’ll cover this in Chapter 5 .

Code:
Sub main(commandline)

	Dim user
	Dim domain
	Dim password
	
	user = “luket”
	domain = “.”
	password = “rocketdog”

	Dim exit_code
	exit_code = TGCtrl.CreateProcessAsUser(CP_INTERACTIVE,user,domain,password,commandline)

	If exit_code = -1 Then 
		TGCtrl.Print(commandline & " failed to start!") 
	Else 
		TGCtrl.Print(commandline & " returned " & exit_code)
	End If
	
End Sub
For CreateProcessAsUser we need a username, a password, and a domain name to validate the username and password.
You’ll want to set these to appropriate values for the user you are trying to impersonate, not necessarily the logged in user.
For our test though, it is perfectly legal to impersonate yourself.

user = “luket”
domain = “.”
password = “rocketdog”

The “.” for domain simply means use the local account database instead of that from some network server.
In this example, we’re saying that “luket” has an account on this machine. The local machine account database (“.”) will recognize his password “rocketdog”.

Okay, now that we’ve setup the username and password, lets change the flags passed to the CreateProcessAsUser function from 0 to CP_INTERACTIVE.

All we need to do is schedule this job to fire when we want.
Save this file now.

Open Schedule.vbs and add a line similar to this one:
If TGCtrl.CheckTime (2, tc, "* * * * *") = True Then TGCtrl.Run 0, "CreateProcessAsUser.vbs", "CMD.EXE"

You see that what we’re going to launch is "CMD.EXE". This is handy for our example because all machines are going to have it.
Now, before we test our new scheduled job, lets make sure the job identifier we’re using (2) isn’t already being used.

Save Schedule.vbs and load it into TaskGhost.
What happened?

You should see a DOS window open on your screen.
If you’re running XP, you should be able to open the TaskManager and verify that the DOS window (CMD.EXE) is running as the user you specified earlier.

Experiments:

1. If you’re part of a greater network domain, try specifying the domain server as the source of the account information.
For example: server.domain.com
2. Try using UPN format for the username, i.e., user@DNS_domain_name.
Hint: If you use UPN format, the domain parameter must be the special value vbNullString.
_________________________
Regards,
Luke Tomasello

Top
#1383 - 07/21/03 03:20 PM Re: Chapter 03 – Running Programs "As User"
Luke Tomasello Administrator Offline
Member

Registered: 09/17/00
Posts: 740
Loc: San Jose, CA., USA
Chapter 03 – Running Programs "As User", Part II

How to run a program as another user while TaskGhost is not running as a system service.

It is possible to run process as another user while TaskGhost is not running as a system service, but there additional considerations.
For instance, most user accounts don’t hold sufficient privileges to run a process as another user, even if the account trying to do the impersonation is an Administrator.

Fortunately it’s pretty easy to tell if this is the case as you will see the following message:
"A required privilege is not held by the client."

Please read the remarks section in the description of the CreateProcessAsUser function.

If you get this error, you can usually remedy it by removing the CP_INTERACTIVE flag and adding the CP_NTI flag.

For example:
Code:
Sub main(commandline)

	Dim user
	Dim domain
	Dim password
	
	user = “luket”
	domain = “.”
	password = “rocketdog”

	Dim exit_code
	exit_code = TGCtrl.CreateProcessAsUser(CP_NTI,user,domain,password,commandline)

	If exit_code = -1 Then 
		TGCtrl.Print(commandline & " failed to start!") 
	Else 
		TGCtrl.Print(commandline & " returned " & exit_code)
	End If
	
End Sub
The problem with this approach is that the program will run invisibly which may or may not be desirable.
The CP_NTI (No Thread Impersonation) flag skips the impersonation of the thread launching the process (and thus the creation of a desktop with which to interact.) The process will however, still run in the context of the impersonated user.

You should attempt to run without relying the CP_NTI flag as it’s intended as a workaround. Use of the CP_NTI flag circumvents the ‘complete’ impersonation environment and its use is therefore discouraged.
_________________________
Regards,
Luke Tomasello

Top


Moderator:  Luke Tomasello