I've spent a few days on this problem and even though there are tons of different examples online it's a tricky problem and I can't get them to work in my scenario.
I have a Windows service that runs under the Local System account. It has a WCF endpoint listening to API requests. When told via the API, the service is supposed to start a new process in the System session (0) and with the "Worker" account credentials. The process is a worker that checks for work in a queue and does it. If it does not find work, it will sleep for a bit and check again. If it does find work, it starts a new process in the same session and with the same credentials and does the work. After it's done the work it closes.
The "Worker" is a domain account and a member of the local administrators group on the machine, which has execute permissions on the executable. The machine is on the same domain as the account.
The problem is that when the service tries to start the process it gets a ERROR_ACCESS_DENIED (5)
error code from the CreateProcessAsUser
method.
I tried running the same code on a Windows 7 machine with the same credentials and it works fine, but it gets that error code when running on Windows Server 2008.
The code's too big to show here, so I've put it elsewhere...
ProcessHelper: http://pastie.org/private/y7idu3nw4xv1fxzeizbn9g
The service calls the StartAsUserFromService
method to start the process, which internally calls CreateProcessAsUser
after establishing a session. The process calls the StartAsUserFromApplication
method to start its successor, which internally calls CreateProcessWithLogonW
.
ImpersonationContext: http://pastie.org/private/xppc7wnoidajmpq8h8sg
The service needs to get the user token to start a process as them. The process doesn't need that to start its successor. As far as I can tell the impersonation is successful on Server 2008, but it doesn't have some permissions, and I can't figure out which.
EDIT:
I tried both a local administrator account and a domain account on the Windows 7 machine, and they work fine. But neither of them work on the Server 2008 machine. There must be a permission missing somewhere, but I don't know where; the error message isn't helpful.
I also tried ticking the "run as administrator" box in the compatibility tab of the executable, but it made no difference.
EDIT:
I used process monitor to see what's going on in the service and this is where it's getting the error...
Date & Time: 12/02/2014 11:44:03
Event Class: File System
Operation: CreateFile
Result: ACCESS DENIED
Path: D:\..\executable.exe
TID: 6244
Duration: 0.0000450
Desired Access: Read Data/List Directory, Execute/Traverse, Read Attributes, Synchronize
Disposition: Open
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: n/a
ShareMode: Read, Delete
AllocationSize: n/a
Impersonating: Domain\Worker
and
Date & Time: 12/02/2014 11:44:03
Event Class: File System
Operation: CreateFile
Result: ACCESS DENIED
Path: D:\..\executable.exe
TID: 6244
Duration: 0.0000480
Desired Access: Execute/Traverse, Synchronize
Disposition: Open
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: n/a
ShareMode: Read, Delete
AllocationSize: n/a
Impersonating: Domain\Worker