Miért NE kezdjünk tárolt eljárást sp_-sal?

Sok fejlesztő használ naming conventiont (nevezési szokást) az adatbázis objektumainak elnevezésénél. Ez kedves tőlük, mivel kiszámíthatóbbá teszik a karbantartók (beleértve saját magukat) életét. Ámde vannak kevésbé szerencsés naming conventionök, és itt nem csak az akkor jó ötletnek tűnő Systems Hungarian notationre gondolok.

Többször találkoztam az sp_ prefixszel, mint tárolt eljárás jelöléssel, ami jó ötletnek tűnik, a Microsoft is ezt favorizálja, úgyhogy biztos jó. De nem az. Az sp_ ugyanis a Microsoft sajátja, amit befoglaltak kódból: minden sp_ kezdetű tárolt eljárást a master adatbázisban keres először az SQL Server, és ha ott nem találja, akkor nézi meg az aktuális adatbázist. Benne is van a BOL-ban, hogy ne használd, mert ráfázol. És íme, a példa:

use tempdb
go
create procedure sp_password 
AS
print 'De rossz nev ez...'
GO

És próbáljuk meg futtatni a mi kis sp_password SP-nket. Ez sosem fog sikerülni, még ha két- vagy háromtagú nevet adunk meg, akkor se.

EXEC sp_password
-- fail
EXEC tempdb.dbo.sp_password
-- ez is fail
GO

Az egyetlen elfogadható kiút, ha nem a dbo schema alá rakjuk, és legalább kéttagú névvel hivatkozunk rá:

create schema test
GO
create procedure test.sp_password 
AS
print 'De rossz nev ez...'
GO
EXEC test.sp_password

Azért valljuk be, ez így gáz. Használjunk valami jobb nevezéket…

Ha esetleg valakiben felmerülne a kérdés, hogy ez miért jó dolog, akkor gondolja végig a fenti példa esetleges működésének következményeit: Gonosz Géza olyan szép trójai sp_password-öt produkálhat, hogy mindenki csak nézni fog. A security fontos dolog…

Disabled login vs locked out login

Alcím: Hogyan nem tud valaki belépni egy SQL Serverbe? A belépés egy két részből álló folyamat, mint minden rendszer esetében: autentikáció és authorizáció. Az autentikáció mondja meg, hogy kik vagyunk: felhasználónév+jelszó például. Az authorizáció pedig megmondja, hogy mi, akik azok vagyunk, akik, mit tehetünk, mire vagyunk feljogosítva.

Ebból következik, hogy a legegyszerűbb nem-belépés az, ha elbukjuk az autentikációt. De az túl egyszerű. Inkább nézzük meg, hogyan lehet elbukni az authorizációt olyan mértékben, hogy be sem jutunk.

A legegyszerűbb a letiltás:

CREATE LOGIN [SQL01\ddisable] FROM WINDOWS;
ALTER LOGIN [SQL01\ddisable] DISABLE;

Csináltunk egy SQL logint egy domain usernek, majd letiltottuk a logint. Könnyű és nyilvánvaló, pipa.

Egy kicsit régebbi történet a DENY LOGIN:

EXEC sp_denylogin 'SQL01\ddeny';

Ez létrehozza az SQL logint a domain userhez, és annak rögtön meg is tiltja, hogy belogoljon. Erről a tárolt eljárásról egyébként azt írja a BOL, hogy elavult:
This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature. Use ALTER LOGIN instead.

Oké, és hogy használjuk az ALTER LOGIN-t? Hát, lehet DISABLE-t mondani, mint az előbb. De az nem egészen ugyanaz: a disable a sys.server_principals catalog is_disabled mezőjét állítja. A deny login pedig nem. Ő a sys. server_permissions catalog view-t bővíti egy sorral, amiben a CONNECT SQL jogot tiltja. Vagyis a fenti deny login script igazából így néz ki modernül:

CREATE LOGIN [SQL01\ddeny] FROM WINDOWS;
DENY CONNECT SQL TO [SQL01\ddeny];

És hab a tortán: ha ez nem elég, akár még ki is lockolhatunk egy accountot. Mi kell ehhez? egy olyan local account (vagy domain) policy, amiben van account lockout N próbálkozás után, plusz be kell állítanunk, hogy az SQL login ellenőrizze a policyt.

CREATE LOGIN slocked WITH PASSWORD='Password2',  CHECK_POLICY=ON;

Természetesen ez csak SQL loginra igaz, mivel a windows accountok lockoutját a Windows maga végzi. Rontsuk el párszor a jelszavát, és azt fogja mondani a jó jelszóra, hogy ki vagyunk lockolva. Erre két lehetőség van: vagy a jelszó ismeretében az ALTER LOGIN UNLOCK, vagy anélkül az ALTER LOGIN CHECK_POLICY=OFF, majd ON:

ALTER LOGIN slocked WITH PASSWORD='Password2' UNLOCK;
ALTER LOGIN slocked CHECK_POLICY=OFF;
ALTER LOGIN slocked CHECK_POLICY=ON;

Már csak egy kérdés maradt: mi a különbség a disable meg a deny között? Hát, a disable kb. arra jó, mint a Windows account disable: fel lehet vele függeszteni valaki-valami hozzáférését egy időre. A deny viszont azt a problémát tudja orvosolni, amikor egy csoportnak adtunk jogot, de azon belül egy kisebb csoportnak, vagy egyes személyeknek nem akarunk hozzáférést adni mégsem. A deny segítségével “kitakarhatjuk” őket a jogosultak köréből.

Az unlocknak pedig az a varázsa, hogy ha beállítjuk egy alkalmazásusernek, akkor simán ki tudja zárni az alkalmazást bárki az adatbázisból… :)

Jogosultság lekérése T-SQL-ben

Keresgéltem a BOL-ban, és belebotlottam egy függvénybe: fn_my_permissions(). Ez igen kedvesen megmondja, hogy milyen jogaim vannak. Néhány példa:

SELECT * FROM fn_my_permissions (NULL, 'DATABASE');
SELECT * FROM fn_my_permissions ('dbo.Mytable', 'OBJECT');

És mivel van kiváló impersonation is, sysadminként más jogait is lekérhetem:

EXECUTE AS LOGIN = 'GipszJakab'
SELECT * FROM fn_my_permissions ('dbo.Mytable', 'OBJECT');
REVERT

SQL Server 2008 SP2 kiadva!

Hölgyeim és Uraim!

Végre a hőn áhított SQL 2008 SP2 kiadatott. Letölthető innen, a fixált bugok listája pedig a KB2285068 cikkben található. Vigyázat, a lista nem hibátlan, 1-2 dolog biztosan hiányzik belőle, például állítólag a lock escalation problémát javították (mely arról szól, hogy SQL 2008-ban van egy bug, amitől az INSERT-nél elfelejt lockot eszkalálni, és annyi lockot tud produkálni, ahány sort beszúrunk), de nincs a listában. Én meg még nem próbáltam ki. Majd megírom, ha igen.

Szóval lehet vinni tesztelni, meg várni még a SQL 2005 utolsó, negyedik SP-jére, melyet az év utolsó negyedévére ígértek.

Windows login és az őt felruházó csoporttagságok

Klasszikus probléma, hogy van egy Windows login az SQL szerveren, aki benne van N csoportban, amik benne vannak másik M csoportban, és a répamese jegyében ez összesen nagyon sok csoport lesz. A kérdés pedig az, hogy pontosan melyik csoporttagságán keresztül milyen jogot is szerzett az SQL szerveren. Na, pont erre nyomtam egy lenyűgöző Powershell demót a SQL 2008 R2 bejelentési eseményen, aztán elhagytam a scriptet. Mivel valami dupla mákos hakkolás volt, próbáltam felhajtani, de nem sikerült. Viszont a vicc, hogy ugyanezt a fícsört megtaláltam beleépítve a SQL szerverbe.

A neve xp_logininfo, és két irányba is működik:

exec master..xp_logininfo [EMEA\EBitemo], 'all'

megmondja az összes csoportot, melyen keresztül engem beenged a SQL Server.

exec master..xp_logininfo [EMEA\#DBA_Operators], 'members'

pedig megmondja, h kiket is enged ő be azon a csoporton keresztül.

Ezzel TT felé való négyhónapos adósságomat rendezettnek tekintem :)