/**********************************************************************/ /** Microsoft Windows NT **/ /** Copyright(c) Microsoft Corp., 1991-1996 **/ /**********************************************************************/ /* WelcomeDlg.cpp CPropertyPage support for User management wizard FILE HISTORY: jony Apr-1996 created */ #include "stdafx.h" #include "Speckle.h" #include "wizbased.h" #include "Welcome.h" #include "trstlist.h" #include #include #include #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CWelcomeDlg property page IMPLEMENT_DYNCREATE(CWelcomeDlg, CWizBaseDlg) CWelcomeDlg::CWelcomeDlg() : CWizBaseDlg(CWelcomeDlg::IDD) { //{{AFX_DATA_INIT(CWelcomeDlg) //}}AFX_DATA_INIT m_pFont = NULL; } CWelcomeDlg::~CWelcomeDlg() { if (m_pFont != NULL) delete m_pFont; } void CWelcomeDlg::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CWelcomeDlg) DDX_Control(pDX, IDC_DOMAIN_LIST, m_cbDomainList); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CWelcomeDlg, CPropertyPage) //{{AFX_MSG_MAP(CWelcomeDlg) ON_WM_SHOWWINDOW() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CWelcomeDlg message handlers BOOL CWelcomeDlg::OnInitDialog() { CPropertyPage::OnInitDialog(); CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp(); // read cached domain list from registry DWORD dwRet; HKEY hKey; DWORD cbProv = 0; TCHAR* lpProv = NULL; BOOL bFoundOne = FALSE; long lRet = RegConnectRegistry( (LPTSTR)pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength()), HKEY_LOCAL_MACHINE, &hKey); dwRet = RegOpenKey(hKey, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hKey ); TCHAR* lpPrimaryDomain = NULL; if ((dwRet = RegQueryValueEx( hKey, TEXT(/*"CachePrimaryDomain"*/"DefaultDomainName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS) { lpPrimaryDomain = (TCHAR*)malloc(cbProv); if (lpPrimaryDomain == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); ExitProcess(1); } dwRet = RegQueryValueEx( hKey, TEXT(/*"CachePrimaryDomain"*/"DefaultDomainName"), NULL, NULL, (LPBYTE) lpPrimaryDomain, &cbProv ); bFoundOne = TRUE; } m_csPrimaryDomain = lpPrimaryDomain; free(lpPrimaryDomain); RegCloseKey(hKey); CString csMachineName; DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1; GetComputerName(csMachineName.GetBufferSetLength(MAX_COMPUTERNAME_LENGTH + 1), &dwSize); pApp->m_csCurrentMachine = csMachineName; // read the list of trusted domains CTrustList pList; if (!pList.BuildTrustList((LPTSTR)pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength()))) { /* if this fails its probably because they are running the wizard from a machine account that doesn't exist on the domain level. Add only the local machine and select it.*/ m_cbDomainList.AddString(pApp->m_csCurrentMachine); m_cbDomainList.SelectString(-1, pApp->m_csCurrentMachine); } else { UINT i; for(i = 0 ; i < pList.m_dwTrustCount ; i++) m_cbDomainList.AddString(pList.m_ppszTrustList[i]); // remove the current machine from the list // if ((i = m_cbDomainList.FindStringExact(-1, pApp->m_csCurrentMachine)) != LB_ERR) // m_cbDomainList.DeleteString(i); // now select the default domain into view int nSel = m_cbDomainList.SelectString(-1, m_csPrimaryDomain); m_cbDomainList.GetWindowText(m_csDomain); UpdateData(FALSE); } // welcome text m_pFont = new CFont; LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); // Clear out structure. lf.lfHeight = 15; _tcscpy(lf.lfFaceName, L"MS Sans Serif"); lf.lfWeight = 700; m_pFont->CreateFontIndirect(&lf); // Create the font. CString cs; cs.LoadString(IDS_WELCOME_STRING); CWnd* pWnd = GetDlgItem(IDC_STATIC1); pWnd->SetWindowText(cs); pWnd->SetFont(m_pFont); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } LRESULT CWelcomeDlg::OnWizardNext() { UpdateData(TRUE); CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp(); // get the DC of the selected domain m_cbDomainList.GetWindowText(m_csDomain); // same as last time? no need to check again. if (m_csLastDomain == m_csDomain) return CPropertyPage::OnWizardNext(); CWaitCursor wait; pApp->m_csDomain = m_csDomain; pApp->m_bDomain = FALSE; TCHAR* pDomain = m_csDomain.GetBuffer(m_csDomain.GetLength()); m_csDomain.ReleaseBuffer(); TCHAR* pDC; NET_API_STATUS nApi; // local machine? if (m_csDomain == pApp->m_csCurrentMachine) { pApp->m_csServer = CString(L"\\\\") + pApp->m_csCurrentMachine; pDC = pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength()); } else { nApi = NetGetDCName(NULL, pDomain, (LPBYTE*)&pDC); if (nApi != NERR_Success) { AfxMessageBox(IDS_NODC, MB_ICONSTOP); return -1; } pApp->m_csServer = pDC; pApp->m_bDomain = TRUE; } // we really shouldn't proceed until we know we are an admin on the remote machine BYTE sidBuffer[100]; PSID pSID = (PSID)&sidBuffer; BOOL bRet; // create a SID for the Administrators group SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; bRet = AllocateAndInitializeSid(&SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID); if (!bRet) { DWORD dw = GetLastError(); ASSERT(0); } TCHAR pName[256]; DWORD dwNameLen = 256; TCHAR pDomainName[256]; DWORD dwDomainNameLen = 256; SID_NAME_USE SNU; bRet = LookupAccountSid(pDC, pSID, pName, &dwNameLen, pDomainName, &dwDomainNameLen, &SNU); // get the users name and domain from the reg for comparison DWORD dwRet; HKEY hKey; DWORD cbProv = 0; CString csUsername; CString csDomainName; dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hKey ); if ((dwRet = RegQueryValueEx( hKey, TEXT("DefaultDomainName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS) { dwRet = RegQueryValueEx( hKey, TEXT("DefaultDomainName"), NULL, NULL, (LPBYTE)csDomainName.GetBufferSetLength(cbProv), &cbProv ); } TCHAR* lpDefaultUserName = NULL; if ((dwRet = RegQueryValueEx( hKey, TEXT("DefaultUserName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS) { dwRet = RegQueryValueEx( hKey, TEXT("DefaultUserName"), NULL, NULL, (LPBYTE)csUsername.GetBufferSetLength(cbProv), &cbProv ); } RegCloseKey(hKey); // now enumerate the members of the admin group to see if we are a member BOOL bAdmin = FALSE; PLOCALGROUP_MEMBERS_INFO_1 pMembers; DWORD dwEntriesRead, dwTotalEntries; DWORD dwResumeHandle = 0; nApi = NetLocalGroupGetMembers(pDC, pName, 1, (LPBYTE*)&pMembers, 5000, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nApi == NERR_Success) { USHORT sIndex = 0; while (sIndex < dwEntriesRead) { TCHAR pName[50]; DWORD dwNameSize = 50; TCHAR pDomain[50]; DWORD dwDomainNameSize = 50; SID_NAME_USE pUse; LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid, pName, &dwNameSize, pDomain, &dwDomainNameSize, &pUse); if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) || ((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain)))) { bAdmin = TRUE; break; } sIndex++; } NetApiBufferFree(pMembers); while ((dwResumeHandle != 0) && (!bAdmin)) { nApi = NetLocalGroupGetMembers(pDC, pName, 1, (LPBYTE*)&pMembers, 5000, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nApi == NERR_Success) { USHORT sIndex = 0; while (sIndex < dwEntriesRead) { TCHAR pName[50]; DWORD dwNameSize = 50; TCHAR pDomain[50]; DWORD dwDomainNameSize = 50; SID_NAME_USE pUse; LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid, pName, &dwNameSize, pDomain, &dwDomainNameSize, &pUse); if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) || ((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain)))) { bAdmin = TRUE; break; } sIndex++; } } NetApiBufferFree(pMembers); } } if (!bAdmin) // not in the administrators group - check the account ops group { BYTE sidBuffer[100]; PSID pSID = (PSID)&sidBuffer; BOOL bRet; // create a SID for the Account Operators group SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; bRet = AllocateAndInitializeSid(&SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS, 0, 0, 0, 0, 0, 0, &pSID); if (!bRet) { DWORD dw = GetLastError(); ASSERT(0); } TCHAR pName[256]; DWORD dwNameLen = 256; TCHAR pDomainName[256]; DWORD dwDomainNameLen = 256; SID_NAME_USE SNU; bRet = LookupAccountSid(pDC, pSID, pName, &dwNameLen, pDomainName, &dwDomainNameLen, &SNU); // now enumerate the members of the group to see if we are a member PLOCALGROUP_MEMBERS_INFO_1 pMembers; DWORD dwEntriesRead, dwTotalEntries; DWORD dwResumeHandle = 0; nApi = NetLocalGroupGetMembers(pDC, pName, 1, (LPBYTE*)&pMembers, 5000, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nApi == NERR_Success) { USHORT sIndex = 0; while (sIndex < dwEntriesRead) { TCHAR pName[50]; DWORD dwNameSize = 50; TCHAR pDomain[50]; DWORD dwDomainNameSize = 50; SID_NAME_USE pUse; LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid, pName, &dwNameSize, pDomain, &dwDomainNameSize, &pUse); if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) || ((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain)))) { bAdmin = TRUE; break; } sIndex++; } NetApiBufferFree(pMembers); while ((dwResumeHandle != 0) && (!bAdmin)) { nApi = NetLocalGroupGetMembers(pDC, pName, 1, (LPBYTE*)&pMembers, 5000, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nApi == NERR_Success) { USHORT sIndex = 0; while (sIndex < dwEntriesRead) { TCHAR pName[50]; DWORD dwNameSize = 50; TCHAR pDomain[50]; DWORD dwDomainNameSize = 50; SID_NAME_USE pUse; LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid, pName, &dwNameSize, pDomain, &dwDomainNameSize, &pUse); if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) || ((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain)))) { bAdmin = TRUE; break; } sIndex++; } } NetApiBufferFree(pMembers); } } } // not an admin? don't continue if (!bAdmin) { AfxMessageBox(IDS_NOT_ADMIN); return -1; } // store the domain name for a possible rerun. m_csLastDomain = m_csDomain; return CPropertyPage::OnWizardNext(); } // this gets called to look into a global group which is included in the admin or account ops local group. // these groups live on the DC of the domain passed in. BOOL CWelcomeDlg::bParseGlobalGroup(LPTSTR lpGroupName, CString& lpName, CString& lpDomain) { DWORD dwEntriesRead; DWORD dwTotalEntries; DWORD dwResumeHandle = 0; CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp(); TCHAR* pDomain = lpDomain.GetBuffer(lpDomain.GetLength()); lpDomain.ReleaseBuffer(); TCHAR* pServer; NET_API_STATUS nApi = NetGetDCName(NULL, pDomain, (LPBYTE*)&pServer); if (nApi != NERR_Success) { AfxMessageBox(IDS_NODC, MB_ICONSTOP); return FALSE; } PGROUP_USERS_INFO_1 pMembers; nApi = NetGroupGetUsers(pServer, lpGroupName, 1, (LPBYTE*)&pMembers, 5000, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nApi != ERROR_SUCCESS) { NetApiBufferFree(pServer); return FALSE; } USHORT sIndex; for (sIndex = 0; sIndex < dwEntriesRead; sIndex++) { if (!lpName.CompareNoCase(pMembers[sIndex].grui1_name)) { NetApiBufferFree(pServer); return TRUE; } } while (dwResumeHandle != 0) { nApi = NetGroupGetUsers(pServer, lpGroupName, 1, (LPBYTE*)&pMembers, 5000, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nApi != ERROR_SUCCESS) { NetApiBufferFree(pServer); return FALSE; } for (sIndex = 0; sIndex < dwEntriesRead; sIndex++) { if (!lpName.CompareNoCase(pMembers[sIndex].grui1_name)) { NetApiBufferFree(pServer); return TRUE; } } } NetApiBufferFree(pServer); return FALSE; } void CWelcomeDlg::OnShowWindow(BOOL bShow, UINT nStatus) { CPropertyPage::OnShowWindow(bShow, nStatus); CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp(); if (bShow) pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT); else pApp->m_cps1.SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT); }