Delphi - Felhasználói jogosultságok lekérdezése

forráskód letöltése
Amikor több felhasználó használ közösen egy számítógépet, nem biztos, hogy mindegyiküknek ugyanolyan jogosultsága van a számítógép erőforrásainak elérésére. Attól függően, hogy egy felhasználó milyen fiókba tartozik, más-más jogokat kap. Természetesen az, aki a rendszergazdai fiókban kapott helyet, korlátlanul hozzáférhet az egyes eszközökhöz, fájlokhoz, míg azok, akik a korlátozott fiókba tartoznak, csak bizonyos megkötésekkel tehetik meg ugyanezt, már ha egyáltalán van joguk a hozzáféréshez. A most bemutatásra kerülő programmal azt listázhatjuk ki, hogy milyen felhasználói jogaink is vannak az adott számítógépen.
Első lépésben megnyitjuk a saját folyamatunk Token-jét az OpenTokenInformation függvénnyel, melynek felépítése a következő:
OpenProcessToken
BOOL OpenProcessToken(
HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle
);
Paraméterek
HANDLE ProcessHandle
Annak a folyamatnak a handle-je, melyhez hozzá szeretnénk férni.
DWORD DesiredAccess
Egy hozzáférési maszkot specifikál, mely azt adja meg, hogy mihez is szeretnénk hozzáférni a megnyitandó Token-ből.
PHANDLE TokenHandle
Egy handle-re utaló mutatót definiál, mellyel az újonnan megnyitott Token-re hivatkozhatunk a függvény lefutása után.
)
Visszatérési érték
A függvény sikeres meghívása után egy nem nulla értéket kapunk eredményként, ellenkező esetben nullát.
Megjegyzés
A megnyitott Token handle-jét a munka befejeztével a TokenHandle paraméterben megadott pointer segítségével a CloseHandle függvény meghívásával zárhatjuk be.
Esetünkben ez a következőkképpen néz ki:
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
    ShowMessage('OpenProcessToken error');
Első paraméterben a GetCurrentProcess függvény által szolgáltatott értéket adjuk, ezzel biztosítva, hogy a saját folyamatunkhoz férünk hozzá. Második paraméterként megadunk egy maszkot, mely jelen esetben azt közli a függvénnyel, hogy a privilégiumokat szeretnénk lekérdezni. Végül definiálunk egy hToken nevű változót, amelybe kapott mutatóval a későbbiekben tudunk hivatkozni a megnyitott Token-re. Amennyiben nem sikerült a függvényhívás, hibaüzenetet íratunk ki.
Ezután a GetTokenInformation függvény segítségével lekérjük a Token információkat. A felépítése a következő:
GetTokenInformation
BOOL GetTokenInformation(
HANDLE TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
LPVOID TokenInformation,
DWORD TokenInformationLength,
PDWORD ReturnLength
);
Paraméterek
HANDLE TokenHandle
Annak a Token-nek a handle-je, melyből az információkat szeretnénk kinyerni.
TOKEN_INFORMATION_CLASS TokenInformationClass
Egy TokenInformationClass osztályban tárolt érték, mely azt azonosítja, hogy milyen típusú Token információra van szükségünk.
LPVOID TokenInformation
Egy buffer-re mutató pointer, melybe a TokenInformationClass paraméter által specifikált információk kerülnek eltárolásra.
DWORD TokenInformationLength
Az ebben a paraméterben megadott szám lesz az a felső határérték amekkora helyet biztosítottunk az információk tárolására.
PDWORD ReturnLength
Egy mutató típusú változó, melyben a TokenInformation paraméterben eltárolt buffer méretét kapjuk meg byte-okban.
)
Visszatérési érték
A függvény sikeres meghívása után egy nem nulla értéket kapunk eredményként, ellenkező esetben nullával tér vissza.
Lássuk a példaprogramban, hogyan használtuk ezt a függvényt:
GetMem(pTokenInfo, TokenSize);
if not GetTokenInformation(hToken, TokenPrivileges, pTokenInfo, TokenSize, ReturnLen) then
    ShowMessage('GetTokenInformation error');
Először is lefoglalunk a memóriában elegendő helyet az információk tárolására. Ezután a függvény első paraméterének az OpenProcessToken paraméter által definiált hToken változót adjuk át, mely a megnyitott Token-re utal. A második paraméterben közöljük, hogy milyen információkra lesz szükségünk. Esetünkben a privilégiumokra. E kapott információk a függvény harmadik paraméterében megadott buffer-ben kerülnek eltárolásra. A negyedik paraméterben megadott szám lesz az az érték, amekkora helyet biztosítottunk az információk tárolására. Amennyiben a függvényhívás sikertelen, hibaüzenetet íratunk ki.
Ezután egy ciklus segítségével kiolvassuk egyenként a privilégiumok nevét, illetve az ahhoz tartozó rövid leírást.
  GetMem(PrivName, 255);
  GetMem(DisplayName, 255);
  for i:=0 to pTokenInfo.PrivilegeCount-1 do
  begin
    DisplSize:=255;
    NameSize:=255;
    LookupPrivilegeName(nil, pTokenInfo.Privileges[i].Luid, PrivName, Namesize);
    LookupPrivilegeDisplayName(nil, PrivName, DisplayName, DisplSize, LangId);
    ListBox1.Items.Add(PrivName);
    ListBox2.Items.Add(DisplayName);
  end;
Észrevehetjük, hogy felhasználtunk két újabb függvényt a cikluson belül. A LookupPrivilegeName függvénnyel a privilégiumok nevét tudjuk kiolvasni. Felépítése a következő:
LookupPrivilegeName
BOOL LookupPrivilegeName(
LPCTSTR lpSystemName,
PLUID lpLuid,
LPTSTR lpName,
LPDWORD cchName
);
Paraméterek
LPCTSTR lpSystemName
Annak a rendszernek a neve, melyben a jogosultságokat le szeretnénk kérdezni. Amennyiben nulla értéket adunk meg, a helyi számítógépen fogja keresni a privilégiumokat.
PLUID lpLuid
Mutató, mely az adott rendszeren belül a jogosultságok egy egyedi azonosítójára (Locally unique identifier - Luid) utal.
LPTSTR lpName
Egy buffer-re mutató pointer, melyben a függvény által eredményül visszaadott jogosultságok nevei lesznek eltárolva.
LPDWORD cchName
Az lpName paraméterben létrejött buffer méretét jelzi.
)
Visszatérési érték
A függvény sikeres meghívása után egy nem nulla értéket kapunk eredményként, ellenkező esetben nullával tér vissza.
A LookupPrivilegeDisplayName függvénnyel az adott privilégium leírását kaphatjuk meg:
LookupPrivilegeDisplayName
BOOL LookupPrivilegeDisplayName(
LPCTSTR lpSystemName,
LPCTSTR lpName,
LPTSTR lpDisplayName,
LPDWORD cchDisplayName,
LPDWORD lpLanguageId
);
Paraméterek
LPCTSTR lpSystemName
Annak a rendszernek a neve, melyben a jogosultságokat le szeretnénk kérdezni. Amennyiben nulla értéket adunk meg, a helyi számítógépen fogja keresni a privilégiumokat.
LPCTSTR lpName
Annak a privilégiumnak a neve, melynek a leírását le szeretnénk kérdezni.
LPTSTR lpDisplayName
Egy buffer-re mutató pointer, melyben a jogosultság rövid leírása kerül eltárolásra.
LPDWORD cchDisplayName
Az lpDisplayName paraméterben létrejött buffer méretét tárolja el.
LPDWORD lpLanguageId
Az operációs rendszer nyelvének azonosítóját tárolja.
)
Visszatérési érték
A függvény sikeres meghívása után egy nem nulla értéket kapunk eredményként, ellenkező esetben nullával tér vissza.
A munka végeztével felszabadítjuk a lefoglalt memóriaterületeket.
  FreeMem(PrivName);
  FreeMem(DisplayName);
  FreeMem(pTokenInfo);