(English version here)
Időnként megesik, hogy valaki nem tud belogolni egy SQL Serverbe, mert elgépeli a jelszavát, nincs joga, stb. Ez nem olyan nagy gond egészen addig, amíg tudjuk, hogy miért nem tud belogolni. De mi van, ha valaki azt mondja, hogy nem sikerült neki, 101%, hogy jó jelszóval próbálkozik, jó szerverre, jó felhasználónévvel, jó adatbázisba, minden jó, csak éppen nem tud belépni? A legegyszerűbb megoldás a nagy kedvencem, az errorlog elolvasása, már megint. Amennyiben a szerveren be van állítva a sikertelen belépési kísérletek naplózása (úgy emlékszem ez a default), akkor az errorlogba is bekerül az az üzenet, amit a kliensnek küld a szerver:
Msg 18456, Level 14, State 1, Server DEMOSQL1, Line 1
Login failed for user ‘kiscsillag’
Illetve igazából nem is ez kerül a logba, hanem valami jobb, de mielőtt ebbe belemegyek, értelmezzük az első sorát az üzenetnek, vagyis az error három numerikus argumentumát: Az első az error number, ez a hiba egyedi azonosítója, a gépek mindig jobban szeretik a számokat, mint a dumát. A második a level vagy severity, azaz mennyire gáz az adott hiba. Minél nagyobb a szám, annál rosszabb a helyzet, severity 20 és 25 között már az is kérdéses, hogy rendesen működik-e a szerver. Az utolsó elem a state, ami egy érdekes állat. Arról adhatunk itt információt, hogy honnan jött az error – például ha van egy általunk definiált hiba, amit több különböző helyen is használunk, akkor a state értékét használhatjuk annak a jelzésére, hogy honnan jött a hiba. És most nézzük azt az errorlogot!
2009-07-27 14:02:02.21 Logon Error: 18456, Severity: 14, State: 8.
2009-07-27 14:02:02.21 Logon Login failed for user 'kiscsillag'. [CLIENT: 10.10.10.1]
A különbség jól látható: az a bizonyos state érték eléggé más itt, mint a kliensoldalon volt, és ez nem a véletlen műve. Az SQL Server, ahogyan azt jó rendszertől elvárjuk, nem mond többet a kliensnek, mint amennyi szükséges, nehogy ezzel segítsen egy esetleges támadást. Viszont aki tényleg segítségre szorul, az megkeresheti a sysadminokat, akik a logban láthatják, hogy miért is nem sikerült az a login. A state kódok pedig a következőek:
| ERROR | LEÍRÁS |
| 2, 5 | Érvénytelen felhasználónév |
| 6 | Windows login névvel próbálkoztál SQL autentikációt használni |
| 7 | Letiltott login |
| 8 | Rossz jelszó |
| 9 | Érvénytelen jelszó |
| 11, 12 | Helyes login, de nincs szerver hozzáférés |
| 13 | SQL Server service paused |
| 16 | Helyes login, de nem lehetséges belépni a kért (vagy a default) adatbázisba |
| 18 | Jelszót kell változtatni |
| 23 | A szerver éppen leáll, nem lehet bejelentkezni (nem sysadminoknak) |
| 27 | Helyes login, de a szerver nem tud meghatározni egy kezdeti adatbázist |
| 38 | [2008] Nem sikerült az explicit megadott adatbázis megnyitása (16 SQL 2005-ben) |
| 40 | [2008] Nem sikerült a felhasználó default adatbázisának a megnyitása (16 SQL 2005-ben) |
Van néhány kód, ami nem olyan triviális, hogy mit is jelent, néhányról magam sem tudom :), úgyhogy néhány jellemzőt kiveséznék:
A state 16 (vagy 38/40 SQL 2008-ban) egyik leggyakoribb oka az auto close-os adatbázis. Azaz az SQL szerver becsukja az adatbázist, ha nem használták már egy ideje, és megint megnyitja, ha kell valakinek. Ez egy kiváló ötlet az MSDE-hez meg egyéb asztali gépes világba, de egyébként mindenkinek melegen ajánlom, hogy nézze meg, hogy van-e auto close-os adatbázisa, és ha van, kapcsolja ki ezt az opciót, mert csak szívás van vele. Hogy mi? Például a state 16: éppen be akar lépni a user, erre az SQL elkezdi megnyitni a DB-t neki, de amíg nem sikerül teljesen megnyitnia, addig ugye nem tudja beléptetni az adatbázisába a usert, és elbukik a login. Újrapróbálva valószínűleg jó lesz, mert addigra már kinyitja. A másik gagyi benne (és erről lehet messziről kiszúrni ezeket az adatbázisokat), hogy teleszemeteli az errorlogot “Starting up database XYZ” üzenetekkel.
A 11-12 tipikusan a Windows loginok esete: az SQL Server kiválóan azonosítja a felhasználót, de nincs neki megfelelő login létrehozva az SQL szerveren, úgyhogy emberünk kívül marad.
A blog alapját a SQL Protocol team blogja és a nyomában kialakuló diskurzus adta, mivel nem sikerül összeszedniük az összes kódot egy táblába, és ez engem baromira zavart – úgyhogy összeszedtem.