2008年6月12日

先日、Windows認証モードに設定された既定のインスタンスが入っている
ActiveDirectryなしの環境で使用するサーバーと出会いました。

そのままではちょっと困るので、認証モードを変更しようとManagement Studioを探してみるも入ってないw
いつもはManagement Studioで変更するけど、ない時どうすんべ?
そういや他の方法知らないや。。。

と思い、ちょいと調べてみたのでメモをアップしますー

※SQL Server 2008についてはSQL Server 2008 RC 0を使用しています。

認証モードの設定(インストール時)
認証モードを最初に設定するのはインストールのタイミングです。
1.GUIから
ウィザードに従ってWindows認証モードか混合モードかを選択します。
SqlServer2005のセットアップ SqlServer2008のセットアップ
操作は見たまんまですね。
詳細は下記を参照してください。
2.コマンドプロンプトから
iniファイルを使用してコマンドプロンプトからインストールを実行する場合は、次のパラメータを使用します。
認証モードパラメータ
Windows認証モードなし
混合モードSECURITYMODE=SQL
コマンドプロンプトからのインストールを実際に試したことはないので以上。
詳細は下記に丸投げ。(気が向いたらそのうちやってみ…るかもw)
認証モードの変更(インストール後)
1~4のいずれかの操作を行った後にインスタンスの再起動が必要です。

1.Management Studioからサーバーのプロパティを操作
一番簡単なのはManagement Studio上からサーバーのプロパティを開いて変更する方法です。
サーバーのプロパティ
これは2005でも2008でも画面レイアウトまで含めてまったく同じ。
2008のドキュメントでは2005のものと比べてセキュリティメモの部分がちょこっと加筆された模様です。
2.SMOを利用して変更
SMOを利用する場合はServerクラスが持っているSettingsプロパティ(Settingsクラス)から
LoginModeを変更します。

認証モードを変更するサーバーがSQLServer2005のインスタンスであれば
  • Microsoft.SqlServer.ConnectionInfo
  • Microsoft.SqlServer.Smo
  • Microsoft.SqlServer.SqlEnum
への参照を追加してください。
また、2008のインスタンスの場合は上記3つに加えて
  • Microsoft.SqlServer.Management.Sdk.Sfc
が必要です。

注)2005のSMOアセンブリを使用して2008のインスタンスに接続することはできません。
  2008のインスタンスに接続する場合は、2005ではなく2008のアセンブリを参照するようにしてください。
using System;
using Microsoft.SqlServer.Management.Smo;
namespace ChangeLoginMode
{
    class Program
    {
        static void Main(string[] args)
        {
            Server Svr = new Server();
            //インスタンスを指定(ここではVM-XPProの既定のインスタンスを使用)
            Svr.ConnectionContext.ServerInstance = "VM-XPPro";
            try
            {
                //接続(既定ではWindows認証)
                Svr.ConnectionContext.Connect();
                if (Svr.Settings.LoginMode == ServerLoginMode.Integrated)
                {
                    //混合モードに変更
                    Svr.Settings.LoginMode = ServerLoginMode.Mixed;
                }
                else
                {
                    //Windows認証モードに変更
                    Svr.Settings.LoginMode = ServerLoginMode.Integrated;
                }
                //LoginModeの変更を反映
                Svr.Alter();
            }
            catch (Exception ex)
            {
                //例外処理は省略
            }
            finally
            {
                //開けたら閉める
                if (Svr.ConnectionContext.IsOpen)Svr.ConnectionContext.Disconnect();
            }
        }
    }
}
LoginModeに設定するServerLoginMode列挙体には次の4つのメンバが含まれます。
(※レジストリのパスについては4にて後述)
メンバ名認証モードレジストリの値
IntegratedWindows認証モード1
Mixed混合モード2
Normal(SQLServer認証)0
Unknown(不明)-
BOLによるとNormalはSQLServer認証を示すとのこと。

SQLServerにはNormalとUnknownにあたる認証モードはないけれど、
コード上はLoginModeにNormalとUnknownを設定できるので、
どうなるのか試しにやってみた。

結果

LoginModeにNormalを設定するとレジストリの値が0になって
挙動としてはWindow認証モードのような感じになり、(内部で正しく動いているのかは不明…)
Unknownを設定するとSvr.Alter()の時点で例外(FailedOperationException)が発生しました。

コード上は設定できてもするなってお話ですね。
3.xp_instance_regwriteで設定
1と2の方法が裏で何をやってるのか?
Profilerでトレースしてみるとどちらも同じことしてんじゃんってことがわかります。

2008のEnterprise Evaluation Editionと2005のStandard Editionの既定のインスタンスと
2005のDeveloper及びExpress Editionの名前付きインスタンスでやってみたところ、
混合モードからWindows認証モードへ変更する際どれであっても同じ
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', 
        N'Software\Microsoft\MSSQLServer\MSSQLServer', N'LoginMode', REG_DWORD, 1
が使われていました。
混合モードにする時は最後の引数が「2」になります。

4.レジストリを直接書き換える
上記の1~3の方法はすべてサーバーに接続しないと行えない方法です。
しかし、結局のところレジストリに書かれているLoginModeの値で認証モードを切り替えているだけなので、
接続しなくてもそこを直接書き換えれば変更できます。 (荒業w)

今回使用した環境ではそれぞれ次の場所にLoginModeの値がありました。
①~③は同じ仮想マシンにインストールした順番です。

①2008 Enterprise Evaluation Edition の既定のインスタンス
→HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQLServer

②2005 Developer Edition の名前付きインスタンス
→HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer

③2005 Express Edition の名前付きインスタンス
→HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.2\MSSQLServer

認証モードはインスタンス毎の設定なので、
複数のインスタンスが存在する場合はそれぞれの場所に値が書き込まれています。

どうしてもレジストリを直接いじりたくてしょうがない人は、
目的のインスタンスのレジストリの場所を探して自己責任の範囲内でやってみてください。

posted @ 7:50 | Feedback (483)