使用 ADO (`_ConnectionPtr`, `_RecordsetPtr`) 呼叫 SQL Server 系統存儲過程 (`sp_addlogin`, `sp_grantdbaccess`, `sp_droplogin`, `sp_revokedbaccess`) 及系統表 (`master..sysdatabases`, `master..syslogins`, `db..sysusers`) 實現帳號全生命週期管理。
void CUserMgr::LoadDatabases() {
_RecordsetPtr rs; rs.CreateInstance(__uuidof(Recordset));
rs->Open("SELECT name FROM master..sysdatabases", m_cn, adOpenDynamic, adLockOptimistic, adCmdText);
while (!rs->EndOfFile) {
m_cbDatabase.AddString((char*)(_bstr_t)rs->Fields->Item["name"]->Value);
rs->MoveNext();
}
}
rs->Open("SELECT name FROM master..syslogins WHERE isntname = 0", m_cn, ...);
BOOL CUserMgr::HasRight(CString user, CString db) {
CString sql; sql.Format(_T("SELECT * FROM [%s]..sysusers WHERE name='%s'"), db, user);
try {
rs->Open(sql, m_cn, ...); rs->Close(); return TRUE;
} catch (...) { return FALSE; }
}
void CUserMgr::OnAddUser() {
if (m_strUser.IsEmpty() || m_strUser == "sa") return;
if (m_lstUsers.FindStringExact(-1, m_strUser) < 0) {
m_cn->Execute("sp_addlogin '" + m_strUser + "','" + m_strUser + "'", NULL, adExecuteNoRecords);
m_lstUsers.AddString(m_strUser);
}
CString db; m_cbDatabase.GetLBText(m_cbDatabase.GetCurSel(), db);
m_cn->PutDefaultDatabase(_bstr_t(db));
m_cn->Execute("sp_grantdbaccess '" + m_strUser + "'", NULL, adExecuteNoRecords);
m_lstUserDBs.AddString(db);
}
void CUserMgr::OnDel() {
if (m_lstUserDBs.GetCount() == 0) { // 刪除帳號
m_cn->Execute("sp_droplogin '" + m_strUser + "'", NULL, adExecuteNoRecords);
m_lstUsers.DeleteString(m_lstUsers.FindStringExact(-1, m_strUser));
} else { // 移除特定資料庫權限
CString db; m_cbDatabase.GetLBText(m_cbDatabase.GetCurSel(), db);
if (m_lstUserDBs.FindStringExact(-1, db) >= 0) {
m_cn->PutDefaultDatabase(_bstr_t(db));
m_cn->Execute("sp_revokedbaccess '" + m_strUser + "'", NULL, adExecuteNoRecords);
m_lstUserDBs.DeleteString(m_lstUserDBs.FindStringExact(-1, db));
}
}
}
m_cn.Open("Provider=SQLOLEDB;Data Source=.;Initial Catalog=master;User ID=sa;Password=;", "", "", adConnectUnspecified);