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.

541 lines
13 KiB

  1. // Finish.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Romaine.h"
  5. #include "Finish.h"
  6. #include "transbmp.h"
  7. #include <lmcons.h>
  8. #include <lmaccess.h>
  9. #include <lmerr.h>
  10. #include <lmapibuf.h>
  11. #include <winnetwk.h>
  12. #include <ntsecapi.h>
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. NTSTATUS OpenPolicy(
  19. LPWSTR ServerName, // machine to open policy on (Unicode)
  20. DWORD DesiredAccess, // desired access to policy
  21. PLSA_HANDLE PolicyHandle); // resultant policy handle
  22. void InitLsaString(
  23. PLSA_UNICODE_STRING LsaString, // destination
  24. LPWSTR String); // source (Unicode)
  25. #ifndef STATUS_SUCCESS
  26. #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
  27. #endif
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CFinish property page
  30. IMPLEMENT_DYNCREATE(CFinish, CPropertyPage)
  31. CFinish::CFinish() : CPropertyPage(CFinish::IDD)
  32. {
  33. //{{AFX_DATA_INIT(CFinish)
  34. m_csGroupType = _T("");
  35. m_csGroupLocation = _T("");
  36. m_csStaticText1 = _T("");
  37. m_csStaticText2 = _T("");
  38. //}}AFX_DATA_INIT
  39. }
  40. CFinish::~CFinish()
  41. {
  42. }
  43. void CFinish::DoDataExchange(CDataExchange* pDX)
  44. {
  45. CPropertyPage::DoDataExchange(pDX);
  46. //{{AFX_DATA_MAP(CFinish)
  47. DDX_Text(pDX, IDC_GROUP_TYPE_STATIC, m_csGroupType);
  48. DDX_Text(pDX, IDC_LOCATION_STATIC, m_csGroupLocation);
  49. DDX_Text(pDX, IDC_STATIC1, m_csStaticText1);
  50. DDX_Text(pDX, IDC_STATIC2, m_csStaticText2);
  51. //}}AFX_DATA_MAP
  52. }
  53. BEGIN_MESSAGE_MAP(CFinish, CPropertyPage)
  54. //{{AFX_MSG_MAP(CFinish)
  55. ON_WM_SHOWWINDOW()
  56. ON_WM_PAINT()
  57. //}}AFX_MSG_MAP
  58. END_MESSAGE_MAP()
  59. /////////////////////////////////////////////////////////////////////////////
  60. // CFinish message handlers
  61. BOOL CFinish::OnWizardFinish()
  62. {
  63. CRomaineApp* pApp = (CRomaineApp*)AfxGetApp();
  64. CWaitCursor wait;
  65. UINT uiMessage;
  66. short sStatus = 0;
  67. if (pApp->m_nGroupType == 0)
  68. {
  69. TCHAR* pServer = pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength());
  70. pApp->m_csServer.ReleaseBuffer();
  71. TCHAR* pGroupName = pApp->m_csGroupName.GetBuffer(pApp->m_csGroupName.GetLength());
  72. pApp->m_csGroupName.ReleaseBuffer();
  73. // create the global group
  74. if (pApp->m_sMode == 0)
  75. {
  76. PGROUP_INFO_1 gi = (PGROUP_INFO_1)malloc(sizeof(GROUP_INFO_1));
  77. gi->grpi1_name = pGroupName;
  78. gi->grpi1_comment = pApp->m_csGroupDesc.GetBuffer(pApp->m_csGroupDesc.GetLength());
  79. pApp->m_csGroupDesc.ReleaseBuffer();
  80. DWORD dwErr = NetGroupAdd(pServer,
  81. 1, (LPBYTE)gi, NULL);
  82. free(gi);
  83. if (dwErr == 2223)
  84. {
  85. AfxMessageBox(IDS_GROUP_EXISTS);
  86. pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
  87. pApp->m_cps1.SetActivePage(1);
  88. return FALSE;
  89. }
  90. else if (dwErr == 5)
  91. {
  92. AfxMessageBox(IDS_INSUFFICIENT_PERMISSION);
  93. pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
  94. pApp->m_cps1.SetActivePage(2);
  95. return FALSE;
  96. }
  97. else if ((dwErr == 1379) || (dwErr == NERR_GroupExists))
  98. {
  99. AfxMessageBox(IDS_GROUP_EXISTS);
  100. pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
  101. pApp->m_cps1.SetActivePage(1);
  102. return FALSE;
  103. }
  104. else if (dwErr != NERR_Success)
  105. {
  106. AfxMessageBox(IDS_UNKNOWN_ERROR);
  107. return CPropertyPage::OnWizardFinish();
  108. }
  109. }
  110. // build the array of users
  111. POSITION pos;
  112. CString csName;
  113. short sCount = pApp->m_csaNames.GetCount();
  114. GROUP_USERS_INFO_0* pUsers = (GROUP_USERS_INFO_0*)malloc(sCount * sizeof(GROUP_USERS_INFO_0));
  115. GROUP_USERS_INFO_0* ppUsers = pUsers;
  116. for (pos = pApp->m_csaNames.GetHeadPosition(); pos != NULL;)
  117. {
  118. csName = pApp->m_csaNames.GetNext(pos);
  119. TCHAR* pName = (TCHAR*)csName.GetBuffer(csName.GetLength());
  120. csName.ReleaseBuffer();
  121. pUsers->grui0_name = (LPTSTR)GlobalAlloc(GPTR, (csName.GetLength() + 1) * sizeof(TCHAR));
  122. _tcscpy(pUsers->grui0_name, pName);
  123. pUsers++;
  124. }
  125. DWORD dwErr = NetGroupSetUsers(pServer,
  126. pGroupName,
  127. 0,
  128. (BYTE*)ppUsers,
  129. sCount);
  130. if (dwErr == NERR_Success) sStatus = 0; // success
  131. else sStatus = 1; //failure
  132. void* pTemp = ppUsers;
  133. // clean up names buffer
  134. while (sCount > 0)
  135. {
  136. GlobalFree((HGLOBAL)ppUsers->grui0_name);
  137. ppUsers++;
  138. sCount--;
  139. }
  140. free(pTemp);
  141. }
  142. else
  143. {
  144. TCHAR* pServer = pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength());
  145. pApp->m_csServer.ReleaseBuffer();
  146. TCHAR* pGroupName = pApp->m_csGroupName.GetBuffer(pApp->m_csGroupName.GetLength());
  147. pApp->m_csGroupName.ReleaseBuffer();
  148. // create the local group
  149. if (pApp->m_sMode == 0)
  150. {
  151. PLOCALGROUP_INFO_1 gi = (PLOCALGROUP_INFO_1)malloc(sizeof(LOCALGROUP_INFO_1));
  152. gi->lgrpi1_name = pGroupName;
  153. gi->lgrpi1_comment = pApp->m_csGroupDesc.GetBuffer(pApp->m_csGroupDesc.GetLength());
  154. DWORD dwErr = NetLocalGroupAdd(pServer,
  155. 1, (LPBYTE)gi, NULL);
  156. pApp->m_csGroupDesc.ReleaseBuffer();
  157. free(gi);
  158. if ((dwErr == 1379) || (dwErr == 2223))
  159. {
  160. AfxMessageBox(IDS_GROUP_EXISTS);
  161. pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
  162. pApp->m_cps1.SetActivePage(1);
  163. return FALSE;
  164. }
  165. else if (dwErr == 5)
  166. {
  167. AfxMessageBox(IDS_INSUFFICIENT_PERMISSION);
  168. pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
  169. pApp->m_cps1.SetActivePage(2);
  170. return FALSE;
  171. }
  172. else if (dwErr != NERR_Success)
  173. {
  174. AfxMessageBox(IDS_UNKNOWN_ERROR);
  175. return CPropertyPage::OnWizardFinish();
  176. }
  177. }
  178. short sCount = pApp->m_csaNames.GetCount();
  179. LOCALGROUP_MEMBERS_INFO_0* pMembers = (LOCALGROUP_MEMBERS_INFO_0*)malloc(sCount * sizeof(LOCALGROUP_MEMBERS_INFO_0));
  180. LOCALGROUP_MEMBERS_INFO_0* ppMembers = pMembers;
  181. // go through the user list and get a SID for each member
  182. POSITION pos;
  183. CString csName;
  184. USHORT uCount = 0;
  185. for (pos = pApp->m_csaNames.GetHeadPosition(); pos != NULL;)
  186. {
  187. CString csName = pApp->m_csaNames.GetNext(pos);
  188. CString csNameLocation = csName.Left(csName.Find(L"\\"));
  189. // if the account comes from a domain, we need a DC name
  190. if ((csNameLocation != (pApp->m_csCurrentMachine.Right(pApp->m_csCurrentMachine.GetLength() - 2))) &&
  191. (csNameLocation != (pApp->m_csServer.Right(pApp->m_csServer.GetLength() - 2))))
  192. {
  193. TCHAR* pDCName;
  194. NET_API_STATUS nAPI = NetGetDCName(NULL,
  195. csNameLocation.GetBuffer(csNameLocation.GetLength()),
  196. (LPBYTE*)&pDCName);
  197. csNameLocation.ReleaseBuffer();
  198. csNameLocation = pDCName;
  199. NetApiBufferFree(pDCName);
  200. if (nAPI != ERROR_SUCCESS)
  201. {
  202. AfxMessageBox(IDS_CANT_ADDNAME);
  203. continue;
  204. }
  205. }
  206. else csNameLocation = pApp->m_csCurrentMachine;
  207. csName = csName.Right(csName.GetLength() - (csName.Find(L"\\") + 1));
  208. TCHAR* pNameLocation = csNameLocation.GetBuffer(csNameLocation.GetLength());
  209. csNameLocation.ReleaseBuffer();
  210. DWORD sidSize = 0;
  211. DWORD strSize = 80;
  212. TCHAR str[80];
  213. SID_NAME_USE sidType;
  214. DWORD ret = LookupAccountName(pNameLocation, (LPCTSTR)csName, NULL, &sidSize, str, &strSize, &sidType);
  215. pMembers->lgrmi0_sid = (PSID)GlobalAlloc(GPTR, sidSize);
  216. strSize = 80;
  217. ret=LookupAccountName(pNameLocation, (LPCTSTR)csName, pMembers->lgrmi0_sid, &sidSize, str, &strSize, &sidType);
  218. pMembers++;
  219. uCount++;
  220. }
  221. DWORD err = NetLocalGroupSetMembers(pServer,
  222. pGroupName,
  223. 0,
  224. (LPBYTE)ppMembers,
  225. sCount);
  226. if (err == NERR_Success) uiMessage = IDS_SUCCESS;
  227. else if ((err == NERR_GroupExists) || (err == 1376) || (err == 1379))
  228. {
  229. AfxMessageBox(IDS_GROUP_EXISTS);
  230. pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
  231. pApp->m_cps1.SetActivePage(1);
  232. return FALSE;
  233. }
  234. else if (err == 2220) sStatus = 1;
  235. else sStatus = 1;
  236. #ifdef _DEBUG
  237. TCHAR tErr[20];
  238. swprintf(tErr, L"Error = %d\n\r", err);
  239. TRACE(tErr);
  240. #endif
  241. pApp->m_csGroupName.ReleaseBuffer();
  242. pApp->m_csServer.ReleaseBuffer();
  243. void* pTemp = ppMembers;
  244. // clean up names buffer
  245. while (uCount > 0)
  246. {
  247. GlobalFree(ppMembers->lgrmi0_sid);
  248. ppMembers++;
  249. uCount--;
  250. }
  251. free(pTemp);
  252. }
  253. if (pApp->m_csCmdLine != L"") //cmdline - no restart
  254. {
  255. if (pApp->m_sMode == 0)//create new
  256. {
  257. if (sStatus == 0) uiMessage = IDS_SUCCESS;
  258. else uiMessage = IDS_CANT_ADD_NAMES;
  259. }
  260. else // modify
  261. {
  262. if (sStatus == 0) uiMessage = IDS_SUCCESS;
  263. else uiMessage = IDS_CANT_ADD_NAMES;
  264. }
  265. AfxMessageBox(uiMessage);
  266. return CPropertyPage::OnWizardFinish();
  267. }
  268. else
  269. {
  270. if (pApp->m_sMode == 0)//create new
  271. {
  272. if (sStatus == 0)
  273. {
  274. // clear out old values
  275. pApp->m_csGroupName = L"";
  276. pApp->m_csGroupDesc = L"";
  277. uiMessage = IDS_SUCCESS_CREATE_RETRY;
  278. }
  279. else uiMessage = IDS_CANT_ADD_NAMES_CREATE_RETRY;
  280. }
  281. else // modify
  282. {
  283. if (sStatus == 0)
  284. {
  285. // clear out old values
  286. pApp->m_csGroupName = L"";
  287. pApp->m_csGroupDesc = L"";
  288. uiMessage = IDS_SUCCESS_MODIFY_RETRY;
  289. }
  290. else uiMessage = IDS_CANT_ADD_NAMES_MODIFY_RETRY;
  291. }
  292. if (AfxMessageBox(uiMessage, MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
  293. {
  294. // clear out old info
  295. pApp->m_csaNames.RemoveAll();
  296. pApp->bRestart1 = TRUE;
  297. pApp->bRestart2 = TRUE;
  298. pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK);
  299. pApp->m_cps1.SetActivePage(1);
  300. return FALSE;
  301. }
  302. }
  303. return CPropertyPage::OnWizardFinish();
  304. }
  305. void InitLsaString(PLSA_UNICODE_STRING LsaString, LPWSTR String)
  306. {
  307. DWORD StringLength;
  308. if (String == NULL)
  309. {
  310. LsaString->Buffer = NULL;
  311. LsaString->Length = 0;
  312. LsaString->MaximumLength = 0;
  313. return;
  314. }
  315. StringLength = wcslen(String);
  316. LsaString->Buffer = String;
  317. LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
  318. LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
  319. }
  320. NTSTATUS OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle)
  321. {
  322. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  323. LSA_UNICODE_STRING ServerString;
  324. PLSA_UNICODE_STRING Server = NULL;
  325. //
  326. // Always initialize the object attributes to all zeroes.
  327. //
  328. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  329. if (ServerName != NULL)
  330. {
  331. //
  332. // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
  333. //
  334. InitLsaString(&ServerString, ServerName);
  335. Server = &ServerString;
  336. }
  337. //
  338. // Attempt to open the policy.
  339. //
  340. return LsaOpenPolicy(
  341. Server,
  342. &ObjectAttributes,
  343. DesiredAccess,
  344. PolicyHandle);
  345. }
  346. void CFinish::OnShowWindow(BOOL bShow, UINT nStatus)
  347. {
  348. CPropertyPage::OnShowWindow(bShow, nStatus);
  349. CRomaineApp* pApp = (CRomaineApp*)AfxGetApp();
  350. if (bShow)
  351. {
  352. if (pApp->m_nGroupType == 1)
  353. m_csGroupType.LoadString(IDS_LOCAL_GROUP);
  354. else
  355. m_csGroupType.LoadString(IDS_GLOBAL_GROUP);
  356. m_csGroupType += pApp->m_csGroupName;
  357. if (pApp->m_bDomain)
  358. m_csGroupLocation = pApp->m_csDomain;
  359. else
  360. m_csGroupLocation = pApp->m_csServer;
  361. if (pApp->m_sMode == 1)
  362. {
  363. m_csStaticText1.LoadString(IDS_MODIFY_TEXT);
  364. m_csStaticText2.LoadString(IDS_MODIFY_TEXT2);
  365. }
  366. else
  367. {
  368. m_csStaticText1.LoadString(IDS_CREATE_TEXT);
  369. m_csStaticText2.LoadString(IDS_CREATE_TEXT2);
  370. }
  371. UpdateData(FALSE);
  372. }
  373. }
  374. void CFinish::OnPaint()
  375. {
  376. CPaintDC dc(this); // device context for painting
  377. CTransBmp* pBitmap = new CTransBmp;
  378. pBitmap->LoadBitmap(IDB_END_FLAG);
  379. pBitmap->DrawTrans(&dc, 0,0);
  380. delete pBitmap;
  381. }
  382. LRESULT CFinish::OnWizardBack()
  383. {
  384. CRomaineApp* pApp = (CRomaineApp*)AfxGetApp();
  385. pApp->m_cps1.SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
  386. if (pApp->m_nGroupType == 0) return IDD_GLOBAL_USERS;
  387. else return IDD_LOCAL_USERS;
  388. }
  389. // im using the LSA functions as the std LookupAccountName doesn't work on Local Users
  390. /*
  391. LSA_HANDLE Policy_Handle;
  392. NTSTATUS Status;
  393. LPTSTR lpServer = pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength());
  394. Status = OpenPolicy(lpServer, POLICY_LOOKUP_NAMES, &Policy_Handle);
  395. // Did OpenPolicy work?
  396. if (Status != STATUS_SUCCESS)
  397. {
  398. AfxMessageBox(IDS_CANT_ADD_NAMES);
  399. pApp->m_csServer.ReleaseBuffer();
  400. return CPropertyPage::OnWizardFinish();
  401. }
  402. POSITION pos;
  403. CString csName;
  404. LPWSTR lpName;
  405. USHORT uCount = 0;
  406. LSA_UNICODE_STRING lusName;
  407. PLSA_UNICODE_STRING plusName = NULL;
  408. BYTE domainbuffer[1000];
  409. PLSA_REFERENCED_DOMAIN_LIST lsarDomainList = (PLSA_REFERENCED_DOMAIN_LIST)&domainbuffer;
  410. BYTE sidbuffer[100];
  411. PLSA_TRANSLATED_SID lsatSID = (PLSA_TRANSLATED_SID)&sidbuffer;
  412. for (pos = pApp->m_csaNames.GetHeadPosition(); pos != NULL;)
  413. {
  414. csName = pApp->m_csaNames.GetNext(pos);
  415. lpName = csName.GetBuffer(csName.GetLength());
  416. InitLsaString(&lusName, lpName); // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
  417. plusName = &lusName;
  418. Status = LsaLookupNames(Policy_Handle,
  419. 1, // count
  420. plusName, // LSA_UNICODE_STRING
  421. &lsarDomainList,
  422. &lsatSID);
  423. ULONG uErr = LsaNtStatusToWinError(Status);
  424. if (!uErr) // success
  425. {
  426. NetLocalGroupAddMember(lpServer,
  427. pApp->m_csGroupName.GetBuffer(pApp->m_csGroupName.GetLength()),
  428. }
  429. csName.ReleaseBuffer();
  430. }
  431. pApp->m_csServer.ReleaseBuffer();
  432. */
  433. /* BYTE sidbuffer[100];
  434. PSID pSID = (PSID)&sidbuffer;
  435. DWORD cbSID = 100;
  436. TCHAR domainBuffer[80];
  437. DWORD domainBufferSize = 80;
  438. SID_NAME_USE snu;
  439. BOOL bRet = LookupAccountName((const TCHAR*)pApp->m_csServer,
  440. L"Guest",
  441. pSID,
  442. &cbSID,
  443. domainBuffer,
  444. &domainBufferSize,
  445. &snu);
  446. TRACE(L"blob"); */