Autor Beitrag
MCPC10
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31

Win 10, Win Server 2016
C# (VS 2015, VS2017), Assembler (Atmel Studio 7.0)
BeitragVerfasst: Mo 06.08.18 18:35 
Guten Tag liebes Forum,
Mal wieder :D habe ich eine Frage an euch.
Nämlich setze ich per Code eine Permission in der Registry, jedoch muss dieser wieder entfernt werden, wenn ich (in dem Fall) denn Benutzer wechsle oder auf das LocalSystem wechsele.
Beim wechsle des Benutzer geht das auch (also die alte Permission geht weg und der neue Benutzer kommt rein), jedoch wenn ich zum LocalSystem wechsle bleibt der User unverändert in der Permission stehen (was nicht sein darf).

NB: Da es sich um eine Open Source "FireDaemon" alternative handelt, könnt ihr (wenn ihr wollt) auch den Source Code direkt ansehen: github.com/TWC-Software/DaemonMaster


Codeabschnitt (zu finden in DaemonMasterCore -> RegistryManagement Zeile: 87+):
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
//Create and give the user the permission to write to this key (needed for save the PID of the process)

                //TODO: Need registry permission to write PID (logs folder the same)
                using (RegistryKey processInfo = key.CreateSubKey("Process"))
                {
                    //Create a new RegistrySecurity object
                    RegistrySecurity rs = new RegistrySecurity();

                    //Add an access rule for the user (only when it is not LocalSystem)
                    if (!serviceStartInfo.UseLocalSystem)
                    {
                        //TODO: not the best method to do that
                        string username = Environment.MachineName + "\\" + DaemonMasterUtils.GetLoginFromUsername(serviceStartInfo.Username);
                        rs.AddAccessRule(new RegistryAccessRule(username, RegistryRights.QueryValues | RegistryRights.SetValue, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow));
                    }

                    processInfo.SetAccessControl(rs);
                    processInfo.Close();
                }


Ich danke für jede hilfe :D :D

Mit freundlichen Grüssen (Belgische Tastaturen haben kein scharfes s :( und Alt + 225 geht nicht :autsch: )
Mike Cr.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4437
Erhaltene Danke: 910


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 06.08.18 19:11 
Den Code sehe ich nicht in Github (weder in Develop noch in Master). Noch nicht gepushed?
MCPC10 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31

Win 10, Win Server 2016
C# (VS 2015, VS2017), Assembler (Atmel Studio 7.0)
BeitragVerfasst: Mo 06.08.18 19:18 
Hallo,
Misst hab ich vergessen, sorry :o
Habs jetzt gemacht :D

MfG
Mike Cremer
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4076
Erhaltene Danke: 845

Win7
C++, C# (VS 2015/17)
BeitragVerfasst: Di 07.08.18 08:12 
Hallo,

mittels Reflector habe ich mir mal den Source-Code von RegistryKey.SetAccessControl angeschaut:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
[SecuritySafeCritical]
public void SetAccessControl(RegistrySecurity registrySecurity)
{
    this.EnsureWriteable();
    if (registrySecurity == null)
    {
        throw new ArgumentNullException("registrySecurity");
    }
    registrySecurity.Persist(this.hkey, this.keyName);
}

[SecurityCritical, SecurityPermission(SecurityAction.Assert, UnmanagedCode=true)]
internal void Persist(SafeRegistryHandle hKey, string keyName)
{
    new RegistryPermission(RegistryPermissionAccess.NoAccess, AccessControlActions.Change, keyName).Demand();
    base.WriteLock();
    try
    {
        AccessControlSections accessControlSectionsFromChanges = this.GetAccessControlSectionsFromChanges();
        if (accessControlSectionsFromChanges != AccessControlSections.None) // <- diese Abfrage meine ich (s.u.)!
        {
            bool flag2;
            bool flag3;
            base.Persist(hKey, accessControlSectionsFromChanges);
            base.AccessRulesModified = flag3 = false;
            base.AuditRulesModified = flag2 = flag3;
            base.OwnerModified = base.GroupModified = flag2;
        }
    }
    finally
    {
        base.WriteUnlock();
    }
}

Wenn ich das richtig interpretiere, werden nur bei Änderungen am RegistrySecurity-Objekt diese auch ausgeführt - da du aber ein initiales RegistrySecurity-Objekt verwendest (ohne Aufruf einer zugehörigen Methode) ist der Methodenaufruf ohne Wirkung.
Du müßtest also mittels RegistryKey.GetAccessControl den aktuellen Status auslesen und dann wieder mittels RegistrySecurity.RemoveAccessRule löschen.

Evtl. hilft auch:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
string username = Environment.MachineName + "\\" + DaemonMasterUtils.GetLoginFromUsername(serviceStartInfo.Username);
var accessRule = new RegistryAccessRule(username, RegistryRights.QueryValues | RegistryRights.SetValue, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow);
rs.AddAccessRule(accessRule);

if (serviceStartInfo.UseLocalSystem)
    rs.RemoveAccessRule(accessRule);

(also immer hinzufügen und nur im Fall LocalSystem wieder entfernen - und evtl. jeweils processInfo.SetAccessControl(rs) dafür aufrufen)

Für diesen Beitrag haben gedankt: MCPC10
MCPC10 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31

Win 10, Win Server 2016
C# (VS 2015, VS2017), Assembler (Atmel Studio 7.0)
BeitragVerfasst: Di 07.08.18 09:14 
Hallo und danke für deine Antwort,
Das Problem bei der Sache ist das sobald auf LocalSystem gewechselt wird der Username gelöscht wird und mir der dann nich mehr zur Verfügung steht (geschieht bei Aufrufer, notfalls änderbar).

NB: Ich weiss nicht ob es dir hilft aber ich benutzte für den Quellcode von .NET immer referencesource.microsoft.com/

MfG
Mike Cremer
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4437
Erhaltene Danke: 910


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 07.08.18 18:17 
Zitat:
NB: Ich weiss nicht ob es dir hilft aber ich benutzte für den Quellcode von .NET immer referencesource.microsoft.com/


Problematisch. Damit habe ich mich schon oft genug reingelegt da Referencesource nur die aktuellste Version durchsucht. Alte Versionen musst du explizit runterladen und lokal durchsuchen. Gerade im Moment unterscheiden sich auch die Minor Versions (4.7 bis 4.7.2) an bestimmten Stellen schon erheblich. Core sei dank.
Dein Projekt scheinst du gegen 4.6.1 zu bauen. Denn Code denn du bei Referencesource siehst (4.7.2) ist also potentiell nicht das was du benutzt.

Also zumindest Vorsicht wenn man Referencesource benutzt und am besten zusätzlich immer eine Disassembler zur Hand haben.

Für diesen Beitrag haben gedankt: MCPC10
MCPC10 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31

Win 10, Win Server 2016
C# (VS 2015, VS2017), Assembler (Atmel Studio 7.0)
BeitragVerfasst: Di 07.08.18 18:24 
Zitat:
Also zumindest Vorsicht wenn man Referencesource benutzt und am besten zusätzlich immer eine Disassembler zur Hand haben.


Stimmt, hab ich ja ganz übersehen, hab aber Gott sei Dank dotPeek und dnSpy für sowas zur Hand :D

MfG
Mike Cremer
MCPC10 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31

Win 10, Win Server 2016
C# (VS 2015, VS2017), Assembler (Atmel Studio 7.0)
BeitragVerfasst: Di 07.08.18 20:14 
Sooo nach langem probieren (und etwas Hilfe :lol:) konnte ich eine Lösung finden die bis jetzt funktioniert wie gewollt.
Dennoch muss ich sagen das ich niemals darauf gekommen wäre mittels SecurityIdentifier den Namen des LocalSystem zu bekommen.
Quelle des Funkensprungs: stackoverflow.com/qu...m-administrators-and

Erklärung:
Es werden dem LocalSystem Rechte gegeben (die es sowieso hat, ist halt das System) die aber eine Änderung sind und so das erfolgreiche überschreiben ermöglichen.
Denn nur bei einer Änderung, wie user profile iconTh69 herausgefunden hat, werden die Permission überschrieben.

Ich hoffe ihr könnt das gleiche Ergebnis reproduzieren (nicht das ich hier noch Müll verzähle).


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
 //Create an give the user the permission to write to this key (needed for save the PID of the process)
                bool isLocalSystem = serviceStartInfo.UseLocalSystem || String.IsNullOrWhiteSpace(serviceStartInfo.Username) || serviceStartInfo.Username == "LocalSystem";


                //TODO: Need registry permission to write PID (logs folder the same)
                using (RegistryKey processInfo = key.CreateSubKey("Process"))
                {
                    //Create a new RegistrySecurity object
                    RegistrySecurity rs = new RegistrySecurity();

                    ////Add access rule for user (only when it is not LocalSystem)
                    if (isLocalSystem)
                    {
                        string localSystem = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Translate(typeof(NTAccount)).Value;
                        rs.AddAccessRule(new RegistryAccessRule(localSystem, RegistryRights.QueryValues | RegistryRights.SetValue, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow));
                    }
                    else
                    {
                        string username = Environment.MachineName + "\\" + DaemonMasterUtils.GetLoginFromUsername(serviceStartInfo.Username);
                        rs.AddAccessRule(new RegistryAccessRule(username, RegistryRights.QueryValues | RegistryRights.SetValue, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow));
                    }

                    processInfo.SetAccessControl(rs);
                    processInfo.Close();
                }



Ich danke wie immer allen die mich unterschützt haben/werden.

MfG
Mike Cremer