DACL für Datei setzen funktioniert nicht



  • 1332 No mapping between account names and security IDs was done.

    Er mag also einen deiner Strings nicht.
    Probier sie einzeln durch, dann weisst du welchen.

    Offensichtliche Probleme: "Users" ist wohl kein Computername. "" wird kein gültiger Username sein. Beim 2. Eintrag setzt du "TrusteeType" nicht (k.A. ob die Null die du von ZeroMemory dort stehen hast der passende TrusteeType ist, ich würd's aber auf jeden Fall trotzdem hinschreiben, auch wenn 0 das ist was du brauchst).

    Alles Schlampigkeitsfehler.


  • Mod

    Ich tippe mal eher auf ein Unicode/MBCS Konflikt, der cast auf LPTSTR gehört da garantiert nicht hin und das Projekt ist vermutlich Unicode und die Strings sind als char angelegt...

    Wie immer...



  • @hustbaer:
    Hab mal meinen Code ein wenig geändert:

    BOOL SetDACLForObject(const char* Object, SE_OBJECT_TYPE ObjectType, int AccessPerms, ACCESS_MODE AccessMode) 
    {
    	char StrTrustee[2][100] = {"Administrators", "System"};
    
    	char UserName[100];
    	DWORD SizeUserName = sizeof(UserName);
    	GetUserName(UserName, &SizeUserName);
    
    	DWORD Res = 0;
    	PACL NewDACL = NULL;
    	PSID SidAdmin = NULL;
    	PSECURITY_DESCRIPTOR SD = NULL;
    	SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
    	EXPLICIT_ACCESS ea[3];
    
    	if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
    		SECURITY_BUILTIN_DOMAIN_RID, 
    		DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0,
    		0, 0, &SidAdmin))
    	{
    		cout <<"AllocateAndInitializeSid() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	ZeroMemory(ea, 3 * sizeof(EXPLICIT_ACCESS));
    	ea[0].grfAccessPermissions	= AccessPerms;
    	ea[0].grfAccessMode			= AccessMode;
    	ea[0].grfInheritance		= NO_INHERITANCE; //NO_INHERITANCE;
    	ea[0].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[0].Trustee.TrusteeType	= TRUSTEE_IS_GROUP;
    	ea[0].Trustee.ptstrName		= (LPTSTR) (StrTrustee[0]);
    
    	/*ea[1].grfAccessPermissions	= AccessPerms;
    	ea[1].grfAccessMode			= AccessMode;
    	ea[1].grfInheritance		= NO_INHERITANCE;
    	ea[1].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[1].Trustee.ptstrName		= (LPTSTR) (CURRENT_USER);*/
    
    	ea[1].grfAccessPermissions	= AccessPerms;
    	ea[1].grfAccessMode			= AccessMode;
    	ea[1].grfInheritance		= NO_INHERITANCE;
    	ea[1].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[1].Trustee.TrusteeType	= TRUSTEE_IS_COMPUTER;
    	ea[1].Trustee.ptstrName		= (LPTSTR) (StrTrustee[1]);
    
    	ea[2].grfAccessPermissions	= AccessPerms;
    	ea[2].grfAccessMode			= AccessMode;
    	ea[2].grfInheritance		= NO_INHERITANCE;
    	ea[2].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[2].Trustee.TrusteeType	= TRUSTEE_IS_USER;
    	ea[2].Trustee.ptstrName		= (LPTSTR) (UserName);
    
    	Res = SetEntriesInAcl(3, ea, NULL, &NewDACL);
    	if (Res != ERROR_SUCCESS)
    	{
    		Res = GetLastError();
    		cout <<"SetEntriesInAcl() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	Res = SetNamedSecurityInfo((LPTSTR) Object, ObjectType, DACL_SECURITY_INFORMATION, SidAdmin, NULL, NewDACL, NULL);
    	if (Res != ERROR_SUCCESS)
    	{
    		cout <<"SetNamedSecurityInfo() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	LocalFree(SD);
    	LocalFree(NewDACL);
    
    	return TRUE;
    }
    

    @Martin Richter:
    Mein Projekt ist auf Multibyte gestellt.



  • Dein Problem sind immer noch die übergeordneten Objekte...



  • Ich glaube immer noch nicht dass "System" ein Computer ist. AFAIK ist "NT AUTHORITY\SYSTEM" ein User-Account.



  • Ja dass stimmt, aber er hat dennoch die Probleme...



  • Ich wollte damit nicht behaupten dass das was du schreibst nicht stimmt.

    Ich meine er sollte schrittweise rangehen. Also erstmal die Ursache für den ersten Fehler den er bekommt suchen, diese fixen, nochmal probieren. Wenns wieder nicht geht (mit neuem Fehler), die Ursache für den finden, fixen, etc.

    Alles auf einmal lösen zu wollen ist nach meiner Erfahrung nicht sinnvoll, weil man länger braucht als wenn man systematisch Schritt für Schritt vorgeht. Bzw. auch oft zu gar keinen Ergebnis kommt.



  • Gut - ich habe die Funktion nochmal überarbeitet und jetzt ergibt sie auch keinen Fehler mehr (das Problem war direkt der erste Eintrag "Administrators", zum Glück hatte ich noch eine SID):

    BOOL SetDACLForObject(const char* Object, SE_OBJECT_TYPE ObjectType, int AccessPerms, ACCESS_MODE AccessMode) 
    {
    	char StrTrustee[100] = "System";
    
    	char UserName[100];
    	DWORD SizeUserName = sizeof(UserName);
    	GetUserName(UserName, &SizeUserName);
    
    	DWORD Res = 0;
    	PACL NewDACL = NULL;
    	PSID SidAdmin = NULL;
    	PSECURITY_DESCRIPTOR SD = NULL;
    	SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
    	EXPLICIT_ACCESS ea[3];
    
    	if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
    		SECURITY_BUILTIN_DOMAIN_RID, 
    		DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0,
    		0, 0, &SidAdmin))
    	{
    		cout <<"AllocateAndInitializeSid() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	ZeroMemory(ea, 3 * sizeof(EXPLICIT_ACCESS));
    	ea[0].grfAccessPermissions	= AccessPerms;
    	ea[0].grfAccessMode			= AccessMode;
    	ea[0].grfInheritance		= NO_INHERITANCE; //NO_INHERITANCE;
    	ea[0].Trustee.TrusteeForm	= TRUSTEE_IS_SID;
    	ea[0].Trustee.TrusteeType	= TRUSTEE_IS_GROUP;
    	ea[0].Trustee.ptstrName		= (LPTSTR) (SidAdmin);
    
    	/*ea[1].grfAccessPermissions	= AccessPerms;
    	ea[1].grfAccessMode			= AccessMode;
    	ea[1].grfInheritance		= NO_INHERITANCE;
    	ea[1].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[1].Trustee.ptstrName		= (LPTSTR) (CURRENT_USER);*/
    
    	ea[1].grfAccessPermissions	= AccessPerms;
    	ea[1].grfAccessMode			= AccessMode;
    	ea[1].grfInheritance		= NO_INHERITANCE;
    	ea[1].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[1].Trustee.TrusteeType	= TRUSTEE_IS_USER;
    	ea[1].Trustee.ptstrName		= (LPTSTR) (StrTrustee);
    
    	ea[2].grfAccessPermissions	= AccessPerms;
    	ea[2].grfAccessMode			= AccessMode;
    	ea[2].grfInheritance		= NO_INHERITANCE;
    	ea[2].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[2].Trustee.TrusteeType	= TRUSTEE_IS_USER;
    	ea[2].Trustee.ptstrName		= (LPTSTR) (UserName);
    
    	Res = SetEntriesInAcl(3, ea, NULL, &NewDACL);
    	if (Res != ERROR_SUCCESS)
    	{
    		cout <<"SetEntriesInAcl() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	Res = SetNamedSecurityInfo((LPTSTR) Object, ObjectType, DACL_SECURITY_INFORMATION, SidAdmin, NULL, NewDACL, NULL);
    	if (Res != ERROR_SUCCESS)
    	{
    		cout <<"SetNamedSecurityInfo() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	LocalFree(SD);
    	LocalFree(NewDACL);
    	FreeSid(SidAdmin);
    
    	return TRUE;
    }
    

    Das Problem nun ist, dass zwar "Berechtigungen ändern" und "Besitz übernehmen" verweigert sind, aber "Löschen" und "Ordner durchsuchen/Datei ausführen" nicht zugelassen sind.



  • Ich habe mal

    SetDACLForObject(systemstartfolder, SE_FILE_OBJECT, CUSTOM_DENY, DENY_ACCESS);
    

    zuerst geschrieben und dannach

    SetDACLForObject(systemstartfolder, SE_FILE_OBJECT, CUSTOM_ALLOW, SET_ACCESS);
    

    Nun sind "Löschen" und "Berechtigungen lesen" zugelassen, aber "Berechtigungen ändern" und "Besitz übernehmen" weder zugelassen noch verweigert. Kann es sein. dass sich zwei Aufrufe irgendwie im Weg stehen?

    (Btw.: Eigentlich wollte ich ja "Ordner durchsuchen/Datei ausführen" zulassen und nicht "Berechtigungen lesen", aber was soll ich anstatt READ_CONTROL nehmen? Schließlich ist STANDARD_RIGHTS_EXECUTE ja auch als READ_CONTROL definiert: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379607(v=vs.85).aspx)



  • Wegen den übergeordneten Objekten... also nochmals widerhole ich mich nicht.



  • der besitzer schrieb:

    Wegen den übergeordneten Objekten... also nochmals widerhole ich mich nicht.

    Tut mir Leid, aber kannst du präzise sagen, wo der Fehler liegt? Wo vererbe ich die übergeordneten Objekte?



  • Ich glaube, ich habe den Fehler gefunden (dank dieses Threads: http://www.c-plusplus.net/forum/p2172437). Ich muss mir erst das bestehende DACL holen und dann modifizieren. Hier mein neuer Code:

    BOOL SetDACLForObject(const char* Object, SE_OBJECT_TYPE ObjectType, int AccessPerms, ACCESS_MODE AccessMode) 
    {
    	char StrTrustee[100] = "System";
    
    	char UserName[100];
    	DWORD SizeUserName = sizeof(UserName);
    	GetUserName(UserName, &SizeUserName);
    
    	DWORD Res = 0;
    	PACL NewDACL = NULL, OldDACL = NULL;
    	PSID SidAdmin = NULL;
    	PSECURITY_DESCRIPTOR SD = NULL;
    	SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
    	EXPLICIT_ACCESS ea[3];
    
    	Res = GetNamedSecurityInfo((LPTSTR) Object, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, &OldDACL, NULL, NULL);
    	if (Res != ERROR_SUCCESS)
    	{
    		cout <<"GetNamedSecurityInfo() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
    		SECURITY_BUILTIN_DOMAIN_RID, 
    		DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0,
    		0, 0, &SidAdmin))
    	{
    		cout <<"AllocateAndInitializeSid() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	ZeroMemory(ea, 3 * sizeof(EXPLICIT_ACCESS));
    	ea[0].grfAccessPermissions	= AccessPerms;
    	ea[0].grfAccessMode			= AccessMode;
    	ea[0].grfInheritance		= NO_INHERITANCE; //NO_INHERITANCE;
    	ea[0].Trustee.TrusteeForm	= TRUSTEE_IS_SID;
    	ea[0].Trustee.TrusteeType	= TRUSTEE_IS_GROUP;
    	ea[0].Trustee.ptstrName		= (LPTSTR) (SidAdmin);
    
    	/*ea[1].grfAccessPermissions	= AccessPerms;
    	ea[1].grfAccessMode			= AccessMode;
    	ea[1].grfInheritance		= NO_INHERITANCE;
    	ea[1].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[1].Trustee.ptstrName		= (LPTSTR) (CURRENT_USER);*/
    
    	ea[1].grfAccessPermissions	= AccessPerms;
    	ea[1].grfAccessMode			= AccessMode;
    	ea[1].grfInheritance		= NO_INHERITANCE;
    	ea[1].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[1].Trustee.TrusteeType	= TRUSTEE_IS_USER;
    	ea[1].Trustee.ptstrName		= (LPTSTR) (StrTrustee);
    
    	ea[2].grfAccessPermissions	= AccessPerms;
    	ea[2].grfAccessMode			= AccessMode;
    	ea[2].grfInheritance		= NO_INHERITANCE;
    	ea[2].Trustee.TrusteeForm	= TRUSTEE_IS_NAME;
    	ea[2].Trustee.TrusteeType	= TRUSTEE_IS_USER;
    	ea[2].Trustee.ptstrName		= (LPTSTR) (UserName);
    
    	Res = SetEntriesInAcl(3, ea, OldDACL, &NewDACL);
    	if (Res != ERROR_SUCCESS)
    	{
    		cout <<"SetEntriesInAcl() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	Res = SetNamedSecurityInfo((LPTSTR) Object, ObjectType, DACL_SECURITY_INFORMATION, SidAdmin, NULL, NewDACL, NULL);
    	if (Res != ERROR_SUCCESS)
    	{
    		cout <<"SetNamedSecurityInfo() failed: " <<GetLastError() <<endl;
    		return FALSE;
    	}
    
    	LocalFree(SD);
    	LocalFree(NewDACL);
    	LocalFree(OldDACL);
    	FreeSid(SidAdmin);
    
    	return TRUE;
    }
    

    Trotzdem habe ich das selbe Problem...



  • Du darfst die übergeordneten Objekte eben nicht vererben!



  • Sorry, aber ich kapiers nicht. Zeig einfach mal genauer wo ich den Fehler mache.



  • Also, man kann ja die bisherige Vererbung garnicht aufheben:

    Martin Richter schrieb:

    Du kannst so die Vererbung nicht aufheben. Du musst dazu die Rechte "kopieren". So macht es der Explorer auch.

    Also bisherige DACL holen, evtl. Änderungen machen und neu setzen.

    (aus http://www.c-plusplus.net/forum/p2172437)

    Genau das mache ich doch, hier bestätigt mich auch dieser MSDN Artikel: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379283(v=vs.85).aspx .


Log in to reply