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.

1044 lines
29 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: cprivs.cpp
  7. //
  8. // Contents: implementation of CConfigPrivs
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "CPrivs.h"
  14. #include "GetUser.h"
  15. #include "AddGrp.h"
  16. #include "snapmgr.h"
  17. #include "util.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. typedef struct _OBJECT_ATTRIBUTES {
  24. ULONG Length;
  25. HANDLE RootDirectory;
  26. PUNICODE_STRING ObjectName;
  27. ULONG Attributes;
  28. PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
  29. PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
  30. } OBJECT_ATTRIBUTES;
  31. typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
  32. #define InitializeObjectAttributes( p, n, a, r, s ) { \
  33. (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
  34. (p)->RootDirectory = r; \
  35. (p)->Attributes = a; \
  36. (p)->ObjectName = n; \
  37. (p)->SecurityDescriptor = s; \
  38. (p)->SecurityQualityOfService = NULL; \
  39. }
  40. #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
  41. BOOL
  42. WseceditGetNameForSpecialSids(
  43. OUT PWSTR *ppszEveryone OPTIONAL,
  44. OUT PWSTR *ppszAuthUsers OPTIONAL,
  45. OUT PWSTR *ppszAdmins OPTIONAL,
  46. OUT PWSTR *ppszAdministrator OPTIONAL
  47. );
  48. PSID
  49. WseceditpGetAccountDomainSid(
  50. );
  51. /////////////////////////////////////////////////////////////////////////////
  52. // CConfigPrivs dialog
  53. /////////////////////////////////////////////////////////////////////////////
  54. CConfigPrivs::CConfigPrivs(UINT nTemplateID)
  55. : CAttribute(nTemplateID ? nTemplateID : IDD),
  56. m_fDirty(false)
  57. {
  58. //{{AFX_DATA_INIT(CConfigPrivs)
  59. //}}AFX_DATA_INIT
  60. m_pHelpIDs = (DWORD_PTR)a106HelpIDs;
  61. m_uTemplateResID = IDD;
  62. }
  63. void CConfigPrivs::DoDataExchange(CDataExchange* pDX)
  64. {
  65. CAttribute::DoDataExchange(pDX);
  66. DDX_Control(pDX, IDC_GRANTLIST, m_lbGrant);
  67. DDX_Control(pDX, IDC_REMOVE, m_btnRemove);
  68. DDX_Control(pDX, IDC_ADD, m_btnAdd);
  69. DDX_Control(pDX, IDC_TITLE, m_btnTitle);
  70. }
  71. BEGIN_MESSAGE_MAP(CConfigPrivs, CAttribute)
  72. ON_BN_CLICKED(IDC_ADD, OnAdd)
  73. ON_BN_CLICKED(IDC_REMOVE, OnRemove)
  74. ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure)
  75. END_MESSAGE_MAP()
  76. /////////////////////////////////////////////////////////////////////////////
  77. // CConfigPrivs message handlers
  78. /////////////////////////////////////////////////////////////////////////////
  79. void CConfigPrivs::OnAdd()
  80. {
  81. CSCEAddGroup gu(this);
  82. PSCE_NAME_LIST pName = 0;
  83. if( IDD_CONFIG_PRIVS == m_uTemplateResID ) //Raid #404989
  84. {
  85. gu.m_fCheckName = FALSE;
  86. }
  87. gu.m_dwFlags = SCE_SHOW_USERS | SCE_SHOW_LOCALGROUPS | SCE_SHOW_GLOBAL | SCE_SHOW_WELLKNOWN | SCE_SHOW_BUILTIN;
  88. gu.SetModeBits(m_pSnapin->GetModeBits());
  89. CString str;
  90. str.LoadString( IDS_ADD_USERGROUP );
  91. gu.m_sTitle.Format( IDS_ADD_TITLE, str );
  92. gu.m_sDescription.LoadString( IDS_ADD_USERGROUP );
  93. CThemeContextActivator activator;
  94. if (gu.DoModal() ==IDOK ) {
  95. pName = gu.GetUsers();
  96. UINT cstrMax = 0; //Raid #271219
  97. LPWSTR pstrMax = NULL;
  98. UINT cstr = 0;
  99. while(pName)
  100. {
  101. if (LB_ERR == m_lbGrant.FindStringExact(-1,pName->Name))
  102. {
  103. if( LB_ERR == m_lbGrant.AddString(pName->Name) )
  104. {
  105. return;
  106. }
  107. m_fDirty = true;
  108. cstr = wcslen(pName->Name);
  109. if( cstr > cstrMax )
  110. {
  111. cstrMax = cstr;
  112. pstrMax = pName->Name;
  113. }
  114. }
  115. pName = pName->Next;
  116. }
  117. SetModified(TRUE);
  118. CDC* pCDC = m_lbGrant.GetDC();
  119. CSize strsize = pCDC->GetOutputTextExtent(pstrMax);
  120. m_lbGrant.ReleaseDC(pCDC);
  121. RECT winsize;
  122. m_lbGrant.GetWindowRect(&winsize);
  123. if( strsize.cx > winsize.right-winsize.left )
  124. {
  125. m_lbGrant.SetHorizontalExtent(strsize.cx);
  126. }
  127. }
  128. }
  129. void CConfigPrivs::OnRemove()
  130. {
  131. int cbItems;
  132. int *pnItems;
  133. cbItems = m_lbGrant.GetSelCount();
  134. pnItems = new int [cbItems];
  135. if ( pnItems ) {
  136. m_lbGrant.GetSelItems(cbItems,pnItems);
  137. if (cbItems) {
  138. m_fDirty = true;
  139. SetModified(TRUE);
  140. }
  141. while(cbItems--) {
  142. m_lbGrant.DeleteString(pnItems[cbItems]);
  143. }
  144. delete[] pnItems;
  145. }
  146. }
  147. void CConfigPrivs::OnConfigure()
  148. {
  149. CAttribute::OnConfigure();
  150. if (m_bConfigure == m_bOriginalConfigure) {
  151. m_fDirty = false;
  152. } else {
  153. m_fDirty = true;
  154. }
  155. }
  156. BOOL CConfigPrivs::OnApply()
  157. {
  158. if ( !m_bReadOnly )
  159. {
  160. PSCE_PRIVILEGE_ASSIGNMENT ppa = 0;
  161. PSCE_NAME_LIST pNames = 0;
  162. CString strItem;
  163. int cItems = 0;
  164. int i = 0;
  165. UpdateData(TRUE);
  166. if(!m_bConfigure)
  167. {
  168. PSCE_PRIVILEGE_ASSIGNMENT pDelete;
  169. pDelete = GetPrivData();
  170. //
  171. // Remove the item from the template
  172. if( pDelete && pDelete != (PSCE_PRIVILEGE_ASSIGNMENT)ULongToPtr(SCE_NO_VALUE) )
  173. {
  174. m_pData->SetID((LONG_PTR)NULL);
  175. if (m_pData->GetSetting()) //Raid #390777
  176. {
  177. m_pData->SetSetting((LONG_PTR)ULongToPtr(SCE_NO_VALUE));
  178. }
  179. m_pData->SetUnits((LPTSTR)pDelete->Name);
  180. m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  181. m_pData->SetBase((LONG_PTR)ULongToPtr(SCE_NO_VALUE));
  182. m_pData->GetBaseProfile()->UpdatePrivilegeAssignedTo(
  183. TRUE, // Delete the profile.
  184. &pDelete);
  185. m_pData->GetBaseProfile()->SetDirty(AREA_PRIVILEGES);
  186. m_pData->Update(m_pSnapin);
  187. }
  188. }
  189. else if (m_fDirty)
  190. {
  191. ppa = GetPrivData();
  192. PWSTR pszPrivName = m_pData->GetUnits();
  193. if ( ppa ) {
  194. //
  195. // to handle configured privilege case where Units is NULL
  196. //
  197. pszPrivName = ppa->Name;
  198. }
  199. int cSpecialItems = m_lbGrant.GetCount();
  200. DWORD dwIds = 0;
  201. CString strDenyItem;
  202. //
  203. // simulate SCE engine behavior to special case certain privileges/rights
  204. //
  205. if ( pszPrivName )
  206. {
  207. if ( lstrcmpi(pszPrivName, SE_INTERACTIVE_LOGON_NAME) == 0 )
  208. {
  209. if ( cSpecialItems == 0 ) {
  210. //
  211. // logon locally right cannot be assigned to no one
  212. //
  213. dwIds = IDS_PRIV_WARNING_LOCAL_LOGON;
  214. } else {
  215. PWSTR pszAdmins = NULL;
  216. //
  217. // get the administrators group name
  218. // logon locally right must be assigned to the administrator group
  219. //
  220. if ( WseceditGetNameForSpecialSids(NULL,
  221. NULL,
  222. &pszAdmins,
  223. NULL) )
  224. {
  225. for (i=0;i<cSpecialItems;i++)
  226. {
  227. m_lbGrant.GetText(i,strDenyItem);
  228. if ( (lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszAdmins)) == 0 )
  229. {
  230. break;
  231. }
  232. }
  233. if ( i >= cSpecialItems ) {
  234. //
  235. // cannot find administrators
  236. //
  237. dwIds = IDS_PRIV_WARNING_LOCAL_LOGON;
  238. }
  239. LocalFree(pszAdmins);
  240. }
  241. else
  242. {
  243. dwIds = IDS_PRIV_WARNING_ACCOUNT_TRANSLATION;
  244. }
  245. }
  246. }
  247. else if (lstrcmpi(pszPrivName, SE_DENY_INTERACTIVE_LOGON_NAME) == 0 )
  248. {
  249. PWSTR pszEveryone = NULL;
  250. PWSTR pszAuthUsers = NULL;
  251. PWSTR pszAdmins = NULL;
  252. PWSTR pszAdministrator=NULL;
  253. //
  254. // deny logon locally right cannot be assigned to any of the following
  255. // everyone, authenticated users, administrators, administrator
  256. //
  257. if ( WseceditGetNameForSpecialSids(&pszEveryone,
  258. &pszAuthUsers,
  259. &pszAdmins,
  260. &pszAdministrator) )
  261. {
  262. //
  263. // make sure this check covers the free text administrator account as well
  264. //
  265. PWSTR pTemp = wcschr(pszAdministrator, L'\\');
  266. if ( pTemp ) {
  267. pTemp++;
  268. }
  269. for (i=0;i<cSpecialItems;i++)
  270. {
  271. m_lbGrant.GetText(i,strDenyItem);
  272. if ( lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszEveryone) == 0 ||
  273. lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszAuthUsers) == 0 ||
  274. lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszAdmins) == 0 ||
  275. lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszAdministrator) == 0 ||
  276. (pTemp && lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pTemp) == 0 ) )
  277. {
  278. dwIds = IDS_PRIV_WARNING_DENYLOCAL_LOGON;
  279. break;
  280. }
  281. }
  282. LocalFree(pszEveryone);
  283. LocalFree(pszAuthUsers);
  284. LocalFree(pszAdmins);
  285. LocalFree(pszAdministrator);
  286. }
  287. else
  288. {
  289. dwIds = IDS_PRIV_WARNING_ACCOUNT_TRANSLATION;
  290. }
  291. }
  292. if (dwIds == IDS_PRIV_WARNING_LOCAL_LOGON ||
  293. dwIds == IDS_PRIV_WARNING_DENYLOCAL_LOGON ||
  294. dwIds == IDS_PRIV_WARNING_ACCOUNT_TRANSLATION )
  295. {
  296. //
  297. // if any of the items fail the check, display the warning
  298. // or popup a warning message box
  299. //
  300. CString strWarning;
  301. strWarning.LoadString(dwIds);
  302. CWnd *pWarn = GetDlgItem(IDC_WARNING);
  303. if (pWarn)
  304. {
  305. pWarn->SetWindowText(strWarning);
  306. pWarn->ShowWindow(SW_SHOW);
  307. pWarn = GetDlgItem(IDC_WARNING_ICON);
  308. if (pWarn)
  309. pWarn->ShowWindow(SW_SHOW);
  310. }
  311. else
  312. {
  313. //
  314. // Dialog box not available in some modes such as Local Policy
  315. //
  316. AfxMessageBox(strWarning);
  317. }
  318. return FALSE;
  319. }
  320. }
  321. if ( ppa == NULL && m_pData->GetUnits() )
  322. {
  323. if ( m_pData->GetBaseProfile()->UpdatePrivilegeAssignedTo(
  324. FALSE,
  325. &ppa,
  326. m_pData->GetUnits()
  327. ) == ERROR_SUCCESS)
  328. {
  329. m_pData->GetBaseProfile()->SetDirty(AREA_PRIVILEGES);
  330. SetPrivData(ppa);
  331. }
  332. }
  333. if ( ppa )
  334. {
  335. PSCE_NAME_LIST pNewList=NULL;
  336. cItems = m_lbGrant.GetCount();
  337. HRESULT hr=S_OK;
  338. if (cItems != LB_ERR && m_bConfigure)
  339. {
  340. for (i=0;i<cItems;i++)
  341. {
  342. m_lbGrant.GetText(i,strItem);
  343. if ( SceAddToNameList(&pNewList, (LPTSTR)(LPCTSTR)strItem, strItem.GetLength()) != SCESTATUS_SUCCESS)
  344. {
  345. hr = E_FAIL;
  346. break;
  347. }
  348. }
  349. }
  350. else
  351. hr = E_FAIL;
  352. if ( SUCCEEDED(hr) )
  353. {
  354. SceFreeMemory(ppa->AssignedTo,SCE_STRUCT_NAME_LIST);
  355. ppa->AssignedTo = pNewList;
  356. SetPrivData(ppa);
  357. m_pData->Update(m_pSnapin);
  358. m_fDirty = false;
  359. }
  360. else
  361. {
  362. //
  363. // free the new list, failed due to memory problem
  364. //
  365. if ( pNewList ) {
  366. SceFreeMemory(pNewList,SCE_STRUCT_NAME_LIST);
  367. }
  368. }
  369. }
  370. }
  371. }
  372. return CAttribute::OnApply();
  373. }
  374. void CConfigPrivs::OnCancel()
  375. {
  376. m_bConfigure = m_bOriginalConfigure;
  377. CAttribute::OnCancel();
  378. }
  379. PSCE_PRIVILEGE_ASSIGNMENT
  380. CConfigPrivs::GetPrivData() {
  381. ASSERT(m_pData);
  382. if (m_pData) {
  383. return (PSCE_PRIVILEGE_ASSIGNMENT) m_pData->GetID();
  384. }
  385. return NULL;
  386. }
  387. void
  388. CConfigPrivs::SetPrivData(PSCE_PRIVILEGE_ASSIGNMENT ppa) {
  389. ASSERT(m_pData);
  390. if (m_pData) {
  391. m_pData->SetID((LONG_PTR)ppa);
  392. if (ppa) {
  393. m_pData->SetBase((LONG_PTR)ppa->AssignedTo);
  394. } else {
  395. m_pData->SetBase(NULL);
  396. }
  397. }
  398. }
  399. BOOL CConfigPrivs::OnInitDialog()
  400. {
  401. CAttribute::OnInitDialog();
  402. PSCE_PRIVILEGE_ASSIGNMENT ppa;
  403. PSCE_NAME_LIST pNames;
  404. UpdateData(FALSE);
  405. ::SetMapMode(::GetDC(m_lbGrant.m_hWnd), MM_TEXT);
  406. ppa = GetPrivData();
  407. if ( ppa ) {
  408. pNames = ppa->AssignedTo;
  409. UINT cstrMax = 0; //Raid #271219
  410. LPWSTR pstrMax = NULL;
  411. UINT cstr = 0;
  412. while(pNames)
  413. {
  414. m_lbGrant.AddString(pNames->Name);
  415. cstr = wcslen(pNames->Name);
  416. if( cstr > cstrMax )
  417. {
  418. cstrMax = cstr;
  419. pstrMax = pNames->Name;
  420. }
  421. pNames = pNames->Next;
  422. }
  423. CDC* pCDC = m_lbGrant.GetDC();
  424. CSize strsize = pCDC->GetOutputTextExtent(pstrMax);
  425. m_lbGrant.ReleaseDC(pCDC);
  426. RECT winsize;
  427. m_lbGrant.GetWindowRect(&winsize);
  428. if( strsize.cx > winsize.right-winsize.left )
  429. {
  430. m_lbGrant.SetHorizontalExtent(strsize.cx);
  431. }
  432. m_bConfigure = TRUE;
  433. } else if(m_pData->GetBase() == (LONG_PTR)ULongToPtr(SCE_NO_VALUE)){
  434. m_bConfigure = FALSE;
  435. }
  436. if (m_pData->GetSetting())
  437. {
  438. CWnd *pWarn = GetDlgItem(IDC_WARNING);
  439. if (pWarn)
  440. {
  441. CString strWarning;
  442. strWarning.LoadString(IDS_PRIV_WARNING);
  443. pWarn->SetWindowText(strWarning);
  444. pWarn->ShowWindow(SW_SHOW);
  445. pWarn = GetDlgItem(IDC_WARNING_ICON);
  446. if (pWarn)
  447. {
  448. pWarn->ShowWindow(SW_SHOW);
  449. }
  450. }
  451. }
  452. m_bOriginalConfigure = m_bConfigure;
  453. //
  454. // Update the user controls depending on the setting.
  455. //
  456. AddUserControl(IDC_GRANTLIST);
  457. AddUserControl(IDC_ADD);
  458. AddUserControl(IDC_REMOVE);
  459. m_btnTitle.SetWindowText(m_pData->GetAttrPretty());
  460. UpdateData(FALSE);
  461. EnableUserControls(m_bConfigure);
  462. return TRUE;
  463. // return TRUE unless you set the focus to a control
  464. // EXCEPTION: OCX Property Pages should return FALSE
  465. }
  466. void CConfigPrivs::SetInitialValue(DWORD_PTR dw)
  467. {
  468. }
  469. BOOL
  470. WseceditGetNameForSpecialSids(
  471. OUT PWSTR *ppszEveryone OPTIONAL,
  472. OUT PWSTR *ppszAuthUsers OPTIONAL,
  473. OUT PWSTR *ppszAdmins OPTIONAL,
  474. OUT PWSTR *ppszAdministrator OPTIONAL
  475. )
  476. /*++
  477. Routine Description:
  478. This routine returns the localized account name for the Everyone and the Auth User SIDs
  479. Arguments:
  480. ppszEveryone - ptr to fill in (should be freed outside)
  481. ppszAuthUsers - ptr to fill in (should be freed outside)
  482. ppszAdmins - ptr to fill in for Administrators
  483. ppszAdministrator - ptr to fill in for local administrator account
  484. Return value:
  485. TRUE if succeeded else FALSE
  486. -- */
  487. {
  488. //
  489. // buffers for the SIDs
  490. //
  491. SID Sid;
  492. DWORD dwSize = sizeof(SID);
  493. PSID pSid=NULL;
  494. BOOL bError = TRUE;
  495. //
  496. // variables for sid lookup
  497. //
  498. SID_NAME_USE tmp;
  499. DWORD dwSizeDom;
  500. PWSTR dummyBuf = NULL;
  501. if ( ppszEveryone ) {
  502. //
  503. // create the SID for "everyone"
  504. //
  505. if ( CreateWellKnownSid(
  506. WinWorldSid,
  507. NULL,
  508. &Sid,
  509. &dwSize)) {
  510. //
  511. // get the required size of the account name and domain buffer
  512. //
  513. dwSize = 0;
  514. dwSizeDom = 0;
  515. LookupAccountSid(
  516. NULL,
  517. &Sid,
  518. NULL,
  519. &dwSize,
  520. NULL,
  521. &dwSizeDom,
  522. &tmp
  523. );
  524. *ppszEveryone = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSize + 1) * sizeof(WCHAR)));
  525. dummyBuf = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSizeDom + 1) * sizeof(WCHAR)));
  526. if ( *ppszEveryone && dummyBuf ) {
  527. //
  528. // lookup the SID to get the account name - domain name is ignored
  529. //
  530. if ( LookupAccountSid(
  531. NULL,
  532. &Sid,
  533. *ppszEveryone,
  534. &dwSize,
  535. dummyBuf,
  536. &dwSizeDom,
  537. &tmp
  538. ) ) {
  539. bError = FALSE;
  540. }
  541. }
  542. }
  543. LocalFree(dummyBuf);
  544. dummyBuf = NULL;
  545. if (bError) {
  546. LocalFree(*ppszEveryone);
  547. *ppszEveryone = NULL;
  548. return FALSE;
  549. }
  550. }
  551. //
  552. // "Authenticated Users"
  553. //
  554. if ( ppszAuthUsers ) {
  555. dwSize = sizeof(SID);
  556. bError = TRUE;
  557. //
  558. // create the SID for "authenticated users"
  559. //
  560. if ( CreateWellKnownSid(
  561. WinAuthenticatedUserSid,
  562. NULL,
  563. &Sid,
  564. &dwSize)) {
  565. //
  566. // get the required size of account name and domain buffers
  567. //
  568. dwSize = 0;
  569. dwSizeDom = 0;
  570. LookupAccountSid(
  571. NULL,
  572. &Sid,
  573. NULL,
  574. &dwSize,
  575. NULL,
  576. &dwSizeDom,
  577. &tmp
  578. );
  579. *ppszAuthUsers = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSize + 1) * sizeof(WCHAR)));
  580. dummyBuf = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSizeDom + 1) * sizeof(WCHAR)));
  581. if ( *ppszAuthUsers && dummyBuf ) {
  582. //
  583. // lookup the SID to get account name - domain name is ignored
  584. //
  585. if ( LookupAccountSid(
  586. NULL,
  587. &Sid,
  588. *ppszAuthUsers,
  589. &dwSize,
  590. dummyBuf,
  591. &dwSizeDom,
  592. &tmp
  593. ) ) {
  594. bError = FALSE;
  595. }
  596. }
  597. }
  598. LocalFree(dummyBuf);
  599. dummyBuf = NULL;
  600. if (bError) {
  601. LocalFree(*ppszAuthUsers);
  602. *ppszAuthUsers = NULL;
  603. if ( ppszEveryone ) {
  604. LocalFree(*ppszEveryone);
  605. *ppszEveryone = NULL;
  606. }
  607. return FALSE;
  608. }
  609. }
  610. //
  611. // administrators group
  612. //
  613. if ( ppszAdmins ) {
  614. dwSize = 0;
  615. bError = TRUE;
  616. //
  617. // get the size for the well known SID of administrators group
  618. //
  619. CreateWellKnownSid(
  620. WinBuiltinAdministratorsSid,
  621. NULL,
  622. pSid,
  623. &dwSize);
  624. if ( dwSize > 0 ) {
  625. //
  626. // alocate buffer and create the well known SID
  627. // cannot use the SID buffer because Admins SID has more than
  628. // one subauthority
  629. //
  630. pSid = (PSID)LocalAlloc(LPTR, dwSize);
  631. if ( pSid &&
  632. CreateWellKnownSid(
  633. WinBuiltinAdministratorsSid,
  634. NULL,
  635. pSid,
  636. &dwSize) ) {
  637. dwSize = 0;
  638. dwSizeDom = 0;
  639. //
  640. // get the size for account name and domain buffers
  641. //
  642. LookupAccountSid(
  643. NULL,
  644. pSid,
  645. NULL,
  646. &dwSize,
  647. NULL,
  648. &dwSizeDom,
  649. &tmp
  650. );
  651. *ppszAdmins = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSize + 1) * sizeof(WCHAR)));
  652. dummyBuf = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSizeDom + 1) * sizeof(WCHAR)));
  653. if ( *ppszAdmins && dummyBuf ) {
  654. //
  655. // look up the name, domain name (BUILTIN) is ignored
  656. //
  657. if ( LookupAccountSid(
  658. NULL,
  659. pSid,
  660. *ppszAdmins,
  661. &dwSize,
  662. dummyBuf,
  663. &dwSizeDom,
  664. &tmp
  665. ) ) {
  666. bError = FALSE;
  667. }
  668. }
  669. }
  670. LocalFree(pSid);
  671. pSid = NULL;
  672. }
  673. LocalFree(dummyBuf);
  674. dummyBuf = NULL;
  675. if (bError) {
  676. //
  677. // anything fail will free all buffers and return FALSE
  678. //
  679. LocalFree(*ppszAdmins);
  680. *ppszAdmins = NULL;
  681. if ( ppszAuthUsers ) {
  682. LocalFree(*ppszAuthUsers);
  683. *ppszAuthUsers = NULL;
  684. }
  685. if ( ppszEveryone ) {
  686. LocalFree(*ppszEveryone);
  687. *ppszEveryone = NULL;
  688. }
  689. return FALSE;
  690. }
  691. }
  692. //
  693. // the administrator user account
  694. //
  695. if ( ppszAdministrator ) {
  696. dwSize = 0;
  697. bError = TRUE;
  698. PWSTR dummy2=NULL;
  699. //
  700. // Get Account domain SID first
  701. //
  702. PSID pDomSid = WseceditpGetAccountDomainSid();
  703. if ( pDomSid ) {
  704. //
  705. // get the size for the administrator account (local account domain is used)
  706. //
  707. CreateWellKnownSid(
  708. WinAccountAdministratorSid,
  709. pDomSid,
  710. pSid,
  711. &dwSize);
  712. if ( dwSize > 0 ) {
  713. //
  714. // cannot use the SID buffer because administrator account SID
  715. // has more than one subauthority
  716. //
  717. pSid = (PSID)LocalAlloc(LPTR, dwSize);
  718. if ( pSid &&
  719. CreateWellKnownSid(
  720. WinAccountAdministratorSid,
  721. pDomSid,
  722. pSid,
  723. &dwSize) ) {
  724. //
  725. // get size for the account name and domain buffer
  726. //
  727. dwSize = 0;
  728. dwSizeDom = 0;
  729. LookupAccountSid(
  730. NULL,
  731. pSid,
  732. NULL,
  733. &dwSize,
  734. NULL,
  735. &dwSizeDom,
  736. &tmp
  737. );
  738. dummy2 = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSize + 1) * sizeof(WCHAR)));
  739. dummyBuf = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSizeDom + 1) * sizeof(WCHAR)));
  740. if ( dummy2 && dummyBuf ) {
  741. //
  742. // lookup the account name and domain name
  743. //
  744. if ( LookupAccountSid(
  745. NULL,
  746. pSid,
  747. dummy2,
  748. &dwSize,
  749. dummyBuf,
  750. &dwSizeDom,
  751. &tmp
  752. ) ) {
  753. *ppszAdministrator = (PWSTR)LocalAlloc(LPTR, (dwSize+dwSizeDom+2)*sizeof(WCHAR));
  754. if ( *ppszAdministrator ) {
  755. //
  756. // the name to return is a fully qualified name such as Domain\Administrator
  757. //
  758. wcscpy(*ppszAdministrator, dummyBuf);
  759. wcscat(*ppszAdministrator, L"\\");
  760. wcscat(*ppszAdministrator, dummy2);
  761. bError = FALSE;
  762. }
  763. }
  764. }
  765. }
  766. LocalFree(pSid);
  767. pSid = NULL;
  768. }
  769. LocalFree(dummyBuf);
  770. dummyBuf = NULL;
  771. LocalFree(dummy2);
  772. dummy2 = NULL;
  773. LocalFree(pDomSid);
  774. }
  775. if (bError) {
  776. //
  777. // anything fail will free all buffers and return FALSE
  778. //
  779. LocalFree(*ppszAdministrator);
  780. *ppszAdministrator = NULL;
  781. if ( ppszAdmins ) {
  782. LocalFree(*ppszAdmins);
  783. *ppszAdmins = NULL;
  784. }
  785. if ( ppszAuthUsers ) {
  786. LocalFree(*ppszAuthUsers);
  787. *ppszAuthUsers = NULL;
  788. }
  789. if ( ppszEveryone ) {
  790. LocalFree(*ppszEveryone);
  791. *ppszEveryone = NULL;
  792. }
  793. return FALSE;
  794. }
  795. }
  796. return TRUE;
  797. }
  798. PSID
  799. WseceditpGetAccountDomainSid(
  800. )
  801. {
  802. NTSTATUS Status;
  803. LSA_HANDLE PolicyHandle;
  804. OBJECT_ATTRIBUTES PolicyObjectAttributes;
  805. PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo=NULL;
  806. PSID DomainSid=NULL;
  807. //
  808. // Open the policy database
  809. //
  810. InitializeObjectAttributes( &PolicyObjectAttributes,
  811. NULL, // Name
  812. 0, // Attributes
  813. NULL, // Root
  814. NULL ); // Security Descriptor
  815. Status = LsaOpenPolicy( NULL,
  816. (PLSA_OBJECT_ATTRIBUTES)&PolicyObjectAttributes,
  817. POLICY_VIEW_LOCAL_INFORMATION,
  818. &PolicyHandle );
  819. if ( NT_SUCCESS(Status) ) {
  820. //
  821. // Query the account domain information
  822. //
  823. Status = LsaQueryInformationPolicy( PolicyHandle,
  824. PolicyAccountDomainInformation,
  825. (PVOID *)&PolicyAccountDomainInfo );
  826. if ( NT_SUCCESS(Status) ) {
  827. DWORD Len = GetLengthSid(PolicyAccountDomainInfo->DomainSid);
  828. DomainSid = (PSID)LocalAlloc(LPTR, Len );
  829. if ( DomainSid ) {
  830. Status = CopySid( Len, DomainSid, PolicyAccountDomainInfo->DomainSid );
  831. if ( !NT_SUCCESS(Status) ) {
  832. LocalFree(DomainSid);
  833. DomainSid = NULL;
  834. }
  835. }
  836. LsaFreeMemory(PolicyAccountDomainInfo);
  837. }
  838. LsaClose( PolicyHandle );
  839. }
  840. return(DomainSid);
  841. }