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.

3915 lines
96 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. sceclnt.cpp
  5. Abstract:
  6. SCE Client APIs
  7. Author:
  8. Jin Huang (jinhuang) 23-Jun-1997 created
  9. Revision History:
  10. jinhuang 23-Jan-1998 split to client-server model
  11. --*/
  12. #include "headers.h"
  13. #include "scerpc.h"
  14. #include "sceutil.h"
  15. #include "clntutil.h"
  16. #include "infp.h"
  17. #include "scedllrc.h"
  18. #include <ntrpcp.h>
  19. #include <rpcasync.h>
  20. #pragma hdrstop
  21. extern PVOID theCallBack;
  22. extern HWND hCallbackWnd;
  23. extern DWORD CallbackType;
  24. extern HINSTANCE MyModuleHandle;
  25. PVOID theBrowseCallBack = NULL;
  26. #define SCE_REGISTER_REGVALUE_SECTION TEXT("Register Registry Values")
  27. typedef BOOL (WINAPI *PFNREFRESHPOLICY)( BOOL );
  28. SCESTATUS
  29. ScepMergeBuffer(
  30. IN OUT PSCE_PROFILE_INFO pOldBuf,
  31. IN PSCE_PROFILE_INFO pNewBuf,
  32. IN AREA_INFORMATION Area
  33. );
  34. SCESTATUS
  35. ScepConvertServices(
  36. IN OUT PVOID *ppServices,
  37. IN BOOL bSRForm
  38. );
  39. SCESTATUS
  40. ScepFreeConvertedServices(
  41. IN PVOID pServices,
  42. IN BOOL bSRForm
  43. );
  44. DWORD
  45. ScepMakeSelfRelativeSD(
  46. IN PSECURITY_DESCRIPTOR pInSD,
  47. OUT PSECURITY_DESCRIPTOR *pOutSD,
  48. OUT PULONG pnLen
  49. );
  50. //
  51. // exported APIs in secedit.h (for secedit UI to use)
  52. //
  53. SCESTATUS
  54. WINAPI
  55. SceGetSecurityProfileInfo(
  56. IN PVOID hProfile OPTIONAL,
  57. IN SCETYPE ProfileType,
  58. IN AREA_INFORMATION Area,
  59. IN OUT PSCE_PROFILE_INFO *ppInfoBuffer,
  60. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  61. )
  62. /*
  63. Routine Description:
  64. SceGetSecurityProfileInfo will return the following type based on the
  65. SCETYPE parameter and profile handle:
  66. Profile Handle SCETYPE USAGE type field in SCE_PROFILE_INFO
  67. ---------------------------------------------------------------------------------------------------------------------------------------------------------
  68. JET SCE_ENGINE_SCP SCE_ENGINE_SCP
  69. JET SCE_ENGINE_SAP SCE_ENGINE_SAP
  70. JET SCE_ENGINE_SMP SCE_ENGINE_SMP
  71. JET all other SCETYPEs INVALID PARAMETER
  72. INF SCE_ENGINE_SCP SCE_STRUCT_INF
  73. INF all other SCETYPEs INVALID PARAMETER
  74. Arguments:
  75. hProfile - the Inf or SCE databas handle
  76. ProfileType - the profile type
  77. Area - the Area to read info for
  78. ppInfoBuffer- the output buffer
  79. Errlog - the error log buffer if there is any
  80. Retuen Value:
  81. SCE status
  82. */
  83. {
  84. SCESTATUS rc;
  85. if ( !ppInfoBuffer || 0 == Area ) {
  86. return(SCESTATUS_INVALID_PARAMETER);
  87. }
  88. if ( !hProfile && ProfileType != SCE_ENGINE_SYSTEM ) {
  89. return(SCESTATUS_INVALID_PARAMETER);
  90. }
  91. BYTE dType;
  92. if ( hProfile ) {
  93. dType = *((BYTE *)hProfile);
  94. } else {
  95. dType = 0;
  96. }
  97. //
  98. // the first component in both INF and JET handle structures
  99. // is the ProfileFormat field - DWORD
  100. //
  101. switch ( dType ) {
  102. case SCE_INF_FORMAT:
  103. //
  104. // Inf format is only available to SCP type
  105. //
  106. if ( ProfileType != SCE_ENGINE_SCP ) {
  107. return(SCESTATUS_INVALID_PARAMETER);
  108. }
  109. //
  110. // initialize the error log buffer
  111. //
  112. if ( Errlog ) {
  113. *Errlog = NULL;
  114. }
  115. rc = SceInfpGetSecurityProfileInfo(
  116. ((PSCE_HINF)hProfile)->hInf,
  117. Area,
  118. ppInfoBuffer,
  119. Errlog
  120. );
  121. break;
  122. default:
  123. if ( ProfileType != SCE_ENGINE_SCP &&
  124. ProfileType != SCE_ENGINE_SMP &&
  125. ProfileType != SCE_ENGINE_SAP &&
  126. ProfileType != SCE_ENGINE_SYSTEM &&
  127. ProfileType != SCE_ENGINE_GPO ) {
  128. return(SCESTATUS_INVALID_PARAMETER);
  129. }
  130. //
  131. // initialize the error log buffer
  132. //
  133. if ( Errlog ) {
  134. *Errlog = NULL;
  135. }
  136. PSCE_PROFILE_INFO pWkBuffer=NULL;
  137. PSCE_ERROR_LOG_INFO pErrTmp=NULL;
  138. //
  139. // handle Rpc exceptions
  140. //
  141. RpcTryExcept {
  142. if ( ProfileType == SCE_ENGINE_SYSTEM ) {
  143. Area &= (AREA_SECURITY_POLICY | AREA_PRIVILEGES);
  144. if ( hProfile ) {
  145. //
  146. // the local policy database can be opened
  147. //
  148. rc = SceRpcGetSystemSecurityFromHandle(
  149. (SCEPR_CONTEXT)hProfile,
  150. (AREAPR)Area,
  151. 0,
  152. (PSCEPR_PROFILE_INFO *)&pWkBuffer,
  153. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  154. );
  155. } else {
  156. //
  157. // just get system settings
  158. // for normal user, the local policy database
  159. // can't be opened.
  160. //
  161. //
  162. // RPC bind to the server
  163. //
  164. handle_t binding_h;
  165. NTSTATUS NtStatus = ScepBindSecureRpc(
  166. NULL,
  167. L"scerpc",
  168. 0,
  169. &binding_h
  170. );
  171. if (NT_SUCCESS(NtStatus)){
  172. RpcTryExcept {
  173. rc = SceRpcGetSystemSecurity(
  174. binding_h,
  175. (AREAPR)Area,
  176. 0,
  177. (PSCEPR_PROFILE_INFO *)&pWkBuffer,
  178. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  179. );
  180. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  181. //
  182. // get exception code (DWORD)
  183. //
  184. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  185. } RpcEndExcept;
  186. //
  187. // Free the binding handle
  188. //
  189. RpcpUnbindRpc( binding_h );
  190. } else {
  191. rc = ScepDosErrorToSceStatus(
  192. RtlNtStatusToDosError( NtStatus ));
  193. }
  194. }
  195. } else {
  196. rc = SceRpcGetDatabaseInfo(
  197. (SCEPR_CONTEXT)hProfile,
  198. (SCEPR_TYPE)ProfileType,
  199. (AREAPR)Area,
  200. (PSCEPR_PROFILE_INFO *)&pWkBuffer,
  201. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  202. );
  203. }
  204. if ( pWkBuffer ) {
  205. if ( ProfileType != SCE_ENGINE_SYSTEM ) {
  206. //
  207. // convert the service list first
  208. //
  209. for ( PSCE_SERVICES ps=pWkBuffer->pServices;
  210. ps != NULL; ps = ps->Next ) {
  211. if ( ps->General.pSecurityDescriptor ) {
  212. //
  213. // this is really the SCEPR_SR_SECURITY_DESCRIPTOR *
  214. //
  215. PSCEPR_SR_SECURITY_DESCRIPTOR pWrap;
  216. pWrap = (PSCEPR_SR_SECURITY_DESCRIPTOR)(ps->General.pSecurityDescriptor);
  217. ps->General.pSecurityDescriptor = (PSECURITY_DESCRIPTOR)(pWrap->SecurityDescriptor);
  218. ScepFree(pWrap);
  219. }
  220. }
  221. }
  222. //
  223. // information is loaded ok, now merge them into ppInfoBuffer
  224. //
  225. if ( *ppInfoBuffer ) {
  226. if ( AREA_ALL != Area ) {
  227. //
  228. // merge new data into this buffer
  229. //
  230. ScepMergeBuffer(*ppInfoBuffer, pWkBuffer, Area);
  231. } else {
  232. PSCE_PROFILE_INFO pTemp=*ppInfoBuffer;
  233. *ppInfoBuffer = pWkBuffer;
  234. pWkBuffer = pTemp;
  235. }
  236. //
  237. // free the work buffer
  238. //
  239. SceFreeProfileMemory(pWkBuffer);
  240. } else {
  241. //
  242. // just assign it to the output buffer
  243. //
  244. *ppInfoBuffer = pWkBuffer;
  245. }
  246. }
  247. //
  248. // assign the error log
  249. //
  250. if ( Errlog ) {
  251. *Errlog = pErrTmp;
  252. pErrTmp = NULL;
  253. }
  254. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  255. //
  256. // get exception code (DWORD)
  257. //
  258. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  259. } RpcEndExcept;
  260. if ( pErrTmp ) {
  261. //
  262. // free this tmp buffer
  263. //
  264. ScepFreeErrorLog(pErrTmp);
  265. }
  266. break;
  267. }
  268. return(rc);
  269. }
  270. SCESTATUS
  271. ScepMergeBuffer(
  272. IN OUT PSCE_PROFILE_INFO pOldBuf,
  273. IN PSCE_PROFILE_INFO pNewBuf,
  274. IN AREA_INFORMATION Area
  275. )
  276. /*
  277. Routine Description:
  278. Merge information for the area(s) from new buffer into old buffer.
  279. Arguments:
  280. Return Value:
  281. */
  282. {
  283. if ( !pOldBuf || !pNewBuf || !Area ) {
  284. return(SCESTATUS_INVALID_PARAMETER);
  285. }
  286. __try {
  287. if ( Area & AREA_SECURITY_POLICY ) {
  288. //
  289. // copy system access section,
  290. // note: free existing memory first
  291. //
  292. if ( pOldBuf->NewAdministratorName ) {
  293. ScepFree(pOldBuf->NewAdministratorName);
  294. }
  295. if ( pOldBuf->NewGuestName ) {
  296. ScepFree(pOldBuf->NewGuestName);
  297. }
  298. size_t nStart = offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordAge);
  299. size_t nEnd = offsetof(struct _SCE_PROFILE_INFO, ClearTextPassword)+sizeof(DWORD);
  300. memcpy((PBYTE)pOldBuf+nStart, (PBYTE)pNewBuf+nStart, nEnd-nStart);
  301. //
  302. // set NULL to memory directly assigned to the old buffer
  303. //
  304. pNewBuf->NewAdministratorName = NULL;
  305. pNewBuf->NewGuestName = NULL;
  306. //
  307. // copy kerberos policy and local policy
  308. // free exist memory used by the old buffer
  309. //
  310. if ( pOldBuf->pKerberosInfo ) {
  311. ScepFree(pOldBuf->pKerberosInfo);
  312. }
  313. nStart = offsetof(struct _SCE_PROFILE_INFO, pKerberosInfo );
  314. nEnd = offsetof(struct _SCE_PROFILE_INFO, CrashOnAuditFull)+sizeof(DWORD);
  315. memcpy((PBYTE)pOldBuf+nStart, (PBYTE)pNewBuf+nStart, nEnd-nStart);
  316. //
  317. // set NULL to memory directly assigned to the old buffer
  318. //
  319. pNewBuf->pKerberosInfo = NULL;
  320. //
  321. // copy registry values info
  322. //
  323. if ( pOldBuf->aRegValues ) {
  324. ScepFreeRegistryValues(&(pOldBuf->aRegValues), pOldBuf->RegValueCount);
  325. }
  326. pOldBuf->RegValueCount = pNewBuf->RegValueCount;
  327. pOldBuf->aRegValues = pNewBuf->aRegValues;
  328. pNewBuf->aRegValues = NULL;
  329. }
  330. //
  331. // do not care user settings
  332. //
  333. if ( Area & AREA_PRIVILEGES ) {
  334. //
  335. // privilege section
  336. //
  337. SceFreeMemory(pOldBuf, AREA_PRIVILEGES);
  338. pOldBuf->OtherInfo.smp.pPrivilegeAssignedTo = pNewBuf->OtherInfo.smp.pPrivilegeAssignedTo;
  339. pNewBuf->OtherInfo.smp.pPrivilegeAssignedTo = NULL;
  340. }
  341. if ( Area & AREA_GROUP_MEMBERSHIP ) {
  342. //
  343. // group membership area
  344. //
  345. if ( pOldBuf->pGroupMembership ) {
  346. ScepFreeGroupMembership(pOldBuf->pGroupMembership);
  347. }
  348. pOldBuf->pGroupMembership = pNewBuf->pGroupMembership;
  349. pNewBuf->pGroupMembership = NULL;
  350. }
  351. if ( Area & AREA_REGISTRY_SECURITY ) {
  352. //
  353. // registry keys
  354. //
  355. if ( pOldBuf->pRegistryKeys.pOneLevel ) {
  356. ScepFreeObjectList( pOldBuf->pRegistryKeys.pOneLevel );
  357. }
  358. pOldBuf->pRegistryKeys.pOneLevel = pNewBuf->pRegistryKeys.pOneLevel;
  359. pNewBuf->pRegistryKeys.pOneLevel = NULL;
  360. }
  361. if ( Area & AREA_FILE_SECURITY ) {
  362. //
  363. // file security
  364. //
  365. if ( pOldBuf->pFiles.pOneLevel ) {
  366. ScepFreeObjectList( pOldBuf->pFiles.pOneLevel );
  367. }
  368. pOldBuf->pFiles.pOneLevel = pNewBuf->pFiles.pOneLevel;
  369. pNewBuf->pFiles.pOneLevel = NULL;
  370. }
  371. #if 0
  372. if ( Area & AREA_DS_OBJECTS ) {
  373. //
  374. // ds objects
  375. //
  376. if ( pOldBuf->pDsObjects.pOneLevel ) {
  377. ScepFreeObjectList( pOldBuf->pDsObjects.pOneLevel );
  378. }
  379. pOldBuf->pDsObjects.pOneLevel = pNewBuf->pDsObjects.pOneLevel;
  380. pNewBuf->pDsObjects.pOneLevel = NULL;
  381. }
  382. #endif
  383. if ( Area & AREA_SYSTEM_SERVICE ) {
  384. //
  385. // system services
  386. //
  387. if ( pOldBuf->pServices ) {
  388. SceFreePSCE_SERVICES( pOldBuf->pServices);
  389. }
  390. pOldBuf->pServices = pNewBuf->pServices;
  391. pNewBuf->pServices = NULL;
  392. }
  393. } __except (EXCEPTION_EXECUTE_HANDLER) {
  394. return (SCESTATUS_OTHER_ERROR);
  395. }
  396. return(SCESTATUS_SUCCESS);
  397. }
  398. SCESTATUS
  399. WINAPI
  400. SceGetObjectChildren(
  401. IN PVOID hProfile,
  402. IN SCETYPE ProfileType,
  403. IN AREA_INFORMATION Area,
  404. IN PWSTR ObjectPrefix,
  405. OUT PSCE_OBJECT_CHILDREN *Buffer,
  406. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  407. )
  408. /*
  409. Routine Description:
  410. Routine to get one level of children from the SCE database for the object
  411. named in ObjectPrefix.
  412. Arguments:
  413. hProfile - the database context handle
  414. ProfileType - the database type
  415. Area - the area to request (files, registry, ds objects, ..)
  416. ObjectPrefix - the parent object name
  417. Buffer - the output buffer for object list
  418. Errlog - the error log buffer
  419. Return Value:
  420. SCE status of this operation
  421. */
  422. {
  423. SCESTATUS rc;
  424. if ( hProfile == NULL ||
  425. Buffer == NULL ||
  426. ObjectPrefix == NULL ) {
  427. return(SCESTATUS_INVALID_PARAMETER);
  428. }
  429. if ( SCE_INF_FORMAT == *((BYTE *)hProfile) ) {
  430. return(SCESTATUS_INVALID_PARAMETER);
  431. }
  432. if ( ProfileType != SCE_ENGINE_SCP &&
  433. ProfileType != SCE_ENGINE_SMP &&
  434. ProfileType != SCE_ENGINE_SAP ) {
  435. return(SCESTATUS_INVALID_PARAMETER);
  436. }
  437. //
  438. // initialize the error log buffer
  439. //
  440. if ( Errlog ) {
  441. *Errlog = NULL;
  442. }
  443. //
  444. // call RPC interface
  445. //
  446. PSCE_ERROR_LOG_INFO pErrTmp=NULL;
  447. RpcTryExcept {
  448. //
  449. // structure types must be casted for RPC data marshelling
  450. //
  451. rc = SceRpcGetObjectChildren(
  452. (SCEPR_CONTEXT)hProfile,
  453. (SCEPR_TYPE)ProfileType,
  454. (AREAPR)Area,
  455. (wchar_t *)ObjectPrefix,
  456. (PSCEPR_OBJECT_CHILDREN *)Buffer,
  457. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  458. );
  459. if ( Errlog ) {
  460. *Errlog = pErrTmp;
  461. } else if ( pErrTmp ) {
  462. ScepFreeErrorLog(pErrTmp);
  463. }
  464. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  465. //
  466. // get exception code (DWORD)
  467. //
  468. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  469. } RpcEndExcept;
  470. return(rc);
  471. }
  472. SCESTATUS
  473. WINAPI
  474. SceOpenProfile(
  475. IN PCWSTR ProfileName OPTIONAL, // for the system database
  476. IN SCE_FORMAT_TYPE ProfileFormat,
  477. OUT PVOID *hProfile
  478. )
  479. /*
  480. Routine Description:
  481. Arguments:
  482. ProfileName - the profile name to open, use UNC name for remote
  483. ProfileFormat - the format of the profile
  484. SCE_INF_FORMAT,
  485. SCE_JET_FORMAT,
  486. SCE_JET_ANALYSIS_REQUIRED
  487. hProfile - the profile handle returned
  488. Return Value:
  489. SCE status of this operation
  490. */
  491. {
  492. SCESTATUS rc;
  493. LPTSTR DefProfile=NULL;
  494. SCEPR_CONTEXT pContext = NULL;
  495. if ( hProfile == NULL ) {
  496. return(SCESTATUS_INVALID_PARAMETER);
  497. }
  498. BOOL bEmptyName=FALSE;
  499. if ( ProfileName == NULL || wcslen(ProfileName) == 0 ) {
  500. bEmptyName = TRUE;
  501. }
  502. switch (ProfileFormat ) {
  503. case SCE_INF_FORMAT:
  504. if ( bEmptyName ) {
  505. return(SCESTATUS_INVALID_PARAMETER);
  506. }
  507. //
  508. // Inf format
  509. //
  510. *hProfile = ScepAlloc( LMEM_ZEROINIT, sizeof(SCE_HINF) );
  511. if ( *hProfile == NULL ) {
  512. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  513. }
  514. ((PSCE_HINF)(*hProfile))->Type = (BYTE)SCE_INF_FORMAT;
  515. rc = SceInfpOpenProfile(
  516. ProfileName,
  517. &(((PSCE_HINF)(*hProfile))->hInf)
  518. );
  519. if ( rc != SCESTATUS_SUCCESS ) {
  520. //
  521. // free memory
  522. //
  523. ScepFree( *hProfile );
  524. *hProfile = NULL;
  525. }
  526. break;
  527. case SCE_JET_ANALYSIS_REQUIRED:
  528. case SCE_JET_FORMAT:
  529. BOOL bAnalysis;
  530. if ( SCE_JET_FORMAT == ProfileFormat ) {
  531. bAnalysis = FALSE;
  532. if ( bEmptyName ) {
  533. //
  534. // looking for the system database
  535. //
  536. rc = ScepGetProfileSetting(
  537. L"DefaultProfile",
  538. TRUE, // in order to get system db name. Access will be checked when opening the database
  539. &DefProfile
  540. );
  541. if ( rc != ERROR_SUCCESS || DefProfile == NULL ) {
  542. return(SCESTATUS_INVALID_PARAMETER);
  543. }
  544. }
  545. } else {
  546. bAnalysis = TRUE;
  547. //
  548. // jet database name is required
  549. //
  550. if ( bEmptyName ) {
  551. return(SCESTATUS_ACCESS_DENIED);
  552. }
  553. }
  554. //
  555. // system database can't be opened for SCM mode
  556. //
  557. if ( bAnalysis &&
  558. SceIsSystemDatabase(ProfileName) ) {
  559. return(SCESTATUS_ACCESS_DENIED);
  560. }
  561. handle_t binding_h;
  562. NTSTATUS NtStatus;
  563. //
  564. // RPC bind to the server
  565. //
  566. NtStatus = ScepBindSecureRpc(
  567. NULL, // should use the system name embedded within the database name
  568. L"scerpc",
  569. 0,
  570. &binding_h
  571. );
  572. if (NT_SUCCESS(NtStatus)){
  573. RpcTryExcept {
  574. rc = SceRpcOpenDatabase(
  575. binding_h,
  576. bEmptyName ? (wchar_t *)DefProfile : (wchar_t *)ProfileName,
  577. bAnalysis ? SCE_OPEN_OPTION_REQUIRE_ANALYSIS : 0,
  578. &pContext
  579. );
  580. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  581. //
  582. // get exception code (DWORD)
  583. //
  584. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  585. } RpcEndExcept;
  586. //
  587. // Free the binding handle
  588. //
  589. RpcpUnbindRpc( binding_h );
  590. } else {
  591. rc = ScepDosErrorToSceStatus(
  592. RtlNtStatusToDosError( NtStatus ));
  593. }
  594. if ( SCESTATUS_SUCCESS == rc ) {
  595. //
  596. // database is opened
  597. //
  598. *hProfile = (PVOID)pContext;
  599. } else {
  600. *hProfile = NULL;
  601. }
  602. break;
  603. default:
  604. rc = SCESTATUS_INVALID_PARAMETER;
  605. break;
  606. }
  607. if ( DefProfile ) {
  608. ScepFree(DefProfile);
  609. }
  610. return(rc);
  611. }
  612. SCESTATUS
  613. WINAPI
  614. SceCloseProfile(
  615. IN PVOID *hProfile
  616. )
  617. /*
  618. Routine Description:
  619. Close the profile handle
  620. Arguments:
  621. hProfile - the address of a profile handle
  622. Return Value:
  623. SCE status of this operation
  624. */
  625. {
  626. if ( hProfile == NULL ) {
  627. return(SCESTATUS_INVALID_PARAMETER);
  628. }
  629. if ( *hProfile == NULL ) {
  630. return(SCESTATUS_SUCCESS);
  631. }
  632. SCESTATUS rc = SCESTATUS_SUCCESS;
  633. switch(*((BYTE *)(*hProfile)) ) {
  634. case SCE_INF_FORMAT:
  635. //
  636. // close the inf handle
  637. //
  638. SceInfpCloseProfile(((PSCE_HINF)(*hProfile))->hInf);
  639. ScepFree(*hProfile);
  640. *hProfile = NULL;
  641. break;
  642. default:
  643. //
  644. // jet database, call rpc to close it
  645. //
  646. RpcTryExcept {
  647. rc = SceRpcCloseDatabase((SCEPR_CONTEXT *)hProfile);
  648. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  649. //
  650. // get exception code (DWORD)
  651. //
  652. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  653. } RpcEndExcept;
  654. break;
  655. }
  656. return(rc);
  657. }
  658. SCESTATUS
  659. WINAPI
  660. SceGetScpProfileDescription(
  661. IN PVOID hProfile,
  662. OUT PWSTR *Description
  663. )
  664. /*
  665. Routine Descripton:
  666. Get profile description from the profile handle
  667. Arguments:
  668. hProfile - the profile handle
  669. Description - the description output buffer
  670. Return Value:
  671. SCE status
  672. */
  673. {
  674. SCESTATUS rc;
  675. if ( hProfile == NULL || Description == NULL ) {
  676. return(SCESTATUS_SUCCESS);
  677. }
  678. switch( *((BYTE *)hProfile) ) {
  679. case SCE_INF_FORMAT:
  680. //
  681. // inf format of profile
  682. //
  683. rc = SceInfpGetDescription(
  684. ((PSCE_HINF)hProfile)->hInf,
  685. Description
  686. );
  687. break;
  688. default:
  689. //
  690. // jet database, call rpc interface
  691. //
  692. RpcTryExcept {
  693. rc = SceRpcGetDatabaseDescription(
  694. (SCEPR_CONTEXT)hProfile,
  695. (wchar_t **)Description
  696. );
  697. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  698. //
  699. // get exception code (DWORD)
  700. //
  701. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  702. } RpcEndExcept;
  703. break;
  704. }
  705. return(rc);
  706. }
  707. SCESTATUS
  708. WINAPI
  709. SceGetTimeStamp(
  710. IN PVOID hProfile,
  711. OUT PWSTR *ConfigTimeStamp OPTIONAL,
  712. OUT PWSTR *AnalyzeTimeStamp OPTIONAL
  713. )
  714. /*
  715. Routine Descripton:
  716. Get SCE database last config and last analysis time stamp
  717. Arguments:
  718. hProfile - the profile handle
  719. ConfigTimeStamp - the time stamp for last config
  720. AnalyzeTimeStamp - the time stamp for last analysis
  721. Return Value:
  722. SCE status
  723. */
  724. {
  725. SCESTATUS rc;
  726. LARGE_INTEGER TimeStamp1;
  727. LARGE_INTEGER TimeStamp2;
  728. LARGE_INTEGER ConfigTime;
  729. LARGE_INTEGER AnalyzeTime;
  730. TIME_FIELDS TimeFields;
  731. if ( hProfile == NULL ||
  732. ( ConfigTimeStamp == NULL &&
  733. AnalyzeTimeStamp == NULL) ) {
  734. return(SCESTATUS_INVALID_PARAMETER);
  735. }
  736. //
  737. // call RPC interface
  738. //
  739. RpcTryExcept {
  740. rc = SceRpcGetDBTimeStamp(
  741. (SCEPR_CONTEXT)hProfile,
  742. &ConfigTime,
  743. &AnalyzeTime
  744. );
  745. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  746. //
  747. // get exception code (DWORD)
  748. //
  749. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  750. } RpcEndExcept;
  751. if ( rc == SCESTATUS_SUCCESS ) {
  752. if ( ConfigTimeStamp ) {
  753. *ConfigTimeStamp = NULL;
  754. if ( ConfigTime.HighPart != 0 || ConfigTime.LowPart != 0 ) {
  755. //
  756. // convert the config time stamp from LARGE_INTEGER to
  757. // string format
  758. //
  759. RtlSystemTimeToLocalTime(&ConfigTime, &TimeStamp1);
  760. if ( TimeStamp1.LowPart != 0 ||
  761. TimeStamp1.HighPart != 0) {
  762. memset(&TimeFields, 0, sizeof(TIME_FIELDS));
  763. RtlTimeToTimeFields (
  764. &TimeStamp1,
  765. &TimeFields
  766. );
  767. if ( TimeFields.Month > 0 && TimeFields.Month <= 12 &&
  768. TimeFields.Day > 0 && TimeFields.Day <= 31 &&
  769. TimeFields.Year > 1600 ) {
  770. *ConfigTimeStamp = (PWSTR)ScepAlloc(0, 60); //60 bytes
  771. swprintf(*ConfigTimeStamp, L"%02d/%02d/%04d %02d:%02d:%02d",
  772. TimeFields.Month, TimeFields.Day, TimeFields.Year,
  773. TimeFields.Hour, TimeFields.Minute, TimeFields.Second);
  774. } else {
  775. *ConfigTimeStamp = (PWSTR)ScepAlloc(0, 40); //40 bytes
  776. swprintf(*ConfigTimeStamp, L"%08x%08x", TimeStamp1.HighPart, TimeStamp1.LowPart);
  777. }
  778. }
  779. }
  780. }
  781. if ( AnalyzeTimeStamp ) {
  782. *AnalyzeTimeStamp = NULL;
  783. if ( AnalyzeTime.HighPart != 0 || AnalyzeTime.LowPart != 0 ) {
  784. //
  785. // convert the analysis time stamp from LARGE_INTEGER
  786. // to string format
  787. //
  788. RtlSystemTimeToLocalTime(&AnalyzeTime, &TimeStamp2);
  789. if ( TimeStamp2.LowPart != 0 ||
  790. TimeStamp2.HighPart != 0) {
  791. memset(&TimeFields, 0, sizeof(TIME_FIELDS));
  792. RtlTimeToTimeFields (
  793. &TimeStamp2,
  794. &TimeFields
  795. );
  796. if ( TimeFields.Month > 0 && TimeFields.Month <= 12 &&
  797. TimeFields.Day > 0 && TimeFields.Day <= 31 &&
  798. TimeFields.Year > 1600 ) {
  799. *AnalyzeTimeStamp = (PWSTR)ScepAlloc(0, 60); //40 bytes
  800. swprintf(*AnalyzeTimeStamp, L"%02d/%02d/%04d %02d:%02d:%02d",
  801. TimeFields.Month, TimeFields.Day, TimeFields.Year,
  802. TimeFields.Hour, TimeFields.Minute, TimeFields.Second);
  803. } else {
  804. *AnalyzeTimeStamp = (PWSTR)ScepAlloc(0, 40); //40 bytes
  805. swprintf(*AnalyzeTimeStamp, L"%08x%08x", TimeStamp2.HighPart, TimeStamp2.LowPart);
  806. }
  807. }
  808. }
  809. }
  810. }
  811. return(rc);
  812. }
  813. SCESTATUS
  814. WINAPI
  815. SceGetDbTime(
  816. IN PVOID hProfile,
  817. OUT SYSTEMTIME *ConfigDateTime,
  818. OUT SYSTEMTIME *AnalyzeDateTime
  819. )
  820. /*
  821. Routine Descripton:
  822. Get SCE database last config and last analysis time (in SYSTEMTIME structure)
  823. Arguments:
  824. hProfile - the profile handle
  825. ConfigDateTime - the system time for last configuration
  826. AnalyzeDateTime - the system time for last analysis
  827. Return Value:
  828. SCE status
  829. */
  830. {
  831. SCESTATUS rc;
  832. LARGE_INTEGER TimeStamp;
  833. LARGE_INTEGER ConfigTimeStamp;
  834. LARGE_INTEGER AnalyzeTimeStamp;
  835. FILETIME ft;
  836. if ( hProfile == NULL ||
  837. ( ConfigDateTime == NULL &&
  838. AnalyzeDateTime == NULL) ) {
  839. return(SCESTATUS_INVALID_PARAMETER);
  840. }
  841. //
  842. // call RPC interface
  843. //
  844. RpcTryExcept {
  845. rc = SceRpcGetDBTimeStamp(
  846. (SCEPR_CONTEXT)hProfile,
  847. &ConfigTimeStamp,
  848. &AnalyzeTimeStamp
  849. );
  850. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  851. //
  852. // get exception code (DWORD)
  853. //
  854. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  855. } RpcEndExcept;
  856. if ( rc == SCESTATUS_SUCCESS ) {
  857. if ( ConfigDateTime ) {
  858. memset(ConfigDateTime, '\0', sizeof(SYSTEMTIME));
  859. if ( ConfigTimeStamp.HighPart != 0 || ConfigTimeStamp.LowPart != 0 ) {
  860. //
  861. // convert the config time stamp from LARGE_INTEGER to
  862. // string format
  863. //
  864. RtlSystemTimeToLocalTime(&ConfigTimeStamp, &TimeStamp);
  865. if ( TimeStamp.LowPart != 0 ||
  866. TimeStamp.HighPart != 0) {
  867. ft.dwLowDateTime = TimeStamp.LowPart;
  868. ft.dwHighDateTime = TimeStamp.HighPart;
  869. if ( !FileTimeToSystemTime(&ft, ConfigDateTime) ) {
  870. rc = ScepDosErrorToSceStatus(GetLastError());
  871. }
  872. }
  873. }
  874. }
  875. if ( AnalyzeDateTime && (SCESTATUS_SUCCESS == rc) ) {
  876. memset(AnalyzeDateTime, '\0', sizeof(SYSTEMTIME));
  877. if ( AnalyzeTimeStamp.HighPart != 0 || AnalyzeTimeStamp.LowPart != 0 ) {
  878. //
  879. // convert the analysis time stamp from LARGE_INTEGER
  880. // to string format
  881. //
  882. RtlSystemTimeToLocalTime(&AnalyzeTimeStamp, &TimeStamp);
  883. if ( TimeStamp.LowPart != 0 ||
  884. TimeStamp.HighPart != 0) {
  885. ft.dwLowDateTime = TimeStamp.LowPart;
  886. ft.dwHighDateTime = TimeStamp.HighPart;
  887. if ( !FileTimeToSystemTime(&ft, AnalyzeDateTime) ) {
  888. rc = ScepDosErrorToSceStatus(GetLastError());
  889. }
  890. }
  891. }
  892. }
  893. }
  894. return(rc);
  895. }
  896. SCESTATUS
  897. WINAPI
  898. SceGetObjectSecurity(
  899. IN PVOID hProfile,
  900. IN SCETYPE ProfileType,
  901. IN AREA_INFORMATION Area,
  902. IN PWSTR ObjectName,
  903. OUT PSCE_OBJECT_SECURITY *ObjSecurity
  904. )
  905. /*
  906. Routine Descripton:
  907. Get security setting for an object from the SCE database
  908. Arguments:
  909. hProfile - the profile handle
  910. ProfileType - the database type
  911. Area - the security area to get info (file, registry, ..)
  912. ObjectName - the object's name (full path)
  913. ObjSecurity - the security settings (flag, SDDL)
  914. Return Value:
  915. SCE status
  916. */
  917. {
  918. SCESTATUS rc;
  919. if ( hProfile == NULL ||
  920. ObjectName == NULL ||
  921. ObjSecurity == NULL ) {
  922. return(SCESTATUS_INVALID_PARAMETER);
  923. }
  924. if ( ProfileType != SCE_ENGINE_SCP &&
  925. ProfileType != SCE_ENGINE_SMP &&
  926. ProfileType != SCE_ENGINE_SAP ) {
  927. return(SCESTATUS_INVALID_PARAMETER);
  928. }
  929. //
  930. // call rpc interface
  931. //
  932. RpcTryExcept {
  933. rc = SceRpcGetObjectSecurity(
  934. (SCEPR_CONTEXT)hProfile,
  935. (SCEPR_TYPE)ProfileType,
  936. (AREAPR)Area,
  937. (wchar_t *)ObjectName,
  938. (PSCEPR_OBJECT_SECURITY *)ObjSecurity
  939. );
  940. //
  941. // convert the security descriptor
  942. //
  943. if ( *ObjSecurity && (*ObjSecurity)->pSecurityDescriptor ) {
  944. //
  945. // this is really the SCEPR_SR_SECURITY_DESCRIPTOR *
  946. //
  947. PSCEPR_SR_SECURITY_DESCRIPTOR pWrap = (PSCEPR_SR_SECURITY_DESCRIPTOR)((*ObjSecurity)->pSecurityDescriptor);
  948. (*ObjSecurity)->pSecurityDescriptor = (PSECURITY_DESCRIPTOR)(pWrap->SecurityDescriptor);
  949. ScepFree(pWrap);
  950. }
  951. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  952. //
  953. // get exception code (DWORD)
  954. //
  955. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  956. } RpcEndExcept;
  957. return(rc);
  958. }
  959. SCESTATUS
  960. WINAPI
  961. SceGetAnalysisAreaSummary(
  962. IN PVOID hProfile,
  963. IN AREA_INFORMATION Area,
  964. OUT PDWORD pCount
  965. )
  966. /*
  967. Routine Descripton:
  968. Get summary information for the security area from SCE database.
  969. Arguments:
  970. hProfile - the profile handle
  971. Area - the security area to get info
  972. pCount - the total object count
  973. Return Value:
  974. SCE status
  975. */
  976. {
  977. if ( hProfile == NULL || pCount == NULL ) {
  978. return(SCESTATUS_INVALID_PARAMETER);
  979. }
  980. //
  981. // call RPC interface
  982. //
  983. SCESTATUS rc;
  984. RpcTryExcept {
  985. rc = SceRpcGetAnalysisSummary(
  986. (SCEPR_CONTEXT)hProfile,
  987. (AREAPR)Area,
  988. pCount
  989. );
  990. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  991. //
  992. // get exception code (DWORD)
  993. //
  994. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  995. } RpcEndExcept;
  996. return(rc);
  997. }
  998. SCESTATUS
  999. WINAPI
  1000. SceCopyBaseProfile(
  1001. IN PVOID hProfile,
  1002. IN SCETYPE ProfileType,
  1003. IN PWSTR InfFileName,
  1004. IN AREA_INFORMATION Area,
  1005. OUT PSCE_ERROR_LOG_INFO *pErrlog OPTIONAL
  1006. )
  1007. /* ++
  1008. Routine Description:
  1009. Copy the base profile from Jet database into a inf profile.
  1010. Arguments:
  1011. hProfile - the database handle
  1012. InfFileName - the inf template name to generate
  1013. Area - the area to generate
  1014. pErrlog - the error log buffer
  1015. Return Value:
  1016. SCE status
  1017. -- */
  1018. {
  1019. SCESTATUS rc;
  1020. PWSTR Description=NULL;
  1021. PSCE_PROFILE_INFO pSmpInfo=NULL;
  1022. SCE_PROFILE_INFO scpInfo;
  1023. AREA_INFORMATION Area2;
  1024. PSCE_ERROR_LOG_INFO pErrTmp=NULL;
  1025. PSCE_ERROR_LOG_INFO errTmp;
  1026. if ( hProfile == NULL || InfFileName == NULL ) {
  1027. return(SCESTATUS_INVALID_PARAMETER);
  1028. }
  1029. if ( ProfileType != SCE_ENGINE_SCP &&
  1030. ProfileType != SCE_ENGINE_SMP ) {
  1031. return(SCESTATUS_INVALID_PARAMETER);
  1032. }
  1033. //
  1034. // make RPC calls to query information
  1035. //
  1036. RpcTryExcept {
  1037. //
  1038. // read profile description, if fails here, continue
  1039. //
  1040. rc = SceRpcGetDatabaseDescription(
  1041. (SCEPR_CONTEXT)hProfile,
  1042. (wchar_t **)&Description
  1043. );
  1044. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1045. //
  1046. // get exception code (DWORD)
  1047. //
  1048. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1049. } RpcEndExcept;
  1050. //
  1051. // create a new inf profile with [Version] section and make it unicode
  1052. //
  1053. if ( !SetupINFAsUCS2(InfFileName) ) {
  1054. //
  1055. //if error continues
  1056. //
  1057. rc = ScepDosErrorToSceStatus(GetLastError());
  1058. }
  1059. if ( !WritePrivateProfileSection(
  1060. L"Version",
  1061. L"signature=\"$CHICAGO$\"\0Revision=1\0\0",
  1062. (LPCTSTR)InfFileName) ) {
  1063. rc = ScepDosErrorToSceStatus(GetLastError());
  1064. goto Cleanup;
  1065. }
  1066. //
  1067. // create [description], if error, continue
  1068. //
  1069. if ( Description ) {
  1070. //
  1071. // empty the description section first.
  1072. //
  1073. WritePrivateProfileSection(
  1074. L"Profile Description",
  1075. NULL,
  1076. (LPCTSTR)InfFileName);
  1077. WritePrivateProfileString(
  1078. L"Profile Description",
  1079. L"Description",
  1080. Description,
  1081. (LPCTSTR)InfFileName);
  1082. }
  1083. //
  1084. // info for the following areas can be retrieved together
  1085. //
  1086. Area2 = Area & ( AREA_SECURITY_POLICY |
  1087. AREA_GROUP_MEMBERSHIP |
  1088. AREA_PRIVILEGES );
  1089. rc = SCESTATUS_SUCCESS;
  1090. //
  1091. // initialize the error log buffer
  1092. //
  1093. if ( pErrlog ) {
  1094. *pErrlog = NULL;
  1095. }
  1096. if ( Area2 != 0 ) {
  1097. //
  1098. // read base profile information
  1099. //
  1100. rc = SceGetSecurityProfileInfo(
  1101. hProfile,
  1102. ProfileType, // SCE_ENGINE_SMP,
  1103. Area2,
  1104. &pSmpInfo,
  1105. &pErrTmp
  1106. );
  1107. if ( pErrlog ) {
  1108. *pErrlog = pErrTmp;
  1109. } else if ( pErrTmp ) {
  1110. ScepFreeErrorLog(pErrTmp);
  1111. }
  1112. pErrTmp = NULL;
  1113. if ( rc == SCESTATUS_SUCCESS && pSmpInfo != NULL ) {
  1114. //
  1115. // use a new error buffer if pErrlog is not NULL
  1116. // because SceWriteSecurityProfileInfo reset the errlog buffer to NULL
  1117. // at beginning
  1118. //
  1119. rc = SceWriteSecurityProfileInfo(
  1120. InfFileName,
  1121. Area2,
  1122. pSmpInfo,
  1123. &pErrTmp
  1124. );
  1125. if ( pErrlog && pErrTmp ) {
  1126. //
  1127. // link the new error buffer to the end of pErrlog
  1128. //
  1129. if ( *pErrlog ) {
  1130. //
  1131. // find the end of the buffer
  1132. //
  1133. for ( errTmp=*pErrlog;
  1134. errTmp && errTmp->next;
  1135. errTmp=errTmp->next);
  1136. //
  1137. // when this loop is done, errTmp->next must be NULL
  1138. //
  1139. errTmp->next = pErrTmp;
  1140. } else {
  1141. *pErrlog = pErrTmp;
  1142. }
  1143. pErrTmp = NULL;
  1144. }
  1145. }
  1146. if ( rc != SCESTATUS_SUCCESS ) {
  1147. goto Cleanup;
  1148. }
  1149. }
  1150. //
  1151. // copy privileges area
  1152. //
  1153. if ( Area & AREA_PRIVILEGES && pSmpInfo != NULL ) {
  1154. //
  1155. // write [Privileges] section
  1156. // a new error buffer is used because the api below reset the error buffer
  1157. //
  1158. scpInfo.OtherInfo.scp.u.pInfPrivilegeAssignedTo = pSmpInfo->OtherInfo.smp.pPrivilegeAssignedTo;
  1159. rc = SceWriteSecurityProfileInfo(
  1160. InfFileName,
  1161. AREA_PRIVILEGES,
  1162. &scpInfo,
  1163. &pErrTmp
  1164. );
  1165. if ( pErrlog && pErrTmp ) {
  1166. //
  1167. // link the new error buffer to the end of pErrlog
  1168. //
  1169. if ( *pErrlog ) {
  1170. //
  1171. // find the end of the buffer
  1172. //
  1173. for ( errTmp=*pErrlog;
  1174. errTmp && errTmp->next;
  1175. errTmp=errTmp->next);
  1176. //
  1177. // when this loop is done, errTmp->next must be NULL
  1178. //
  1179. errTmp->next = pErrTmp;
  1180. } else {
  1181. *pErrlog = pErrTmp;
  1182. }
  1183. pErrTmp = NULL;
  1184. }
  1185. if ( rc != SCESTATUS_SUCCESS )
  1186. goto Cleanup;
  1187. }
  1188. //
  1189. // copy objects
  1190. //
  1191. Area2 = Area & ( AREA_REGISTRY_SECURITY |
  1192. AREA_FILE_SECURITY |
  1193. // AREA_DS_OBJECTS |
  1194. AREA_SYSTEM_SERVICE |
  1195. AREA_SECURITY_POLICY |
  1196. AREA_ATTACHMENTS);
  1197. if ( Area2 ) {
  1198. //
  1199. // write objects section (szRegistryKeys, szFileSecurity,
  1200. // szDSSecurity, szServiceGeneral)
  1201. //
  1202. RpcTryExcept {
  1203. rc = SceRpcCopyObjects(
  1204. (SCEPR_CONTEXT)hProfile,
  1205. (SCEPR_TYPE)ProfileType,
  1206. (wchar_t *)InfFileName,
  1207. (AREAPR)Area2,
  1208. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  1209. );
  1210. if ( pErrlog && pErrTmp ) {
  1211. //
  1212. // link the new error buffer to the end of pErrlog
  1213. //
  1214. if ( *pErrlog ) {
  1215. //
  1216. // find the end of the buffer
  1217. //
  1218. for ( errTmp=*pErrlog;
  1219. errTmp && errTmp->next;
  1220. errTmp=errTmp->next);
  1221. //
  1222. // when this loop is done, errTmp->next must be NULL
  1223. //
  1224. errTmp->next = pErrTmp;
  1225. } else {
  1226. *pErrlog = pErrTmp;
  1227. }
  1228. pErrTmp = NULL;
  1229. }
  1230. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1231. //
  1232. // get exception code (DWORD)
  1233. //
  1234. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1235. } RpcEndExcept;
  1236. }
  1237. Cleanup:
  1238. if ( Description != NULL ) {
  1239. ScepFree(Description);
  1240. }
  1241. if ( pSmpInfo != NULL ) {
  1242. Area2 = Area & ( AREA_SECURITY_POLICY |
  1243. AREA_GROUP_MEMBERSHIP |
  1244. AREA_PRIVILEGES );
  1245. SceFreeProfileMemory(pSmpInfo);
  1246. }
  1247. if ( pErrTmp ) {
  1248. ScepFreeErrorLog(pErrTmp);
  1249. }
  1250. return(rc);
  1251. }
  1252. SCESTATUS
  1253. WINAPI
  1254. SceConfigureSystem(
  1255. IN LPTSTR SystemName OPTIONAL,
  1256. IN PCWSTR InfFileName OPTIONAL,
  1257. IN PCWSTR DatabaseName,
  1258. IN PCWSTR LogFileName OPTIONAL,
  1259. IN DWORD ConfigOptions,
  1260. IN AREA_INFORMATION Area,
  1261. IN PSCE_AREA_CALLBACK_ROUTINE pCallback OPTIONAL,
  1262. IN HANDLE hCallbackWnd OPTIONAL,
  1263. OUT PDWORD pdWarning OPTIONAL
  1264. )
  1265. // see ScepConfigSystem
  1266. {
  1267. AREA_INFORMATION Area2=Area;
  1268. if ( DatabaseName == NULL ||
  1269. SceIsSystemDatabase(DatabaseName) ) {
  1270. //
  1271. // detect if this is system database (admin logon)
  1272. // no configuration is allowed.
  1273. //
  1274. if ( DatabaseName == NULL ) {
  1275. BOOL bAdminLogon=FALSE;
  1276. ScepIsAdminLoggedOn(&bAdminLogon);
  1277. if ( bAdminLogon ) {
  1278. return(SCESTATUS_ACCESS_DENIED);
  1279. }
  1280. } else
  1281. return(SCESTATUS_ACCESS_DENIED);
  1282. }
  1283. SCESTATUS rc;
  1284. DWORD dOptions;
  1285. ScepSetCallback((PVOID)pCallback, hCallbackWnd, SCE_AREA_CALLBACK);
  1286. //
  1287. // filter out invalid options from clients
  1288. // filter out areas other than security policy and user rights
  1289. //
  1290. dOptions = ConfigOptions & 0xFFL;
  1291. rc = ScepConfigSystem(
  1292. SystemName,
  1293. InfFileName,
  1294. DatabaseName,
  1295. LogFileName,
  1296. dOptions,
  1297. Area2,
  1298. pCallback,
  1299. hCallbackWnd,
  1300. pdWarning
  1301. );
  1302. ScepSetCallback(NULL, NULL, 0);
  1303. if ( DatabaseName != NULL &&
  1304. !SceIsSystemDatabase(DatabaseName) &&
  1305. !(ConfigOptions & SCE_NO_CONFIG) &&
  1306. (Area2 & AREA_SECURITY_POLICY) ) {
  1307. //
  1308. // private database, should trigger policy propagation
  1309. // delete the last configuration time
  1310. //
  1311. HKEY hKey=NULL;
  1312. if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1313. SCE_ROOT_PATH,
  1314. 0,
  1315. KEY_READ | KEY_WRITE,
  1316. &hKey
  1317. ) == ERROR_SUCCESS ) {
  1318. RegDeleteValue(hKey, TEXT("LastWinlogonConfig"));
  1319. RegCloseKey( hKey );
  1320. }
  1321. HINSTANCE hLoadDll = LoadLibrary(TEXT("userenv.dll"));
  1322. if ( hLoadDll) {
  1323. PFNREFRESHPOLICY pfnRefreshPolicy = (PFNREFRESHPOLICY)GetProcAddress(
  1324. hLoadDll,
  1325. "RefreshPolicy");
  1326. if ( pfnRefreshPolicy ) {
  1327. (*pfnRefreshPolicy )( TRUE );
  1328. }
  1329. FreeLibrary(hLoadDll);
  1330. }
  1331. }
  1332. return(rc);
  1333. }
  1334. SCESTATUS
  1335. ScepConfigSystem(
  1336. IN LPTSTR SystemName OPTIONAL,
  1337. IN PCWSTR InfFileName OPTIONAL,
  1338. IN PCWSTR DatabaseName OPTIONAL,
  1339. IN PCWSTR LogFileName OPTIONAL,
  1340. IN DWORD ConfigOptions,
  1341. IN AREA_INFORMATION Area,
  1342. IN PSCE_AREA_CALLBACK_ROUTINE pCallback OPTIONAL,
  1343. IN HANDLE hCallbackWnd OPTIONAL,
  1344. OUT PDWORD pdWarning OPTIONAL
  1345. )
  1346. /* ++
  1347. Routine Description:
  1348. Routine to configure a system or local system if SystemName is NULL.
  1349. If DatabaseName is NULL, the default databae on the system is used.
  1350. if InfFileName is provided, depending on the ConfigOptions, info in
  1351. the InfFileName is either appended to the database (if exist), or used
  1352. to create/overwrite the database.
  1353. ConfigOptions can contain flags such as verbose log, no log, and overwrite
  1354. /update database. When overwrite is specified, existing database info
  1355. is overwritten by the inf template, and all analysis information is
  1356. cleaned up.
  1357. Callback pointers to the client can be registered as the arguments for
  1358. progress indication.
  1359. A warning code is also returned if there is any warning occurs during the
  1360. operation while the SCESTATUS return code is SCESTATUS_SUCCESS. Examples
  1361. such as ERROR_FILE_NOT_FOUND, or ERROR_ACCESS_DENIED when configuring
  1362. the system won't be counted as error of this operation because the current
  1363. user context may not have proper access to some of the resources specified
  1364. in the template.
  1365. Arguments:
  1366. SystemName - the system name where this operation will run, NULL for local system
  1367. InfFileName - optional inf template name, if NULL, existing info in the SCe
  1368. database is used to configure.
  1369. DatabaseName - the SCE database name. if NULL, the default is used.
  1370. LogFileName - optional log file name for the operation
  1371. ConfigOptions - the options to configure
  1372. SCE_OVERWRITE_DB
  1373. SCE_UPDATE_DB
  1374. SCE_VERBOSE_LOG
  1375. SCE_DISABLE_LOG
  1376. Area - Area to configure
  1377. pCallback - optional client callback routine
  1378. hCallbackWnd - a callback window handle
  1379. pdWarning - the warning code
  1380. Return Value:
  1381. SCE status
  1382. -- */
  1383. {
  1384. SCESTATUS rc;
  1385. handle_t binding_h;
  1386. NTSTATUS NtStatus;
  1387. DWORD dOptions;
  1388. dOptions = ConfigOptions & ~(SCE_CALLBACK_DELTA |
  1389. SCE_CALLBACK_TOTAL |
  1390. SCE_POLBIND_NO_AUTH);
  1391. if ( pCallback ) {
  1392. dOptions |= SCE_CALLBACK_TOTAL;
  1393. }
  1394. //
  1395. // check the input arguments
  1396. //
  1397. LPCTSTR NewInf = NULL;
  1398. LPCTSTR NewDb = NULL;
  1399. LPCTSTR NewLog = NULL;
  1400. __try {
  1401. if ( InfFileName && wcslen(InfFileName) > 0 ) {
  1402. NewInf = InfFileName;
  1403. }
  1404. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1405. }
  1406. __try {
  1407. if ( DatabaseName && wcslen(DatabaseName) > 0 ) {
  1408. NewDb = DatabaseName;
  1409. }
  1410. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1411. }
  1412. __try {
  1413. if ( LogFileName && wcslen(LogFileName) > 0 ) {
  1414. NewLog = LogFileName;
  1415. }
  1416. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1417. }
  1418. /*
  1419. if ( (ConfigOptions & SCE_POLICY_TEMPLATE) &&
  1420. !(ConfigOptions & SCE_NO_CONFIG) &&
  1421. (Area & (AREA_SECURITY_POLICY | AREA_PRIVILEGES)) ) {
  1422. //
  1423. // turn off policy filter
  1424. //
  1425. ScepRegSetIntValue(HKEY_LOCAL_MACHINE,
  1426. SCE_ROOT_PATH,
  1427. TEXT("PolicyFilterOff"),
  1428. 1
  1429. );
  1430. }
  1431. */
  1432. //
  1433. // RPC bind to the server
  1434. //
  1435. if ( ConfigOptions & SCE_POLBIND_NO_AUTH ) {
  1436. NtStatus = ScepBindRpc(
  1437. SystemName,
  1438. L"scerpc",
  1439. L"security=impersonation dynamic false",
  1440. &binding_h
  1441. );
  1442. } else {
  1443. NtStatus = ScepBindSecureRpc(
  1444. SystemName,
  1445. L"scerpc",
  1446. L"security=impersonation dynamic false",
  1447. &binding_h
  1448. );
  1449. }
  1450. if (NT_SUCCESS(NtStatus)){
  1451. LPVOID pebClient = GetEnvironmentStrings();
  1452. DWORD ebSize = ScepGetEnvStringSize(pebClient);
  1453. RpcTryExcept {
  1454. DWORD dWarn=0;
  1455. rc = SceRpcConfigureSystem(
  1456. binding_h,
  1457. (wchar_t *)NewInf,
  1458. (wchar_t *)NewDb,
  1459. (wchar_t *)NewLog,
  1460. dOptions,
  1461. (AREAPR)Area,
  1462. ebSize,
  1463. (UCHAR *)pebClient,
  1464. &dWarn
  1465. );
  1466. if ( pdWarning ) {
  1467. *pdWarning = dWarn;
  1468. }
  1469. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1470. //
  1471. // get exception code (DWORD)
  1472. //
  1473. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1474. } RpcEndExcept;
  1475. //
  1476. // Free the binding handle
  1477. //
  1478. RpcpUnbindRpc( binding_h );
  1479. } else {
  1480. rc = ScepDosErrorToSceStatus(
  1481. RtlNtStatusToDosError( NtStatus ));
  1482. }
  1483. /*
  1484. if ( (ConfigOptions & SCE_POLICY_TEMPLATE) &&
  1485. !(ConfigOptions & SCE_NO_CONFIG) &&
  1486. (Area & (AREA_SECURITY_POLICY | AREA_PRIVILEGES)) ) {
  1487. //
  1488. // delete the value
  1489. //
  1490. dOptions = ScepRegDeleteValue(HKEY_LOCAL_MACHINE,
  1491. SCE_ROOT_PATH,
  1492. TEXT("PolicyFilterOff")
  1493. );
  1494. if ( dOptions != ERROR_SUCCESS &&
  1495. dOptions != ERROR_FILE_NOT_FOUND &&
  1496. dOptions != ERROR_PATH_NOT_FOUND ) {
  1497. ScepRegSetIntValue(HKEY_LOCAL_MACHINE,
  1498. SCE_ROOT_PATH,
  1499. TEXT("PolicyFilterOff"),
  1500. 0
  1501. );
  1502. }
  1503. }
  1504. */
  1505. return(rc);
  1506. }
  1507. SCESTATUS
  1508. WINAPI
  1509. SceAnalyzeSystem(
  1510. IN LPTSTR SystemName OPTIONAL,
  1511. IN PCWSTR InfFileName OPTIONAL,
  1512. IN PCWSTR DatabaseName,
  1513. IN PCWSTR LogFileName OPTIONAL,
  1514. IN DWORD AnalyzeOptions,
  1515. IN AREA_INFORMATION Area,
  1516. IN PSCE_AREA_CALLBACK_ROUTINE pCallback OPTIONAL,
  1517. IN HANDLE hCallbackWnd OPTIONAL,
  1518. OUT PDWORD pdWarning OPTIONAL
  1519. )
  1520. /* ++
  1521. Routine Description:
  1522. Routine to analyze a system or local system if SystemName is NULL.
  1523. If DatabaseName is NULL, the default databae on the system is used.
  1524. if InfFileName is provided with OVERWRITE flag in AnalyzeOptions,
  1525. the database must NOT exist, otherwise, the Inf template is ignored
  1526. and the system is analyzed based on the info in the database. When
  1527. APPEND is specified in the flag, the InfFileName is appended to the
  1528. database (if exist), or used to create the database, then overall
  1529. information in the database is used to analyze the system.
  1530. AnalyzeOptions can contain flags such as verbose log, no log, and overwrite
  1531. /update database.
  1532. Callback pointers to the client can be registered as the arguments for
  1533. progress indication.
  1534. A warning code is also returned if there is any warning occurs during the
  1535. operation while the SCESTATUS return code is SCESTATUS_SUCCESS. Examples
  1536. such as ERROR_FILE_NOT_FOUND, or ERROR_ACCESS_DENIED when configuring
  1537. the system won't be counted as error of this operation because the current
  1538. user context may not have proper access to some of the resources specified
  1539. in the template.
  1540. Arguments:
  1541. SystemName - the system name where this operation will run, NULL for local system
  1542. InfFileName - optional inf template name, if NULL, existing info in the SCe
  1543. database is used to configure.
  1544. DatabaseName - the SCE database name. if NULL, the default is used.
  1545. LogFileName - optional log file name for the operation
  1546. AnalzyeOptions - the options to configure
  1547. SCE_OVERWRITE_DB
  1548. SCE_UPDATE_DB
  1549. SCE_VERBOSE_LOG
  1550. SCE_DISABLE_LOG
  1551. Area - reserved
  1552. pCallback - optional client callback routine
  1553. hCallbackWnd - a callback window handle
  1554. pdWarning - the warning code
  1555. Return Value:
  1556. SCE status
  1557. -- */
  1558. {
  1559. if ( DatabaseName == NULL ||
  1560. SceIsSystemDatabase(DatabaseName) ) {
  1561. //
  1562. // detect if this is system database (admin logon)
  1563. // no configuration is allowed.
  1564. //
  1565. if ( DatabaseName == NULL ) {
  1566. BOOL bAdminLogon=FALSE;
  1567. ScepIsAdminLoggedOn(&bAdminLogon);
  1568. if ( bAdminLogon ) {
  1569. return(SCESTATUS_ACCESS_DENIED);
  1570. }
  1571. } else
  1572. return(SCESTATUS_ACCESS_DENIED);
  1573. }
  1574. SCESTATUS rc;
  1575. handle_t binding_h;
  1576. NTSTATUS NtStatus;
  1577. DWORD dOptions;
  1578. ScepSetCallback((PVOID)pCallback, hCallbackWnd, SCE_AREA_CALLBACK);
  1579. //
  1580. // filter out invalid options
  1581. //
  1582. dOptions = AnalyzeOptions & 0xFFL;
  1583. dOptions = dOptions & ~(SCE_CALLBACK_DELTA | SCE_CALLBACK_TOTAL);
  1584. if ( pCallback ) {
  1585. dOptions |= SCE_CALLBACK_TOTAL;
  1586. }
  1587. //
  1588. // check the input arguments
  1589. //
  1590. LPCTSTR NewInf = NULL;
  1591. LPCTSTR NewDb = NULL;
  1592. LPCTSTR NewLog = NULL;
  1593. __try {
  1594. if ( InfFileName && wcslen(InfFileName) > 0 ) {
  1595. NewInf = InfFileName;
  1596. }
  1597. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1598. }
  1599. __try {
  1600. if ( DatabaseName && wcslen(DatabaseName) > 0 ) {
  1601. NewDb = DatabaseName;
  1602. }
  1603. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1604. }
  1605. __try {
  1606. if ( LogFileName && wcslen(LogFileName) > 0 ) {
  1607. NewLog = LogFileName;
  1608. }
  1609. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1610. }
  1611. //
  1612. // RPC bind to the server
  1613. //
  1614. NtStatus = ScepBindSecureRpc(
  1615. SystemName,
  1616. L"scerpc",
  1617. L"security=impersonation dynamic false",
  1618. &binding_h
  1619. );
  1620. if (NT_SUCCESS(NtStatus)){
  1621. LPVOID pebClient = GetEnvironmentStrings();
  1622. DWORD ebSize = ScepGetEnvStringSize(pebClient);
  1623. RpcTryExcept {
  1624. DWORD dwWarn=0;
  1625. rc = SceRpcAnalyzeSystem(
  1626. binding_h,
  1627. (wchar_t *)NewInf,
  1628. (wchar_t *)NewDb,
  1629. (wchar_t *)NewLog,
  1630. (AREAPR)Area,
  1631. dOptions,
  1632. ebSize,
  1633. (UCHAR *)pebClient,
  1634. &dwWarn
  1635. );
  1636. if ( pdWarning ) {
  1637. *pdWarning = dwWarn;
  1638. }
  1639. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1640. //
  1641. // get exception code (DWORD)
  1642. //
  1643. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1644. } RpcEndExcept;
  1645. //
  1646. // Free the binding handle
  1647. //
  1648. RpcpUnbindRpc( binding_h );
  1649. } else {
  1650. rc = ScepDosErrorToSceStatus(
  1651. RtlNtStatusToDosError( NtStatus ));
  1652. }
  1653. ScepSetCallback(NULL, NULL, 0);
  1654. return(rc);
  1655. }
  1656. SCESTATUS
  1657. WINAPI
  1658. SceGenerateRollback(
  1659. IN LPTSTR SystemName OPTIONAL,
  1660. IN PCWSTR InfFileName,
  1661. IN PCWSTR InfRollback,
  1662. IN PCWSTR LogFileName OPTIONAL,
  1663. IN DWORD Options,
  1664. IN AREA_INFORMATION Area,
  1665. OUT PDWORD pdWarning OPTIONAL
  1666. )
  1667. /* ++
  1668. Routine Description:
  1669. Routine to generate a rollback template based on the input configuration
  1670. template. Must be called by admins. System database is used to analyze
  1671. system settings with the confgiuration template and mismatches are saved
  1672. to the rollback template on top of the configuration.
  1673. Options can contain flags such as verbose log and no log
  1674. A warning code is also returned if there is any warning occurs during the
  1675. operation while the SCESTATUS return code is SCESTATUS_SUCCESS. Examples
  1676. such as ERROR_FILE_NOT_FOUND, or ERROR_ACCESS_DENIED when querying
  1677. the system won't be counted as error of this operation
  1678. Arguments:
  1679. SystemName - the system name where this operation will run, NULL for local system
  1680. InfFileName - optional inf template name, if NULL, existing info in the SCe
  1681. database is used to configure.
  1682. InfRollback - the rollback template name
  1683. LogFileName - optional log file name for the operation
  1684. Options - the options to configure
  1685. SCE_VERBOSE_LOG
  1686. SCE_DISABLE_LOG
  1687. Area - reserved
  1688. pdWarning - the warning code
  1689. Return Value:
  1690. SCE status
  1691. -- */
  1692. {
  1693. if ( InfFileName == NULL || InfRollback == NULL )
  1694. return (SCESTATUS_INVALID_PARAMETER);
  1695. SCESTATUS rc;
  1696. handle_t binding_h;
  1697. NTSTATUS NtStatus;
  1698. DWORD dOptions;
  1699. //
  1700. // filter out invalid options
  1701. //
  1702. dOptions = Options & 0xFFL;
  1703. //
  1704. // check the input arguments
  1705. //
  1706. LPCTSTR NewLog = NULL;
  1707. if ( InfFileName[0] == L'\0' ||
  1708. InfRollback[0] == L'\0' ) {
  1709. return(SCESTATUS_INVALID_PARAMETER);
  1710. }
  1711. __try {
  1712. if ( LogFileName && wcslen(LogFileName) > 0 ) {
  1713. NewLog = LogFileName;
  1714. }
  1715. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1716. }
  1717. //
  1718. // RPC bind to the server
  1719. //
  1720. NtStatus = ScepBindSecureRpc(
  1721. SystemName,
  1722. L"scerpc",
  1723. L"security=impersonation dynamic false",
  1724. &binding_h
  1725. );
  1726. if (NT_SUCCESS(NtStatus)){
  1727. LPVOID pebClient = GetEnvironmentStrings();
  1728. DWORD ebSize = ScepGetEnvStringSize(pebClient);
  1729. RpcTryExcept {
  1730. DWORD dwWarn=0;
  1731. rc = SceRpcAnalyzeSystem(
  1732. binding_h,
  1733. (wchar_t *)InfFileName,
  1734. (wchar_t *)InfRollback,
  1735. (wchar_t *)NewLog,
  1736. (AREAPR)Area,
  1737. dOptions | SCE_GENERATE_ROLLBACK,
  1738. ebSize,
  1739. (UCHAR *)pebClient,
  1740. &dwWarn
  1741. );
  1742. if ( pdWarning ) {
  1743. *pdWarning = dwWarn;
  1744. }
  1745. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1746. //
  1747. // get exception code (DWORD)
  1748. //
  1749. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1750. } RpcEndExcept;
  1751. //
  1752. // Free the binding handle
  1753. //
  1754. RpcpUnbindRpc( binding_h );
  1755. } else {
  1756. rc = ScepDosErrorToSceStatus(
  1757. RtlNtStatusToDosError( NtStatus ));
  1758. }
  1759. return(rc);
  1760. }
  1761. SCESTATUS
  1762. WINAPI
  1763. SceUpdateSecurityProfile(
  1764. IN PVOID cxtProfile OPTIONAL,
  1765. IN AREA_INFORMATION Area,
  1766. IN PSCE_PROFILE_INFO pInfo,
  1767. IN DWORD dwMode
  1768. )
  1769. /*
  1770. Routine Description:
  1771. See description in SceRpcUpdateDatabaseInfo
  1772. */
  1773. {
  1774. if ( !pInfo ) {
  1775. return(SCESTATUS_INVALID_PARAMETER);
  1776. }
  1777. if ( !cxtProfile && !(dwMode & SCE_UPDATE_SYSTEM ) ) {
  1778. //
  1779. // if it's not update for system, profile context can't be NULL.
  1780. //
  1781. return(SCESTATUS_INVALID_PARAMETER);
  1782. }
  1783. if ( ( dwMode & (SCE_UPDATE_LOCAL_POLICY | SCE_UPDATE_SYSTEM) ) &&
  1784. ( Area & ~(AREA_SECURITY_POLICY | AREA_PRIVILEGES) ) ) {
  1785. //
  1786. // local policy mode can only take security policy area and
  1787. // privileges area
  1788. //
  1789. return(SCESTATUS_INVALID_PARAMETER);
  1790. }
  1791. SCESTATUS rc=SCESTATUS_SUCCESS;
  1792. PSCE_SERVICES pOldServices=NULL;
  1793. if ( pInfo && pInfo->pServices ) {
  1794. //
  1795. // save the old service structure
  1796. //
  1797. pOldServices = pInfo->pServices;
  1798. }
  1799. if ( Area & AREA_SYSTEM_SERVICE ) {
  1800. //
  1801. // now convert the security descriptor (within PSCE_SERVICES) to self
  1802. // relative format and to the RPC structure.
  1803. //
  1804. rc = ScepConvertServices( (PVOID *)&(pInfo->pServices), FALSE );
  1805. } else {
  1806. //
  1807. // if don't care service area, don't bother to convert the structures
  1808. //
  1809. pInfo->pServices = NULL;
  1810. }
  1811. if ( SCESTATUS_SUCCESS == rc ) {
  1812. RpcTryExcept {
  1813. if ( dwMode & SCE_UPDATE_SYSTEM ) {
  1814. PSCE_ERROR_LOG_INFO pErrTmp=NULL;
  1815. if ( cxtProfile ) {
  1816. rc = SceRpcSetSystemSecurityFromHandle(
  1817. (SCEPR_CONTEXT)cxtProfile,
  1818. (AREAPR)Area,
  1819. 0,
  1820. (PSCEPR_PROFILE_INFO)pInfo,
  1821. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  1822. );
  1823. } else {
  1824. //
  1825. // set system settings
  1826. // for normal user, the local policy database can't be opened.
  1827. //
  1828. // RPC bind to the server
  1829. //
  1830. handle_t binding_h;
  1831. NTSTATUS NtStatus = ScepBindSecureRpc(
  1832. NULL,
  1833. L"scerpc",
  1834. 0,
  1835. &binding_h
  1836. );
  1837. if (NT_SUCCESS(NtStatus)){
  1838. RpcTryExcept {
  1839. rc = SceRpcSetSystemSecurity(
  1840. binding_h,
  1841. (AREAPR)Area,
  1842. 0,
  1843. (PSCEPR_PROFILE_INFO)pInfo,
  1844. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  1845. );
  1846. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1847. //
  1848. // get exception code (DWORD)
  1849. //
  1850. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1851. } RpcEndExcept;
  1852. //
  1853. // Free the binding handle
  1854. //
  1855. RpcpUnbindRpc( binding_h );
  1856. } else {
  1857. rc = ScepDosErrorToSceStatus(
  1858. RtlNtStatusToDosError( NtStatus ));
  1859. }
  1860. }
  1861. if ( pErrTmp ) {
  1862. //
  1863. // free this tmp buffer
  1864. //
  1865. ScepFreeErrorLog(pErrTmp);
  1866. }
  1867. } else {
  1868. rc = SceRpcUpdateDatabaseInfo(
  1869. (SCEPR_CONTEXT)cxtProfile,
  1870. (SCEPR_TYPE)(pInfo->Type),
  1871. (AREAPR)Area,
  1872. (PSCEPR_PROFILE_INFO)pInfo,
  1873. dwMode
  1874. );
  1875. }
  1876. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1877. //
  1878. // get exception code (DWORD)
  1879. //
  1880. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1881. } RpcEndExcept;
  1882. }
  1883. //
  1884. // should free the new service security descriptor buffer
  1885. //
  1886. ScepFreeConvertedServices( (PVOID)(pInfo->pServices), TRUE );
  1887. //
  1888. // restore the old buffer
  1889. //
  1890. pInfo->pServices = pOldServices;
  1891. return(rc);
  1892. }
  1893. SCESTATUS
  1894. WINAPI
  1895. SceUpdateObjectInfo(
  1896. IN PVOID cxtProfile,
  1897. IN AREA_INFORMATION Area,
  1898. IN PWSTR ObjectName,
  1899. IN DWORD NameLen, // number of characters
  1900. IN BYTE ConfigStatus,
  1901. IN BOOL IsContainer,
  1902. IN PSECURITY_DESCRIPTOR pSD,
  1903. IN SECURITY_INFORMATION SeInfo,
  1904. OUT PBYTE pAnalysisStatus
  1905. )
  1906. /*
  1907. Routine Description:
  1908. See description in SceRpcUpdateObjectInfo
  1909. */
  1910. {
  1911. if ( !cxtProfile || !ObjectName || 0 == Area ) {
  1912. return(SCESTATUS_INVALID_PARAMETER);
  1913. }
  1914. SCESTATUS rc=SCESTATUS_SUCCESS;
  1915. //
  1916. // handle RPC exceptions
  1917. //
  1918. PSCEPR_SR_SECURITY_DESCRIPTOR pNewWrap=NULL;
  1919. PSECURITY_DESCRIPTOR pNewSrSD=NULL;
  1920. //
  1921. // there is a security descriptor, must be self relative
  1922. // if the SD is not self relative, should convert it
  1923. //
  1924. if ( pSD ) {
  1925. if ( !RtlValidSid (pSD) ) {
  1926. return(SCESTATUS_INVALID_PARAMETER);
  1927. }
  1928. SECURITY_DESCRIPTOR_CONTROL ControlBits=0;
  1929. ULONG Revision;
  1930. ULONG nLen=0;
  1931. RtlGetControlSecurityDescriptor ( pSD, &ControlBits, &Revision);
  1932. if ( !(ControlBits & SE_SELF_RELATIVE) ) {
  1933. //
  1934. // if it's absolute format, convert it
  1935. //
  1936. rc = ScepDosErrorToSceStatus(
  1937. ScepMakeSelfRelativeSD( pSD, &pNewSrSD, &nLen ) );
  1938. if ( SCESTATUS_SUCCESS != rc ) {
  1939. return(rc);
  1940. }
  1941. } else {
  1942. //
  1943. // already self relative, just use it
  1944. //
  1945. nLen = RtlLengthSecurityDescriptor (pSD);
  1946. }
  1947. if ( nLen > 0 ) {
  1948. //
  1949. // create a wrapper node to contain the security descriptor
  1950. //
  1951. pNewWrap = (PSCEPR_SR_SECURITY_DESCRIPTOR)ScepAlloc(0, sizeof(SCEPR_SR_SECURITY_DESCRIPTOR));
  1952. if ( pNewWrap ) {
  1953. //
  1954. // assign the wrap to the structure
  1955. //
  1956. if ( ControlBits & SE_SELF_RELATIVE ) {
  1957. pNewWrap->SecurityDescriptor = (UCHAR *)pSD;
  1958. } else {
  1959. pNewWrap->SecurityDescriptor = (UCHAR *)pNewSrSD;
  1960. }
  1961. pNewWrap->Length = nLen;
  1962. } else {
  1963. //
  1964. // no memory is available, but still continue to parse all nodes
  1965. //
  1966. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1967. }
  1968. } else {
  1969. //
  1970. // something is wrong with the SD
  1971. //
  1972. rc = SCESTATUS_INVALID_PARAMETER;
  1973. }
  1974. if ( SCESTATUS_SUCCESS != rc ) {
  1975. if ( pNewSrSD ) {
  1976. ScepFree(pNewSrSD);
  1977. }
  1978. return(rc);
  1979. }
  1980. }
  1981. RpcTryExcept {
  1982. rc = SceRpcUpdateObjectInfo(
  1983. (SCEPR_CONTEXT)cxtProfile,
  1984. (AREAPR)Area,
  1985. (wchar_t *)ObjectName,
  1986. NameLen,
  1987. ConfigStatus,
  1988. IsContainer,
  1989. (SCEPR_SR_SECURITY_DESCRIPTOR *)pNewWrap,
  1990. SeInfo,
  1991. pAnalysisStatus
  1992. );
  1993. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1994. //
  1995. // get exception code (DWORD)
  1996. //
  1997. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1998. } RpcEndExcept;
  1999. if ( pNewSrSD ) {
  2000. ScepFree(pNewSrSD);
  2001. }
  2002. return(rc);
  2003. }
  2004. SCESTATUS
  2005. WINAPI
  2006. SceStartTransaction(
  2007. IN PVOID cxtProfile
  2008. )
  2009. {
  2010. if ( cxtProfile == NULL ) {
  2011. return(SCESTATUS_INVALID_PARAMETER);
  2012. }
  2013. SCESTATUS rc;
  2014. RpcTryExcept {
  2015. rc = SceRpcStartTransaction((SCEPR_CONTEXT)cxtProfile);
  2016. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2017. //
  2018. // get exception code (DWORD)
  2019. //
  2020. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2021. } RpcEndExcept;
  2022. return(rc);
  2023. }
  2024. SCESTATUS
  2025. WINAPI
  2026. SceCommitTransaction(
  2027. IN PVOID cxtProfile
  2028. )
  2029. {
  2030. if ( cxtProfile == NULL ) {
  2031. return(SCESTATUS_INVALID_PARAMETER);
  2032. }
  2033. SCESTATUS rc;
  2034. RpcTryExcept {
  2035. rc = SceRpcCommitTransaction((SCEPR_CONTEXT)cxtProfile);
  2036. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2037. //
  2038. // get exception code (DWORD)
  2039. //
  2040. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2041. } RpcEndExcept;
  2042. return(rc);
  2043. }
  2044. SCESTATUS
  2045. WINAPI
  2046. SceRollbackTransaction(
  2047. IN PVOID cxtProfile
  2048. )
  2049. {
  2050. if ( cxtProfile == NULL ) {
  2051. return(SCESTATUS_INVALID_PARAMETER);
  2052. }
  2053. SCESTATUS rc;
  2054. RpcTryExcept {
  2055. rc = SceRpcRollbackTransaction((SCEPR_CONTEXT)cxtProfile);
  2056. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2057. //
  2058. // get exception code (DWORD)
  2059. //
  2060. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2061. } RpcEndExcept;
  2062. return(rc);
  2063. }
  2064. SCESTATUS
  2065. WINAPI
  2066. SceGetServerProductType(
  2067. IN LPTSTR SystemName OPTIONAL,
  2068. OUT PSCE_SERVER_TYPE pServerType
  2069. )
  2070. /*
  2071. Routine Description:
  2072. Query product type and NT version of the server where SCE server is
  2073. running on
  2074. See description of SceRpcGetServerProductType
  2075. */
  2076. {
  2077. if ( !SystemName ) {
  2078. //
  2079. // the local call
  2080. //
  2081. return(ScepGetProductType(pServerType));
  2082. }
  2083. handle_t binding_h;
  2084. NTSTATUS NtStatus;
  2085. SCESTATUS rc;
  2086. //
  2087. // RPC bind to the server
  2088. //
  2089. NtStatus = ScepBindSecureRpc(
  2090. SystemName,
  2091. L"scerpc",
  2092. 0,
  2093. &binding_h
  2094. );
  2095. if (NT_SUCCESS(NtStatus)){
  2096. //
  2097. // handle RPC exceptions
  2098. //
  2099. RpcTryExcept {
  2100. rc = SceRpcGetServerProductType(
  2101. binding_h,
  2102. (PSCEPR_SERVER_TYPE)pServerType
  2103. );
  2104. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2105. //
  2106. // get exception code (DWORD)
  2107. //
  2108. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2109. } RpcEndExcept;
  2110. //
  2111. // Free the binding handle
  2112. //
  2113. RpcpUnbindRpc( binding_h );
  2114. } else {
  2115. rc = ScepDosErrorToSceStatus(
  2116. RtlNtStatusToDosError( NtStatus ));
  2117. }
  2118. return(rc);
  2119. }
  2120. SCESTATUS
  2121. WINAPI
  2122. SceSvcUpdateInfo(
  2123. IN PVOID hProfile,
  2124. IN PCWSTR ServiceName,
  2125. IN PSCESVC_CONFIGURATION_INFO Info
  2126. )
  2127. /*
  2128. Routine Description:
  2129. Load service's engine dll and pass the Info buffer to service engine's
  2130. update API (SceSvcAttachmentUpdate). Currently security manager engine
  2131. is not doing any processing for the service data.
  2132. This routine triggers the update of configuration database and/or
  2133. analysis information by the service engine. Info may contain the
  2134. modifications only, or the whole configuratio data for the service,
  2135. or partial configuration data, depending on the agreement between service
  2136. extension and service engine.
  2137. This routine does not really write info to security manager database directly,
  2138. instead, it passes the info buffer to the service engine's update interface
  2139. and service engine will determine what and when to write inot the database.
  2140. Arguments:
  2141. hProfile - the security database handle (returned from SCE server)
  2142. ServiceName - The service's name as used by service control manager
  2143. Info - The information modified
  2144. */
  2145. {
  2146. if ( hProfile == NULL || ServiceName == NULL ||
  2147. Info == NULL ) {
  2148. return(SCESTATUS_INVALID_PARAMETER);
  2149. }
  2150. SCESTATUS rc;
  2151. RpcTryExcept {
  2152. //
  2153. // call the RPC interface to update info.
  2154. // the RPC interface loads service engine dll on the server site
  2155. // and passes the info buffer to service engine to process
  2156. //
  2157. rc = SceSvcRpcUpdateInfo(
  2158. (SCEPR_CONTEXT)hProfile,
  2159. (wchar_t *)ServiceName,
  2160. (PSCEPR_SVCINFO)Info
  2161. );
  2162. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2163. //
  2164. // get exception code (DWORD) and convert it into SCESTATUS
  2165. //
  2166. rc = ScepDosErrorToSceStatus(
  2167. RpcExceptionCode());
  2168. } RpcEndExcept;
  2169. return(rc);
  2170. }
  2171. DWORD
  2172. WINAPI
  2173. SceRegisterRegValues(
  2174. IN LPTSTR InfFileName
  2175. )
  2176. /*
  2177. Routine Description:
  2178. Register the registry values from the inf file into reg values location
  2179. under SecEdit key
  2180. This routine can be called from DllRegisterServer, or from the command
  2181. line tool /register
  2182. Arguments:
  2183. InfFileName - the inf file which contains the register values to register
  2184. Return Value:
  2185. Win32 error code
  2186. */
  2187. {
  2188. if ( !InfFileName ) {
  2189. return(ERROR_INVALID_PARAMETER);
  2190. }
  2191. SCESTATUS rc;
  2192. HINF hInf;
  2193. DWORD Win32rc;
  2194. rc = SceInfpOpenProfile(
  2195. InfFileName,
  2196. &hInf
  2197. );
  2198. if ( SCESTATUS_SUCCESS == rc ) {
  2199. INFCONTEXT InfLine;
  2200. HKEY hKeyRoot;
  2201. DWORD dwDisp;
  2202. if(SetupFindFirstLine(hInf,SCE_REGISTER_REGVALUE_SECTION,NULL,&InfLine)) {
  2203. //
  2204. // create the root key first
  2205. //
  2206. Win32rc = RegCreateKeyEx (HKEY_LOCAL_MACHINE,
  2207. SCE_ROOT_REGVALUE_PATH,
  2208. 0,
  2209. NULL,
  2210. REG_OPTION_NON_VOLATILE,
  2211. KEY_READ | KEY_WRITE,
  2212. NULL,
  2213. &hKeyRoot,
  2214. &dwDisp);
  2215. if ( ERROR_SUCCESS == Win32rc ||
  2216. ERROR_ALREADY_EXISTS == Win32rc ) {
  2217. DWORD dSize;
  2218. PWSTR RegKeyName, DisplayName;
  2219. DWORD dType;
  2220. HKEY hKey;
  2221. do {
  2222. //
  2223. // Get key names, value type, diaply name, and display type.
  2224. //
  2225. if(SetupGetStringField(&InfLine,1,NULL,0,&dSize) && dSize > 0) {
  2226. RegKeyName = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR));
  2227. if( RegKeyName == NULL ) {
  2228. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2229. } else {
  2230. RegKeyName[dSize] = L'\0';
  2231. if(SetupGetStringField(&InfLine,1,RegKeyName,dSize, NULL)) {
  2232. //
  2233. // make sure not \\ is specified, if there is
  2234. // change it to /
  2235. //
  2236. ScepConvertMultiSzToDelim(RegKeyName, dSize, L'\\', L'/');
  2237. //
  2238. // get the filed count
  2239. // if count is 1, this key should be deleted
  2240. //
  2241. dwDisp = SetupGetFieldCount( &InfLine );
  2242. if ( dwDisp <= 1 ) {
  2243. //
  2244. // delete this key, don't care error
  2245. //
  2246. RegDeleteKey ( hKeyRoot, RegKeyName );
  2247. Win32rc = ERROR_SUCCESS;
  2248. } else {
  2249. Win32rc = RegCreateKeyEx (hKeyRoot,
  2250. RegKeyName,
  2251. 0,
  2252. NULL,
  2253. REG_OPTION_NON_VOLATILE,
  2254. KEY_WRITE,
  2255. NULL,
  2256. &hKey,
  2257. NULL);
  2258. }
  2259. if ( (dwDisp > 1) &&
  2260. ERROR_SUCCESS == Win32rc ||
  2261. ERROR_ALREADY_EXISTS == Win32rc ) {
  2262. //
  2263. // get registry value type
  2264. //
  2265. dType = REG_DWORD;
  2266. SetupGetIntField( &InfLine, 2, (INT *)&dType );
  2267. RegSetValueEx (hKey,
  2268. SCE_REG_VALUE_TYPE,
  2269. 0,
  2270. REG_DWORD,
  2271. (LPBYTE)&dType,
  2272. sizeof(DWORD));
  2273. //
  2274. // get registry value display type
  2275. //
  2276. dType = SCE_REG_DISPLAY_ENABLE;
  2277. SetupGetIntField( &InfLine, 4, (INT *)&dType );
  2278. RegSetValueEx (hKey,
  2279. SCE_REG_DISPLAY_TYPE,
  2280. 0,
  2281. REG_DWORD,
  2282. (LPBYTE)&dType,
  2283. sizeof(DWORD));
  2284. //
  2285. // get registry display name
  2286. //
  2287. if(SetupGetStringField(&InfLine,3,NULL,0,&dSize) && dSize > 0) {
  2288. DisplayName = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR));
  2289. if( DisplayName == NULL ) {
  2290. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2291. } else {
  2292. DisplayName[dSize] = L'\0';
  2293. if(SetupGetStringField(&InfLine,3,DisplayName,dSize, NULL)) {
  2294. RegSetValueEx (hKey,
  2295. SCE_REG_DISPLAY_NAME,
  2296. 0,
  2297. REG_SZ,
  2298. (LPBYTE)DisplayName,
  2299. dSize*sizeof(TCHAR));
  2300. }
  2301. ScepFree(DisplayName);
  2302. DisplayName = NULL;
  2303. }
  2304. }
  2305. //
  2306. // get registry display unit (optional)
  2307. //
  2308. if ( dType == SCE_REG_DISPLAY_NUMBER ||
  2309. dType == SCE_REG_DISPLAY_CHOICE ||
  2310. dType == SCE_REG_DISPLAY_FLAGS ) {
  2311. if ( SetupGetMultiSzField(&InfLine,5,NULL,0,&dSize) && dSize > 0) {
  2312. DisplayName = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR));
  2313. if( DisplayName == NULL ) {
  2314. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2315. } else {
  2316. DisplayName[dSize] = L'\0';
  2317. if(SetupGetMultiSzField(&InfLine,5,DisplayName,dSize, NULL)) {
  2318. if ( dType == SCE_REG_DISPLAY_NUMBER ) {
  2319. dSize = wcslen(DisplayName);
  2320. }
  2321. switch (dType) {
  2322. case SCE_REG_DISPLAY_NUMBER:
  2323. RegSetValueEx (hKey,
  2324. SCE_REG_DISPLAY_UNIT,
  2325. 0,
  2326. REG_SZ,
  2327. (LPBYTE)DisplayName,
  2328. dSize*sizeof(TCHAR));
  2329. break;
  2330. case SCE_REG_DISPLAY_CHOICE:
  2331. RegSetValueEx (hKey,
  2332. SCE_REG_DISPLAY_CHOICES,
  2333. 0,
  2334. REG_MULTI_SZ,
  2335. (LPBYTE)DisplayName,
  2336. dSize*sizeof(TCHAR));
  2337. break;
  2338. case SCE_REG_DISPLAY_FLAGS:
  2339. RegSetValueEx (hKey,
  2340. SCE_REG_DISPLAY_FLAGLIST,
  2341. 0,
  2342. REG_MULTI_SZ,
  2343. (LPBYTE)DisplayName,
  2344. dSize*sizeof(TCHAR));
  2345. break;
  2346. default:
  2347. break;
  2348. }
  2349. }
  2350. ScepFree(DisplayName);
  2351. DisplayName = NULL;
  2352. }
  2353. }
  2354. }
  2355. RegCloseKey(hKey);
  2356. hKey = NULL;
  2357. }
  2358. } else {
  2359. Win32rc = GetLastError();
  2360. }
  2361. ScepFree(RegKeyName);
  2362. RegKeyName = NULL;
  2363. }
  2364. } else {
  2365. Win32rc = GetLastError();
  2366. }
  2367. if ( ERROR_SUCCESS != Win32rc ) {
  2368. break;
  2369. }
  2370. } while (SetupFindNextLine(&InfLine,&InfLine));
  2371. RegCloseKey(hKeyRoot);
  2372. }
  2373. } else {
  2374. Win32rc = GetLastError();
  2375. }
  2376. SceInfpCloseProfile(hInf);
  2377. } else {
  2378. Win32rc = ScepSceStatusToDosError(rc);
  2379. }
  2380. return(Win32rc);
  2381. }
  2382. //
  2383. // the RPC callback
  2384. //
  2385. SCEPR_STATUS
  2386. SceClientBrowseCallback(
  2387. IN LONG GpoID,
  2388. IN wchar_t *KeyName OPTIONAL,
  2389. IN wchar_t *GpoName OPTIONAL,
  2390. IN SCEPR_SR_SECURITY_DESCRIPTOR *Value OPTIONAL
  2391. )
  2392. /*
  2393. Routine Description:
  2394. The RPC client callback routine which is called from the server when
  2395. the callback flag is set. This routine is registered in scerpc.idl.
  2396. The callbacks are registered to SCE as arguments when calling from the
  2397. browse API
  2398. Arguments:
  2399. Return Value:
  2400. SCEPR_STATUS
  2401. */
  2402. {
  2403. //
  2404. // the static variables holding callback pointer to client
  2405. //
  2406. if ( theBrowseCallBack != NULL ) {
  2407. //
  2408. // callback to browse progress
  2409. //
  2410. PSCE_BROWSE_CALLBACK_ROUTINE pcb;
  2411. pcb = (PSCE_BROWSE_CALLBACK_ROUTINE)theBrowseCallBack;
  2412. __try {
  2413. //
  2414. // callback
  2415. //
  2416. if ( !((*pcb)(GpoID,
  2417. KeyName,
  2418. GpoName,
  2419. ((Value && Value->Length) ? (PWSTR)(Value->SecurityDescriptor) : NULL),
  2420. Value ? (Value->Length)/sizeof(WCHAR) : 0
  2421. )) ) {
  2422. return SCESTATUS_SERVICE_NOT_SUPPORT;
  2423. }
  2424. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2425. return(SCESTATUS_INVALID_PARAMETER);
  2426. }
  2427. }
  2428. return(SCESTATUS_SUCCESS);
  2429. }
  2430. SCESTATUS
  2431. SceBrowseDatabaseTable(
  2432. IN PWSTR DatabaseName OPTIONAL,
  2433. IN SCETYPE ProfileType,
  2434. IN AREA_INFORMATION Area,
  2435. IN BOOL bDomainPolicyOnly,
  2436. IN PSCE_BROWSE_CALLBACK_ROUTINE pCallback OPTIONAL
  2437. )
  2438. {
  2439. if ( bDomainPolicyOnly &&
  2440. (ProfileType != SCE_ENGINE_SCP) &&
  2441. (ProfileType != SCE_ENGINE_SAP) ) {
  2442. return(SCESTATUS_INVALID_PARAMETER);
  2443. }
  2444. if ( bDomainPolicyOnly && (ProfileType == SCE_ENGINE_SAP) ) {
  2445. /*
  2446. // No, should allow any database for debugging
  2447. //
  2448. // should only work for the system database
  2449. //
  2450. if ( DatabaseName != NULL && !SceIsSystemDatabase(DatabaseName) ) {
  2451. return(SCESTATUS_INVALID_PARAMETER);
  2452. }
  2453. */
  2454. if ( DatabaseName == NULL ) {
  2455. //
  2456. // if it's a normal user logon, should return invalid
  2457. //
  2458. BOOL bAdmin=FALSE;
  2459. if ( ERROR_SUCCESS != ScepIsAdminLoggedOn(&bAdmin) || !bAdmin )
  2460. return(SCESTATUS_INVALID_PARAMETER);
  2461. }
  2462. }
  2463. if ( ProfileType != SCE_ENGINE_SCP &&
  2464. ProfileType != SCE_ENGINE_SMP &&
  2465. ProfileType != SCE_ENGINE_SAP ) {
  2466. return(SCESTATUS_INVALID_PARAMETER);
  2467. }
  2468. NTSTATUS NtStatus;
  2469. SCESTATUS rc;
  2470. handle_t binding_h;
  2471. //
  2472. // RPC bind to the server
  2473. //
  2474. NtStatus = ScepBindSecureRpc(
  2475. NULL,
  2476. L"scerpc",
  2477. 0,
  2478. &binding_h
  2479. );
  2480. if (NT_SUCCESS(NtStatus)){
  2481. theBrowseCallBack = (PVOID)pCallback;
  2482. RpcTryExcept {
  2483. rc = SceRpcBrowseDatabaseTable(
  2484. binding_h,
  2485. (wchar_t *)DatabaseName,
  2486. (SCEPR_TYPE)ProfileType,
  2487. (AREAPR)Area,
  2488. bDomainPolicyOnly
  2489. );
  2490. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2491. //
  2492. // get exception code (DWORD)
  2493. //
  2494. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2495. } RpcEndExcept;
  2496. theBrowseCallBack = NULL;
  2497. //
  2498. // Free the binding handle
  2499. //
  2500. RpcpUnbindRpc( binding_h );
  2501. } else {
  2502. rc = ScepDosErrorToSceStatus(
  2503. RtlNtStatusToDosError( NtStatus ));
  2504. }
  2505. return(rc);
  2506. }
  2507. SCESTATUS
  2508. ScepConvertServices(
  2509. IN OUT PVOID *ppServices,
  2510. IN BOOL bSRForm
  2511. )
  2512. {
  2513. if ( !ppServices ) {
  2514. return(SCESTATUS_INVALID_PARAMETER);
  2515. }
  2516. PSCE_SERVICES pTemp = (PSCE_SERVICES)(*ppServices);
  2517. SCESTATUS rc=SCESTATUS_SUCCESS;
  2518. PSCE_SERVICES pNewNode;
  2519. PSCE_SERVICES pNewServices=NULL;
  2520. while ( pTemp ) {
  2521. pNewNode = (PSCE_SERVICES)ScepAlloc(0,sizeof(SCE_SERVICES));
  2522. if ( pNewNode ) {
  2523. pNewNode->ServiceName = pTemp->ServiceName;
  2524. pNewNode->DisplayName = pTemp->DisplayName;
  2525. pNewNode->Status = pTemp->Status;
  2526. pNewNode->Startup = pTemp->Startup;
  2527. pNewNode->SeInfo = pTemp->SeInfo;
  2528. pNewNode->General.pSecurityDescriptor = NULL;
  2529. pNewNode->Next = pNewServices;
  2530. pNewServices = pNewNode;
  2531. if ( bSRForm ) {
  2532. //
  2533. // Service node is in SCEPR_SERVICES structure
  2534. // convert it to SCE_SERVICES structure
  2535. // in this case, just use the self relative security descriptor
  2536. //
  2537. if ( pTemp->General.pSecurityDescriptor) {
  2538. pNewNode->General.pSecurityDescriptor = ((PSCEPR_SERVICES)pTemp)->pSecurityDescriptor->SecurityDescriptor;
  2539. }
  2540. } else {
  2541. //
  2542. // Service node is in SCE_SERVICES strucutre
  2543. // convert it to SCEPR_SERVICES structure
  2544. //
  2545. // make the SD to self relative format and PSCEPR_SR_SECURITY_DESCRIPTOR
  2546. //
  2547. if ( pTemp->General.pSecurityDescriptor ) {
  2548. if ( !RtlValidSid ( pTemp->General.pSecurityDescriptor ) ) {
  2549. rc = SCESTATUS_INVALID_PARAMETER;
  2550. break;
  2551. }
  2552. DWORD nLen = 0;
  2553. PSECURITY_DESCRIPTOR pSD=NULL;
  2554. rc = ScepDosErrorToSceStatus(
  2555. ScepMakeSelfRelativeSD(
  2556. pTemp->General.pSecurityDescriptor,
  2557. &pSD,
  2558. &nLen
  2559. ));
  2560. if ( SCESTATUS_SUCCESS == rc ) {
  2561. //
  2562. // create a wrapper node to contain the security descriptor
  2563. //
  2564. PSCEPR_SR_SECURITY_DESCRIPTOR pNewWrap;
  2565. pNewWrap = (PSCEPR_SR_SECURITY_DESCRIPTOR)ScepAlloc(0, sizeof(SCEPR_SR_SECURITY_DESCRIPTOR));
  2566. if ( pNewWrap ) {
  2567. //
  2568. // assign the wrap to the structure
  2569. //
  2570. pNewWrap->SecurityDescriptor = (UCHAR *)pSD;
  2571. pNewWrap->Length = nLen;
  2572. } else {
  2573. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2574. ScepFree(pSD);
  2575. break;
  2576. }
  2577. //
  2578. // now link the SR_SD to the list
  2579. //
  2580. ((PSCEPR_SERVICES)pNewNode)->pSecurityDescriptor = pNewWrap;
  2581. } else {
  2582. break;
  2583. }
  2584. }
  2585. }
  2586. } else {
  2587. //
  2588. // all allocated buffer are in the list of pNewServices
  2589. //
  2590. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2591. break;
  2592. }
  2593. pTemp = pTemp->Next;
  2594. }
  2595. if ( SCESTATUS_SUCCESS != rc ) {
  2596. //
  2597. // free pNewServices
  2598. //
  2599. ScepFreeConvertedServices( (PVOID)pNewServices, !bSRForm );
  2600. pNewServices = NULL;
  2601. }
  2602. *ppServices = (PVOID)pNewServices;
  2603. return(rc);
  2604. }
  2605. SCESTATUS
  2606. ScepFreeConvertedServices(
  2607. IN PVOID pServices,
  2608. IN BOOL bSRForm
  2609. )
  2610. {
  2611. if ( pServices == NULL ) {
  2612. return(SCESTATUS_SUCCESS);
  2613. }
  2614. PSCEPR_SERVICES pNewNode = (PSCEPR_SERVICES)pServices;
  2615. PSCEPR_SERVICES pTempNode;
  2616. while ( pNewNode ) {
  2617. if ( bSRForm && pNewNode->pSecurityDescriptor ) {
  2618. //
  2619. // free this allocated buffer (PSCEPR_SR_SECURITY_DESCRIPTOR)
  2620. //
  2621. if ( pNewNode->pSecurityDescriptor->SecurityDescriptor ) {
  2622. ScepFree( pNewNode->pSecurityDescriptor->SecurityDescriptor);
  2623. }
  2624. ScepFree(pNewNode->pSecurityDescriptor);
  2625. }
  2626. //
  2627. // also free the PSCEPR_SERVICE node (but not the names referenced by this node)
  2628. //
  2629. pTempNode = pNewNode;
  2630. pNewNode = pNewNode->Next;
  2631. ScepFree(pTempNode);
  2632. }
  2633. return(SCESTATUS_SUCCESS);
  2634. }
  2635. DWORD
  2636. ScepMakeSelfRelativeSD(
  2637. IN PSECURITY_DESCRIPTOR pInSD,
  2638. OUT PSECURITY_DESCRIPTOR *pOutSD,
  2639. OUT PULONG pnLen
  2640. )
  2641. {
  2642. if ( pInSD == NULL ||
  2643. pOutSD == NULL ||
  2644. pnLen == NULL ) {
  2645. return(ERROR_INVALID_PARAMETER);
  2646. }
  2647. //
  2648. // get the length
  2649. //
  2650. RtlMakeSelfRelativeSD( pInSD,
  2651. NULL,
  2652. pnLen
  2653. );
  2654. if ( *pnLen > 0 ) {
  2655. *pOutSD = (PSECURITY_DESCRIPTOR)ScepAlloc(LMEM_ZEROINIT, *pnLen);
  2656. if ( !(*pOutSD) ) {
  2657. return(ERROR_NOT_ENOUGH_MEMORY);
  2658. }
  2659. DWORD NewLen=*pnLen;
  2660. DWORD rc = RtlNtStatusToDosError(
  2661. RtlMakeSelfRelativeSD( pInSD,
  2662. *pOutSD,
  2663. &NewLen
  2664. ) );
  2665. if ( rc != ERROR_SUCCESS ) {
  2666. ScepFree(*pOutSD);
  2667. *pOutSD = NULL;
  2668. *pnLen = 0;
  2669. return(rc);
  2670. }
  2671. } else {
  2672. //
  2673. // something is wrong with the SD
  2674. //
  2675. return(ERROR_INVALID_PARAMETER);
  2676. }
  2677. return(ERROR_SUCCESS);
  2678. }
  2679. SCESTATUS
  2680. WINAPI
  2681. SceGetDatabaseSetting(
  2682. IN PVOID hProfile,
  2683. IN SCETYPE ProfileType,
  2684. IN PWSTR SectionName,
  2685. IN PWSTR KeyName,
  2686. OUT PWSTR *Value,
  2687. OUT DWORD *pnBytes OPTIONAL
  2688. )
  2689. /*
  2690. Routine Descripton:
  2691. Get database setting (from SMP table) for the given key
  2692. Arguments:
  2693. hProfile - the profile handle
  2694. ProfileType - the database type
  2695. SectionName - the section to query data from
  2696. KeyName - the key name
  2697. Value - output buffer for the setting
  2698. ValueLen - the nubmer of bytes to output
  2699. Return Value:
  2700. SCE status
  2701. */
  2702. {
  2703. SCESTATUS rc;
  2704. if ( hProfile == NULL ||
  2705. KeyName == NULL ||
  2706. SectionName == NULL ||
  2707. Value == NULL ) {
  2708. return(SCESTATUS_INVALID_PARAMETER);
  2709. }
  2710. if ( ProfileType != SCE_ENGINE_SMP ) {
  2711. return(SCESTATUS_INVALID_PARAMETER);
  2712. }
  2713. //
  2714. // call rpc interface
  2715. //
  2716. PSCEPR_VALUEINFO ValueInfo=NULL;
  2717. RpcTryExcept {
  2718. rc = SceRpcGetDatabaseSetting(
  2719. (SCEPR_CONTEXT)hProfile,
  2720. (SCEPR_TYPE)ProfileType,
  2721. (wchar_t *)SectionName,
  2722. (wchar_t *)KeyName,
  2723. &ValueInfo
  2724. );
  2725. if ( ValueInfo && ValueInfo->Value ) {
  2726. //
  2727. // output the data
  2728. //
  2729. *Value = (PWSTR)ValueInfo->Value;
  2730. if ( pnBytes )
  2731. *pnBytes = ValueInfo->ValueLen;
  2732. ValueInfo->Value = NULL;
  2733. }
  2734. //
  2735. // free buffer
  2736. if ( ValueInfo ) {
  2737. if ( ValueInfo->Value ) ScepFree(ValueInfo->Value);
  2738. ScepFree(ValueInfo);
  2739. }
  2740. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2741. //
  2742. // get exception code (DWORD)
  2743. //
  2744. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2745. } RpcEndExcept;
  2746. return(rc);
  2747. }
  2748. SCESTATUS
  2749. WINAPI
  2750. SceSetDatabaseSetting(
  2751. IN PVOID hProfile,
  2752. IN SCETYPE ProfileType,
  2753. IN PWSTR SectionName,
  2754. IN PWSTR KeyName,
  2755. IN PWSTR Value OPTIONAL,
  2756. IN DWORD nBytes
  2757. )
  2758. /*
  2759. Routine Descripton:
  2760. Set a setting to the database (SMP table) for the given key
  2761. Arguments:
  2762. hProfile - the profile handle
  2763. ProfileType - the database type
  2764. SectionName - the section name to write to
  2765. KeyName - the key name to write to or delete
  2766. Value - the value to write. If NULL, delete the key
  2767. nBytes - the number of bytes of the input Value buffer
  2768. Return Value:
  2769. SCE status
  2770. */
  2771. {
  2772. SCESTATUS rc;
  2773. if ( hProfile == NULL ||
  2774. SectionName == NULL ||
  2775. KeyName == NULL ) {
  2776. return(SCESTATUS_INVALID_PARAMETER);
  2777. }
  2778. if ( ProfileType != SCE_ENGINE_SMP ) {
  2779. return(SCESTATUS_INVALID_PARAMETER);
  2780. }
  2781. //
  2782. // call rpc interface
  2783. //
  2784. RpcTryExcept {
  2785. SCEPR_VALUEINFO ValueInfo;
  2786. ValueInfo.Value = (byte *)Value;
  2787. ValueInfo.ValueLen = nBytes;
  2788. rc = SceRpcSetDatabaseSetting(
  2789. (SCEPR_CONTEXT)hProfile,
  2790. (SCEPR_TYPE)ProfileType,
  2791. (wchar_t *)SectionName,
  2792. (wchar_t *)KeyName,
  2793. Value ? &ValueInfo : NULL
  2794. );
  2795. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2796. //
  2797. // get exception code (DWORD)
  2798. //
  2799. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2800. } RpcEndExcept;
  2801. return(rc);
  2802. }
  2803. DWORD
  2804. ScepControlNotificationQProcess(
  2805. IN PWSTR szLogFileName,
  2806. IN BOOL bThisIsDC,
  2807. IN DWORD ControlFlag
  2808. )
  2809. /*
  2810. Description:
  2811. To suspend or resume policy notification queue processing on DCs
  2812. This routine is used to make sure that the latest group policy is
  2813. being processed in policy proapgation (copied to the cache)
  2814. */
  2815. {
  2816. if ( !bThisIsDC ) return ERROR_SUCCESS;
  2817. handle_t binding_h;
  2818. NTSTATUS NtStatus;
  2819. DWORD rc;
  2820. NtStatus = ScepBindRpc(
  2821. NULL,
  2822. L"scerpc",
  2823. L"security=impersonation dynamic false",
  2824. &binding_h
  2825. );
  2826. rc = RtlNtStatusToDosError( NtStatus );
  2827. if (NT_SUCCESS(NtStatus)){
  2828. RpcTryExcept {
  2829. rc = SceRpcControlNotificationQProcess(
  2830. binding_h,
  2831. ControlFlag
  2832. );
  2833. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2834. //
  2835. // get exception code (DWORD)
  2836. //
  2837. rc = RpcExceptionCode();
  2838. } RpcEndExcept;
  2839. }
  2840. //
  2841. // Free the binding handle
  2842. //
  2843. RpcpUnbindRpc( binding_h );
  2844. //
  2845. // log the operation
  2846. //
  2847. if ( szLogFileName ) {
  2848. LogEventAndReport(MyModuleHandle,
  2849. szLogFileName,
  2850. 1,
  2851. 0,
  2852. IDS_CONTROL_QUEUE,
  2853. rc,
  2854. ControlFlag
  2855. );
  2856. }
  2857. return rc;
  2858. }