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.

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