次の方法で共有


Kerberos 相互認証の取得

このサンプルでは、SQL Server Native Client で ODBC を使用して、Kerberos 相互認証を行う方法を紹介しています。

このサンプルは、SQL Server 2008 より前のバージョンの SQL Server では動作しません。

詳細については、「クライアント接続でのサービス プリンシパル名 (SPN) のサポート」を参照してください。

使用例

このサンプルを 64 ビット オペレーティング システムで 32 ビット アプリケーションとしてビルドし、実行する場合、%windir%\SysWOW64\odbcad32.exe の ODBC アドミニストレーターを使用して ODBC データ ソースを作成する必要があります。

このサンプルでは、コンピューターの既定の SQL Server インスタンスに接続します。 名前付きインスタンスに接続するには、ODBC データ ソースの定義を変更し、server\namedinstance 形式でそのインスタンスを指定します。 SQL Server Express は、既定で名前付きインスタンスとしてインストールされます。

"MyServer" の部分を SQL Server 2008 以降のインスタンスが実行されているコンピューター名に変更してください。

また、顧客から提供された SPN を指定する必要があります。 " CP_SPN " の部分を顧客から提供された SPN に変更してください。

/EHsc、/D "_UNICODE"、/D "UNICODE"、および odbc32.lib を使用してコンパイルします。 INCLUDE 環境変数に、sqlncli.h が保存されているディレクトリが含まれていることを確認します。

// compile with: /EHsc /D "_UNICODE" /D "UNICODE" odbc32.lib
#define WIN32_LEAN_AND_MEAN
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>

#define _SQLNCLI_ODBC_
#include <sqlncli.h>

#define SUCCESS(x) (!((x) & 0xFFFE))

#define CHKRC(stmt) do \
                    { \
                    rc = (stmt); \
                    if (!SUCCESS(rc)) \
                    throw (RETCODE) rc; \
                    } while(0);

void PrintError(SQLSMALLINT HandleType, SQLHANDLE Handle) {
   RETCODE rc = SQL_SUCCESS;
   SQLTCHAR szSqlState[6], szMessage[1024];
   SQLSMALLINT i = 1, msgLen = 0;
   SQLINTEGER NativeError;

   do {
      i = 1;
      while (SQL_NO_DATA != (rc = SQLGetDiagRec(HandleType, Handle, i, szSqlState, &NativeError, 
         szMessage, sizeof(szMessage)/sizeof(SQLTCHAR), &msgLen)) && SUCCESS(rc)) {
            _tprintf(_T("SQLState=%s, NativeError=%ld, Message=%s\r\n"), szSqlState, NativeError, szMessage);
            i++;
      }
   } 
   while (SQL_NO_DATA != (rc = SQLMoreResults(Handle)) && SUCCESS(rc));
}

int _tmain(int argc, _TCHAR* argv[]) {
   RETCODE rc = SQL_SUCCESS;
   HENV henv = SQL_NULL_HENV;
   HDBC hdbc = SQL_NULL_HDBC;
   SQLHSTMT hstmt = SQL_NULL_HSTMT;
   SQLTCHAR * pszConnection = _T("DRIVER={SQL Server Native Client 10.0};")
      _T("Server=MyServer;")          // server with SQL Server 2008 (or later)
      _T("Trusted_Connection=Yes;")
      _T("ServerSPN=CP_SPN");    // customer-provided SPN

   TCHAR szIntgAuthMethod[64];
   SQLSMALLINT fMutuallyAuth = 0;

   try {
      CHKRC(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HENV, &henv));
      CHKRC(SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0));
      CHKRC(SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc));
      CHKRC(SQLDriverConnect( hdbc, NULL, pszConnection, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT));
      CHKRC(SQLGetConnectAttr(hdbc, SQL_COPT_SS_INTEGRATED_AUTHENTICATION_METHOD, szIntgAuthMethod, sizeof(szIntgAuthMethod)/sizeof(szIntgAuthMethod[0]), NULL));
      CHKRC(::SQLGetConnectAttrW(hdbc, SQL_COPT_SS_MUTUALLY_AUTHENTICATED, &fMutuallyAuth, SQL_IS_SMALLINT, NULL));

      _tprintf(_T("Authentication method: %s\r\n"), szIntgAuthMethod);
      _tprintf(_T("Mutually authenticated: %s\r\n"), fMutuallyAuth?_T("yes"):_T("no"));
   }
   catch (RETCODE retcode) {
      rc = retcode;
   }

   if (!SUCCESS(rc)) {
      if (hstmt)
         PrintError(SQL_HANDLE_STMT, hstmt);
      else if (hdbc)
         PrintError(SQL_HANDLE_DBC, hdbc);
      else if(henv)
         PrintError(SQL_HANDLE_ENV, henv);
   }

   if (hstmt)
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
   if (hdbc) {
      SQLDisconnect(hdbc);
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
   }
   if (henv)
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
}