NamedPipes unter Vista (Austausch zwischen Elevated und normal)



  • Hi Leute :),

    ich möchte unter Vista Informationen von einem Programm mit Standard-Rechten an eines mit Admin-Rechten senden. Fenster-Nachrichten fallen da weg, da das OS die direkt ausfiltert. Also dachte ich mir, dass eine Named Pipe sinnvoll ist.

    Ich erstelle sie (im Admin-Programm) wie folgt:

    SECURITY_DESCRIPTOR securityDesc;
    if(!InitializeSecurityDescriptor(&securityDesc, SECURITY_DESCRIPTOR_REVISION))
    	return false;
    if(!SetSecurityDescriptorDacl(&securityDesc, false, NULL, false))
    	return false;
    if(!SetSecurityDescriptorSacl(&securityDesc, false, NULL, false))
    	return false;
    
    SECURITY_ATTRIBUTES securityAttributes;
    securityAttributes.nLength = sizeof(securityAttributes);
    securityAttributes.lpSecurityDescriptor = &securityDesc;
    securityAttributes.bInheritHandle = false;
    
    msgListenerPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_NOWAIT, 1, 4096, 4096, 5000, &securityAttributes);
    

    Das funktioniert auch perfekt. Jetzt möchte ich mich von dem Programm mit Standard-Rechten aus connecten:

    CallNamedPipe(pipeName, &data, 4, out, 0, &written, NMPWAIT_NOWAIT);
    

    Dies schlägt fehl und GetLastError liefert mir 5 (ERROR_ACCESS_DENIED).

    Wo liegt mein Fehler?

    Vielen Dank schon mal 🙂

    Greetz!
    M.T.



  • Du kannst auch via Messages kommunizieren. Du musst nur für die Message eine Ausnahme definieren:
    ChangeWindowMessageFilter



  • Genial. Danke Jochen 🙂

    Schönes Wochenende!
    M.T.


  • Mod



  • Macht er doch, oder? Deshalb sollte es ja auch gehen... oder wie müsste die DACL hier genau aussehen? Everyone?


  • Mod

    Stimmt macht er richtig! Allerdings die SACL braucht er nicht.

    Folgender Code erzeugt bei mir eine named Pipe in einem Service, mit Rechten auf Everyone und erlaubt Zugriff damit auch von nicht elevated Programmen.

    // Get an empty DACL to allow everyone to connect. A NULL DACL allows
    	// only Admins a full connect. Other users can only read.
    	SECURITY_DESCRIPTOR sd; 
    	if (!::InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) 
    	{
    		TRACE_LAST_ERROR(_T("InitializeSecurityDescriptor failed"));
    		return false;
    	}
    
    	// Allow access to really everyone!
    	if (!::SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE)) 
    	{
    		TRACE_LAST_ERROR(_T("SetSecurityDescriptorDacl failed"));
    		return false;
    	}
    
    	SECURITY_ATTRIBUTES sa; 
    	sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
    	sa.lpSecurityDescriptor = static_cast<PVOID>(&sd); 
    	sa.bInheritHandle = false; 
    
    	// Create the pipe from the server side
    	m_hPipe = ::CreateNamedPipe(PIPENAME, 
    								PIPE_ACCESS_DUPLEX |
    								FILE_FLAG_OVERLAPPED,    // overlapped mode 
    								PIPE_TYPE_MESSAGE|PIPE_WAIT,
    								1,			// 1 instance
    								4096, 4096, // buffer sizes for I/O
    								1,			// default timeout
    								&sa);
    	TRACE_LAST_ERROR_IF(m_hPipe==INVALID_HANDLE_VALUE,_T("CreateNamedPipe failed"));
    	return m_hPipe!=INVALID_HANDLE_VALUE;
    


  • Stimmt. So funktionierts. Mein Fehler war der 2. Parameter bei SetSecurityDescriptorDacl. War mir nicht im Klaren darüber dass ein DACL von InitializeSecurityDescriptor standardmäßig gesetzt wird.

    Werds aber dennoch mit Window-Messages machen. Das mit den Ausnahmen war mir neu. Seit Vista ist echt eine Menge an neuen Funktionen dazu gekommen ... ^^

    Danke euch beiden für die Mühe 🙂

    Greetz
    M.T.


Anmelden zum Antworten