Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CreateSymbolicLink als normaler Benutzer ausführen (https://www.delphipraxis.net/96308-createsymboliclink-als-normaler-benutzer-ausfuehren.html)

ringli 22. Jul 2007 01:34


CreateSymbolicLink als normaler Benutzer ausführen
 
Ich habe zu Testzwecken ein wenig mit der API-Funktion CreateSymbolicLink - die es ja seit Vista gibt - herumexperimentiert. Herausgekommen ist dabei der folgende Code der grundsätzlich auch funktioniert, d.h. es wird ein symbolischer Link erstellt.

Das Problem sind mal wieder die Benutzerrechte, das heisst wenn ich das Testprogramm als Administrator laufen lasse wird der symbolische Link erfolgreich erstellt. Starte ich das Programm jedoch als normaler Benutzer erhalte ich die Fehlermeldung

Code:
#1314 : Dem Client fehlt ein erforderliches Recht
Hier mal der Code meines Testprogrammes:
Delphi-Quellcode:
const
  KERNEL32_DLL                : String = 'KERNEL32.DLL';
  SYMBOLIC_LINK_FLAG_FILE     : DWORD = $0; // Datei als Link erstellen
  SYMBOLIC_LINK_FLAG_DIRECTORY : DWORD = $1; // Verzeichnis als Link erstellen

// CreateSymbolicLink dynamisch importieren
type
  TCreateSymbolicLink = function (lpSymlinkFileName : LPCWSTR;
                                  lpTargetFileName : LPCWSTR;
                                  dwFlags          : DWORD) : Boolean; stdcall;


function CreateSymbolicLink(lpSymlinkFileName : LPCWSTR;
                            lpTargetFileName : LPCWSTR;
                            dwFlags          : DWORD) : Boolean;
var
  DLL_Handle            : THandle;            // für dynamischen Funktionsimport!
  DLL_CreateSymbolicLink : TCreateSymbolicLink; // für dynamischen Funktionsimport!
begin
  Result := False;
  // Handle für die KERNEL32.DLL erhalten
  DLL_Handle := LoadLibrary(PChar(KERNEL32_DLL));
  // Wenn Handle vorhanden, Adressen der Funktionen ermitteln
  if DLL_Handle <> 0 then
    begin
      // Adresse in der DLL ermitteln
      @DLL_CreateSymbolicLink := GetProcAddress(DLL_Handle, 'CreateSymbolicLinkW');
      // Wurde CreateSymbolicLink in der DLL gefunden?
      if @DLL_CreateSymbolicLink <> nil then
        begin
          // Symbolischen Link erstellen
          if DLL_CreateSymbolicLink(lpSymlinkFileName,
                                    lpTargetFileName,
                                    dwFlags) then Result := True;
        end
      else
        begin
          // Wenn die gewünschte Funktion in der KERNEL32.DLL nicht
          // gefunden wurde soll eine Fehlermeldung angezeigt werden
          ShowMessage('Es ist ein Fehler aufgetreten.' + #13#10 +
                      'Eine benötigte Funktion konnte in der Datei "' + KERNEL32_DLL + '" ' + #13#10 +
                      'nicht gefunden werden.');
          Result := False;
        end;
      FreeLibrary(DLL_Handle);
    end
  else
    begin
      // Wenn die gewünschte Datei KERNEL32.DLL nicht gefunden
      // wurde soll eine Fehlermeldung angezeigt werden
      ShowMessage('Es ist ein Fehler aufgetreten.' + #13#10 +
                  'Die benötigte Datei "' + KERNEL32_DLL + '" konnte nicht geladen werden.');
      Result := False;
    end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  SelectedDir : WideString;
  NameOfSymLink : WideString;
begin
  if GetLastError <> 0 then
    showmessage('#' + IntToStr(GetLastError) + ' : ' + SysErrorMessage(GetLastError) + '.');

  NameOfSymLink := 'D:\Test-SymLink';
  if FileOpenDialog1.Execute then
    begin
      SelectedDir := WideString(FileOpenDialog1.FileName);
      if CreateSymbolicLink(PWideChar(NameOfSymLink),
                            PWideChar(SelectedDir),
                            SYMBOLIC_LINK_FLAG_DIRECTORY) then
        showmessage('Symbolic Link erstellt');
    end;

  if GetLastError <> 0 then
    showmessage('#' + IntToStr(GetLastError) + ' : ' + SysErrorMessage(GetLastError) + '.');
end;
Jetzt meine Frage:
Kann man einem normalen Benutzer die Erstellung von symbolischen Links (unter Verwendung der API-Funktion CreateSymbolicLink) ermöglichen?

[EDIT]
Der FileOpenDialog1 ist übrigends via Objektinspektor so eingestellt das nur Ordner zurückgegeben werden.
[/EDIT]

Dezipaitor 22. Jul 2007 12:24

Re: CreateSymbolicLink als normaler Benutzer ausführen
 
Hmm, also die MSDN Hilfe dazu sagt nichts über ein benötigtes Privileg.

Wo wird denn der 1314 Fehler ausgegeben?

Ich sehe du testest innerhalb von Button1Click sofort auf GetLastError. Jedoch kann dort noch kein Fehler aufgetreten sein.

ringli 22. Jul 2007 12:35

Re: CreateSymbolicLink als normaler Benutzer ausführen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Dezipaitor
Hmm, also die MSDN Hilfe dazu sagt nichts über ein benötigtes Privileg.

Wo wird denn der 1314 Fehler ausgegeben?

Ich sehe du testest innerhalb von Button1Click sofort auf GetLastError. Jedoch kann dort noch kein Fehler aufgetreten sein.

Der Fehler 1314 wird ausgegeben nachdem ich versucht habe einen symbolischen Link zu erstellen. In meinem Quelltext ist das also das letzte ShowMessage in der Button1Click-Prozedur.

Die erste Abfrage von GetLastError war/ist da auch nur zu Testzwecken drinne um zu sehen ob vielleicht vorher noch ein Fehler vorhanden war.

[EDIT]
Ich hänge das Testprojekt einfach mal an, vielleicht kann dann jemand mehr damit anfangen.
[/EDIT]

Dezipaitor 22. Jul 2007 12:57

Re: CreateSymbolicLink als normaler Benutzer ausführen
 
Da ich kein Vista verwende, kann ich es nicht testen.

Aber setze doch einfach mal vor dem Aufruf
Delphi-Quellcode:
SetLastError(0);

ringli 22. Jul 2007 13:07

Re: CreateSymbolicLink als normaler Benutzer ausführen
 
Habe ich jetzt auch mal probiert, aber leider ändert das nichts am Ergebnis. :(

Ferax 21. Aug 2007 14:37

Re: CreateSymbolicLink als normaler Benutzer ausführen
 
Hallo,

ich habe dein Code unter Vista probiert und festgestellt, dass doch ein Privileg erforderlich ist: SeCreateSymbolicLinkPrivilege

Standardmäßig verfügen nur Administratoren über dieses Privileg. Willst du es normalen Benutzern ermöglichen, auch symbolische Links zu erzeugen, dann musst du in den Lokalen Sicherheitsrichtlinien unter "Sicherheitseinstellungen/Lokale Richtlinien/Zuweisen von Benutzerrechten" die Gruppe Benutzer zur Richtlinie "Erstellen symbolischer Verknüpfungen" hinzufügen.

ringli 21. Aug 2007 15:15

Re: CreateSymbolicLink als normaler Benutzer ausführen
 
Danke für deine Antwort. :)

Kann man sich das Recht nicht über das Programm holen? Ich meine so in der Art wie für das Herunterfahren von Windows. Da muss man sich auch doch auch erstmal die Rechte für diese Aktion holen.

OregonGhost 21. Aug 2007 15:24

Re: CreateSymbolicLink als normaler Benutzer ausführen
 
Man holt sich für das Herunterfahren keine Rechte, sondern nur ein entsprechendes Token. Wenn du die Rechte zum Herunterfahren nicht hast, kannst du dir das Token nicht besorgen.

Das ist mit diesem hier dasselbe. Du hast das Recht als normaler Benutzer nicht, also kannst du auch kein Token damit erstellen. Es führt also wohl kein Weg drumherum, das Recht explizit zuzuteilen.

Als Literatur für das grundlegende Verständnis werfe ich mal diesen Artikel in den Raum.

Olli 23. Aug 2007 02:40

Re: CreateSymbolicLink als normaler Benutzer ausführen
 
Zitat:

Zitat von OregonGhost
Man holt sich für das Herunterfahren keine Rechte, sondern nur ein entsprechendes Token. Wenn du die Rechte zum Herunterfahren nicht hast, kannst du dir das Token nicht besorgen.

Na du würfelst aber auch die Begriffe durcheinander ;)

Das Token ist doch sozusagen der Ausweis des Polizisten (um beim Beispiel zu bleiben). Wenn der also im Job unterwegs ist und seinen Ausweis (oder irgendwelche anderen Nachweise) dabei hat, wird man ihm eben bestimmte Privilegien zugestehen. Um das fortzuführen, du bekommst schon dein Token, wenn du es anforderst. Nur sind eben bestimmte Privilegien dort nicht vermerkt, wenn du ein normaler Benutzer bist. Daher kannst du diese Privilegien die du hast auch nicht aktivieren (aktiv nutzen) oder deaktivieren (passiv nutzen).

Übrigens sollte man an der GP bitte nicht rumfummeln. Es hat schon seine Gründe, daß bestimmte Dinge nur von Admins gemacht werden können. Ansonsten kann man ja auch gleich das TCB-Privileg allen Nutzern geben.

MuTzE.Y85 26. Dez 2013 00:39

AW: CreateSymbolicLink als normaler Benutzer ausführen
 
Ich glaube ab Delphi XE oder so gibt es ja eine Funktion namens FileCreateSymLink, die das Gleiche macht. Weiß jemand, ob die Links da auf die gleiche Weise erstellt werden wie hier?

Bzw. gibt es eine Möglichkeit den Code aus der SysUtils von den XE Versionen für Delphi 2010 zu benutzen, und wenn legal?


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:13 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz