Search code examples
c++winapiwinsock2

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.


Solution

  • 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...