Leaked source code of windows server 2003
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.

1060 lines
23 KiB

  1. //
  2. // chngpwd.cpp
  3. //
  4. // Copyright (c) Microsoft Corp, 1998
  5. //
  6. // This file contains source code for testing protected storage's key
  7. // backup and recovery capabilities under a real world scenario, by creating
  8. // a local user account, performing a data protection operation, and then
  9. // change the pwd, then performing data unprotect, and comparing the data.
  10. //
  11. // History:
  12. //
  13. // Todds 8/15/98 Created
  14. //
  15. #include <windows.h>
  16. #include <winbase.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <wincrypt.h>
  20. #include <userenv.h>
  21. #include <lm.h>
  22. #include <psapi.h>
  23. #define MyAlloc(cb) HeapAlloc(GetProcessHeap(), 0, cb)
  24. #define MyFree(pv) HeapFree(GetProcessHeap(), 0, pv)
  25. #define WSZ_BYTECOUNT(s) (2 * wcslen(s) + 2)
  26. #define MAX_BLOBS 20
  27. #define MAX_PROCESSES 200
  28. #define MAX_SD 2048
  29. #define BLOB_INCREMENT 0x4001 // 1 page + 1 byte...
  30. VOID
  31. TERROR(
  32. IN LPWSTR string
  33. )
  34. {
  35. printf("%ls\n", string);
  36. }
  37. VOID
  38. TERRORVAL(
  39. IN LPWSTR string,
  40. IN ULONG error
  41. )
  42. {
  43. printf("%ls (errorcode=%lu)\n", string, error);
  44. }
  45. //
  46. // SetSidOnAcl
  47. //
  48. BOOL
  49. SetSidOnAcl(
  50. PSID pSid,
  51. PACL pAclSource,
  52. PACL *pAclDestination,
  53. DWORD AccessMask,
  54. BYTE AceFlags,
  55. BOOL bAddSid
  56. )
  57. {
  58. ACL_SIZE_INFORMATION AclInfo;
  59. DWORD dwNewAclSize, dwErr = S_OK;
  60. LPVOID pAce;
  61. DWORD AceCounter;
  62. BOOL bSuccess=FALSE; // assume this function will fail
  63. //
  64. // If we were given a NULL Acl, just provide a NULL Acl
  65. //
  66. if(pAclSource == NULL) {
  67. *pAclDestination = NULL;
  68. return TRUE;
  69. }
  70. if(!IsValidSid(pSid)) return FALSE;
  71. if(!GetAclInformation(
  72. pAclSource,
  73. &AclInfo,
  74. sizeof(ACL_SIZE_INFORMATION),
  75. AclSizeInformation
  76. )) return FALSE;
  77. //
  78. // compute size for new Acl, based on addition or subtraction of Ace
  79. //
  80. if(bAddSid) {
  81. dwNewAclSize=AclInfo.AclBytesInUse +
  82. sizeof(ACCESS_ALLOWED_ACE) +
  83. GetLengthSid(pSid) -
  84. sizeof(DWORD) ;
  85. }
  86. else {
  87. dwNewAclSize=AclInfo.AclBytesInUse -
  88. sizeof(ACCESS_ALLOWED_ACE) -
  89. GetLengthSid(pSid) +
  90. sizeof(DWORD) ;
  91. }
  92. *pAclDestination = (PACL)MyAlloc(dwNewAclSize);
  93. if(*pAclDestination == NULL) {
  94. TERRORVAL(L"Alloc failed!", E_OUTOFMEMORY);
  95. return FALSE;
  96. }
  97. //
  98. // initialize new Acl
  99. //
  100. if(!InitializeAcl(
  101. *pAclDestination,
  102. dwNewAclSize,
  103. ACL_REVISION
  104. )){
  105. dwErr = GetLastError();
  106. TERRORVAL(L"InitilizeAcl failed!", dwErr);
  107. goto ret;
  108. }
  109. //
  110. // if appropriate, add ace representing pSid
  111. //
  112. if(bAddSid) {
  113. PACCESS_ALLOWED_ACE pNewAce;
  114. if(!AddAccessAllowedAce(
  115. *pAclDestination,
  116. ACL_REVISION,
  117. AccessMask,
  118. pSid
  119. )) {
  120. dwErr = GetLastError();
  121. TERRORVAL(L"AddAccessAllowedAce failed!", dwErr);
  122. goto ret;
  123. }
  124. //
  125. // get pointer to ace we just added, so we can change the AceFlags
  126. //
  127. if(!GetAce(
  128. *pAclDestination,
  129. 0, // this is the first ace in the Acl
  130. (void**) &pNewAce
  131. )){
  132. dwErr = GetLastError();
  133. TERRORVAL(L"GetAce failed!", dwErr);
  134. goto ret;
  135. }
  136. pNewAce->Header.AceFlags = AceFlags;
  137. }
  138. //
  139. // copy existing aces to new Acl
  140. //
  141. for(AceCounter = 0 ; AceCounter < AclInfo.AceCount ; AceCounter++) {
  142. //
  143. // fetch existing ace
  144. //
  145. if(!GetAce(pAclSource, AceCounter, &pAce)){
  146. dwErr = GetLastError();
  147. TERRORVAL(L"GetAce failed!", dwErr);
  148. goto ret;
  149. }
  150. //
  151. // check to see if we are removing the Ace
  152. //
  153. if(!bAddSid) {
  154. //
  155. // we only care about ACCESS_ALLOWED aces
  156. //
  157. if((((PACE_HEADER)pAce)->AceType) == ACCESS_ALLOWED_ACE_TYPE) {
  158. PSID pTempSid=(PSID)&((PACCESS_ALLOWED_ACE)pAce)->SidStart;
  159. //
  160. // if the Sid matches, skip adding this Sid
  161. //
  162. if(EqualSid(pSid, pTempSid)) continue;
  163. }
  164. }
  165. //
  166. // append ace to Acl
  167. //
  168. if(!AddAce(
  169. *pAclDestination,
  170. ACL_REVISION,
  171. MAXDWORD, // maintain Ace order
  172. pAce,
  173. ((PACE_HEADER)pAce)->AceSize
  174. )) {
  175. dwErr = GetLastError();
  176. TERRORVAL(L"AddAccessAllowedAce failed!", dwErr);
  177. goto ret;
  178. }
  179. }
  180. bSuccess=TRUE; // indicate success
  181. ret:
  182. //
  183. // free memory if an error occurred
  184. //
  185. if(!bSuccess) {
  186. if(*pAclDestination != NULL)
  187. MyFree(*pAclDestination);
  188. }
  189. return bSuccess;
  190. }
  191. //
  192. // AddSIDToKernelObject()
  193. //
  194. // This function takes a given SID and dwAccess and adds it to a given token.
  195. //
  196. // ** Be sure to restore old kernel object
  197. // ** using call to GetKernelObjectSecurity()
  198. //
  199. BOOL
  200. AddSIDToKernelObjectDacl(PSID pSid,
  201. DWORD dwAccess,
  202. HANDLE OriginalToken,
  203. PSECURITY_DESCRIPTOR* ppSDOld)
  204. {
  205. PSECURITY_DESCRIPTOR pSD = NULL;
  206. SECURITY_DESCRIPTOR sdNew;
  207. DWORD cbByte = MAX_SD, cbNeeded = 0, dwErr = 0;
  208. PACL pOldDacl = NULL, pNewDacl = NULL;
  209. BOOL fDaclPresent, fDaclDefaulted, fRet = FALSE;
  210. pSD = (PSECURITY_DESCRIPTOR) MyAlloc(cbByte);
  211. if (NULL == pSD) {
  212. TERRORVAL(L"Alloc failed!", E_OUTOFMEMORY);
  213. return FALSE;
  214. }
  215. if (!InitializeSecurityDescriptor(
  216. &sdNew,
  217. SECURITY_DESCRIPTOR_REVISION
  218. )) {
  219. dwErr = GetLastError();
  220. TERRORVAL(L"InitializeSecurityDescriptor failed!", dwErr);
  221. goto ret;
  222. }
  223. if (!GetKernelObjectSecurity(
  224. OriginalToken,
  225. DACL_SECURITY_INFORMATION,
  226. pSD,
  227. cbByte,
  228. &cbNeeded
  229. )) {
  230. dwErr = GetLastError();
  231. if (cbNeeded > MAX_SD && dwErr == ERROR_MORE_DATA) {
  232. MyFree(pSD);
  233. pSD = NULL;
  234. pSD = (PSECURITY_DESCRIPTOR) MyAlloc(cbNeeded);
  235. if (NULL == pSD) {
  236. TERRORVAL(L"Alloc failed!", E_OUTOFMEMORY);
  237. dwErr = E_OUTOFMEMORY;
  238. goto ret;
  239. }
  240. dwErr = S_OK;
  241. if (!GetKernelObjectSecurity(
  242. OriginalToken,
  243. DACL_SECURITY_INFORMATION,
  244. pSD,
  245. cbNeeded,
  246. &cbNeeded
  247. )) {
  248. dwErr = GetLastError();
  249. }
  250. }
  251. if (dwErr != S_OK) {
  252. TERRORVAL(L"GetKernelObjectSecurity failed!", dwErr);
  253. goto ret;
  254. }
  255. }
  256. if (!GetSecurityDescriptorDacl(
  257. pSD,
  258. &fDaclPresent,
  259. &pOldDacl,
  260. &fDaclDefaulted
  261. )) {
  262. dwErr = GetLastError();
  263. TERRORVAL(L"GetSecurityDescriptorDacl failed!", dwErr);
  264. goto ret;
  265. }
  266. if (!SetSidOnAcl(
  267. pSid,
  268. pOldDacl,
  269. &pNewDacl,
  270. dwAccess,
  271. 0,
  272. TRUE
  273. )) {
  274. goto ret;
  275. }
  276. if (!SetSecurityDescriptorDacl(
  277. &sdNew,
  278. TRUE,
  279. pNewDacl,
  280. FALSE
  281. )) {
  282. dwErr = GetLastError();
  283. TERRORVAL(L"SetSecurityDescriptorDacl failed!", dwErr);
  284. goto ret;
  285. }
  286. if (!SetKernelObjectSecurity(
  287. OriginalToken,
  288. DACL_SECURITY_INFORMATION,
  289. &sdNew
  290. )) {
  291. dwErr = GetLastError();
  292. TERRORVAL(L"SetKernelObjectSecurity failed!", dwErr);
  293. goto ret;
  294. }
  295. *ppSDOld = pSD;
  296. fRet = TRUE;
  297. ret:
  298. if (NULL != pNewDacl) {
  299. MyFree(pNewDacl);
  300. }
  301. if (!fRet) {
  302. if (NULL != pSD) {
  303. MyFree(pSD);
  304. *ppSDOld = NULL;
  305. }
  306. }
  307. return fRet;
  308. }
  309. BOOL
  310. SetPrivilege(
  311. HANDLE hToken, // token handle
  312. LPCTSTR Privilege, // Privilege to enable/disable
  313. BOOL bEnablePrivilege // to enable or disable privilege
  314. )
  315. {
  316. TOKEN_PRIVILEGES tp;
  317. LUID luid;
  318. TOKEN_PRIVILEGES tpPrevious;
  319. DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
  320. if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
  321. //
  322. // first pass. get current privilege setting
  323. //
  324. tp.PrivilegeCount = 1;
  325. tp.Privileges[0].Luid = luid;
  326. tp.Privileges[0].Attributes = 0;
  327. AdjustTokenPrivileges(
  328. hToken,
  329. FALSE,
  330. &tp,
  331. sizeof(TOKEN_PRIVILEGES),
  332. &tpPrevious,
  333. &cbPrevious
  334. );
  335. if (GetLastError() != ERROR_SUCCESS) return FALSE;
  336. //
  337. // second pass. set privilege based on previous setting
  338. //
  339. tpPrevious.PrivilegeCount = 1;
  340. tpPrevious.Privileges[0].Luid = luid;
  341. if(bEnablePrivilege) {
  342. tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
  343. }
  344. else {
  345. tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
  346. tpPrevious.Privileges[0].Attributes);
  347. }
  348. AdjustTokenPrivileges(
  349. hToken,
  350. FALSE,
  351. &tpPrevious,
  352. cbPrevious,
  353. NULL,
  354. NULL
  355. );
  356. if (GetLastError() != ERROR_SUCCESS) return FALSE;
  357. return TRUE;
  358. }
  359. BOOL
  360. SetCurrentPrivilege(
  361. LPCTSTR Privilege, // Privilege to enable/disable
  362. BOOL bEnablePrivilege // to enable or disable privilege
  363. )
  364. {
  365. BOOL bSuccess=FALSE; // assume failure
  366. HANDLE hToken;
  367. if (!OpenThreadToken(
  368. GetCurrentThread(),
  369. TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
  370. FALSE,
  371. &hToken)){
  372. if(!OpenProcessToken(
  373. GetCurrentProcess(),
  374. TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
  375. &hToken
  376. )) return FALSE;
  377. }
  378. if(SetPrivilege(hToken, Privilege, bEnablePrivilege)) bSuccess=TRUE;
  379. CloseHandle(hToken);
  380. return bSuccess;
  381. }
  382. //
  383. // GetUserSid
  384. //
  385. // This function takes a token, and returns the user SID from that token.
  386. //
  387. // Note: SID must be freed by MyFree()
  388. // hToken is optional... NULL means we'll grab it.
  389. //
  390. BOOL
  391. GetUserSid(HANDLE hClientToken,
  392. PSID* ppSid,
  393. DWORD* lpcbSid)
  394. {
  395. DWORD cbUserInfo = 0;
  396. PTOKEN_USER pUserInfo = NULL;
  397. PUCHAR pnSubAuthorityCount = 0;
  398. DWORD cbSid = 0;
  399. BOOL fRet = FALSE;
  400. HANDLE hToken = hClientToken;
  401. *ppSid = NULL;
  402. if (NULL == hClientToken) {
  403. if (!OpenThreadToken(
  404. GetCurrentThread(),
  405. TOKEN_QUERY,
  406. FALSE,
  407. &hToken
  408. )) {
  409. // not impersonating, use process token...
  410. if (!OpenProcessToken(
  411. GetCurrentProcess(),
  412. TOKEN_QUERY,
  413. &hToken
  414. )) {
  415. TERRORVAL(L"OpenProcessToken failed!", GetLastError());
  416. return FALSE;
  417. }
  418. }
  419. }
  420. // this will fail, usually w/ ERROR_INSUFFICIENT_BUFFER
  421. GetTokenInformation(
  422. hToken,
  423. TokenUser,
  424. NULL,
  425. 0,
  426. &cbUserInfo
  427. );
  428. pUserInfo = (PTOKEN_USER) MyAlloc(cbUserInfo);
  429. if (NULL == pUserInfo) {
  430. TERRORVAL(L"ALLOC FAILURE!", E_OUTOFMEMORY);
  431. return FALSE;
  432. }
  433. if (!GetTokenInformation(
  434. hToken,
  435. TokenUser,
  436. pUserInfo,
  437. cbUserInfo,
  438. &cbUserInfo
  439. )) {
  440. TERRORVAL(L"GetTokenInformation failed!", GetLastError());
  441. goto ret;
  442. }
  443. //
  444. // Now that we've got the SID AND ATTRIBUTES struct, get the SID lenght,
  445. // alloc room, and return *just the SID*
  446. //
  447. if (!IsValidSid(pUserInfo->User.Sid)) goto ret;
  448. pnSubAuthorityCount = GetSidSubAuthorityCount(pUserInfo->User.Sid);
  449. cbSid = GetSidLengthRequired(*pnSubAuthorityCount);
  450. *ppSid = (PSID) MyAlloc(cbSid);
  451. if (NULL == *ppSid ) {
  452. TERRORVAL(L"Alloc failed!", E_OUTOFMEMORY);
  453. goto ret;
  454. }
  455. if (!CopySid(
  456. cbSid,
  457. *ppSid,
  458. pUserInfo->User.Sid
  459. )) {
  460. TERRORVAL(L"CopySid failed!", GetLastError());
  461. goto copyerr;
  462. }
  463. *lpcbSid = cbSid; // may be useful later on...
  464. fRet = TRUE;
  465. ret:
  466. if (NULL == hClientToken && NULL != hToken) { // supplied our own
  467. CloseHandle(hToken);
  468. }
  469. if (NULL != pUserInfo) {
  470. MyFree(pUserInfo);
  471. }
  472. return fRet;
  473. copyerr:
  474. if (NULL != *ppSid) {
  475. MyFree(*ppSid);
  476. *ppSid = NULL;
  477. }
  478. goto ret;
  479. }
  480. //
  481. // IsLocalSystem()
  482. // This function makes the determination if the given process token
  483. // is running as local system.
  484. //
  485. BOOL
  486. IsLocalSystem(HANDLE hToken)
  487. {
  488. PSID pLocalSid = NULL, pTokenSid = NULL;
  489. SID_IDENTIFIER_AUTHORITY IDAuthorityNT = SECURITY_NT_AUTHORITY;
  490. DWORD cbSid = 0;
  491. BOOL fRet = FALSE;
  492. if (!GetUserSid(
  493. hToken,
  494. &pTokenSid,
  495. &cbSid
  496. )) {
  497. goto ret;
  498. }
  499. if (!AllocateAndInitializeSid(
  500. &IDAuthorityNT,
  501. 1,
  502. SECURITY_LOCAL_SYSTEM_RID,
  503. 0,0,0,0,0,0,0,
  504. &pLocalSid
  505. )) {
  506. TERRORVAL(L"AllocateAndInitializeSid failed!", GetLastError());
  507. goto ret;
  508. }
  509. if (EqualSid(pLocalSid, pTokenSid)) {
  510. fRet = TRUE; // got one!
  511. }
  512. ret:
  513. if (NULL != pTokenSid) {
  514. MyFree(pTokenSid);
  515. }
  516. if (NULL != pLocalSid) {
  517. FreeSid(pLocalSid);
  518. }
  519. return fRet;
  520. }
  521. //
  522. // GetLocalSystemToken()
  523. //
  524. // This function grabs a process token from a LOCAL SYSTEM process and uses it
  525. // to run as local system for the duration of the test
  526. //
  527. // RevertToSelf() must be called to restore original token
  528. //
  529. //
  530. DWORD
  531. GetLocalSystemToken(
  532. IN ULONG ProcessId,
  533. OUT HANDLE *hPDupToken
  534. )
  535. {
  536. HANDLE hProcess = NULL;
  537. HANDLE hPToken = NULL, hPTokenNew = NULL;
  538. DWORD rgPIDs[MAX_PROCESSES], cbNeeded = 0, dwErr = S_OK, i = 0;
  539. DWORD cbrgPIDs = sizeof(DWORD) * MAX_PROCESSES;
  540. PSECURITY_DESCRIPTOR pSD = NULL;
  541. PSID pSid = NULL;
  542. DWORD cbSid = 0;
  543. BOOL fSet = FALSE;
  544. // SLOW BUFFERs
  545. BYTE rgByte[MAX_SD], rgByte2[MAX_SD];
  546. DWORD cbByte = MAX_SD, cbByte2 = MAX_SD;
  547. // *phRet = NULL;
  548. //
  549. // Get current user's sid for use in expanding SD.
  550. //
  551. if (!GetUserSid(
  552. NULL,
  553. &pSid,
  554. &cbSid
  555. )) {
  556. goto ret;
  557. }
  558. //
  559. // Walk processes until we find one that's running as
  560. // local system
  561. //
  562. do {
  563. hProcess = OpenProcess(
  564. PROCESS_ALL_ACCESS,
  565. FALSE,
  566. ProcessId
  567. );
  568. if (NULL == hProcess) {
  569. dwErr = GetLastError();
  570. TERRORVAL(L"OpenProcess failed! ", dwErr);
  571. goto ret;
  572. }
  573. if (!OpenProcessToken(
  574. hProcess,
  575. READ_CONTROL | WRITE_DAC,
  576. &hPToken
  577. )) {
  578. dwErr = GetLastError();
  579. TERRORVAL(L"OpenProcessToken failed!", dwErr);
  580. goto ret;
  581. }
  582. //
  583. // We've got a token, but we can't use it for
  584. // TOKEN_DUPLICATE access. So, instead, we'll go
  585. // ahead and whack the DACL on the object to grant us
  586. // this access, and get a new token.
  587. // **** BE SURE TO RESTORE hProcess to Original SD!!! ****
  588. //
  589. if (!AddSIDToKernelObjectDacl(
  590. pSid,
  591. TOKEN_DUPLICATE,
  592. hPToken,
  593. &pSD
  594. )) {
  595. goto ret;
  596. }
  597. fSet = TRUE;
  598. if (!OpenProcessToken(
  599. hProcess,
  600. TOKEN_DUPLICATE,
  601. &hPTokenNew
  602. )) {
  603. dwErr = GetLastError();
  604. TERRORVAL(L"OpenProcessToken failed!", dwErr);
  605. goto ret;
  606. }
  607. //
  608. // Duplicate the token
  609. //
  610. if (!DuplicateTokenEx(
  611. hPTokenNew,
  612. TOKEN_ALL_ACCESS,
  613. NULL,
  614. SecurityImpersonation,
  615. TokenPrimary,
  616. hPDupToken
  617. )) {
  618. dwErr = GetLastError();
  619. TERRORVAL(L"DuplicateToken failed!", dwErr);
  620. goto ret;
  621. }
  622. if (IsLocalSystem(*hPDupToken)) {
  623. break; // found a local system token
  624. }
  625. // Loop cleanup
  626. if (!SetKernelObjectSecurity(
  627. hPToken,
  628. DACL_SECURITY_INFORMATION,
  629. pSD
  630. )) {
  631. dwErr = GetLastError();
  632. TERRORVAL(L"SetKernelObjectSecurity failed!", dwErr);
  633. goto ret;
  634. }
  635. fSet = FALSE;
  636. #if 0
  637. if (NULL != hPDupToken) {
  638. CloseHandle(hPDupToken);
  639. hPDupToken = NULL;
  640. }
  641. #endif
  642. if (NULL != pSD) {
  643. MyFree(pSD);
  644. pSD = NULL;
  645. }
  646. if (NULL != hPToken) {
  647. CloseHandle(hPToken);
  648. hPToken = NULL;
  649. }
  650. if (NULL != hProcess) {
  651. CloseHandle(hProcess);
  652. hProcess = NULL;
  653. }
  654. goto ret;
  655. } while(FALSE);
  656. if (!ImpersonateLoggedOnUser(*hPDupToken)) {
  657. dwErr = GetLastError();
  658. TERRORVAL(L"ImpersonateLoggedOnUser failed!", dwErr);
  659. goto ret;
  660. }
  661. ret:
  662. //***** REMEMBER TO RESTORE ORIGINAL SD TO OBJECT*****
  663. if (fSet) {
  664. if (!SetKernelObjectSecurity(
  665. hPToken,
  666. DACL_SECURITY_INFORMATION,
  667. pSD
  668. )) {
  669. dwErr = GetLastError();
  670. TERRORVAL(L"SetKernelObjectSecurity failed (cleanup)!", dwErr);
  671. }
  672. }
  673. if (NULL != pSid) {
  674. MyFree(pSid);
  675. }
  676. if (NULL != hPToken) {
  677. CloseHandle(hPToken);
  678. }
  679. if (NULL != pSD) {
  680. MyFree(pSD);
  681. }
  682. if (NULL != hProcess) {
  683. CloseHandle(hProcess);
  684. }
  685. return dwErr;
  686. }
  687. //
  688. // LogoffAndRevert()
  689. //
  690. // This function simply RevertsToSelf(), and then closes the logon token
  691. //
  692. // Params:
  693. //
  694. // hToken - Logon token from LogonUserW
  695. //
  696. // Returns:
  697. //
  698. // dwErr from last failure, S_OK otherwise.
  699. //
  700. DWORD
  701. LogoffAndRevert(HANDLE hToken,
  702. PSECURITY_DESCRIPTOR pSD)
  703. {
  704. HANDLE hThread = INVALID_HANDLE_VALUE;
  705. DWORD dwErr = 0;
  706. //
  707. // Verify impersonation, and revert
  708. //
  709. if (OpenThreadToken(
  710. GetCurrentThread(),
  711. TOKEN_QUERY,
  712. TRUE,
  713. &hThread
  714. )) {
  715. CloseHandle(hThread);
  716. RevertToSelf();
  717. }
  718. /*if (!SetKernelObjectSecurity(
  719. hToken,
  720. DACL_SECURITY_INFORMATION,
  721. pSD
  722. )) {
  723. dwErr = GetLastError();
  724. TCOMMENT(L"Security was not reset on kernel object!");
  725. }*/
  726. return dwErr;
  727. }
  728. extern "C"
  729. int __cdecl wmain(
  730. int argc,
  731. WCHAR* argv[]
  732. )
  733. {
  734. LPWSTR wszUPN = NULL;
  735. LPWSTR wszOldPwd = NULL;
  736. LPWSTR wszNewPwd = NULL;
  737. DATA_BLOB* arCipherData = NULL;
  738. INT i = 1;
  739. DWORD dwErr = S_OK;
  740. DWORD dwCleanupErrors = S_OK;
  741. HANDLE hToken = INVALID_HANDLE_VALUE;
  742. HANDLE hLocalSystem = NULL;
  743. HANDLE hProfile = INVALID_HANDLE_VALUE;
  744. BOOL fTest = TRUE;
  745. PSECURITY_DESCRIPTOR pSD = NULL;
  746. ULONG ProcessId = 8;
  747. #if 0
  748. while (i < carg) {
  749. if (!_wcsicmp(rgwszarg[i], L"-?")) {
  750. Usage();
  751. return 0;
  752. }
  753. if (!_wcsicmp(rgwszarg[i], L"-reset")) {
  754. ResetTestUser();
  755. return 0;
  756. }
  757. if (!_wcsicmp(rgwszarg[i], L"-create")) {
  758. CreateTestUser();
  759. return 0;
  760. }
  761. if (!_wcsicmp(rgwszarg[i], L"-user")) {
  762. if (carg < 4) {
  763. Usage();
  764. }
  765. fTest = TRUE;
  766. }
  767. i++;
  768. }
  769. #endif
  770. if( argc == 2 )
  771. {
  772. ProcessId = _wtoi( argv[1] );
  773. }
  774. //
  775. // Enable debug privilege
  776. //
  777. if(!SetCurrentPrivilege(SE_DEBUG_NAME, TRUE)) {
  778. TERROR(L"SetCurrentPrivilege (debug) failed!");
  779. return E_FAIL;
  780. }
  781. if(!SetCurrentPrivilege(SE_TAKE_OWNERSHIP_NAME, TRUE)) {
  782. TERROR(L"SetCurrentPrivilege (TCB) failed!");
  783. return E_FAIL;
  784. }
  785. //
  786. // Run as local system
  787. //
  788. dwErr = GetLocalSystemToken(ProcessId, &hLocalSystem);
  789. if (NULL == hLocalSystem || dwErr != S_OK) {
  790. goto Ret;
  791. }
  792. // dwErr = LogoffAndRevert(hToken, pSD);
  793. {
  794. STARTUPINFO si;
  795. PROCESS_INFORMATION pi;
  796. ZeroMemory( &si, sizeof(si) );
  797. ZeroMemory( &pi, sizeof(pi) );
  798. si.cb = sizeof(si);
  799. si.lpTitle = "NT AUTHORITY\\SYSTEM";
  800. if(!CreateProcessAsUserA(
  801. hLocalSystem,
  802. NULL,
  803. "cmd.exe",
  804. NULL,
  805. NULL,
  806. FALSE,
  807. CREATE_NEW_CONSOLE,
  808. NULL,
  809. NULL,
  810. &si,
  811. &pi
  812. ))
  813. {
  814. TERRORVAL(L"CreateProcessAsUser", GetLastError());
  815. }
  816. }
  817. if (NULL != pSD) {
  818. MyFree(pSD);
  819. pSD = NULL;
  820. }
  821. if (hToken != INVALID_HANDLE_VALUE) {
  822. CloseHandle(hToken);
  823. hToken = INVALID_HANDLE_VALUE;
  824. }
  825. Ret:
  826. if (hToken != INVALID_HANDLE_VALUE) {
  827. CloseHandle(hToken);
  828. }
  829. if (NULL != hLocalSystem) {
  830. RevertToSelf();
  831. CloseHandle(hLocalSystem);
  832. }
  833. return dwErr;
  834. }