Zugriffsrechte für Netzwerkfreigabe bestimmen
-
Hallo,
wie bestimme ich clientseitig die Zugriffsrechte für eine Netzwerkfreigabe oder einen Unterordner dieser Freigabe?
Beispiel:
Ich möchte prüfen, ob ich in das Unterverzeichnisdaten
der Freigabe\\server\freigabe
schreiben darf. Erschwerend kommt hinzu, dass der Zugriff auf die Netzwerkfreigabe durch einen anderen Benutzer erfolgen kann.
Konkret sieht das so aus, dass es ein Formular gibt, auf dem sich 4 Bedienelemente befinden:- ein Texteingabefeld für den Freigabenamen (optional mit weiteren Unterverzeichnisse)
- ein Texteingabefeld für einen (optionalen) Benutzernamen
- ein Texteingabefeld für das (optionale) Kennwort des Benutzers aus 2)
- ein Button, bei dessen Klicken geprüft werden soll, ob das Programm unter der Benutzung des Benutzernamens/Kennwort in den Ordner aus 1) schreiben darf.
Ich habe da jetzt schon einiges ausprobiert, z.B.
NetShareGetInfo
undAccessCheck
, komme da aber irgendwie nicht weiter. Entweder bekomme ich die keine Informationen (NetShareGetInfo
liefert keine Permissions zurück) oder falsche (AccessCheck
behauptet, das Programm hätte Schreibrechte, obwohl die Freigabe nur lesbar ist.).
Bevor ich mich jetzt da festbeiße und mich durch das komplette Windows Sicherheitskonzept arbeite wollte ich mal fragen, ob jemand sowas schon mal gemacht hat oder hilfreiche Tipps hat.Habe im INet einen Beispielquelltext gefunden und angepasst, allerdings liefert der mir für jeden Maskierung true zurück, funktioniert also nicht richtig. Die Unterstützung für andere Benutzer fehlt auch noch, aber dazu habe ich schon eine Idee (Zeile 17:
DuplicateToken
durchLogonUser
ersetzen).#include <windows.h> #include <Aclapi.h> bool check_folder_access_rights( LPCTSTR FolderName, DWORD AccessRightsMask ) { bool Result = false; DWORD SecurityLength = 0; DWORD SecurityInformation = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; if( !::GetFileSecurity( FolderName, SecurityInformation, NULL, NULL, &SecurityLength ) && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { vector<char> SecBuffer( SecurityLength ); PSECURITY_DESCRIPTOR SecDesc = static_cast< PSECURITY_DESCRIPTOR >( &SecBuffer[0] ); if( ::GetFileSecurity( FolderName, SecurityInformation, SecDesc, SecurityLength, &SecurityLength )) { HANDLE TokenProcess = NULL; if( ::OpenProcessToken( ::GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &TokenProcess )) { HANDLE TokenImpersonated = NULL; if( ::DuplicateToken( TokenProcess, SecurityImpersonation, &TokenImpersonated ) ) { GENERIC_MAPPING Mapping = { 0xFFFFFFFF }; PRIVILEGE_SET Privileges; ::ZeroMemory( &Privileges, sizeof( Privileges ) ); DWORD PrivilegesLength = sizeof( Privileges ); DWORD GrantedAccess = 0; BOOL AccessCheck = FALSE; Mapping.GenericRead = FILE_GENERIC_READ; Mapping.GenericWrite = FILE_GENERIC_WRITE; Mapping.GenericExecute = FILE_GENERIC_EXECUTE; Mapping.GenericAll = FILE_ALL_ACCESS; ::MapGenericMask( &AccessRightsMask, &Mapping ); if( ::AccessCheck( SecDesc, TokenImpersonated, AccessRightsMask, &Mapping, &Privileges, &PrivilegesLength, &GrantedAccess, &AccessCheck )) { Result = AccessCheck; } ::CloseHandle( TokenImpersonated ); } ::CloseHandle( TokenProcess ); } } } return Result; }
-
Um zu prüfen ob Du schreiben kannst, wird Dir nichts anderen übrig bleiben als zu schreiben...
Alles andere ist der Mühe nicht wert...