Ausführen von Operationen unter anderem Benutzernamen
Moderators: Hacker, Stefan2, white
Ausführen von Operationen unter anderem Benutzernamen
Ich würde gerne wissen, ob es machbar wäre interne Kommandos (z.B. Entpacken oder Kopieren) unter einem anderen Benutzernamen (z.B. einem Mitglied der Gruppe Administratoren) auszuführen ohne dafür eine neue TC-Instanz zu öffnen. Beim Aufruf der Aktion müsste dann ein Häckchen gesetzt sowie Benutzername und Passwort angegegben werden. Mir ist bekannt, dass es Kommandozeilen-Programme gibt, die man bei Bedarf mit runas starten kann. Ich würde jedoch gerne die internen Kommandos des TC in ähnlicher Form nutzen.
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Mit internen Befehlen ist das leider nicht möglich - die benötigen ja den Total Commander und seine Funktionen als Laufzeitumgebung. Deshalb muss zwingend ein neuer Total Commander unter diesem Namen gestartet werden. Meines Wissens kann man nicht einfach einen Thread unter fremdem Usernamen starten.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Hallo,
untenstehend ein kleines Programm im Quellcode. Es sollte mit eingeschränkten Benutzerrechten gestartet werden sollte. Es tut folgendes:
1. Kopieren einer Datei in den Windows-Ordner -> Das schlägt fehl.
2. Erlangen von Adminrechten.
3. Kopieren einer Datei in den Windows-Ordner -> Das funktioniert.
4. Zurückwechseln zu den eingeschränkten Rechten.
5. Kopieren einer Datei in den Windows-Ordner -> Das schlägt fehl.
Das Programm muss zum Funktionieren noch angepasst werden (Login/Passwort/Pfadnamen).
Das Programm enthält Verweise auf die MSDN-Dokumentation der eingesetzten Funktionen.
untenstehend ein kleines Programm im Quellcode. Es sollte mit eingeschränkten Benutzerrechten gestartet werden sollte. Es tut folgendes:
1. Kopieren einer Datei in den Windows-Ordner -> Das schlägt fehl.
2. Erlangen von Adminrechten.
3. Kopieren einer Datei in den Windows-Ordner -> Das funktioniert.
4. Zurückwechseln zu den eingeschränkten Rechten.
5. Kopieren einer Datei in den Windows-Ordner -> Das schlägt fehl.
Das Programm muss zum Funktionieren noch angepasst werden (Login/Passwort/Pfadnamen).
Das Programm enthält Verweise auf die MSDN-Dokumentation der eingesetzten Funktionen.
Code: Select all
#include <windows.h>
#include <tchar.h>
void copyFile ();
BOOL b = FALSE;
int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR lpCmdLine,int)
{
/*
Es wird davon ausgegangen, dass der Aufrufer des Programms Mitglied der
Benutzergruppe "Benutzer" ist und keine Schreibrechte für das Windows-Verzeichnis hat.
Es wird erwartet, dass nur der zweite der drei Versuche erfolgreich ist.
Das Beispiel ist absolut quick & dirty. Die Parameter von LogonUser und die Pfade
in CopyFile müssen angepasst werden. Außerdem muss die Quelldatei (C:\1.txt) vorhanden sein.
*/
HANDLE token = NULL;
// Es wird versucht eine Datei als eingeschränkter Benutzer zu kopieren.
copyFile();
// Als Administrator einloggen
// http://msdn.microsoft.com/library/en-us/security/security/logonuser.asp
b = LogonUser (TEXT("Administrator"), TEXT("Domäne"), TEXT("Passwort"),
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &token);
// Den eingeloggten Benutzer, also hier den Administrator, anstelle des aktuellen einsetzen.
// http://msdn.microsoft.com/library/en-us/security/security/impersonateloggedonuser.asp
b = ImpersonateLoggedOnUser(token);
// Es wird versucht eine Datei als Administrator zu kopieren.
copyFile();
// Zum eingeschränkten Benutzer zurückkehren
// http://msdn.microsoft.com/library/en-us/security/security/reverttoself.asp
b = RevertToSelf ();
// Es wird abermals versucht eine Datei als eingeschränkter Benutzer zu kopieren.
copyFile();
CloseHandle (token);
return 0;
}
void copyFile ()
{
b = CopyFile (
TEXT("C:\\1.txt"),
TEXT("C:\\Windows\\1.txt"),
FALSE);
if (b)
{
MessageBox (NULL, TEXT("Copy OK"), TEXT("INFO!"), MB_ICONINFORMATION);
}
else
{
MessageBox (NULL, TEXT("Copy failed"), TEXT("ERROR!"), MB_ICONERROR);
}
}
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Danke für den Code! Noch eine Frage: Woher bekomme ich die aktuelle Domain, und was ist, wenn der PC nicht an einer Domain hängt?
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Es macht nichts, wenn der Rechner nicht an einer Domäne hängt. Mein Rechner zum Beispiel hängt nicht an einer Domäne. Die Benutzung der API Funktionen ist hier dem runas-Kommando ähnlich wo man die Domäne auch weglassen kann.ghisler(Author) wrote:Danke für den Code! Noch eine Frage: Woher bekomme ich die aktuelle Domain, und was ist, wenn der PC nicht an einer Domain hängt?
Ich zitiere hier mal aus der MSDN-Hilfe:
Die Domäne ist also kein Stolperstein.lpszDomain
[in] Pointer to a null-terminated string that specifies the name of the domain or server whose account database contains the lpszUsername account. If this parameter is NULL, the user name must be specified in UPN format. If this parameter is ".", the function validates the account using only the local account database.
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Gut, nur wie bekomme ich den Namen der aktuellen Domain?
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Das geht mit der Funktion NetWkstaUserGetInfo.ghisler(Author) wrote:Gut, nur wie bekomme ich den Namen der aktuellen Domain?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netwkstausergetinfo.asp
Auf der Seite ist auch ein Beispiel wie man diese Funktion aufruft.
Wenn der Benutzer also nicht an einer Domäne hängt, dann ist die aktuelle Domäne der Computername.
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Danke, ich kann da manchmal stundenlang suchen, ohne die richtige Funktion zu finden.
Zur Zeit suche ich gerade eine Funktion, mit welcher man anhand eines Netzwerk-Pfades wie \\servername\share herausfinden kann, was das für ein Server ist! Es muss irgendwie gehen, denn smbclient unter Linux meldet mir das. Bei einem Samba-Server meldet es:
Domain=[MYDOMAIN] OS=[Unix] Server=[Samba 3.0.0],
Und bei Windows 2000:
Domain=[MYDOMAIN] OS=[Windows 5.0] Server=[Windows 2000 LAN Manager],
Wieso ich das brauche? Weil Samba leider ab und zu Probleme macht. Es meldet sich bei GetVolumeInformation als NTFS, führt dann aber bei Funktionen wie NtQueryInformationFile zu Fehlern.
Irgend eine Idee?
Zur Zeit suche ich gerade eine Funktion, mit welcher man anhand eines Netzwerk-Pfades wie \\servername\share herausfinden kann, was das für ein Server ist! Es muss irgendwie gehen, denn smbclient unter Linux meldet mir das. Bei einem Samba-Server meldet es:
Domain=[MYDOMAIN] OS=[Unix] Server=[Samba 3.0.0],
Und bei Windows 2000:
Domain=[MYDOMAIN] OS=[Windows 5.0] Server=[Windows 2000 LAN Manager],
Wieso ich das brauche? Weil Samba leider ab und zu Probleme macht. Es meldet sich bei GetVolumeInformation als NTFS, führt dann aber bei Funktionen wie NtQueryInformationFile zu Fehlern.

Irgend eine Idee?
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Ich weiß nicht, ob das jetzt das 100% Richtige ist. Einfach mal testen (ich hab hier keinen samba server am laufen):
NetServerGetInfo
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netservergetinfo.asp
Ich habe das Beispiel von der Seite noch etwas erweitert, weil es nicht so aussagekräftig war. Als Kommandozeilenparameter muss "\\servername" angegeben werden.
Es gibt auch noch ein paar andere SERVER_INFO-Strukturen:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/server_functions.asp
NetServerGetInfo
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netservergetinfo.asp
Ich habe das Beispiel von der Seite noch etwas erweitert, weil es nicht so aussagekräftig war. Als Kommandozeilenparameter muss "\\servername" angegeben werden.
Es gibt auch noch ein paar andere SERVER_INFO-Strukturen:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/server_functions.asp
Code: Select all
#ifndef UNICODE
#define UNICODE
#endif
#include <stdio.h>
#include <windows.h>
#include <lm.h>
// Netapi32.lib muss gelinkt weden
int wmain(int argc, wchar_t *argv[])
{
DWORD dwLevel = 101;
LPSERVER_INFO_101 pBuf = NULL;
NET_API_STATUS nStatus;
LPTSTR pszServerName = NULL;
if (argc > 2)
{
fwprintf(stderr, L"Usage: %s [\\\\ServerName]\n", argv[0]);
exit(1);
}
// The server is not the default local computer.
//
if (argc == 2)
pszServerName = argv[1];
//
// Call the NetServerGetInfo function, specifying level 101.
//
nStatus = NetServerGetInfo(pszServerName,
dwLevel,
(LPBYTE *)&pBuf);
//
// If the call succeeds,
//
if (nStatus == NERR_Success)
{
//
// Check for the type of server.
// The values are defined in lmserver.h
//
if (pBuf->sv101_type & SV_TYPE_WORKSTATION)
printf("SV_TYPE_WORKSTATION\n");
if (pBuf->sv101_type & SV_TYPE_SERVER)
printf("SV_TYPE_SERVER\n");
if (pBuf->sv101_type & SV_TYPE_SQLSERVER)
printf("SV_TYPE_SQLSERVER\n");
if (pBuf->sv101_type & SV_TYPE_DOMAIN_CTRL)
printf("SV_TYPE_DOMAIN_CTRL\n");
if (pBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL)
printf("SV_TYPE_DOMAIN_BAKCTRL\n");
if (pBuf->sv101_type & SV_TYPE_TIME_SOURCE)
printf("SV_TYPE_TIME_SOURCE\n");
if (pBuf->sv101_type & SV_TYPE_AFP)
printf("SV_TYPE_AFP\n");
if (pBuf->sv101_type & SV_TYPE_NOVELL)
printf("SV_TYPE_NOVELL\n");
if (pBuf->sv101_type & SV_TYPE_DOMAIN_MEMBER)
printf("SV_TYPE_DOMAIN_MEMBER\n");
if (pBuf->sv101_type & SV_TYPE_PRINTQ_SERVER)
printf("SV_TYPE_PRINTQ_SERVER\n");
if (pBuf->sv101_type & SV_TYPE_DIALIN_SERVER)
printf("SV_TYPE_DIALIN_SERVER\n");
if (pBuf->sv101_type & SV_TYPE_SERVER_UNIX)
printf("SV_TYPE_SERVER_UNIX\n");
if (pBuf->sv101_type & SV_TYPE_NT)
printf("SV_TYPE_NT\n");
if (pBuf->sv101_type & SV_TYPE_WFW)
printf("SV_TYPE_WFW\n");
if (pBuf->sv101_type & SV_TYPE_SERVER_MFPN)
printf("SV_TYPE_SERVER_MFPN\n");
if (pBuf->sv101_type & SV_TYPE_SERVER_NT)
printf("SV_TYPE_SERVER_NT\n");
if (pBuf->sv101_type & SV_TYPE_POTENTIAL_BROWSER)
printf("SV_TYPE_POTENTIAL_BROWSER\n");
if (pBuf->sv101_type & SV_TYPE_BACKUP_BROWSER)
printf("SV_TYPE_BACKUP_BROWSER\n");
if (pBuf->sv101_type & SV_TYPE_MASTER_BROWSER)
printf("SV_TYPE_MASTER_BROWSER\n");
if (pBuf->sv101_type & SV_TYPE_DOMAIN_MASTER)
printf("SV_TYPE_DOMAIN_MASTER\n");
if (pBuf->sv101_type & SV_TYPE_SERVER_OSF)
printf("SV_TYPE_SERVER_OSF\n");
if (pBuf->sv101_type & SV_TYPE_SERVER_VMS)
printf("SV_TYPE_SERVER_VMS\n");
if (pBuf->sv101_type & SV_TYPE_WINDOWS)
printf("SV_TYPE_WINDOWS\n");
if (pBuf->sv101_type & SV_TYPE_DFS)
printf("SV_TYPE_DFS\n");
if (pBuf->sv101_type & SV_TYPE_CLUSTER_NT)
printf("SV_TYPE_CLUSTER_NT\n");
if (pBuf->sv101_type & SV_TYPE_TERMINALSERVER)
printf("SV_TYPE_TERMINALSERVER\n");
if (pBuf->sv101_type & SV_TYPE_CLUSTER_VS_NT)
printf("SV_TYPE_CLUSTER_VS_NT\n");
if (pBuf->sv101_type & SV_TYPE_DCE)
printf("SV_TYPE_DCE\n");
if (pBuf->sv101_type & SV_TYPE_ALTERNATE_XPORT)
printf("SV_TYPE_ALTERNATE_XPORT\n");
if (pBuf->sv101_type & SV_TYPE_LOCAL_LIST_ONLY)
printf("SV_TYPE_LOCAL_LIST_ONLY\n");
if (pBuf->sv101_type & SV_TYPE_DOMAIN_ENUM)
printf("SV_TYPE_DOMAIN_ENUM\n");
if (pBuf->sv101_type & SV_TYPE_ALL)
printf("SV_TYPE_ALL\n");
}
//
// Otherwise, print the system error.
//
else
fprintf(stderr, "A system error has occurred: %d\n", nStatus);
//
// Free the allocated memory.
//
if (pBuf != NULL)
NetApiBufferFree(pBuf);
return 0;
}
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Sieht gut aus, werde ich mir mal näher ansehen - vielen Dank!
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
2Lefteous
Fuer die Installationsfunktion der Dateisystem-Plugins wollte ich das jetzt einbauen, doch leider funktioniert es nicht! Der Grund ist folgender (aus der MSDN-Beschreibung von LogonUser):
>>The process that calls LogonUser must have the SE_TCB_NAME privilege.
The privilege does not need to be enabled. The LogonUser function enables the privilege as necessary. The function fails if the calling process does not have the SE_TCB_NAME privilege, and GetLastError returns the error code ERROR_PRIVILEGE_NOT_HELD.<<
Leider haben normale User dieses Privileg nicht! Die Funktion kann deshalb leider nur von Admins benutzt werden, um sich als normaler User anzumelden, nicht aber umgekehrt. Wieso Microsoft dieses Privileg normalen Usern vorenthält ist mir schleierhaft, man braucht ja noch das Admin-Passwort...
Fuer die Installationsfunktion der Dateisystem-Plugins wollte ich das jetzt einbauen, doch leider funktioniert es nicht! Der Grund ist folgender (aus der MSDN-Beschreibung von LogonUser):
>>The process that calls LogonUser must have the SE_TCB_NAME privilege.
The privilege does not need to be enabled. The LogonUser function enables the privilege as necessary. The function fails if the calling process does not have the SE_TCB_NAME privilege, and GetLastError returns the error code ERROR_PRIVILEGE_NOT_HELD.<<
Leider haben normale User dieses Privileg nicht! Die Funktion kann deshalb leider nur von Admins benutzt werden, um sich als normaler User anzumelden, nicht aber umgekehrt. Wieso Microsoft dieses Privileg normalen Usern vorenthält ist mir schleierhaft, man braucht ja noch das Admin-Passwort...
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
2ghisler(Author)
Wie merkwürdig die Notwendigkeit für das Attribut ist, ist z.B die Tatsache, dass eine ähnlich gelagerte Funktion wie CreateProcessWithLogonW, was von "runas" oder auch "Launch TC" benutzt wird, dieses Attribut unter keinem Betriebsystem benötigt. Somit funktioniert mein Tool auch unter Windows 2000...
Ich würde mich freuen, wenn sie die Funktion trotz des offensichtlich fehlerhaften Verhaltens unter Windows 2000 einbauen würden. Die Zahl der Windows XP Benutzer nimmt ja ständig zu und warum ein Feature nicht einbauen, nur weil es in einer älteren Windows-Version nicht geht?
Ja das ist richtig. Allerdings taucht in der Online-Dokumentation zusätzlich der Hinweis auf, dass dies ausschließlich für Windows 2000 gilt. Unter Windows XP und Windows Server 2003 wird dieses Privileg nicht benötigt. Ich habe das auch anhand von einigen Tests nachvollziehen können. Unter Windows NT gibt es wahrscheinlich das gleiche Problem wie unter Windows 2000.The process that calls LogonUser must have the SE_TCB_NAME privilege.
Normalerweise hat es nur der Local Service-Account, auch nicht ein Mitglied der Administratoren-Gruppe. Mit dem Attribut kann man ne Menge machen, viel mehr als ein Administrator. Es ist also in keinem Fall eine Lösung jemanden zu empfehlen das Privileg zu setzen - sei es programmatisch durch den TC oder durch ein Admintool.Leider haben normale User dieses Privileg nicht!
Wie merkwürdig die Notwendigkeit für das Attribut ist, ist z.B die Tatsache, dass eine ähnlich gelagerte Funktion wie CreateProcessWithLogonW, was von "runas" oder auch "Launch TC" benutzt wird, dieses Attribut unter keinem Betriebsystem benötigt. Somit funktioniert mein Tool auch unter Windows 2000...
Ich würde mich freuen, wenn sie die Funktion trotz des offensichtlich fehlerhaften Verhaltens unter Windows 2000 einbauen würden. Die Zahl der Windows XP Benutzer nimmt ja ständig zu und warum ein Feature nicht einbauen, nur weil es in einer älteren Windows-Version nicht geht?
- ghisler(Author)
- Site Admin
- Posts: 50390
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Ah, interessant, ich ging davon aus, dass sich XP wie Windows 2000 verhalten würde. Allerdings frage ich mich mittlerweile, ob so eine Installationsfunktion wirklich Sinn macht. Einige Plugins speichern ihre ini-Datei im selben Verzeichnis (siehe aktuelle Diskussion im Plugin-Forum), da würde es wenig Sinn machen, das Plugin in ein solches Verzeichnis zu installieren, wenn danach keine Einstellungen gespeichert werden können.
Ich z.B. arbeite immer als normaler User, habe aber viele Tools in c:\utils installiert statt in c:\Programme, weil die Tools einfach nicht laufen, wenn sie keine Schreibrechte auf ihr Verzeichnis haben.
Ich z.B. arbeite immer als normaler User, habe aber viele Tools in c:\utils installiert statt in c:\Programme, weil die Tools einfach nicht laufen, wenn sie keine Schreibrechte auf ihr Verzeichnis haben.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
2ghisler(Author)
Das Verhalten der Plugins ist nicht schnittstellenkonform. Darauf Rücksicht zu nehmen halte ich für falsch. Ich hatte ja schonmal vorgeschlagen nur noch solche Plugins auf die offizielle Pluginseite zu nehmen, die sie an die Dokumentation halten. Naja habe ich ja alles schon im Pluginforum geschrieben.
Ich würde es begrüßen, wenn Sie mit gutem Beispiel vorangehen würden. Ich kenne kein Tool, dass das Arbeiten als "Admin on demand", also Eingabe des Passworts wenn mehr Rechte benötigt werden wirklich gut unterstützt. Der Total Commander könnte sich hier hervortun.Allerdings frage ich mich mittlerweile, ob so eine Installationsfunktion wirklich Sinn macht.
Das Verhalten der Plugins ist nicht schnittstellenkonform. Darauf Rücksicht zu nehmen halte ich für falsch. Ich hatte ja schonmal vorgeschlagen nur noch solche Plugins auf die offizielle Pluginseite zu nehmen, die sie an die Dokumentation halten. Naja habe ich ja alles schon im Pluginforum geschrieben.
Ich habe die Nase langsam voll davon andauernd Sicherheitsdeskriptoren zu ändern.ch z.B. arbeite immer als normaler User, habe aber viele Tools in c:\utils installiert statt in c:\Programme, weil die Tools einfach nicht laufen, wenn sie keine Schreibrechte auf ihr Verzeichnis haben.