SQL Server 認証のユーザー パスワードの変更 (OLE DB)
このサンプルでは、SQL Server 認証のユーザー アカウントのパスワードを OLE DB を使用して変更する方法を紹介しています。
セキュリティに関する注意 |
---|
可能な場合は、Windows 認証を使用します。 Windows 認証が使用できない場合は、実行時に資格情報を入力するようユーザーに求めます。 資格情報をファイルに保存するのは避けてください。 資格情報を保存する必要がある場合は、Win32 Crypto API を使用して暗号化してください。 |
使用例
ビルド前に、.C++ コードを修正し、実際のユーザー ID、古いパスワード、および新しいパスワードを指定してください。
このアプリケーションは、コンピューターの既定の SQL Server インスタンスに接続します。 一部の Windows オペレーティング システムでは、(localhost) または (local) を実際の SQL Server インスタンスの名前に変更する必要があります。 名前付きインスタンスに接続するには、接続文字列を L"(local)" から L"(local)\\name" に変更します。name は名前付きインスタンスです。 SQL Server Express は、既定で名前付きインスタンスとしてインストールされます。 INCLUDE 環境変数に、sqlncli.h が保存されているディレクトリが含まれていることを確認します。
ole32.lib と oleaut32.lib を使用してコンパイルします。
このサンプルをビルドするには、パスワードがわかっている SQL Server 認証のユーザー アカウントが必要です。 SQL Server 認証でのログインを許可するには、SQL Server Management Studio を開き、オブジェクト エクスプローラーでサーバー ノードを右クリックし、[プロパティ] をクリックします。 [セキュリティ] をクリックし、[SQL Server 認証モードと Windows 認証モード] を有効にします。 SQL Server 認証用のユーザー アカウントを追加するには、オブジェクト エクスプローラーで [セキュリティ] ノードを右クリックし、[追加] をクリックします。
このサンプルを実行するサーバーには、SQL Server 認証が有効になっているログインが少なくとも 1 つ必要です。 また、SQL Server 認証でのログインを許可するようにサーバーを設定する必要があります。
// compile with: ole32.lib oleaut32.lib
void InitializeAndEstablishConnection();
#define STATUSDUMP(status) case status : wprintf(L"status"); break;
#define UNICODE
#define DBINITCONSTANTS
#define INITGUID
#include <assert.h>
#include <windows.h>
#include <stdio.h>
#include <stddef.h>
#include <IOSTREAM>
#include <cguid.h>
#include <oledb.h>
#include <oledberr.h>
#include <SQLNCLI.h>
LPMALLOC pMalloc = NULL;
IDBInitialize * pIDBInitialize = NULL;
HRESULT hr;
void DumpErrorInfo (IUnknown* pObjectWithError, REFIID IID_InterfaceWithError);
void DumpErrorInfo (IUnknown* pObjectWithError, REFIID IID_InterfaceWithError, BOOL &has_sql_errors);
int main() {
// All the initialization activities in a separate function.
InitializeAndEstablishConnection();
if ( FAILED( pIDBInitialize->Uninitialize() ) )
// Uninitialize is not required, but fails if an interface was not released.
printf("Problem uninitializing.\n");
pIDBInitialize->Release();
CoUninitialize();
};
void InitializeAndEstablishConnection() {
IDBProperties * pIDBProperties = NULL;
const ULONG nInitProps = 4;
DBPROP InitProperties[nInitProps];
const ULONG nSSInitProps = 1;
DBPROP SSInitProperties[nSSInitProps];
const ULONG nPropSet = 2;
DBPROPSET rgInitPropSet[nPropSet];
// Initialize the COM library.
CoInitialize(NULL);
CoGetMalloc(1, &pMalloc);
CLSID clsid;
CLSIDFromProgID(L"SQLNCLI11", &clsid);
// Obtain access to the SQLOLEDB provider.
hr = CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void **) &pIDBInitialize);
if (FAILED(hr))
printf("Failed in CoCreateInstance().\n");
// Initialize the property values needed to establish the connection.
for (int i = 0; i < nInitProps; i++)
VariantInit(&InitProperties[i].vValue);
// Specify database name.
InitProperties[0].dwPropertyID = DBPROP_INIT_CATALOG;
InitProperties[0].vValue.vt = VT_BSTR;
// Change the following line to use any database on your server
InitProperties[0].vValue.bstrVal = SysAllocString(L"master");
InitProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
InitProperties[0].colid = DB_NULLID;
InitProperties[1].dwPropertyID = DBPROP_AUTH_USERID;
InitProperties[1].vValue.vt = VT_BSTR;
// Modify the following line to add the user ID of a SQL Server Authentication account on your server
InitProperties[1].vValue.bstrVal = SysAllocString(L"");
InitProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;
InitProperties[1].colid = DB_NULLID;
InitProperties[2].dwPropertyID = DBPROP_AUTH_PASSWORD;
InitProperties[2].vValue.vt = VT_BSTR;
// Modify the following line to add the new SQL Server Authentication password
InitProperties[2].vValue.bstrVal = SysAllocString(L"");
InitProperties[2].dwOptions = DBPROPOPTIONS_REQUIRED;
InitProperties[2].colid = DB_NULLID;
InitProperties[3].dwPropertyID = DBPROP_INIT_DATASOURCE;
InitProperties[3].vValue.vt = VT_BSTR;
InitProperties[3].vValue.bstrVal = SysAllocString(L"(local)");
InitProperties[3].dwOptions = DBPROPOPTIONS_REQUIRED;
InitProperties[3].colid = DB_NULLID;
SSInitProperties[0].dwPropertyID = SSPROP_AUTH_OLD_PASSWORD;
SSInitProperties[0].vValue.vt = VT_BSTR;
// Modify the following line to specify the existing SQL Server Authentication password
SSInitProperties[0].vValue.bstrVal = SysAllocString(L"");
SSInitProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
SSInitProperties[0].colid = DB_NULLID;
rgInitPropSet[0].guidPropertySet = DBPROPSET_DBINIT;
rgInitPropSet[0].cProperties = nInitProps;
rgInitPropSet[0].rgProperties = InitProperties;
rgInitPropSet[1].guidPropertySet = DBPROPSET_SQLSERVERDBINIT;
rgInitPropSet[1].cProperties = nSSInitProps;
rgInitPropSet[1].rgProperties = SSInitProperties;
// Set initialization properties.
hr = pIDBInitialize->QueryInterface( IID_IDBProperties, (void **)&pIDBProperties);
if (FAILED(hr))
printf("Failed to obtain IDBProperties interface.\n");
hr = pIDBProperties->SetProperties( nPropSet, rgInitPropSet);
if (FAILED(hr))
printf("Failed to set initialization properties.\n");
pIDBProperties->Release();
// establish connection to the data source.
DWORD now = GetTickCount();
if ( FAILED(pIDBInitialize->Initialize()) ) {
printf("Problem in initializing.\n");
DumpErrorInfo(pIDBInitialize, IID_IDBInitialize);
}
DWORD tookms = GetTickCount() - now;
printf("Connection took %d ms.\n", tookms);
}
// DumpErrorInfo queries SQLOLEDB error interfaces, retrieving available status
// or error information. This version is called when SQL Server errors are not expected.
void DumpErrorInfo (IUnknown* pObjectWithError, REFIID IID_InterfaceWithError) {
BOOL has_sql_errors;
DumpErrorInfo (pObjectWithError, IID_InterfaceWithError, has_sql_errors);
}
// DumpErrorInfo queries SQLOLEDB error interfaces, retrieving available status
// or error information. This version is called when an SQL Server error could occur.
void DumpErrorInfo (IUnknown* pObjectWithError, REFIID IID_InterfaceWithError, BOOL &has_sql_errors ) {
// Interfaces used in the example.
IErrorInfo * pIErrorInfoAll = NULL;
IErrorInfo * pIErrorInfoRecord = NULL;
IErrorRecords * pIErrorRecords = NULL;
ISupportErrorInfo * pISupportErrorInfo = NULL;
ISQLErrorInfo * pISQLErrorInfo = NULL;
ISQLServerErrorInfo * pISQLServerErrorInfo = NULL;
// Number of error records.
ULONG nRecs;
ULONG nRec;
// Basic error information from GetBasicErrorInfo.
ERRORINFO errorinfo;
// IErrorInfo values.
BSTR bstrDescription;
BSTR bstrSource;
// ISQLErrorInfo parameters.
BSTR bstrSQLSTATE;
LONG lNativeError;
// ISQLServerErrorInfo parameter pointers.
SSERRORINFO * pSSErrorInfo = NULL;
OLECHAR * pSSErrorStrings = NULL;
// Hard-code an American English locale for the example.
DWORD MYLOCALEID = 0x0409;
has_sql_errors = 0;
// Only ask for error information if the interface supports it.
if (FAILED(pObjectWithError->QueryInterface(IID_ISupportErrorInfo, (void**) &pISupportErrorInfo)))
wprintf(L"SupportErrorErrorInfo interface not supported\n");
else if (FAILED(pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_InterfaceWithError)))
wprintf(L"InterfaceWithError interface not supported\n");
// Do not test the return of GetErrorInfo. It can succeed and return
// a NULL pointer in pIErrorInfoAll. Simply test the pointer.
GetErrorInfo(0, &pIErrorInfoAll);
// Test to see if it's a valid OLE DB IErrorInfo interface exposing a list of records.
if (pIErrorInfoAll != NULL) {
if (SUCCEEDED(pIErrorInfoAll->QueryInterface(IID_IErrorRecords, (void**) &pIErrorRecords))) {
pIErrorRecords->GetRecordCount(&nRecs);
// Within each record, retrieve information from each of the defined interfaces.
for (nRec = 0; nRec < nRecs; nRec++) {
ULONG errorno = nRecs - nRec - 1;
// From IErrorRecords, get the HRESULT and a reference to the ISQLErrorInfo interface.
pIErrorRecords->GetBasicErrorInfo(errorno, &errorinfo);
pIErrorRecords->GetCustomErrorObject(errorno,IID_ISQLErrorInfo, (IUnknown**) &pISQLErrorInfo);
// Display the HRESULT, then use the ISQLErrorInfo.
wprintf(L"HRESULT:\t%#X\n", errorinfo.hrError);
if (pISQLErrorInfo != NULL) {
pISQLErrorInfo->GetSQLInfo(&bstrSQLSTATE, &lNativeError);
// Display SQLSTATE and native error values.
wprintf(L"SQLSTATE:\t%s\nNative Error:\t%ld\n", bstrSQLSTATE, lNativeError);
// SysFree BSTR references.
SysFreeString(bstrSQLSTATE);
// Get the ISQLServerErrorInfo interface from
// ISQLErrorInfo before releasing the reference.
pISQLErrorInfo->QueryInterface(IID_ISQLServerErrorInfo, (void**) &pISQLServerErrorInfo);
pISQLErrorInfo->Release();
}
// Test to ensure the reference is valid, then get error information from ISQLServerErrorInfo.
if (pISQLServerErrorInfo != NULL) {
pISQLServerErrorInfo->GetErrorInfo(&pSSErrorInfo, &pSSErrorStrings);
// ISQLServerErrorInfo::GetErrorInfo succeeds even when it
// has nothing to return. Test the pointers before using.
if (pSSErrorInfo) {
// Display the state and severity from the returned
// information. The error message comes from
// IErrorInfo::GetDescription.
wprintf(L"Error state:\t%d\nSeverity:\t%d\n", pSSErrorInfo->bState, pSSErrorInfo->bClass);
wprintf(L"Procedure:\t%s\nLine:\t%d\n", pSSErrorInfo->pwszProcedure, pSSErrorInfo->wLineNumber);
has_sql_errors++;
// IMalloc::Free needed to release references on returned values.
pMalloc->Free(pSSErrorStrings);
pMalloc->Free(pSSErrorInfo);
}
pISQLServerErrorInfo->Release();
}
if (SUCCEEDED(pIErrorRecords->GetErrorInfo(errno, MYLOCALEID, &pIErrorInfoRecord))) {
// Get the source and description (error message) from the record's IErrorInfo.
pIErrorInfoRecord->GetSource(&bstrSource);
pIErrorInfoRecord->GetDescription(&bstrDescription);
if (bstrSource != NULL) {
wprintf(L"Source:\t\t%s\n", bstrSource);
SysFreeString(bstrSource);
}
if (bstrDescription != NULL) {
wprintf(L"Error message:\t%s\n", bstrDescription);
SysFreeString(bstrDescription);
}
pIErrorInfoRecord->Release();
}
}
pIErrorRecords->Release();
}
else {
// IErrorInfo is valid; get the source and
// description to see what it is.
pIErrorInfoAll->GetSource(&bstrSource);
pIErrorInfoAll->GetDescription(&bstrDescription);
if (bstrSource != NULL) {
wprintf(L"Source:\t\t%s\n", bstrSource);
SysFreeString(bstrSource);
}
if (bstrDescription != NULL) {
wprintf(L"Error message:\t%s\n", bstrDescription);
SysFreeString(bstrDescription);
}
}
pIErrorInfoAll->Release();
}
else
wprintf(L"GetErrorInfo failed.\n");
if (pISupportErrorInfo != NULL)
pISupportErrorInfo->Release();
}