Effekt beim Speichern einer Datei ohne Administrator-Rechte

  • C#

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Effekt beim Speichern einer Datei ohne Administrator-Rechte

    Moin Leute.
    Zur Konfiguration eines Geräts nutze ich ein spezielles Programm, normalerweise arbeitet das nicht mit Administrator-Rechten und alles funktioniert prächtig.
    Aus irgend einem Grund startete ich dieses Programm mit Administrator-Rechten und speicherte die Konfiguration.
    Das Geräteprogramm, das nicht über Administrator-Rechte verfügt, konnte danach nicht mehr auf die Konfigurationsdatei zugreifen, es kam eine UnauthorizedAccessException.
    Ich sah mir die Eigenschaften der Datei im Explorer an und folgendes kam heraus:
    linls ist die Sicherheitskopie der ursprünglichen Datei, rechts ist die neu geschriebene Datei:
    vorher: nachher:

    Beim Schreiben hat das System den User (24DUK\User) aus den Benutzernamen entfernt.
    Hat jemand von Euch eine Idee, wie dieses Problem zu umgehen ist?
    Ansonsten muss ich bei Start mit Admin-Rechten das Schreiben verhindern oder zumindest warnen.
    Danke.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @nafets Danke, die Idee ist gut, aber mein Problem löst sie leider nicht.
    Herangehensweise:
    Ich starte das Testprogramm mit Administrator-Rechten und wechsle die Identität.
    Wenn ich mich als WindowsIdentity.GetAnonymous() einlogge, hat diese Identität immer noch Administrator-Rechte.
    ====
    Momentan überwache ich die Administrator-Rechte beim Schreiben und warne den User entsprechend.
    ========

    Es geht doch.
    Ich habe einen weiteren Standard-User Namens "Test" angelegt.
    Logge ich mich als dieser ein, hat dessen Identität keine Administrator-Rechte.
    Nun muss ich noch testen, ob ich danach als "ich" Zugriff auf seine geschriebene Datei habe.

    Allerdings ist ein weiterer User weder eine Lösung noch ein Arbeitsdrumherum.
    Die Verwendung eines anderen Users scheidet auch aus, da dessen Login-Daten benötigt werden, und das ist ein NoGo.

    Bleibt nur die Überwachung der Administrator-Rechte beim Schreiben der Datei.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    Ich will Euch natürlich meinen Code nicht vorenthalten:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Runtime.InteropServices;
    3. using System.Security.Permissions;
    4. using System.Security.Principal;
    5. namespace TestImpersonate
    6. {
    7. internal class ImpersonationDemo
    8. {
    9. #region API Code
    10. private const int LOGON32_PROVIDER_DEFAULT = 0;
    11. /// <summary>
    12. /// This parameter causes LogonUser to create a primary token.
    13. /// </summary>
    14. private const int LOGON32_LOGON_INTERACTIVE = 2;
    15. [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    16. public static extern bool LogonUser(string userName, string domain, string password, int logonType, int logonProvider, out SafeTokenHandle token);
    17. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    18. public extern static bool CloseHandle(IntPtr handle);
    19. #endregion API Code
    20. // Test harness.
    21. // If you incorporate this code into a DLL, be sure to demand FullTrust.
    22. [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    23. public static bool DoIt(string userName, string domainName, string password)
    24. {
    25. try
    26. {
    27. SafeTokenHandle safeTokenHandle;
    28. // Call LogonUser to obtain a handle to an access token.
    29. bool retVal = ImpersonationDemo.LogonUser(userName, domainName, password, ImpersonationDemo.LOGON32_LOGON_INTERACTIVE, ImpersonationDemo.LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);
    30. Console.WriteLine("LogonUser called.");
    31. if (!retVal)
    32. {
    33. int ret = Marshal.GetLastWin32Error();
    34. Console.WriteLine("LogonUser failed with error code : {0}", ret);
    35. //throw new System.ComponentModel.Win32Exception(ret);
    36. return false;
    37. }
    38. using (safeTokenHandle)
    39. {
    40. Console.WriteLine("Did LogonUser Succeed? " + (retVal ? "Yes" : "No"));
    41. Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);
    42. // Check the identity.
    43. Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name);
    44. // Use the token handle returned by LogonUser.
    45. IntPtr token = safeTokenHandle.DangerousGetHandle();
    46. using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(token))
    47. {
    48. // Check the identity.
    49. Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
    50. // TODO: Hier erfolgt die Arbeit im fremden Kontext
    51. ImpersonationDemo.DoOtherWork();
    52. }
    53. // Releasing the context object stops the impersonation
    54. // Check the identity.
    55. Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
    56. return true;
    57. }
    58. }
    59. catch (Exception ex)
    60. {
    61. Console.WriteLine("Exception occurred. " + ex.Message);
    62. return false;
    63. }
    64. }
    65. internal static void DoIt()
    66. {
    67. // Warnung CS0162: Unerreichbarer Code wurde entdeckt.
    68. #pragma warning disable 162
    69. IntPtr token;
    70. if (true)
    71. {
    72. token = WindowsIdentity.GetCurrent().Token;
    73. }
    74. else
    75. {
    76. token = WindowsIdentity.GetAnonymous().Token;
    77. }
    78. #pragma warning restore 162
    79. // Check the identity.
    80. Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name);
    81. using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(token))
    82. {
    83. // Check the identity.
    84. Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
    85. ImpersonationDemo.DoOtherWork();
    86. }
    87. // Releasing the context object stops the impersonation
    88. // Check the identity.
    89. Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
    90. }
    91. private static void DoOtherWork()
    92. {
    93. // TODO: Hier erfolgt die Arbeit im fremden Kontext
    94. if (ImpersonationDemo.CheckAdministrator())
    95. {
    96. Console.WriteLine("Administrator");
    97. }
    98. else
    99. {
    100. Console.WriteLine("kein Administrator");
    101. }
    102. }
    103. /// <summary>
    104. /// Abfrage, ob this Programm mit Administratorrechten läuft
    105. /// </summary>
    106. /// <returns>Administrator</returns>
    107. internal static bool CheckAdministrator()
    108. {
    109. WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
    110. return principal.IsInRole(WindowsBuiltInRole.Administrator);
    111. }
    112. }
    113. }
    Aufruf mit

    C#-Quellcode

    1. DoIt(userName, domainName, password);
    2. // bzw.
    3. DoIt();
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wenn du eh schon Administrator Rechte hast, könntest du natürlich auch direkt die Berechtigungen der Datei nach dem Schreiben einfach anpassen:

    C#-Quellcode

    1. FileInfo fi = new FileInfo("yourFile");
    2. FileSecurity fiSecurity = fi.GetAccessControl();
    3. fiSecurity.AddAccessRule(new FileSystemAccessRule(newSecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, AccressControlType.Allow));
    4. fi.SetAccessControl(fiSecurity);

    Anstatt hier die SID für "Jeder" zu benutzen, müsstest du natürlich die SID des Users verwenden.
    Nachtrag 2:
    Gas ganze ist ja noch viel unübersichtlicher.
    Das ganze passiert nur, wenn ich die Daten in das Verzeichnis C:\ProgramData\... speichere.
    In C:\Temp\... gibt es da keine Probleme.
    Also:
    In ein "öffentliches" Verzeichnis speichern und dann nach C:\ProgramData\... kopieren.
    Mal sehen.
    ====
    Und die UnauthorizedAccessException gedenke ich zu umgehen, indem ich die Datei über einem ReadOnly-Stream einlese, Notpad und Notpad++ können das ja auch.
    ========

    @EaranMaleasi Ich seh es mir mal an.
    Hat wunderbar funktioniert, ich pack das ganze mal zu den Tipps und Tricks, Link folgt nach Freigabe.
    Hier ist der Link:
    Probleme beim Speichern von Dateien ohne Administrator-Rechte


    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „RodFromGermany“ ()