Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

576 lines
13 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1991-1996 **/
  4. /**********************************************************************/
  5. /*
  6. WelcomeDlg.cpp
  7. CPropertyPage support for User management wizard
  8. FILE HISTORY:
  9. jony Apr-1996 created
  10. */
  11. #include "stdafx.h"
  12. #include "Speckle.h"
  13. #include "wizbased.h"
  14. #include "Welcome.h"
  15. #include "trstlist.h"
  16. #include <winreg.h>
  17. #include <lmerr.h>
  18. #include <lmapibuf.h>
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CWelcomeDlg property page
  25. IMPLEMENT_DYNCREATE(CWelcomeDlg, CWizBaseDlg)
  26. CWelcomeDlg::CWelcomeDlg() : CWizBaseDlg(CWelcomeDlg::IDD)
  27. {
  28. //{{AFX_DATA_INIT(CWelcomeDlg)
  29. //}}AFX_DATA_INIT
  30. m_pFont = NULL;
  31. }
  32. CWelcomeDlg::~CWelcomeDlg()
  33. {
  34. if (m_pFont != NULL) delete m_pFont;
  35. }
  36. void CWelcomeDlg::DoDataExchange(CDataExchange* pDX)
  37. {
  38. CPropertyPage::DoDataExchange(pDX);
  39. //{{AFX_DATA_MAP(CWelcomeDlg)
  40. DDX_Control(pDX, IDC_DOMAIN_LIST, m_cbDomainList);
  41. //}}AFX_DATA_MAP
  42. }
  43. BEGIN_MESSAGE_MAP(CWelcomeDlg, CPropertyPage)
  44. //{{AFX_MSG_MAP(CWelcomeDlg)
  45. ON_WM_SHOWWINDOW()
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CWelcomeDlg message handlers
  50. BOOL CWelcomeDlg::OnInitDialog()
  51. {
  52. CPropertyPage::OnInitDialog();
  53. CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp();
  54. // read cached domain list from registry
  55. DWORD dwRet;
  56. HKEY hKey;
  57. DWORD cbProv = 0;
  58. TCHAR* lpProv = NULL;
  59. BOOL bFoundOne = FALSE;
  60. long lRet = RegConnectRegistry(
  61. (LPTSTR)pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength()),
  62. HKEY_LOCAL_MACHINE,
  63. &hKey);
  64. dwRet = RegOpenKey(hKey,
  65. TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hKey );
  66. TCHAR* lpPrimaryDomain = NULL;
  67. if ((dwRet = RegQueryValueEx( hKey, TEXT(/*"CachePrimaryDomain"*/"DefaultDomainName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS)
  68. {
  69. lpPrimaryDomain = (TCHAR*)malloc(cbProv);
  70. if (lpPrimaryDomain == NULL)
  71. {
  72. AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION);
  73. ExitProcess(1);
  74. }
  75. dwRet = RegQueryValueEx( hKey, TEXT(/*"CachePrimaryDomain"*/"DefaultDomainName"), NULL, NULL, (LPBYTE) lpPrimaryDomain, &cbProv );
  76. bFoundOne = TRUE;
  77. }
  78. m_csPrimaryDomain = lpPrimaryDomain;
  79. free(lpPrimaryDomain);
  80. RegCloseKey(hKey);
  81. CString csMachineName;
  82. DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  83. GetComputerName(csMachineName.GetBufferSetLength(MAX_COMPUTERNAME_LENGTH + 1), &dwSize);
  84. pApp->m_csCurrentMachine = csMachineName;
  85. // read the list of trusted domains
  86. CTrustList pList;
  87. if (!pList.BuildTrustList((LPTSTR)pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength())))
  88. {
  89. /* if this fails its probably because they are running the wizard
  90. from a machine account that doesn't exist on the domain level.
  91. Add only the local machine and select it.*/
  92. m_cbDomainList.AddString(pApp->m_csCurrentMachine);
  93. m_cbDomainList.SelectString(-1, pApp->m_csCurrentMachine);
  94. }
  95. else
  96. {
  97. UINT i;
  98. for(i = 0 ; i < pList.m_dwTrustCount ; i++)
  99. m_cbDomainList.AddString(pList.m_ppszTrustList[i]);
  100. // remove the current machine from the list
  101. // if ((i = m_cbDomainList.FindStringExact(-1, pApp->m_csCurrentMachine)) != LB_ERR)
  102. // m_cbDomainList.DeleteString(i);
  103. // now select the default domain into view
  104. int nSel = m_cbDomainList.SelectString(-1, m_csPrimaryDomain);
  105. m_cbDomainList.GetWindowText(m_csDomain);
  106. UpdateData(FALSE);
  107. }
  108. // welcome text
  109. m_pFont = new CFont;
  110. LOGFONT lf;
  111. memset(&lf, 0, sizeof(LOGFONT)); // Clear out structure.
  112. lf.lfHeight = 15;
  113. _tcscpy(lf.lfFaceName, L"MS Sans Serif");
  114. lf.lfWeight = 700;
  115. m_pFont->CreateFontIndirect(&lf); // Create the font.
  116. CString cs;
  117. cs.LoadString(IDS_WELCOME_STRING);
  118. CWnd* pWnd = GetDlgItem(IDC_STATIC1);
  119. pWnd->SetWindowText(cs);
  120. pWnd->SetFont(m_pFont);
  121. return TRUE; // return TRUE unless you set the focus to a control
  122. // EXCEPTION: OCX Property Pages should return FALSE
  123. }
  124. LRESULT CWelcomeDlg::OnWizardNext()
  125. {
  126. UpdateData(TRUE);
  127. CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp();
  128. // get the DC of the selected domain
  129. m_cbDomainList.GetWindowText(m_csDomain);
  130. // same as last time? no need to check again.
  131. if (m_csLastDomain == m_csDomain) return CPropertyPage::OnWizardNext();
  132. CWaitCursor wait;
  133. pApp->m_csDomain = m_csDomain;
  134. pApp->m_bDomain = FALSE;
  135. TCHAR* pDomain = m_csDomain.GetBuffer(m_csDomain.GetLength());
  136. m_csDomain.ReleaseBuffer();
  137. TCHAR* pDC;
  138. NET_API_STATUS nApi;
  139. // local machine?
  140. if (m_csDomain == pApp->m_csCurrentMachine)
  141. {
  142. pApp->m_csServer = CString(L"\\\\") + pApp->m_csCurrentMachine;
  143. pDC = pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength());
  144. }
  145. else
  146. {
  147. nApi = NetGetDCName(NULL,
  148. pDomain,
  149. (LPBYTE*)&pDC);
  150. if (nApi != NERR_Success)
  151. {
  152. AfxMessageBox(IDS_NODC, MB_ICONSTOP);
  153. return -1;
  154. }
  155. pApp->m_csServer = pDC;
  156. pApp->m_bDomain = TRUE;
  157. }
  158. // we really shouldn't proceed until we know we are an admin on the remote machine
  159. BYTE sidBuffer[100];
  160. PSID pSID = (PSID)&sidBuffer;
  161. BOOL bRet;
  162. // create a SID for the Administrators group
  163. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
  164. bRet = AllocateAndInitializeSid(&SIDAuth,
  165. 2,
  166. SECURITY_BUILTIN_DOMAIN_RID,
  167. DOMAIN_ALIAS_RID_ADMINS,
  168. 0,
  169. 0,
  170. 0,
  171. 0,
  172. 0,
  173. 0,
  174. &pSID);
  175. if (!bRet)
  176. {
  177. DWORD dw = GetLastError();
  178. ASSERT(0);
  179. }
  180. TCHAR pName[256];
  181. DWORD dwNameLen = 256;
  182. TCHAR pDomainName[256];
  183. DWORD dwDomainNameLen = 256;
  184. SID_NAME_USE SNU;
  185. bRet = LookupAccountSid(pDC,
  186. pSID,
  187. pName,
  188. &dwNameLen,
  189. pDomainName,
  190. &dwDomainNameLen,
  191. &SNU);
  192. // get the users name and domain from the reg for comparison
  193. DWORD dwRet;
  194. HKEY hKey;
  195. DWORD cbProv = 0;
  196. CString csUsername;
  197. CString csDomainName;
  198. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE,
  199. TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hKey );
  200. if ((dwRet = RegQueryValueEx( hKey, TEXT("DefaultDomainName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS)
  201. {
  202. dwRet = RegQueryValueEx( hKey, TEXT("DefaultDomainName"),
  203. NULL,
  204. NULL,
  205. (LPBYTE)csDomainName.GetBufferSetLength(cbProv),
  206. &cbProv );
  207. }
  208. TCHAR* lpDefaultUserName = NULL;
  209. if ((dwRet = RegQueryValueEx( hKey, TEXT("DefaultUserName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS)
  210. {
  211. dwRet = RegQueryValueEx( hKey, TEXT("DefaultUserName"),
  212. NULL,
  213. NULL,
  214. (LPBYTE)csUsername.GetBufferSetLength(cbProv),
  215. &cbProv );
  216. }
  217. RegCloseKey(hKey);
  218. // now enumerate the members of the admin group to see if we are a member
  219. BOOL bAdmin = FALSE;
  220. PLOCALGROUP_MEMBERS_INFO_1 pMembers;
  221. DWORD dwEntriesRead, dwTotalEntries;
  222. DWORD dwResumeHandle = 0;
  223. nApi = NetLocalGroupGetMembers(pDC,
  224. pName,
  225. 1,
  226. (LPBYTE*)&pMembers,
  227. 5000,
  228. &dwEntriesRead,
  229. &dwTotalEntries,
  230. &dwResumeHandle);
  231. if (nApi == NERR_Success)
  232. {
  233. USHORT sIndex = 0;
  234. while (sIndex < dwEntriesRead)
  235. {
  236. TCHAR pName[50];
  237. DWORD dwNameSize = 50;
  238. TCHAR pDomain[50];
  239. DWORD dwDomainNameSize = 50;
  240. SID_NAME_USE pUse;
  241. LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid,
  242. pName, &dwNameSize,
  243. pDomain, &dwDomainNameSize,
  244. &pUse);
  245. if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) ||
  246. ((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain))))
  247. {
  248. bAdmin = TRUE;
  249. break;
  250. }
  251. sIndex++;
  252. }
  253. NetApiBufferFree(pMembers);
  254. while ((dwResumeHandle != 0) && (!bAdmin))
  255. {
  256. nApi = NetLocalGroupGetMembers(pDC,
  257. pName,
  258. 1,
  259. (LPBYTE*)&pMembers,
  260. 5000,
  261. &dwEntriesRead,
  262. &dwTotalEntries,
  263. &dwResumeHandle);
  264. if (nApi == NERR_Success)
  265. {
  266. USHORT sIndex = 0;
  267. while (sIndex < dwEntriesRead)
  268. {
  269. TCHAR pName[50];
  270. DWORD dwNameSize = 50;
  271. TCHAR pDomain[50];
  272. DWORD dwDomainNameSize = 50;
  273. SID_NAME_USE pUse;
  274. LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid,
  275. pName, &dwNameSize,
  276. pDomain, &dwDomainNameSize,
  277. &pUse);
  278. if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) ||
  279. ((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain))))
  280. {
  281. bAdmin = TRUE;
  282. break;
  283. }
  284. sIndex++;
  285. }
  286. }
  287. NetApiBufferFree(pMembers);
  288. }
  289. }
  290. if (!bAdmin) // not in the administrators group - check the account ops group
  291. {
  292. BYTE sidBuffer[100];
  293. PSID pSID = (PSID)&sidBuffer;
  294. BOOL bRet;
  295. // create a SID for the Account Operators group
  296. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
  297. bRet = AllocateAndInitializeSid(&SIDAuth,
  298. 2,
  299. SECURITY_BUILTIN_DOMAIN_RID,
  300. DOMAIN_ALIAS_RID_ACCOUNT_OPS,
  301. 0,
  302. 0,
  303. 0,
  304. 0,
  305. 0,
  306. 0,
  307. &pSID);
  308. if (!bRet)
  309. {
  310. DWORD dw = GetLastError();
  311. ASSERT(0);
  312. }
  313. TCHAR pName[256];
  314. DWORD dwNameLen = 256;
  315. TCHAR pDomainName[256];
  316. DWORD dwDomainNameLen = 256;
  317. SID_NAME_USE SNU;
  318. bRet = LookupAccountSid(pDC,
  319. pSID,
  320. pName,
  321. &dwNameLen,
  322. pDomainName,
  323. &dwDomainNameLen,
  324. &SNU);
  325. // now enumerate the members of the group to see if we are a member
  326. PLOCALGROUP_MEMBERS_INFO_1 pMembers;
  327. DWORD dwEntriesRead, dwTotalEntries;
  328. DWORD dwResumeHandle = 0;
  329. nApi = NetLocalGroupGetMembers(pDC,
  330. pName,
  331. 1,
  332. (LPBYTE*)&pMembers,
  333. 5000,
  334. &dwEntriesRead,
  335. &dwTotalEntries,
  336. &dwResumeHandle);
  337. if (nApi == NERR_Success)
  338. {
  339. USHORT sIndex = 0;
  340. while (sIndex < dwEntriesRead)
  341. {
  342. TCHAR pName[50];
  343. DWORD dwNameSize = 50;
  344. TCHAR pDomain[50];
  345. DWORD dwDomainNameSize = 50;
  346. SID_NAME_USE pUse;
  347. LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid,
  348. pName, &dwNameSize,
  349. pDomain, &dwDomainNameSize,
  350. &pUse);
  351. if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) ||
  352. ((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain))))
  353. {
  354. bAdmin = TRUE;
  355. break;
  356. }
  357. sIndex++;
  358. }
  359. NetApiBufferFree(pMembers);
  360. while ((dwResumeHandle != 0) && (!bAdmin))
  361. {
  362. nApi = NetLocalGroupGetMembers(pDC,
  363. pName,
  364. 1,
  365. (LPBYTE*)&pMembers,
  366. 5000,
  367. &dwEntriesRead,
  368. &dwTotalEntries,
  369. &dwResumeHandle);
  370. if (nApi == NERR_Success)
  371. {
  372. USHORT sIndex = 0;
  373. while (sIndex < dwEntriesRead)
  374. {
  375. TCHAR pName[50];
  376. DWORD dwNameSize = 50;
  377. TCHAR pDomain[50];
  378. DWORD dwDomainNameSize = 50;
  379. SID_NAME_USE pUse;
  380. LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid,
  381. pName, &dwNameSize,
  382. pDomain, &dwDomainNameSize,
  383. &pUse);
  384. if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) ||
  385. ((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain))))
  386. {
  387. bAdmin = TRUE;
  388. break;
  389. }
  390. sIndex++;
  391. }
  392. }
  393. NetApiBufferFree(pMembers);
  394. }
  395. }
  396. }
  397. // not an admin? don't continue
  398. if (!bAdmin)
  399. {
  400. AfxMessageBox(IDS_NOT_ADMIN);
  401. return -1;
  402. }
  403. // store the domain name for a possible rerun.
  404. m_csLastDomain = m_csDomain;
  405. return CPropertyPage::OnWizardNext();
  406. }
  407. // this gets called to look into a global group which is included in the admin or account ops local group.
  408. // these groups live on the DC of the domain passed in.
  409. BOOL CWelcomeDlg::bParseGlobalGroup(LPTSTR lpGroupName, CString& lpName, CString& lpDomain)
  410. {
  411. DWORD dwEntriesRead;
  412. DWORD dwTotalEntries;
  413. DWORD dwResumeHandle = 0;
  414. CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp();
  415. TCHAR* pDomain = lpDomain.GetBuffer(lpDomain.GetLength());
  416. lpDomain.ReleaseBuffer();
  417. TCHAR* pServer;
  418. NET_API_STATUS nApi = NetGetDCName(NULL,
  419. pDomain,
  420. (LPBYTE*)&pServer);
  421. if (nApi != NERR_Success)
  422. {
  423. AfxMessageBox(IDS_NODC, MB_ICONSTOP);
  424. return FALSE;
  425. }
  426. PGROUP_USERS_INFO_1 pMembers;
  427. nApi = NetGroupGetUsers(pServer,
  428. lpGroupName,
  429. 1,
  430. (LPBYTE*)&pMembers,
  431. 5000,
  432. &dwEntriesRead,
  433. &dwTotalEntries,
  434. &dwResumeHandle);
  435. if (nApi != ERROR_SUCCESS)
  436. {
  437. NetApiBufferFree(pServer);
  438. return FALSE;
  439. }
  440. USHORT sIndex;
  441. for (sIndex = 0; sIndex < dwEntriesRead; sIndex++)
  442. {
  443. if (!lpName.CompareNoCase(pMembers[sIndex].grui1_name))
  444. {
  445. NetApiBufferFree(pServer);
  446. return TRUE;
  447. }
  448. }
  449. while (dwResumeHandle != 0)
  450. {
  451. nApi = NetGroupGetUsers(pServer,
  452. lpGroupName,
  453. 1,
  454. (LPBYTE*)&pMembers,
  455. 5000,
  456. &dwEntriesRead,
  457. &dwTotalEntries,
  458. &dwResumeHandle);
  459. if (nApi != ERROR_SUCCESS)
  460. {
  461. NetApiBufferFree(pServer);
  462. return FALSE;
  463. }
  464. for (sIndex = 0; sIndex < dwEntriesRead; sIndex++)
  465. {
  466. if (!lpName.CompareNoCase(pMembers[sIndex].grui1_name))
  467. {
  468. NetApiBufferFree(pServer);
  469. return TRUE;
  470. }
  471. }
  472. }
  473. NetApiBufferFree(pServer);
  474. return FALSE;
  475. }
  476. void CWelcomeDlg::OnShowWindow(BOOL bShow, UINT nStatus)
  477. {
  478. CPropertyPage::OnShowWindow(bShow, nStatus);
  479. CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp();
  480. if (bShow) pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT);
  481. else pApp->m_cps1.SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
  482. }