hidden hit counter
Help!

CreateProcessAsUser


Post new topic   General Reply to Topic (not reply to a specific post)    Forums Home -> Security RSS
Next:  Published application does not appear in GPO  
Author Message
Ian Boyd1
External


Since: Jul 03, 2004
Posts: 7



PostPosted: Wed Jul 25, 2007 1:09 am    Post subject: CreateProcessAsUser
Archived from groups: microsoft>public>platformsdk>base, others (more info?)

An application running in a Windows 2000 enterprise by standard domain users
needs to launch an external application as a different domain user. i'm
looking for a functional code sample that calls CreateProcessAsUser.

i've not been able to find any sample code, or write my own, that doesn't
fail with error 1314.

The function prototype that everyone who ever calls CreateProcessAsUser is:
boolean CreateProcessAsUserEx(string Username, Password, Domain,
ApplicationName, CommandLine);


Can someone please reply with one of the following:
a) functional code body of CreateProcessAsUserEx
b) a statement saying that it is not possible to call CreateProcessAsUser
from a standard user account
Back to top
Skywing [MVP]
External


Since: Jul 25, 2007
Posts: 1



PostPosted: Wed Jul 25, 2007 2:28 am    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

I assume that you are really failing at a call to LogonUser. On Windows
2000 (and below), LogonUser requires SeTcbPrivilege. On Windows XP or
later, it can be used by a plain user account with no privileges.

On Windows 2000, you may be able to use CreateProcessWithLogonW, which takes
no special privileges. This is essentially how runas (secondary logon) on
Windows 2000 works.

--
Ken Johnson (Skywing)
Windows SDK MVP
http://www.nynaeve.net
"Ian Boyd" <admin DeleteThis @SWIFTPA.NET> wrote in message
news:ACFF54C7-4C4D-4EB3-8323-24FD1A707528@microsoft.com...
> An application running in a Windows 2000 enterprise by standard domain
> users needs to launch an external application as a different domain user.
> i'm looking for a functional code sample that calls CreateProcessAsUser.
>
> i've not been able to find any sample code, or write my own, that doesn't
> fail with error 1314.
>
> The function prototype that everyone who ever calls CreateProcessAsUser
> is:
> boolean CreateProcessAsUserEx(string Username, Password, Domain,
> ApplicationName, CommandLine);
>
>
> Can someone please reply with one of the following:
> a) functional code body of CreateProcessAsUserEx
> b) a statement saying that it is not possible to call CreateProcessAsUser
> from a standard user account
>
>
>
Back to top
Kellie Fitton
External


Since: Jul 25, 2007
Posts: 1



PostPosted: Wed Jul 25, 2007 8:07 am    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

On Jul 25, 7:55 am, "Ian Boyd" <ian.msnews....RemoveThis@avatopia.com> wrote:
> "Skywing [MVP]" wrote:
> >I assume that you are really failing at a call to LogonUser. On Windows
> >2000 (and below), LogonUser requires SeTcbPrivilege.
>
> Is there a way to grant SeTcbPrivlege (Act as part of the operating system)
> to a domain account without granting SeTcbPrivlege to the domain account?
> Obviously i'm not going to grant every user in the global enterprise the
> ability to act as part of the operating system.
>
> > On Windows XP or later, it can be used by a plain user account with no
> > privileges.
>
> On Windows XP, the call to LogonUser succeeds, but the call to
> CreateProcessAsUser fails with code 1314 (A required privilege is not held
> by the client).
>
> > On Windows 2000, you may be able to use CreateProcessWithLogonW, which
> > takes no special privileges. This is essentially how runas (secondary
> > logon) on Windows 2000 works.
>
> This does seem to work with my most likely incorrect code, but here's the
> code anyway:
>
> function ExecuteFileAsUser(
> const Username, Domain, Password: WideString;
> const FileName: WideString;
> const Params: WideString='';
> const DefaultDir: WideString ='';
> const ShowCmd: Integer=SW_SHOWNORMAL): Boolean;
> var
> LocallyModifiableParams: WideString;
> startupInfo: TStartupInfo;
> processInformation: PROCESS_INFORMATION;
> const
> LOGON_WITH_PROFILE = $00000001;
> begin
> {
> Sample Usage:
> ExecuteFileAsUser(
> 'forest', //user name
> 'goldshire', //domain name
> 'gump', //password
> 'c:\windows\system32\notepad.exe', //filename
> 'c:\20070608.log', //params
> 'c:\develop' //default dir
> );
>
> }
>
> LocallyModifiableParams := Filename+' '+Params;
> {A command line contains the executable name, e.g.
> notepad.exe c:\somefile.txt
> }
>
> {From the Platform SDK:
> The function can modify the contents of this string.
> Therefore, this parameter cannot be a pointer to read-only memory
> (such as a const variable or a literal string).
> If this parameter is a constant string, the function may cause an
> access violation.
>
> ed: A function that tries to cause access violations. Nice.}
>
> //An empty structure that the function wants
> ZeroMemory(@startupInfo, SizeOf(startupInfo));
> startupInfo.cb :=SizeOf(startupInfo);
>
> //An empty structure that the function wants
> ZeroMemory(@processInformation, SizeOf(processInformation));
>
> Result := CreateProcessWithLogonW(
> PWideChar(Username),
> PWideChar(Domain),
> PWideChar(Password),
> LOGON_WITH_PROFILE, //dwLogonFlags: DWORD
> PWideChar(Filename),
> PWideChar(LocallyModifiableParams),
> 0, //dwCreationFlags: DWORD
> nil, //lpEnvironment: Pointer
> PWideChar(DefaultDir), //lpCurrentDirectory: PWideChar;
> startupInfo,
> processInformation);
> if Result then
> begin
> {From the Platform SDK:
> Handles in PROCESS_INFORMATION must be closed with the
> CloseHandle
> function when they are not needed.}
>
> //We don't need either of the handles in ProcessInformation.
> //Hopefully Microsoft won't add any more to the structure in
> the future
> CloseHandle(processInformation.hProcess);
> CloseHandle(processInformation.hThread);
> end;
> end;


Hi,

Well, when using the API CreateProcessAsUser() does not succeed,
and the function GetLastError() returns the error code # 1314,
which is ERROR_PRIVILEGE_NOT_HELD, this is usually because the
users token does not have the needed access rights, which are the:

TOKEN_QUERY
TOKEN_DUPLICATE
TOKEN_ASSIGN_PRIMARY

Moreover, the process that calls the API CreateProcessAsUser(),
must have the following privileges:

SE_ASSIGNPRIMARYTOKEN_NAME
SE_INCREASE_QUOTA_NAME

So, another valid option is using the API CreateProcessWithLogonW(),
this would spawn your application in the correct security context,
and the function does exactly the same thing as LogonUserEx() and
CreateProcessAsUser(), and does not require any special privileges.
just make sure that the user account you specify is allowed to logIn
interactively to your machine, you check that in the domain/local
policies.

http://msdn2.microsoft.com/en-us/library/ms682429.aspx

http://msdn2.microsoft.com/en-us/library/ms682431.aspx

Kellie.
Back to top
Ian Boyd
External


Since: Apr 12, 2006
Posts: 7



PostPosted: Wed Jul 25, 2007 10:55 am    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

"Skywing [MVP]" wrote:
>I assume that you are really failing at a call to LogonUser. On Windows
>2000 (and below), LogonUser requires SeTcbPrivilege.

Is there a way to grant SeTcbPrivlege (Act as part of the operating system)
to a domain account without granting SeTcbPrivlege to the domain account?
Obviously i'm not going to grant every user in the global enterprise the
ability to act as part of the operating system.


> On Windows XP or later, it can be used by a plain user account with no
> privileges.

On Windows XP, the call to LogonUser succeeds, but the call to
CreateProcessAsUser fails with code 1314 (A required privilege is not held
by the client).


> On Windows 2000, you may be able to use CreateProcessWithLogonW, which
> takes no special privileges. This is essentially how runas (secondary
> logon) on Windows 2000 works.

This does seem to work with my most likely incorrect code, but here's the
code anyway:

function ExecuteFileAsUser(
const Username, Domain, Password: WideString;
const FileName: WideString;
const Params: WideString='';
const DefaultDir: WideString ='';
const ShowCmd: Integer=SW_SHOWNORMAL): Boolean;
var
LocallyModifiableParams: WideString;
startupInfo: TStartupInfo;
processInformation: PROCESS_INFORMATION;
const
LOGON_WITH_PROFILE = $00000001;
begin
{
Sample Usage:
ExecuteFileAsUser(
'forest', //user name
'goldshire', //domain name
'gump', //password
'c:\windows\system32\notepad.exe', //filename
'c:\20070608.log', //params
'c:\develop' //default dir
);
}

LocallyModifiableParams := Filename+' '+Params;
{A command line contains the executable name, e.g.
notepad.exe c:\somefile.txt
}

{From the Platform SDK:
The function can modify the contents of this string.
Therefore, this parameter cannot be a pointer to read-only memory
(such as a const variable or a literal string).
If this parameter is a constant string, the function may cause an
access violation.

ed: A function that tries to cause access violations. Nice.}

//An empty structure that the function wants
ZeroMemory(@startupInfo, SizeOf(startupInfo));
startupInfo.cb :=SizeOf(startupInfo);

//An empty structure that the function wants
ZeroMemory(@processInformation, SizeOf(processInformation));


Result := CreateProcessWithLogonW(
PWideChar(Username),
PWideChar(Domain),
PWideChar(Password),
LOGON_WITH_PROFILE, //dwLogonFlags: DWORD
PWideChar(Filename),
PWideChar(LocallyModifiableParams),
0, //dwCreationFlags: DWORD
nil, //lpEnvironment: Pointer
PWideChar(DefaultDir), //lpCurrentDirectory: PWideChar;
startupInfo,
processInformation);
if Result then
begin
{From the Platform SDK:
Handles in PROCESS_INFORMATION must be closed with the
CloseHandle
function when they are not needed.}

//We don't need either of the handles in ProcessInformation.
//Hopefully Microsoft won't add any more to the structure in
the future
CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);
end;
end;
Back to top
Roger Abell MVP
External


Since: Apr 12, 2004
Posts: 671



PostPosted: Wed Jul 25, 2007 10:55 am    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

"Ian Boyd" <ian.msnews010.RemoveThis@avatopia.com> wrote in message
news:%23cVx%23vszHHA.4816@TK2MSFTNGP04.phx.gbl...
> "Skywing [MVP]" wrote:
>>I assume that you are really failing at a call to LogonUser. On Windows
>>2000 (and below), LogonUser requires SeTcbPrivilege.
>
> Is there a way to grant SeTcbPrivlege (Act as part of the operating
> system) to a domain account without granting SeTcbPrivlege to the domain
> account?

Did you proof read that questions? On the face of it, of course not.
If you were meaning grant on one member only, not at domain level (in
way that would be effective on multiple machines), yes that can be done.
However, SeTchPrivilege should not be given even on just that machine
as it does present a large security risk for anything running on the machine
that is limited only by how well use of the account is tightly controlled.

> Obviously i'm not going to grant every user in the global enterprise the
> ability to act as part of the operating system.
>
>
>> On Windows XP or later, it can be used by a plain user account with no
>> privileges.
>
> On Windows XP, the call to LogonUser succeeds, but the call to
> CreateProcessAsUser fails with code 1314 (A required privilege is not held
> by the client).
>
>
>> On Windows 2000, you may be able to use CreateProcessWithLogonW, which
>> takes no special privileges. This is essentially how runas (secondary
>> logon) on Windows 2000 works.
>
> This does seem to work with my most likely incorrect code, but here's the
> code anyway:
>
> function ExecuteFileAsUser(
> const Username, Domain, Password: WideString;
> const FileName: WideString;
> const Params: WideString='';
> const DefaultDir: WideString ='';
> const ShowCmd: Integer=SW_SHOWNORMAL): Boolean;
> var
> LocallyModifiableParams: WideString;
> startupInfo: TStartupInfo;
> processInformation: PROCESS_INFORMATION;
> const
> LOGON_WITH_PROFILE = $00000001;
> begin
> {
> Sample Usage:
> ExecuteFileAsUser(
> 'forest', //user name
> 'goldshire', //domain name
> 'gump', //password
> 'c:\windows\system32\notepad.exe', //filename
> 'c:\20070608.log', //params
> 'c:\develop' //default dir
> );
> }
>
> LocallyModifiableParams := Filename+' '+Params;
> {A command line contains the executable name, e.g.
> notepad.exe c:\somefile.txt
> }
>
> {From the Platform SDK:
> The function can modify the contents of this string.
> Therefore, this parameter cannot be a pointer to read-only memory
> (such as a const variable or a literal string).
> If this parameter is a constant string, the function may cause an
> access violation.
>
> ed: A function that tries to cause access violations. Nice.}
>
> //An empty structure that the function wants
> ZeroMemory(@startupInfo, SizeOf(startupInfo));
> startupInfo.cb :=SizeOf(startupInfo);
>
> //An empty structure that the function wants
> ZeroMemory(@processInformation, SizeOf(processInformation));
>
>
> Result := CreateProcessWithLogonW(
> PWideChar(Username),
> PWideChar(Domain),
> PWideChar(Password),
> LOGON_WITH_PROFILE, //dwLogonFlags: DWORD
> PWideChar(Filename),
> PWideChar(LocallyModifiableParams),
> 0, //dwCreationFlags: DWORD
> nil, //lpEnvironment: Pointer
> PWideChar(DefaultDir), //lpCurrentDirectory: PWideChar;
> startupInfo,
> processInformation);
> if Result then
> begin
> {From the Platform SDK:
> Handles in PROCESS_INFORMATION must be closed with the
> CloseHandle
> function when they are not needed.}
>
> //We don't need either of the handles in ProcessInformation.
> //Hopefully Microsoft won't add any more to the structure in
> the future
> CloseHandle(processInformation.hProcess);
> CloseHandle(processInformation.hThread);
> end;
> end;
>
>
Back to top
Chris Becke
External


Since: Jul 26, 2007
Posts: 1



PostPosted: Thu Jul 26, 2007 1:45 pm    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

"Ian Boyd" <ian.msnews010 RemoveThis @avatopia.com> wrote in message
news:%23cVx%23vszHHA.4816@TK2MSFTNGP04.phx.gbl...
> "Skywing [MVP]" wrote:
>>I assume that you are really failing at a call to LogonUser. On Windows
>>2000 (and below), LogonUser requires SeTcbPrivilege.
>
> Is there a way to grant SeTcbPrivlege (Act as part of the operating
> system) to a domain account without granting SeTcbPrivlege to the domain
> account? Obviously i'm not going to grant every user in the global
> enterprise the ability to act as part of the operating system.

Yes. The general method to do this kind of elevation without granting non
admin users dangerous privlege's is to create a service process that uses an
account with the Privlege - the default SYSTEM account used by services
often sufices here. The application that needs to use the function that
needs the privlege would proxy the call to the service. The service can
decide wether the request is legitimate and perform it on behalf of the
user.

The idea being that the service's interface to non domain accounts is
strictly controlled to ensure that it cant be misused by users to do
anything other than the required elevation.
Back to top
Stefan Kuhr
External


Since: Jul 26, 2007
Posts: 1



PostPosted: Thu Jul 26, 2007 5:34 pm    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Hello Ian,

Ian Boyd wrote:
> "Skywing [MVP]" wrote:
>> I assume that you are really failing at a call to LogonUser. On Windows
>> 2000 (and below), LogonUser requires SeTcbPrivilege.
>
> Is there a way to grant SeTcbPrivlege (Act as part of the operating system)
> to a domain account without granting SeTcbPrivlege to the domain account?
> Obviously i'm not going to grant every user in the global enterprise the
> ability to act as part of the operating system.


You don't "grant every user in the global enterprise" a privilege, you
always grant a privilege to a user and a computer. This means that a
domain user can have the SE_TCB_NAME privilege on one computer in the
domain, but not on the other.

--
S
Back to top
Jakob Bohm
External


Since: Jul 30, 2007
Posts: 1



PostPosted: Mon Jul 30, 2007 3:12 pm    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Chris Becke wrote:
> "Ian Boyd" <ian.msnews010.TakeThisOut@avatopia.com> wrote in message
> news:%23cVx%23vszHHA.4816@TK2MSFTNGP04.phx.gbl...
>> "Skywing [MVP]" wrote:
>>> I assume that you are really failing at a call to LogonUser. On Windows
>>> 2000 (and below), LogonUser requires SeTcbPrivilege.
>> Is there a way to grant SeTcbPrivlege (Act as part of the operating
>> system) to a domain account without granting SeTcbPrivlege to the domain
>> account? Obviously i'm not going to grant every user in the global
>> enterprise the ability to act as part of the operating system.
>
> Yes. The general method to do this kind of elevation without granting non
> admin users dangerous privlege's is to create a service process that uses an
> account with the Privlege - the default SYSTEM account used by services
> often sufices here. The application that needs to use the function that
> needs the privlege would proxy the call to the service. The service can
> decide wether the request is legitimate and perform it on behalf of the
> user.
>
> The idea being that the service's interface to non domain accounts is
> strictly controlled to ensure that it cant be misused by users to do
> anything other than the required elevation.
>
>
Which is exactly what Microsoft has done for us with the "RunAs" service
included by default in Windows 2000 and later. The tightly controlled
API consists of CreateProcessWithLogonW and little else. For NT 4.0 you
can use the "su" service from the NT 4 Resource Kit Supplement 3 or
write your own. For NT 3.x you would need to write your own.

--
Jakob Bøhm, M.Sc.Eng. * jb.TakeThisOut@danware.dk * direct tel:+45-45-90-25-33
Danware Data A/S * Bregnerodvej 127 * DK-3460 Birkerod * DENMARK
http://www.netop.com * tel:+45-45-90-25-25 * fax:+45-45-90-25-26
Information in this mail is hasty, not binding and may not be right.
Information in this posting may not be the official position of Danware
Data A/S, only the personal opinions of the author.
Back to top
Ian Boyd
External


Since: Apr 12, 2006
Posts: 7



PostPosted: Wed Aug 08, 2007 11:45 am    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

>> Is there a way to grant SeTcbPrivlege (Act as part of the operating
>> system) to a domain account without granting SeTcbPrivlege to the domain
>> account?
>
> Did you proof read that questions? On the face of it, of course not.
> If you were meaning grant on one member only, not at domain level (in
> way that would be effective on multiple machines), yes that can be done.
> However, SeTchPrivilege should not be given even on just that machine
> as it does present a large security risk for anything running on the
> machine
> that is limited only by how well use of the account is tightly controlled.

Users are the ones who are running the application that needs to call
LogonUser.

It's not a good idea to give users the permission required to run the
software that will internally call LogonUser.

So i want to give all users the ability to run the software that calls
LogonUser, but not give them the privelages that are required to call
LogonUser.


In the end, i switched to CreateProcessWithLoginW. i thought it was only
available on XP and later, i didn't realize it was also available for 2000.

Which begs the question: What was the point of CreateProcessAsUser, since no
typical users can run it. Although, the answer also presents itself: There
was no point. That's why MS created CreateProcessWithLoginW, a version of
CreateProcessAsUser that users can run.
Back to top
Ian Boyd
External


Since: Apr 12, 2006
Posts: 7



PostPosted: Wed Aug 08, 2007 11:47 am    Post subject: Re: CreateProcessAsUser [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

> You don't "grant every user in the global enterprise" a privilege, you
> always grant a privilege to a user and a computer.

> This means that a domain user can have the SE_TCB_NAME privilege on one
> computer in the domain, but not on the other.

The other what?

All user needs to be able to run some software that calls
CreateProcessAsUser internall, and they need to be able to run the software
wherever they login.


The answer is: don't try. Use CreateProcessWithLogonW
Back to top
Display posts from previous:   
Post new topic   General Reply to Topic (not reply to a specific post)    Forums Home -> Security All times are: Eastern Time (US & Canada) (change)
Page 1 of 1

 
You can post new topics in this forum
You can reply to topics in this forum
You can edit your posts in this forum
You can delete your posts in this forum
You can vote in polls in this forum