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.

1940 lines
40 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. usrbrows.cpp
  5. Abstract:
  6. User Browser Dialog
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include <iiscnfgp.h>
  18. #include "comprop.h"
  19. #include "objpick.h"
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char BASED_CODE THIS_FILE[] = __FILE__;
  23. #endif
  24. extern "C"
  25. {
  26. #define _NTSEAPI_ // Don't want the security API hdrs
  27. #include <getuser.h>
  28. }
  29. #define SZ_USER_CLASS _T("user")
  30. #define SZ_GROUP_CLASS _T("group")
  31. BOOL
  32. CAccessEntry::LookupAccountSid(
  33. OUT CString & strFullUserName,
  34. OUT int & nPictureID,
  35. IN PSID pSid,
  36. IN LPCTSTR lpstrSystemName /* OPTIONAL */
  37. )
  38. /*++
  39. Routine Description:
  40. Get a full user name and picture ID from the SID
  41. Arguments:
  42. CString &strFullUserName : Returns the user name
  43. int & nPictureID : Returns offset into the imagemap that
  44. represents the account type.
  45. PSID pSid : Input SID pointer
  46. LPCTSTR lpstrSystemName : System name or NULL
  47. Return Value:
  48. TRUE for success, FALSE for failure.
  49. --*/
  50. {
  51. DWORD cbUserName = PATHLEN * sizeof(TCHAR);
  52. DWORD cbRefDomainName = PATHLEN * sizeof(TCHAR);
  53. CString strUserName;
  54. CString strRefDomainName;
  55. SID_NAME_USE SidToNameUse;
  56. LPTSTR lpUserName = strUserName.GetBuffer(PATHLEN);
  57. LPTSTR lpRefDomainName = strRefDomainName.GetBuffer(PATHLEN);
  58. BOOL fLookUpOK = ::LookupAccountSid(
  59. lpstrSystemName,
  60. pSid,
  61. lpUserName,
  62. &cbUserName,
  63. lpRefDomainName,
  64. &cbRefDomainName,
  65. &SidToNameUse
  66. );
  67. strUserName.ReleaseBuffer();
  68. strRefDomainName.ReleaseBuffer();
  69. strFullUserName.Empty();
  70. if (fLookUpOK)
  71. {
  72. if (!strRefDomainName.IsEmpty()
  73. && strRefDomainName.CompareNoCase(_T("BUILTIN")))
  74. {
  75. strFullUserName += strRefDomainName;
  76. strFullUserName += "\\";
  77. }
  78. strFullUserName += strUserName;
  79. nPictureID = SidToNameUse;
  80. }
  81. else
  82. {
  83. strFullUserName.LoadString(IDS_UNKNOWN_USER);
  84. nPictureID = SidTypeUnknown;
  85. }
  86. //
  87. // SID_NAME_USE is 1-based
  88. //
  89. --nPictureID ;
  90. return fLookUpOK;
  91. }
  92. CAccessEntry::CAccessEntry(
  93. IN LPVOID pAce,
  94. IN BOOL fResolveSID
  95. )
  96. /*++
  97. Routine Description:
  98. Construct from an ACE
  99. Arguments:
  100. LPVOID pAce : Pointer to ACE object
  101. BOOL fResolveSID : TRUE to resolve the SID immediately
  102. Return Value:
  103. N/A
  104. --*/
  105. : m_pSid(NULL),
  106. m_fSIDResolved(FALSE),
  107. m_fDeletable(TRUE),
  108. m_fInvisible(FALSE),
  109. m_nPictureID(SidTypeUnknown-1), // SID_NAME_USE is 1-based
  110. m_lpstrSystemName(NULL),
  111. m_accMask(0L),
  112. m_fDeleted(FALSE),
  113. m_strUserName()
  114. {
  115. MarkEntryAsClean();
  116. PACE_HEADER ph = (PACE_HEADER)pAce;
  117. PSID pSID = NULL;
  118. switch(ph->AceType)
  119. {
  120. case ACCESS_ALLOWED_ACE_TYPE:
  121. pSID = (PSID)&((PACCESS_ALLOWED_ACE)pAce)->SidStart;
  122. m_accMask = ((PACCESS_ALLOWED_ACE)pAce)->Mask;
  123. break;
  124. case ACCESS_DENIED_ACE_TYPE:
  125. case SYSTEM_AUDIT_ACE_TYPE:
  126. case SYSTEM_ALARM_ACE_TYPE:
  127. default:
  128. //
  129. // Not supported!
  130. //
  131. ASSERT(FALSE);
  132. break;
  133. }
  134. if (pSID == NULL)
  135. {
  136. return;
  137. }
  138. //
  139. // Allocate a new copy of the sid.
  140. //
  141. DWORD cbSize = ::RtlLengthSid(pSID);
  142. m_pSid = (PSID)AllocMem(cbSize);
  143. DWORD err = ::RtlCopySid(cbSize, m_pSid, pSID);
  144. ASSERT(err == ERROR_SUCCESS);
  145. //
  146. // Only the non-deletable administrators have execute
  147. // privileges
  148. //
  149. m_fDeletable = (m_accMask & FILE_EXECUTE) == 0L;
  150. //
  151. // Enum_keys is a special access right that literally "everyone"
  152. // has, but it doesn't designate an operator, so it should not
  153. // show up in the operator list if this is the only right it has.
  154. //
  155. m_fInvisible = (m_accMask == MD_ACR_ENUM_KEYS);
  156. //SetAccessMask(lpAccessEntry);
  157. if (fResolveSID)
  158. {
  159. ResolveSID();
  160. }
  161. }
  162. CAccessEntry::CAccessEntry(
  163. IN ACCESS_MASK accPermissions,
  164. IN PSID pSid,
  165. IN LPCTSTR lpstrSystemName, OPTIONAL
  166. IN BOOL fResolveSID
  167. )
  168. /*++
  169. Routine Description:
  170. Constructor from access permissions and SID.
  171. Arguments:
  172. ACCESS_MASK accPermissions : Access mask
  173. PSID pSid : Pointer to SID
  174. LPCTSTR lpstrSystemName : Optional system name
  175. BOOL fResolveSID : TRUE to resolve SID immediately
  176. Return Value:
  177. N/A
  178. --*/
  179. : m_pSid(NULL),
  180. m_fSIDResolved(FALSE),
  181. m_fDeletable(TRUE),
  182. m_fInvisible(FALSE),
  183. m_fDeleted(FALSE),
  184. m_nPictureID(SidTypeUnknown-1), // SID_NAME_USE is 1-based
  185. m_strUserName(),
  186. m_lpstrSystemName(NULL),
  187. m_accMask(accPermissions)
  188. {
  189. MarkEntryAsClean();
  190. //
  191. // Allocate a new copy of the sid.
  192. //
  193. DWORD cbSize = ::RtlLengthSid(pSid);
  194. m_pSid = (PSID)AllocMem(cbSize);
  195. DWORD err = ::RtlCopySid(cbSize, m_pSid, pSid);
  196. ASSERT(err == ERROR_SUCCESS);
  197. if (lpstrSystemName != NULL)
  198. {
  199. m_lpstrSystemName = AllocTString(::lstrlen(lpstrSystemName) + 1);
  200. ::lstrcpy(m_lpstrSystemName, lpstrSystemName);
  201. }
  202. if (fResolveSID)
  203. {
  204. TRACEEOLID("Bogus SID");
  205. ResolveSID();
  206. }
  207. }
  208. CAccessEntry::CAccessEntry(
  209. IN PSID pSid,
  210. IN LPCTSTR pszUserName,
  211. IN LPCTSTR pszClassName
  212. )
  213. : m_pSid(NULL),
  214. m_fSIDResolved(pszUserName != NULL),
  215. m_fDeletable(TRUE),
  216. m_fInvisible(FALSE),
  217. m_fDeleted(FALSE),
  218. m_nPictureID(SidTypeUnknown-1), // SID_NAME_USE is 1-based
  219. m_strUserName(pszUserName),
  220. m_lpstrSystemName(NULL),
  221. m_accMask(0)
  222. {
  223. MarkEntryAsClean();
  224. //
  225. // Allocate a new copy of the sid.
  226. //
  227. DWORD cbSize = ::RtlLengthSid(pSid);
  228. m_pSid = (PSID)AllocMem(cbSize);
  229. DWORD err = ::RtlCopySid(cbSize, m_pSid, pSid);
  230. ASSERT(err == ERROR_SUCCESS);
  231. if (lstrcmpi(SZ_USER_CLASS, pszClassName) == 0)
  232. m_nPictureID = SidTypeUser - 1;
  233. else if (lstrcmpi(SZ_GROUP_CLASS, pszClassName) == 0)
  234. m_nPictureID = SidTypeGroup - 1;
  235. }
  236. CAccessEntry::CAccessEntry(
  237. IN CAccessEntry& ae
  238. )
  239. : m_fSIDResolved(ae.m_fSIDResolved),
  240. m_fDeletable(ae.m_fDeletable),
  241. m_fInvisible(ae.m_fInvisible),
  242. m_fDeleted(ae.m_fDeleted),
  243. m_fDirty(ae.m_fDirty),
  244. m_nPictureID(ae.m_nPictureID),
  245. m_strUserName(ae.m_strUserName),
  246. m_lpstrSystemName(ae.m_lpstrSystemName),
  247. m_accMask(ae.m_accMask)
  248. {
  249. DWORD cbSize = ::RtlLengthSid(ae.m_pSid);
  250. m_pSid = (PSID)AllocMem(cbSize);
  251. DWORD err = ::RtlCopySid(cbSize, m_pSid, ae.m_pSid);
  252. ASSERT(err == ERROR_SUCCESS);
  253. }
  254. CAccessEntry::~CAccessEntry()
  255. /*++
  256. Routine Description:
  257. Destructor
  258. Arguments:
  259. N/A
  260. Return Value:
  261. N/A
  262. --*/
  263. {
  264. TRACEEOLID(_T("Destroying local copy of the SID"));
  265. ASSERT(m_pSid != NULL);
  266. FreeMem(m_pSid);
  267. if (m_lpstrSystemName != NULL)
  268. {
  269. FreeMem(m_lpstrSystemName);
  270. }
  271. }
  272. BOOL
  273. CAccessEntry::ResolveSID()
  274. /*++
  275. Routine Description:
  276. Look up the user name and type.
  277. Arguments:
  278. None
  279. Return Value:
  280. TRUE for success, FALSE for failure.
  281. Notes:
  282. This could take some time.
  283. --*/
  284. {
  285. //
  286. // Even if it fails, it will be considered
  287. // resolved
  288. //
  289. m_fSIDResolved = TRUE;
  290. return CAccessEntry::LookupAccountSid(
  291. m_strUserName,
  292. m_nPictureID,
  293. m_pSid,
  294. m_lpstrSystemName
  295. );
  296. }
  297. void
  298. CAccessEntry::AddPermissions(
  299. IN ACCESS_MASK accNewPermissions
  300. )
  301. /*++
  302. Routine Description:
  303. Add permissions to this entry.
  304. Arguments:
  305. ACCESS_MASK accNewPermissions : New access permissions to be added
  306. Return Value:
  307. None.
  308. --*/
  309. {
  310. m_accMask |= accNewPermissions;
  311. m_fInvisible = (m_accMask == MD_ACR_ENUM_KEYS);
  312. m_fDeletable = (m_accMask & FILE_EXECUTE) == 0L;
  313. MarkEntryAsChanged();
  314. }
  315. void
  316. CAccessEntry::RemovePermissions(
  317. IN ACCESS_MASK accPermissions
  318. )
  319. /*++
  320. Routine Description:
  321. Remove permissions from this entry.
  322. Arguments:
  323. ACCESS_MASK accPermissions : Access permissions to be taken away
  324. --*/
  325. {
  326. m_accMask &= ~accPermissions;
  327. MarkEntryAsChanged();
  328. }
  329. //
  330. // Helper Functions
  331. //
  332. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  333. PSID
  334. GetOwnerSID()
  335. /*++
  336. Routine Description:
  337. Return a pointer to the primary owner SID we're using.
  338. Arguments:
  339. None
  340. Return Value:
  341. Pointer to owner SID.
  342. --*/
  343. {
  344. PSID pSID = NULL;
  345. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  346. if (!::AllocateAndInitializeSid(
  347. &NtAuthority,
  348. 2,
  349. SECURITY_BUILTIN_DOMAIN_RID,
  350. DOMAIN_ALIAS_RID_ADMINS,
  351. 0, 0, 0, 0, 0, 0,
  352. &pSID
  353. ))
  354. {
  355. TRACEEOLID("Unable to get primary SID " << ::GetLastError());
  356. }
  357. return pSID;
  358. }
  359. BOOL
  360. BuildAclBlob(
  361. IN CObListPlus & oblSID,
  362. OUT CBlob & blob
  363. )
  364. /*++
  365. Routine Description:
  366. Build a security descriptor blob from the access entries in the oblist
  367. Arguments:
  368. CObListPlus & oblSID : Input list of access entries
  369. CBlob & blob : Output blob
  370. Return Value:
  371. TRUE if the list is dirty. If the list had no entries marked
  372. as dirty, the blob generated will be empty, and this function will
  373. return FALSE.
  374. Notes:
  375. Entries marked as deleted will not be added to the list.
  376. --*/
  377. {
  378. ASSERT(blob.IsEmpty());
  379. BOOL fAclDirty = FALSE;
  380. CAccessEntry * pEntry;
  381. DWORD dwAclSize = sizeof(ACL) - sizeof(DWORD);
  382. CObListIter obli(oblSID);
  383. int cItems = 0;
  384. while(pEntry = (CAccessEntry *)obli.Next())
  385. {
  386. if (!pEntry->IsDeleted())
  387. {
  388. dwAclSize += GetLengthSid(pEntry->GetSid());
  389. dwAclSize += sizeof(ACCESS_ALLOWED_ACE);
  390. ++cItems;
  391. }
  392. if (pEntry->IsDirty())
  393. {
  394. fAclDirty = TRUE;
  395. }
  396. }
  397. if (fAclDirty)
  398. {
  399. //
  400. // Build the acl
  401. //
  402. PACL pacl = NULL;
  403. try
  404. {
  405. if (cItems > 0 && dwAclSize > 0)
  406. {
  407. pacl = (PACL)AllocMem(dwAclSize);
  408. if (InitializeAcl(pacl, dwAclSize, ACL_REVISION))
  409. {
  410. obli.Reset();
  411. while(pEntry = (CAccessEntry *)obli.Next())
  412. {
  413. if (!pEntry->IsDeleted())
  414. {
  415. BOOL f = AddAccessAllowedAce(
  416. pacl,
  417. ACL_REVISION,
  418. pEntry->QueryAccessMask(),
  419. pEntry->GetSid()
  420. );
  421. ASSERT(f);
  422. }
  423. }
  424. }
  425. }
  426. //
  427. // Build the security descriptor
  428. //
  429. PSECURITY_DESCRIPTOR pSD =
  430. (PSECURITY_DESCRIPTOR)AllocMem(SECURITY_DESCRIPTOR_MIN_LENGTH);
  431. VERIFY(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION));
  432. VERIFY(SetSecurityDescriptorDacl(pSD, TRUE, pacl, FALSE));
  433. //
  434. // Set owner and primary group
  435. //
  436. PSID pSID = GetOwnerSID();
  437. ASSERT(pSID);
  438. VERIFY(SetSecurityDescriptorOwner(pSD, pSID, TRUE));
  439. VERIFY(SetSecurityDescriptorGroup(pSD, pSID, TRUE));
  440. //
  441. // Convert to self-relative
  442. //
  443. PSECURITY_DESCRIPTOR pSDSelfRelative = NULL;
  444. DWORD dwSize = 0L;
  445. MakeSelfRelativeSD(pSD, pSDSelfRelative, &dwSize);
  446. pSDSelfRelative = AllocMem(dwSize);
  447. MakeSelfRelativeSD(pSD, pSDSelfRelative, &dwSize);
  448. //
  449. // Blob takes ownership
  450. //
  451. blob.SetValue(dwSize, (PBYTE)pSDSelfRelative, FALSE);
  452. //
  453. // Clean up
  454. //
  455. FreeMem(pSD);
  456. FreeSid(pSID);
  457. }
  458. catch(CMemoryException * e)
  459. {
  460. e->ReportError();
  461. e->Delete();
  462. }
  463. }
  464. return fAclDirty;
  465. }
  466. DWORD
  467. BuildAclOblistFromBlob(
  468. IN CBlob & blob,
  469. OUT CObListPlus & oblSID
  470. )
  471. /*++
  472. Routine Description:
  473. Build an oblist of access entries from a security descriptor blob
  474. Arguments:
  475. CBlob & blob : Input blob
  476. CObListPlus & oblSID : Output oblist of access entries
  477. Return Value:
  478. Error return code
  479. --*/
  480. {
  481. PSECURITY_DESCRIPTOR pSD = NULL;
  482. if (!blob.IsEmpty())
  483. {
  484. pSD = (PSECURITY_DESCRIPTOR)blob.GetData();
  485. }
  486. if (pSD == NULL)
  487. {
  488. //
  489. // Empty...
  490. //
  491. return ERROR_SUCCESS;
  492. }
  493. if (!IsValidSecurityDescriptor(pSD))
  494. {
  495. return ::GetLastError();
  496. }
  497. ASSERT(GetSecurityDescriptorLength(pSD) == blob.GetSize());
  498. PACL pacl;
  499. BOOL fDaclPresent;
  500. BOOL fDaclDef;
  501. VERIFY(GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pacl, &fDaclDef));
  502. if (!fDaclPresent || pacl == NULL)
  503. {
  504. return ERROR_SUCCESS;
  505. }
  506. if (!IsValidAcl(pacl))
  507. {
  508. return GetLastError();
  509. }
  510. CError err;
  511. for (WORD w = 0; w < pacl->AceCount; ++w)
  512. {
  513. PVOID pAce;
  514. if (GetAce(pacl, w, &pAce))
  515. {
  516. CAccessEntry * pEntry = new CAccessEntry(pAce, TRUE);
  517. oblSID.AddTail(pEntry);
  518. }
  519. else
  520. {
  521. //
  522. // Save last error, but continue
  523. //
  524. err.GetLastWinError();
  525. }
  526. }
  527. //
  528. // Return last error
  529. //
  530. return err;
  531. }
  532. //
  533. // CAccessEntryListBox - a listbox of user SIDs
  534. //
  535. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  536. IMPLEMENT_DYNAMIC(CAccessEntryListBox, CRMCListBox);
  537. const int CAccessEntryListBox::nBitmaps = 8;
  538. void
  539. CAccessEntryListBox::DrawItemEx(
  540. IN CRMCListBoxDrawStruct& ds
  541. )
  542. /*++
  543. Routine Description:
  544. Draw item in the listbox
  545. Arguments:
  546. CRMCListBoxDrawStruct & ds : Input data structure
  547. Return Value:
  548. N/A
  549. --*/
  550. {
  551. CAccessEntry * pEntry = (CAccessEntry *)ds.m_ItemData;
  552. ASSERT(pEntry != NULL);
  553. ASSERT(pEntry->IsSIDResolved());
  554. DrawBitmap(ds, 0, pEntry->QueryPictureID());
  555. ColumnText(ds, 0, TRUE, pEntry->QueryUserName());
  556. }
  557. void
  558. CAccessEntryListBox::FillAccessListBox(
  559. IN CObListPlus & obl
  560. )
  561. /*++
  562. Routine Description:
  563. Fill a listbox with entries from the oblist.
  564. Entries will not be shown if the deleted flag is set, or if
  565. their access mask does not fit with the requested access mask.
  566. Arguments:
  567. CObListPlus & obl : List of access entries
  568. Return Value:
  569. None.
  570. --*/
  571. {
  572. CObListIter obli(obl);
  573. CAccessEntry * pAccessEntry;
  574. //
  575. // Remember the selection.
  576. //
  577. CAccessEntry * pSelEntry = GetSelectedItem();
  578. SetRedraw(FALSE);
  579. ResetContent();
  580. int cItems = 0;
  581. for ( /**/ ; pAccessEntry = (CAccessEntry *)obli.Next(); ++cItems)
  582. {
  583. if (pAccessEntry->IsVisible() && !pAccessEntry->IsDeleted())
  584. {
  585. AddItem(pAccessEntry);
  586. }
  587. }
  588. SetRedraw(TRUE);
  589. SelectItem(pSelEntry);
  590. }
  591. void
  592. CAccessEntryListBox::ResolveAccessList(
  593. IN CObListPlus &obl
  594. )
  595. /*++
  596. Routine Description:
  597. For each member of the list, resolve the SID into a username.
  598. Arguments:
  599. CObListPlus & obl : List of access entries
  600. Return Value:
  601. None.
  602. --*/
  603. {
  604. CObListIter obli(obl);
  605. CAccessEntry * pAccessEntry;
  606. while (pAccessEntry = (CAccessEntry *)obli.Next())
  607. {
  608. if (!pAccessEntry->IsSIDResolved())
  609. {
  610. pAccessEntry->ResolveSID();
  611. }
  612. }
  613. }
  614. BOOL
  615. CAccessEntryListBox::AddUserPermissions(
  616. IN LPCTSTR lpstrServer,
  617. IN CObListPlus &oblSID,
  618. IN CAccessEntry * newUser,
  619. IN ACCESS_MASK accPermissions
  620. )
  621. /*++
  622. Routine Description:
  623. Add a user to the service list. The return value is
  624. the what would be its listbox index.
  625. Arguments:
  626. LPCTSTR lpstrServer : Server name
  627. CObListPlus &oblSID : List of SIDs
  628. LPUSERDETAILS pusdtNewUser : User details from user browser
  629. ACCESS_MASK accPermissions : Access permissions
  630. Return Value:
  631. TRUE for success, FALSE for failure.
  632. --*/
  633. {
  634. CAccessEntry * pAccessEntry;
  635. //
  636. // Look it up in the list to see if it exists already
  637. //
  638. CObListIter obli(oblSID);
  639. while(pAccessEntry = (CAccessEntry *)obli.Next())
  640. {
  641. if (*pAccessEntry == newUser->GetSid())
  642. {
  643. TRACEEOLID("Found existing account -- adding permissions");
  644. if (pAccessEntry->IsDeleted())
  645. {
  646. //
  647. // Back again..
  648. //
  649. pAccessEntry->FlagForDeletion(FALSE);
  650. }
  651. break;
  652. }
  653. }
  654. if (pAccessEntry == NULL)
  655. {
  656. // I am creating new entry here to be sure that I could delete it from
  657. // the input array. SID is copied to new entry.
  658. pAccessEntry = new CAccessEntry(*newUser);
  659. if (pAccessEntry == NULL)
  660. return FALSE;
  661. pAccessEntry->MarkEntryAsNew();
  662. oblSID.AddTail(pAccessEntry);
  663. }
  664. pAccessEntry->AddPermissions(accPermissions);
  665. return TRUE;
  666. }
  667. BOOL
  668. CAccessEntryListBox::AddToAccessList(
  669. IN CWnd * pWnd,
  670. IN LPCTSTR lpstrServer,
  671. OUT CObListPlus & obl
  672. )
  673. /*++
  674. Routine Description:
  675. Bring up the Add Users and Groups dialogs from netui.
  676. Arguments:
  677. CWnd * pWnd : Parent window
  678. LPCTSTR lpstrServer : Server that owns the accounts
  679. CObListPlus & obl : Returns the list of selected users.
  680. Return Value:
  681. TRUE if anything was added, FALSE otherwise.
  682. --*/
  683. {
  684. CGetUsers usrBrowser(lpstrServer, TRUE);
  685. BOOL bRes = usrBrowser.GetUsers(pWnd->GetSafeHwnd());
  686. UINT cItems = 0;
  687. if (bRes)
  688. {
  689. //
  690. // Specify access mask for an operator
  691. //
  692. ACCESS_MASK accPermissions =
  693. (MD_ACR_READ | MD_ACR_WRITE | MD_ACR_ENUM_KEYS);
  694. for (int i = 0; i < usrBrowser.GetSize(); i++)
  695. {
  696. if (!AddUserPermissions(lpstrServer, obl, usrBrowser[i], accPermissions))
  697. {
  698. bRes = FALSE;
  699. break;
  700. }
  701. cItems++;
  702. }
  703. }
  704. if (cItems > 0)
  705. {
  706. FillAccessListBox(obl);
  707. }
  708. return bRes;
  709. #if 0
  710. USERBROWSER ub;
  711. CError err;
  712. //
  713. // Specify access mask for an operator
  714. //
  715. ACCESS_MASK accPermissions =
  716. (MD_ACR_READ | MD_ACR_WRITE | MD_ACR_ENUM_KEYS);
  717. CString strDomain(lpstrServer);
  718. //
  719. // Ensure the computer name starts with
  720. // backslashes
  721. //
  722. if (strDomain[0] != _T('\\'))
  723. {
  724. strDomain = _T("\\\\") + strDomain;
  725. }
  726. CString strTitle;
  727. VERIFY(strTitle.LoadString(IDS_SELECT_ADMIN));
  728. ub.ulStructSize = sizeof(ub);
  729. ub.fUserCancelled = FALSE;
  730. ub.fExpandNames = FALSE;
  731. ub.hwndOwner = pWnd ? pWnd->m_hWnd : NULL;
  732. ub.pszTitle = NULL;
  733. ub.pszInitialDomain = (LPTSTR)(LPCTSTR)strDomain;
  734. ub.Flags = USRBROWS_INCL_EVERYONE
  735. | USRBROWS_SHOW_ALL
  736. | USRBROWS_EXPAND_USERS;
  737. ub.pszHelpFileName = NULL;
  738. ub.ulHelpContext = IDHELP_MULT_USRBROWSER;
  739. CWinApp * pApp = ::AfxGetApp();
  740. ASSERT(pApp);
  741. if (pApp)
  742. {
  743. ub.pszHelpFileName = (LPTSTR)(LPCTSTR)pApp->m_pszHelpFilePath;
  744. }
  745. HUSERBROW hUserBrowser = ::OpenUserBrowser(&ub);
  746. if (hUserBrowser == NULL)
  747. {
  748. err.GetLastWinError();
  749. err.MessageBoxOnFailure(MB_OK | MB_ICONHAND);
  750. return FALSE;
  751. }
  752. int cItems = 0;
  753. if (!ub.fUserCancelled)
  754. {
  755. //
  756. // Selected users are granted the new privilege
  757. //
  758. try
  759. {
  760. //
  761. // We break out of this loop ourselves
  762. //
  763. for ( ;; )
  764. {
  765. LPUSERDETAILS pusdtNewUser;
  766. DWORD cbSize;
  767. //
  768. // First call should always fail, but tell
  769. // us the size required.
  770. //
  771. cbSize = 0;
  772. EnumUserBrowserSelection(hUserBrowser, NULL, &cbSize);
  773. err.GetLastWinError();
  774. if (err.Win32Error() == ERROR_NO_MORE_ITEMS)
  775. {
  776. //
  777. // All done
  778. //
  779. err.Reset();
  780. break;
  781. }
  782. if (err.Win32Error() == ERROR_INSUFFICIENT_BUFFER)
  783. {
  784. err.Reset();
  785. }
  786. if (err.Failed())
  787. {
  788. break;
  789. }
  790. //
  791. // The EnumUserBrowserSelection API has a bug in which
  792. // the size returned might actually by insufficient.
  793. //
  794. cbSize += 100;
  795. TRACEEOLID("Enum structure size requested is " << cbSize);
  796. pusdtNewUser = (LPUSERDETAILS)AllocMem(cbSize);
  797. if (pusdtNewUser == NULL)
  798. {
  799. err.GetLastWinError();
  800. break;
  801. }
  802. if (!EnumUserBrowserSelection(
  803. hUserBrowser,
  804. pusdtNewUser,
  805. &cbSize
  806. ))
  807. {
  808. err.GetLastWinError();
  809. break;
  810. }
  811. TRACEEOLID("Adding user " << pusdtNewUser->pszAccountName);
  812. AddUserPermissions(
  813. lpstrServer,
  814. obl,
  815. pusdtNewUser,
  816. accPermissions
  817. );
  818. ++cItems;
  819. FreeMem(pusdtNewUser);
  820. if (err.Failed())
  821. {
  822. break;
  823. }
  824. }
  825. }
  826. catch(CException * e)
  827. {
  828. err.GetLastWinError();
  829. TRACEEOLID("Exception generated while enumerating users");
  830. e->Delete();
  831. }
  832. }
  833. err.MessageBoxOnFailure();
  834. ::CloseUserBrowser(hUserBrowser);
  835. if (cItems > 0)
  836. {
  837. FillAccessListBox(obl);
  838. return TRUE;
  839. }
  840. return FALSE;
  841. #endif
  842. }
  843. static
  844. int
  845. BrowseCallbackProc(
  846. IN HWND hwnd,
  847. IN UINT uMsg,
  848. IN LPARAM lParam,
  849. IN LPARAM lpData
  850. )
  851. /*++
  852. Routine Description:
  853. Callback function for the folder browser
  854. Arguments:
  855. hwnd : Handle to the browse dialog box. The callback function can
  856. send the following messages to this window:
  857. BFFM_ENABLEOK Enables the OK button if the wParam parameter
  858. is nonzero or disables it if wParam is zero.
  859. BFFM_SETSELECTION Selects the specified folder. The lParam
  860. parameter is the PIDL of the folder to select
  861. if wParam is FALSE, or it is the path of the
  862. folder otherwise.
  863. BFFM_SETSTATUSTEXT Sets the status text to the null-terminated
  864. string specified by the lParam parameter.
  865. uMsg : Value identifying the event. This parameter can be one of the
  866. following values:
  867. 0 Initialize dir path. lParam is the path.
  868. BFFM_INITIALIZED The browse dialog box has finished
  869. initializing. lpData is NULL.
  870. BFFM_SELCHANGED The selection has changed. lpData
  871. is a pointer to the item identifier list for
  872. the newly selected folder.
  873. lParam : Message-specific value. For more information, see the
  874. description of uMsg.
  875. lpData : Application-defined value that was specified in the lParam
  876. member of the BROWSEINFO structure.
  877. Return Value:
  878. 0
  879. --*/
  880. {
  881. static LPCTSTR lpstrDomain = NULL;
  882. switch(uMsg)
  883. {
  884. case 0:
  885. lpstrDomain = (LPCTSTR)lParam;
  886. break;
  887. case BFFM_INITIALIZED:
  888. //
  889. // Dialog initialized -- select desired folder
  890. //
  891. if (lpstrDomain != NULL)
  892. {
  893. ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpstrDomain);
  894. }
  895. break;
  896. }
  897. return 0;
  898. }
  899. CBrowseDomainDlg::CBrowseDomainDlg(
  900. IN CWnd * pParent OPTIONAL,
  901. IN LPCTSTR lpszInitialDomain OPTIONAL
  902. )
  903. /*++
  904. Routine Description:
  905. Constructor for domain browser dialog
  906. Arguments:
  907. CWnd * pParent : Parent window or NULL
  908. LPCTSTR lpszInitialDomain : Initial domain, or NULL
  909. Return Value:
  910. N/A
  911. --*/
  912. : m_strInitialDomain(lpszInitialDomain)
  913. {
  914. VERIFY(m_strTitle.LoadString(IDS_BROWSE_DOMAIN));
  915. m_bi.pidlRoot = NULL;
  916. m_bi.hwndOwner = pParent ? pParent->m_hWnd : NULL;
  917. m_bi.pszDisplayName = m_szBuffer;
  918. m_bi.lpszTitle = m_strTitle;
  919. m_bi.ulFlags = BIF_DONTGOBELOWDOMAIN;
  920. m_bi.lpfn = BrowseCallbackProc;
  921. m_bi.lParam = 0;
  922. //
  923. // Let the callback function know the default dir is
  924. //
  925. lpszInitialDomain = !m_strInitialDomain.IsEmpty()
  926. ? (LPCTSTR)m_strInitialDomain
  927. : NULL;
  928. BrowseCallbackProc(m_bi.hwndOwner, 0, (LPARAM)lpszInitialDomain, NULL);
  929. //
  930. // Only display network items
  931. //
  932. LPITEMIDLIST pidl;
  933. if (SUCCEEDED(::SHGetSpecialFolderLocation(m_bi.hwndOwner,
  934. CSIDL_NETWORK, &pidl)))
  935. {
  936. m_bi.pidlRoot = pidl;
  937. }
  938. }
  939. CBrowseDomainDlg::~CBrowseDomainDlg()
  940. /*++
  941. Routine Description:
  942. Destructor for directory browser dialog
  943. Arguments:
  944. N/A
  945. Return Value:
  946. N/A
  947. --*/
  948. {
  949. if (m_bi.pidlRoot != NULL)
  950. {
  951. LPITEMIDLIST pidl = (LPITEMIDLIST)m_bi.pidlRoot;
  952. //
  953. // Free using shell allocator
  954. //
  955. LPMALLOC pMalloc;
  956. if (::SHGetMalloc(&pMalloc) == NOERROR)
  957. {
  958. pMalloc->Free(pidl);
  959. pMalloc->Release();
  960. }
  961. }
  962. }
  963. /* virtual */
  964. int
  965. CBrowseDomainDlg::DoModal()
  966. /*++
  967. Routine Description:
  968. Display the browser dialog, and fill in the selected domain.
  969. Arguments:
  970. None
  971. Return Value:
  972. IDOK if the OK button was pressed, IDCANCEL otherwise.
  973. --*/
  974. {
  975. BOOL fSelectionMade = FALSE;
  976. //
  977. // Gets the Shell's default allocator
  978. //
  979. LPMALLOC pMalloc;
  980. if (::SHGetMalloc(&pMalloc) == NOERROR)
  981. {
  982. LPITEMIDLIST pidl;
  983. if ((pidl = ::SHBrowseForFolder(&m_bi)) != NULL)
  984. {
  985. //
  986. // m_szBuffer contains the selected path already
  987. //
  988. fSelectionMade = TRUE;
  989. //
  990. // Free the PIDL allocated by SHBrowseForFolder.
  991. //
  992. pMalloc->Free(pidl);
  993. }
  994. //
  995. // Release the shell's allocator.
  996. //
  997. pMalloc->Release();
  998. }
  999. return fSelectionMade ? IDOK : IDCANCEL;
  1000. }
  1001. LPCTSTR
  1002. CBrowseDomainDlg::GetSelectedDomain(
  1003. OUT CString & strName
  1004. ) const
  1005. /*++
  1006. Routine Description:
  1007. Get the selected domain
  1008. Arguments:
  1009. CString & strName : String in which to return the domain
  1010. Return Value:
  1011. A pointer to the domain string or NULL in case of error.
  1012. Notes:
  1013. This function should be called only after the dialog has been dismissed.
  1014. --*/
  1015. {
  1016. LPCTSTR lp = NULL;
  1017. try
  1018. {
  1019. strName = m_szBuffer;
  1020. lp = strName;
  1021. }
  1022. catch(CMemoryException * e)
  1023. {
  1024. TRACEEOLID("!!!exception getting path");
  1025. e->ReportError();
  1026. e->Delete();
  1027. strName.Empty();
  1028. }
  1029. return lp;
  1030. }
  1031. CBrowseUserDlg::CBrowseUserDlg(
  1032. IN CWnd * pParentWnd OPTIONAL,
  1033. IN LPCTSTR lpszTitle,
  1034. IN LPCTSTR lpszInitialDomain,
  1035. IN BOOL fExpandNames,
  1036. IN BOOL fSkipInitialDomainInName,
  1037. IN DWORD dwFlags,
  1038. IN LPCTSTR lpszHelpFileName,
  1039. IN ULONG ulHelpContext
  1040. )
  1041. /*++
  1042. Routine Description:
  1043. Constructor for user browser dialog
  1044. Arguments:
  1045. CWnd * pParentWnd : Parent window
  1046. LPCTSTR lpszTitle : Dialog title text
  1047. LPCTSTR lpszInitialDomain : Initial domain name
  1048. BOOL fExpandNames : Expand the names
  1049. BOOL fSkipInitialDomainInName : Skip the initial domain when expanding
  1050. DWORD dwFlags : Flags
  1051. LPCTSTR lpszHelpFileName : Help file path and name
  1052. ULONG ulHelpContext : Help context ID
  1053. Return Value:
  1054. N/A
  1055. --*/
  1056. : m_fSkipInitialDomainInName(fSkipInitialDomainInName),
  1057. m_strTitle(lpszTitle),
  1058. m_strInitialDomain(lpszInitialDomain),
  1059. m_strHelpFileName(lpszHelpFileName)
  1060. {
  1061. m_ub.ulStructSize = sizeof(m_ub);
  1062. m_ub.fExpandNames = fExpandNames;
  1063. m_ub.hwndOwner = pParentWnd->m_hWnd;
  1064. m_ub.pszTitle = (LPTSTR)(LPCTSTR)m_strTitle;
  1065. m_ub.pszInitialDomain = (LPTSTR)(LPCTSTR)m_strInitialDomain;
  1066. m_ub.Flags = dwFlags;
  1067. m_ub.pszHelpFileName = (LPTSTR)(LPCTSTR)m_strHelpFileName;
  1068. m_ub.ulHelpContext = ulHelpContext;
  1069. }
  1070. /* virtual */
  1071. int
  1072. CBrowseUserDlg::DoModal()
  1073. /*++
  1074. Routine Description:
  1075. Show the user browser dialog
  1076. Arguments:
  1077. None
  1078. Return Value:
  1079. IDOK if the OK button was pressed, IDCANCEL if the dialog
  1080. was cancelled.
  1081. --*/
  1082. {
  1083. CError err;
  1084. m_ub.fUserCancelled = FALSE;
  1085. m_strSelectedAccounts.RemoveAll();
  1086. HUSERBROW hUserBrowser = ::OpenUserBrowser(&m_ub);
  1087. if (hUserBrowser == NULL)
  1088. {
  1089. err.GetLastWinError();
  1090. err.MessageBoxOnFailure(MB_OK | MB_ICONHAND);
  1091. return IDCANCEL;
  1092. }
  1093. if (!m_ub.fUserCancelled)
  1094. {
  1095. try
  1096. {
  1097. CString strInitialDomain(PURE_COMPUTER_NAME(m_ub.pszInitialDomain));
  1098. //
  1099. // We break out of this loop ourselves
  1100. //
  1101. for ( ;; )
  1102. {
  1103. LPUSERDETAILS pusdtNewUser;
  1104. DWORD cbSize;
  1105. //
  1106. // First call should always fail, but tell
  1107. // us the size required.
  1108. //
  1109. cbSize = 0;
  1110. EnumUserBrowserSelection(hUserBrowser, NULL, &cbSize);
  1111. err.GetLastWinError();
  1112. if (err.Win32Error() == ERROR_NO_MORE_ITEMS)
  1113. {
  1114. //
  1115. // All done
  1116. //
  1117. err.Reset();
  1118. break;
  1119. }
  1120. if (err.Win32Error() == ERROR_INSUFFICIENT_BUFFER)
  1121. {
  1122. err.Reset();
  1123. }
  1124. if (err.Failed())
  1125. {
  1126. break;
  1127. }
  1128. //
  1129. // The EnumUserBrowserSelection API has a bug in which
  1130. // the size returned might actually be insufficient.
  1131. //
  1132. cbSize += 100;
  1133. TRACEEOLID("Enum structure size requested is " << cbSize);
  1134. pusdtNewUser = (LPUSERDETAILS)AllocMem(cbSize);
  1135. if (pusdtNewUser == NULL)
  1136. {
  1137. err.GetLastWinError();
  1138. break;
  1139. }
  1140. if (!EnumUserBrowserSelection(
  1141. hUserBrowser,
  1142. pusdtNewUser,
  1143. &cbSize
  1144. ))
  1145. {
  1146. err.GetLastWinError();
  1147. break;
  1148. }
  1149. TRACEEOLID("Adding user " << pusdtNewUser->pszAccountName);
  1150. CString strAccount;
  1151. //
  1152. // If the domain name doesn't match that of the
  1153. // intial domain, add it as well.
  1154. //
  1155. if (!m_fSkipInitialDomainInName ||
  1156. strInitialDomain.CompareNoCase(pusdtNewUser->pszDomainName) != 0)
  1157. {
  1158. strAccount += pusdtNewUser->pszDomainName;
  1159. strAccount += _T('\\');
  1160. }
  1161. strAccount += pusdtNewUser->pszAccountName;
  1162. m_strSelectedAccounts.AddTail(strAccount);
  1163. FreeMem(pusdtNewUser);
  1164. if (err.Failed())
  1165. {
  1166. break;
  1167. }
  1168. }
  1169. }
  1170. catch(CMemoryException * e)
  1171. {
  1172. TRACEEOLID("!!!exception generated while enumerating users");
  1173. err = ERROR_NOT_ENOUGH_MEMORY;
  1174. e->Delete();
  1175. }
  1176. }
  1177. err.MessageBoxOnFailure();
  1178. ::CloseUserBrowser(hUserBrowser);
  1179. return m_ub.fUserCancelled ? IDCANCEL : IDOK;
  1180. }
  1181. //
  1182. // CUserAccountDlg dialog
  1183. //
  1184. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1185. CUserAccountDlg::CUserAccountDlg(
  1186. IN LPCTSTR lpstrServer,
  1187. IN LPCTSTR lpstrUserName,
  1188. IN LPCTSTR lpstrPassword,
  1189. IN CWnd * pParent OPTIONAL
  1190. )
  1191. /*++
  1192. Routine Description:
  1193. Constructor for bringing up the user account dialog
  1194. Arguments:
  1195. LPCTSTR lpstrServer : Server
  1196. LPCTSTR lpstrUserName : Starting Username
  1197. LPCTSTR lpstrPassword : Starting Password
  1198. CWnd * pParent : Parent window handle
  1199. Return Value:
  1200. N/A
  1201. --*/
  1202. : m_strUserName(lpstrUserName),
  1203. m_strPassword(lpstrPassword),
  1204. m_strServer(lpstrServer),
  1205. CDialog(CUserAccountDlg::IDD, pParent)
  1206. {
  1207. //{{AFX_DATA_INIT(CUserAccountDlg)
  1208. //}}AFX_DATA_INIT
  1209. }
  1210. void
  1211. CUserAccountDlg::DoDataExchange(
  1212. IN CDataExchange * pDX
  1213. )
  1214. /*++
  1215. Routine Description:
  1216. Initialise/Store control Data
  1217. Arguments:
  1218. CDataExchange * pDX : DDX/DDV struct
  1219. Return Value:
  1220. None.
  1221. --*/
  1222. {
  1223. CDialog::DoDataExchange(pDX);
  1224. //{{AFX_DATA_MAP(CUserAccountDlg)
  1225. DDX_Control(pDX, IDC_EDIT_USERNAME, m_edit_UserName);
  1226. DDX_Control(pDX, IDC_EDIT_PASSWORD, m_edit_Password);
  1227. //}}AFX_DATA_MAP
  1228. //
  1229. // Private DDX/DDV Routines
  1230. //
  1231. DDX_Text(pDX, IDC_EDIT_USERNAME, m_strUserName);
  1232. DDV_MinMaxChars(pDX, m_strUserName, 1, UNLEN);
  1233. DDX_Password(pDX, IDC_EDIT_PASSWORD, m_strPassword, g_lpszDummyPassword);
  1234. DDV_MaxChars(pDX, m_strPassword, PWLEN);
  1235. }
  1236. //
  1237. // Message Map
  1238. //
  1239. BEGIN_MESSAGE_MAP(CUserAccountDlg, CDialog)
  1240. //{{AFX_MSG_MAP(CUserAccountDlg)
  1241. ON_BN_CLICKED(IDC_BUTTON_BROWSE_USERS, OnButtonBrowseUsers)
  1242. ON_BN_CLICKED(IDC_BUTTON_CHECK_PASSWORD, OnButtonCheckPassword)
  1243. ON_EN_CHANGE(IDC_EDIT_USERNAME, OnChangeEditUsername)
  1244. //}}AFX_MSG_MAP
  1245. END_MESSAGE_MAP()
  1246. //
  1247. // Message Handlers
  1248. //
  1249. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1250. BOOL
  1251. GetIUsrAccount(
  1252. IN LPCTSTR lpstrServer,
  1253. IN CWnd * pParent, OPTIONAL
  1254. OUT CString & str
  1255. )
  1256. /*++
  1257. Routine Description:
  1258. Helper function to browse for IUSR Account
  1259. Arguments:
  1260. LPCTSTR lpstrServer : Server
  1261. CWnd * pParent : Parent window
  1262. CString & str : Will contain the selected account
  1263. Return Value:
  1264. TRUE if an account was selected FALSE if not
  1265. --*/
  1266. {
  1267. CGetUsers usrBrowser(lpstrServer);
  1268. BOOL bRes = usrBrowser.GetUsers(pParent->GetSafeHwnd(), TRUE);
  1269. if (bRes)
  1270. {
  1271. if (usrBrowser.GetSize() != 0)
  1272. {
  1273. str = usrBrowser.GetAt(0)->QueryUserName();
  1274. }
  1275. else
  1276. bRes = FALSE;
  1277. }
  1278. return bRes;
  1279. #if 0
  1280. CString strDomain(lpstrServer);
  1281. //
  1282. // Ensure the computer name starts with
  1283. // backslashes
  1284. //
  1285. if (strDomain[0] != _T('\\'))
  1286. {
  1287. strDomain = _T("\\\\") + strDomain;
  1288. }
  1289. CString strTitle;
  1290. LPCTSTR lpszHelpPath = NULL;
  1291. ULONG ulHelpID = IDHELP_USRBROWSER;
  1292. VERIFY(strTitle.LoadString(IDS_SELECT_IUSR_ACCOUNT));
  1293. CWinApp * pApp = ::AfxGetApp();
  1294. ASSERT(pApp);
  1295. if (pApp)
  1296. {
  1297. lpszHelpPath = pApp->m_pszHelpFilePath;
  1298. }
  1299. CBrowseUserDlg dlg(
  1300. pParent,
  1301. strTitle,
  1302. strDomain,
  1303. FALSE,
  1304. TRUE,
  1305. USRBROWS_EXPAND_USERS
  1306. | USRBROWS_SINGLE_SELECT
  1307. | USRBROWS_SHOW_USERS,
  1308. lpszHelpPath,
  1309. ulHelpID
  1310. );
  1311. if (dlg.DoModal() == IDOK
  1312. && dlg.GetSelectionCount() > 0)
  1313. {
  1314. str = dlg.GetSelectedAccounts().GetHead();
  1315. return TRUE;
  1316. }
  1317. return FALSE;
  1318. #endif
  1319. }
  1320. DWORD
  1321. VerifyUserPassword(
  1322. IN LPCTSTR lpstrUserName,
  1323. IN LPCTSTR lpstrPassword
  1324. )
  1325. /*++
  1326. Routine Description:
  1327. Verify the usernamer password combo checks out
  1328. Arguments:
  1329. LPCTSTR lpstrUserName : Domain/username combo
  1330. LPCTSTR lpstrPassword : Password
  1331. Return Value:
  1332. ERROR_SUCCESS if the password checks out, an error code
  1333. otherwise.
  1334. --*/
  1335. {
  1336. CString strDomain;
  1337. CString strUser(lpstrUserName);
  1338. CString strPassword(lpstrPassword);
  1339. SplitUserNameAndDomain(strUser, strDomain);
  1340. //
  1341. // In order to look up an account name, this process
  1342. // must first be granted the privilege of doing so.
  1343. //
  1344. CError err;
  1345. {
  1346. HANDLE hToken;
  1347. LUID AccountLookupValue;
  1348. TOKEN_PRIVILEGES tkp;
  1349. do
  1350. {
  1351. if (!OpenProcessToken(GetCurrentProcess(),
  1352. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  1353. &hToken)
  1354. )
  1355. {
  1356. err.GetLastWinError();
  1357. break;
  1358. }
  1359. if (!LookupPrivilegeValue(NULL, SE_TCB_NAME, &AccountLookupValue))
  1360. {
  1361. err.GetLastWinError();
  1362. break;
  1363. }
  1364. tkp.PrivilegeCount = 1;
  1365. tkp.Privileges[0].Luid = AccountLookupValue;
  1366. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  1367. AdjustTokenPrivileges(
  1368. hToken,
  1369. FALSE,
  1370. &tkp,
  1371. sizeof(TOKEN_PRIVILEGES),
  1372. (PTOKEN_PRIVILEGES)NULL,
  1373. (PDWORD)NULL
  1374. );
  1375. err.GetLastWinError();
  1376. if (err.Failed())
  1377. {
  1378. break;
  1379. }
  1380. HANDLE hUser = NULL;
  1381. if (LogonUser(
  1382. strUser.GetBuffer(0),
  1383. strDomain.GetBuffer(0),
  1384. strPassword.GetBuffer(0),
  1385. LOGON32_LOGON_NETWORK,
  1386. LOGON32_PROVIDER_DEFAULT,
  1387. &hUser
  1388. ))
  1389. {
  1390. //
  1391. // Success!
  1392. //
  1393. CloseHandle(hUser);
  1394. }
  1395. else
  1396. {
  1397. err.GetLastWinError();
  1398. }
  1399. //
  1400. // Remove the privilege
  1401. //
  1402. }
  1403. while(FALSE);
  1404. }
  1405. HANDLE hUser = NULL;
  1406. if (LogonUser(
  1407. strUser.GetBuffer(0),
  1408. strDomain.GetBuffer(0),
  1409. strPassword.GetBuffer(0),
  1410. LOGON32_LOGON_NETWORK,
  1411. LOGON32_PROVIDER_DEFAULT,
  1412. &hUser))
  1413. {
  1414. //
  1415. // Success!
  1416. //
  1417. CloseHandle(hUser);
  1418. }
  1419. else
  1420. {
  1421. err.GetLastWinError();
  1422. }
  1423. return err;
  1424. }
  1425. void
  1426. CUserAccountDlg::OnButtonBrowseUsers()
  1427. /*++
  1428. Routine Description:
  1429. User browse dialog pressed, bring up
  1430. the user browser
  1431. Arguments:
  1432. None
  1433. Return Value:
  1434. None
  1435. --*/
  1436. {
  1437. CString str;
  1438. if (GetIUsrAccount(m_strServer, this, str))
  1439. {
  1440. //
  1441. // If a name was selected, blank
  1442. // out the password
  1443. //
  1444. m_edit_UserName.SetWindowText(str);
  1445. m_edit_Password.SetFocus();
  1446. }
  1447. }
  1448. void
  1449. CUserAccountDlg::OnChangeEditUsername()
  1450. /*++
  1451. Routine Description:
  1452. Handle change in user name edit box by blanking out the password
  1453. Arguments:
  1454. None
  1455. Return Value:
  1456. None
  1457. --*/
  1458. {
  1459. m_edit_Password.SetWindowText(_T(""));
  1460. }
  1461. void
  1462. CUserAccountDlg::OnButtonCheckPassword()
  1463. /*++
  1464. Routine Description:
  1465. 'Check Password' has been pressed. Try to validate
  1466. the password that has been entered
  1467. Arguments:
  1468. None
  1469. Return Value:
  1470. None
  1471. --*/
  1472. {
  1473. if (!UpdateData(TRUE))
  1474. {
  1475. return;
  1476. }
  1477. CError err(VerifyUserPassword(m_strUserName, m_strPassword));
  1478. if (!err.MessageBoxOnFailure())
  1479. {
  1480. ::AfxMessageBox(IDS_PASSWORD_OK);
  1481. }
  1482. }