und3ath
und3ath

Reputation: 21

CreateProcessAsUser and createevent permissions

I'm creating an application which listens on a port, and when a client makes a request, it spawns a new process with a different user using LogonUser,CreateProcessAsUser .

I've setup 2 events with CreateEvent() function to signal the child that WSADuplicateSocket is ready to pass the SOCKADD_STORAGEW structure to the child process via a memory mapped file.

The OpenEvent() in the child process keep failing with error 5 (access denied ) when it is spawned from the application.

If I manually run a child/client using (shift + right click, run as) the OpenEvent function successfully manages to open the event.

The event is created in the global namespace (Global\myevent) and for testing purposes I have created a null Dacl ( i have verified permission on the Event with winobj )passed to the the CreateEvent() function.

I don't see what I'm missing .

here the concerned code snippet:

Server:

SECURITY_ATTRIBUTES sa;
CreateNullDacl(&sa);


if ((ghParentFileMappingEvent = CreateEvent(&sa, TRUE, FALSE, szParentEventName)) == NULL) {
    fprintf(stderr, "CreateEvent() failed: %d\n", GetLastError());
    return false;
}

if ((ghChildFileMappingEvent = CreateEvent(&sa, TRUE, FALSE, szChildEventName)) == NULL) {
    fprintf(stderr, "CreateEvent() failed: %d\n", GetLastError());
    CloseHandle(ghParentFileMappingEvent);
    return false;
}





PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
SECURITY_ATTRIBUTES procSa;
CreateNullDacl(&procSa);

HANDLE htok;
if (!LogonUser(chall->user, ".", chall->pass, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &htok)) {
    fprintf(stderr, "LogonUser() failed: %d\n", GetLastError());
    return false;

}


if(CreateProcessAsUser(htok, 0, szChildComandLineBuf, &procSa, 0, FALSE, NULL, NULL, "C:\\Users\\ch99", &si, &pi)) {
 //... 
}

CLient spawned from CreateProcessAsUser()

 if ((ghParentFileMappingEvent = OpenEventA(SYNCHRONIZE, FALSE, szParentEventName)) == 0)  // return 5 , access denied
{
    fprintf(fp, "OpenParentEvent failed: %d\n", GetLastError());
    return INVALID_SOCKET;
}

if ((ghChildFileMappingEvent = OpenEventA(SYNCHRONIZE, FALSE, szChildEventName)) == 0) { // return 5 access denied
    fprintf(fp, "OpenChildEvent failed: %d\n", GetLastError());
    CloseHandle(ghParentFileMappingEvent);
    ghParentFileMappingEvent = NULL;
    return INVALID_SOCKET;
}

Thanks for your reply.

Upvotes: 1

Views: 565

Answers (2)

und3ath
und3ath

Reputation: 21

After tried so many different thing, CreateEvent() keep returning access denied.

I have found a ugly workaround : in the SECURITY_ATTRIBUTES passed to CreateEvent() , i've set bInheritHandle to TRUE, and passed the handle value to the child process in argument .

At this point i'm able to use WaitForSingleObject() on the handle .

I'm realy curious to know why it didn't work as described in my first question...

Upvotes: 1

Rita Han
Rita Han

Reputation: 9700

Based on document of CreateProcessAsUser:

A handle to the primary token that represents a user. The handle must have the TOKEN_QUERY, TOKEN_DUPLICATE, and TOKEN_ASSIGN_PRIMARY access rights.

The following code works for me:

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &htok))
    printf("OpenProcessToken() failed: %d\n", GetLastError());
if (!CreateProcessAsUser(htok, L"childProc.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
    printf("CreateProcessAsUser() failed: %d\n", GetLastError());
}

Or you can use CreateProcessWithToken instead (this require run as administrator):

HANDLE htok;
if (!LogonUser(L"userName", L"domain", L"password", LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &htok)) {
    printf("LogonUser() failed: %d\n", GetLastError());
    return false;
}

if (!CreateProcessWithTokenW(htok, LOGON_WITH_PROFILE,L"childProc.exe", NULL, 0, NULL, NULL, &si, &pi)) {
    printf("CreateProcessAsUser() failed: %d\n", GetLastError());
}

With both above methods, child process can open the event successfully.

For your code I get error code 1314 (A required privilege is not held by the client.) when calling CreateProcessAsUser. Point out what am I missing and reproduce steps for your issue.

Upvotes: 0

Related Questions