[WinAPI/ Delphi] Bestandsmachtigingen achterhalen

Pagina: 1
Acties:

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 19-05 12:05

Tomatoman

Fulltime prutser

Topicstarter
In Windows NT4/2000/XP kunnen aan bestanden specifieke bestandsmachtigingen aan gebruikers worden toegekend, zoals in onderstaand plaatje:

Om de machtigingen van de huidige gebruiker te achterhalen probeer ik GetEffectiveRightsFromAcl te gebruiken. Deze functie wordt veelvuldig op internet genoemd, maar iedereen verwijst naar een paar onbruikbare voorbeelden zonder zelf wat te laten zien hoe je die functie moet gebruiken. Dit is mijn aanzet tot nu toe:

Afbeeldingslocatie: http://img61.exs.cx/img61/2489/u4amachtigingen.png
Delphi:
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
35
36
37
38
39
40
41
42
function GetFileAccessRights(const FileName: string): ACCESS_MASK;
var
  pSD: PSECURITY_DESCRIPTOR;
  LengthNeeded, LengthAlloc, Err: Cardinal;
  DACLPresent, DACLDefaulted: LongBool;
  DACL: PACL;
  ATrustee: TRUSTEE;
  AccessRights: ACCESS_MASK;
begin
  { Retrieve number of bytes necessary to store the security descriptor. This
    should cause an ERROR_INSUFFICIENT_BUFFER error. }
  pSD := nil;
  GetFileSecurity(PChar(FileName), DACL_SECURITY_INFORMATION, pSD, 0, LengthNeeded);
  Err := GetLastError;
  if Err <> ERROR_INSUFFICIENT_BUFFER then
  begin
    SetLastError(Err); // Restore the now removed error
    RaiseLastOSError;
  end;

  { Allocate memory for security descriptor }
  GetMem(pSD, LengthNeeded);
  try
    { Retrieve security descriptor }
    LengthAlloc := 0;
    if not GetFileSecurity(PChar(FileName), DACL_SECURITY_INFORMATION, pSD,
      LengthNeeded, LengthAlloc) then
      RaiseLastOSError;

    { Get discretionary access control list (DACL) }
    if not GetSecurityDescriptorDacl(pSD, DACLPresent, DACL, DACLDefaulted) then
      RaiseLastOSError;

    BuildTrusteeWithName(@ATrustee, 'Administrator'); // Hard gecodeerd voor deze test

    if GetEffectiveRightsFromAcl(DACL^, ATrustee, AccessRights) <> ERROR_SUCCESS then
      RaiseLastOSError;
    Result := AccessRights;
  finally
    FreeMem(pSD);
  end;
end;

Tot en met regel 29 32 gaat alles goed. Ik heb gecontroleerd of de verkregen security descriptor (pSD) en DACL geldig zijn en dat blijkt inderdaad het geval. Op regel 36 gaat het echter mis: ik krijg een access violation in module NTMARTA.DLL, terwijl GetEffectiveRightsFromAcl door ADVAPI32.DLL wordt geëxporteerd. Vaag.

Hoe krijg ik mijn code werkend?

Een goede grap mag vrienden kosten.


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 19-05 00:34

alienfruit

the alien you never expected

Ben je lid van TDM? Want daar stond een hele tijd terug een artikel hierover in.

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 19-05 12:05

Tomatoman

Fulltime prutser

Topicstarter
Nee, helaas niet. Ik heb wel dit vrij toegankelijke artikel op TDM doorgenomen voor ik aan de slag ging, maar daar staat helaas niets over GetEffectiveRightsFromAcl of iets in die richting in.

Een goede grap mag vrienden kosten.


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 19-05 00:34

alienfruit

the alien you never expected

Ooh, ik dacht eerlijk gezegt dat GetEffectiveRightsFromAcl ook gebruikte, dan kan ik je helaas niet helpen... Maar misschien moet je Marcel maar gewoon e-mail-en, die weet het vast wel :) Ik neem aan dat je al wel op MSDN hebt gekeken etc. ?

Misschien heb je hier wat aan, zit vast niet het antwoord in maar toch:
http://support.microsoft.com/?scid=kb;en-us;102102 of
http://www.torry.net/quic...+Security+v.1.0&Title=Yes

[ Voor 31% gewijzigd door alienfruit op 05-12-2004 14:23 ]


Verwijderd

ik programmeer normaal niet in delphi.... maar de 3e parameter,

DACL: PACL;

werkt de functie wel als je hier gewoon een 'long' voor gebruikt ?

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 19-05 12:05

Tomatoman

Fulltime prutser

Topicstarter
Verwijderd schreef op zondag 05 december 2004 @ 23:06:
ik programmeer normaal niet in delphi.... maar de 3e parameter,

DACL: PACL;

werkt de functie wel als je hier gewoon een 'long' voor gebruikt ?
De functie op regel 31 werkt probleemloos, de pointer naar een ACL (die in mijn code DACL) heet, wordt correct geretourneerd. Met de oorspronkelijke regelaanduiding in mijn post heb ik je misschien het bos in gestuurd (oeps, mijn ondertitel klopt nog steeds :o).
alienfruit schreef op zondag 05 december 2004 @ 14:15:
Ooh, ik dacht eerlijk gezegt dat GetEffectiveRightsFromAcl ook gebruikte, dan kan ik je helaas niet helpen... Maar misschien moet je Marcel maar gewoon e-mail-en, die weet het vast wel :) Ik neem aan dat je al wel op MSDN hebt gekeken etc. ?

Misschien heb je hier wat aan, zit vast niet het antwoord in maar toch:
http://support.microsoft.com/?scid=kb;en-us;102102 of
http://www.torry.net/quic...+Security+v.1.0&Title=Yes
Die tweede link ziet er interessant uit. Ik heb net de broncode afgedrukt (1500+ regels) en ga die nu maar eens doornemen.

Een goede grap mag vrienden kosten.


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 19-05 00:34

alienfruit

the alien you never expected

En heb je al success, tomatoman?

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 19-05 12:05

Tomatoman

Fulltime prutser

Topicstarter
Het ziet ernaar uit dat ik de verklaring voor het probleem gevonden heb: er zit een bug in Windows. Volgens dit artikel op MSDN kan de bug een access violation veroorzaken in... Ntmarta.dll Afbeeldingslocatie: http://www.area61.nl/smiley/boringcheer.gif

Microsoft biedt op aanvraag een fix voor deze bug. Hij is in Windows sowieso gepatcht vanaf Windows 2000 SP4; het MSDN-artikel is van november 2003. Aangezien ik het probleem ervaar met Windows XP Professional SP1 en SP1 dateert van vóór november 2003, verwacht ik dat de bug pas verholpen wordt door WinXP SP2. Aangezien dat op mijn computer niet draait, kan ik het echter niet testen.

Dat impliceert meteen dat GetEffectiveRightsFromAcl op zeer veel computers een probleem zal veroorzaken en daarmee eigenlijk geen optie is om te gebruiken. Ik ga die functie lekker overboord zetten en de afzonderlijke access control entries in de DACL evalueren. Het zal wel een hoop code opleveren, maar het is niet anders :/

Een goede grap mag vrienden kosten.


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 19-05 00:34

alienfruit

the alien you never expected

Aaah, vervelend voor je, maar het is eindelijk niet weggegooid tijd geweest... (naja ligt er aan 8)7) Weet je voor de volgende keer dat deze oplossing onbruikbaar is.

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 19-05 12:05

Tomatoman

Fulltime prutser

Topicstarter
Het is zover, ik heb een kant en klare oplossing, compleet met commentaar 8)

Je kunt hem hier downloaden. Aangezien de code ruim 150 regels lang is, geef ik hier alleen uitleg. Dit zijn de stappen:
[list=1]
• Controleer of de file of directory bestaat. Zo nee: raise een exception.
• Controleer of we wel op NT/2000/XP werken. Zo nee: alle rechten toekennen.
• Vraag de grootte van de security descriptor op en alloceer er een buffer voor.
• Nu de security descriptor zelf opvragen.
• Impersonate de client.
• Vraag een access token van de impersonated client.
• Nu kun je eindelijk een bitmask met de access rights opvragen met AccessCheck.
• Als het bestandssysteem geen rechten ondersteunt (FAT/FAT32), alle rechten toekennen.
• Access token opruimen.
• Impersonated client verlaten.
• Buffer voor de security descriptor opruimen.
• Bitmask met access rights omzetten naar een gemakkelijker hanteerbare set.
Het kost wat moeite, maar dan heb je ook wat: een functie die de toegangsrechten van de huidige gebruiker op een bestand of map achterhaalt.

* Tomatoman veegt het zweet van zijn voorhoofd en haalt een biertje uit de koelkast. Bedankt voor de hulp alienfruit!

Een goede grap mag vrienden kosten.

Pagina: 1