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.

3951 lines
101 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. if(errTmp)
  1140. {
  1141. errTmp->next = pErrTmp;
  1142. }
  1143. } else {
  1144. *pErrlog = pErrTmp;
  1145. }
  1146. pErrTmp = NULL;
  1147. }
  1148. }
  1149. if ( rc != SCESTATUS_SUCCESS ) {
  1150. goto Cleanup;
  1151. }
  1152. }
  1153. //
  1154. // copy privileges area
  1155. //
  1156. if ( Area & AREA_PRIVILEGES && pSmpInfo != NULL ) {
  1157. //
  1158. // write [Privileges] section
  1159. // a new error buffer is used because the api below reset the error buffer
  1160. //
  1161. scpInfo.OtherInfo.scp.u.pInfPrivilegeAssignedTo = pSmpInfo->OtherInfo.smp.pPrivilegeAssignedTo;
  1162. rc = SceWriteSecurityProfileInfo(
  1163. InfFileName,
  1164. AREA_PRIVILEGES,
  1165. &scpInfo,
  1166. &pErrTmp
  1167. );
  1168. if ( pErrlog && pErrTmp ) {
  1169. //
  1170. // link the new error buffer to the end of pErrlog
  1171. //
  1172. if ( *pErrlog ) {
  1173. //
  1174. // find the end of the buffer
  1175. //
  1176. for ( errTmp=*pErrlog;
  1177. errTmp && errTmp->next;
  1178. errTmp=errTmp->next);
  1179. //
  1180. // when this loop is done, errTmp->next must be NULL
  1181. //
  1182. errTmp->next = pErrTmp;
  1183. } else {
  1184. *pErrlog = pErrTmp;
  1185. }
  1186. pErrTmp = NULL;
  1187. }
  1188. if ( rc != SCESTATUS_SUCCESS )
  1189. goto Cleanup;
  1190. }
  1191. //
  1192. // copy objects
  1193. //
  1194. Area2 = Area & ( AREA_REGISTRY_SECURITY |
  1195. AREA_FILE_SECURITY |
  1196. // AREA_DS_OBJECTS |
  1197. AREA_SYSTEM_SERVICE |
  1198. AREA_SECURITY_POLICY |
  1199. AREA_ATTACHMENTS);
  1200. if ( Area2 ) {
  1201. //
  1202. // write objects section (szRegistryKeys, szFileSecurity,
  1203. // szDSSecurity, szServiceGeneral)
  1204. //
  1205. RpcTryExcept {
  1206. rc = SceRpcCopyObjects(
  1207. (SCEPR_CONTEXT)hProfile,
  1208. (SCEPR_TYPE)ProfileType,
  1209. (wchar_t *)InfFileName,
  1210. (AREAPR)Area2,
  1211. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  1212. );
  1213. if ( pErrlog && pErrTmp ) {
  1214. //
  1215. // link the new error buffer to the end of pErrlog
  1216. //
  1217. if ( *pErrlog ) {
  1218. //
  1219. // find the end of the buffer
  1220. //
  1221. for ( errTmp=*pErrlog;
  1222. errTmp && errTmp->next;
  1223. errTmp=errTmp->next);
  1224. //
  1225. // when this loop is done, errTmp->next must be NULL
  1226. //
  1227. errTmp->next = pErrTmp;
  1228. } else {
  1229. *pErrlog = pErrTmp;
  1230. }
  1231. pErrTmp = NULL;
  1232. }
  1233. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1234. //
  1235. // get exception code (DWORD)
  1236. //
  1237. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1238. } RpcEndExcept;
  1239. }
  1240. Cleanup:
  1241. if ( Description != NULL ) {
  1242. ScepFree(Description);
  1243. }
  1244. if ( pSmpInfo != NULL ) {
  1245. Area2 = Area & ( AREA_SECURITY_POLICY |
  1246. AREA_GROUP_MEMBERSHIP |
  1247. AREA_PRIVILEGES );
  1248. SceFreeProfileMemory(pSmpInfo);
  1249. }
  1250. if ( pErrTmp ) {
  1251. ScepFreeErrorLog(pErrTmp);
  1252. }
  1253. return(rc);
  1254. }
  1255. SCESTATUS
  1256. WINAPI
  1257. SceConfigureSystem(
  1258. IN LPTSTR SystemName OPTIONAL,
  1259. IN PCWSTR InfFileName OPTIONAL,
  1260. IN PCWSTR DatabaseName,
  1261. IN PCWSTR LogFileName OPTIONAL,
  1262. IN DWORD ConfigOptions,
  1263. IN AREA_INFORMATION Area,
  1264. IN PSCE_AREA_CALLBACK_ROUTINE pCallback OPTIONAL,
  1265. IN HANDLE hCallbackWnd OPTIONAL,
  1266. OUT PDWORD pdWarning OPTIONAL
  1267. )
  1268. // see ScepConfigSystem
  1269. {
  1270. AREA_INFORMATION Area2=Area;
  1271. if ( DatabaseName == NULL ||
  1272. SceIsSystemDatabase(DatabaseName) ) {
  1273. //
  1274. // detect if this is system database (admin logon)
  1275. // no configuration is allowed.
  1276. //
  1277. if ( DatabaseName == NULL ) {
  1278. BOOL bAdminLogon=FALSE;
  1279. ScepIsAdminLoggedOn(&bAdminLogon, FALSE);
  1280. if ( bAdminLogon ) {
  1281. return(SCESTATUS_ACCESS_DENIED);
  1282. }
  1283. } else
  1284. return(SCESTATUS_ACCESS_DENIED);
  1285. }
  1286. SCESTATUS rc;
  1287. DWORD dOptions;
  1288. ScepSetCallback((PVOID)pCallback, hCallbackWnd, SCE_AREA_CALLBACK);
  1289. //
  1290. // filter out invalid options from clients
  1291. // filter out areas other than security policy and user rights
  1292. //
  1293. dOptions = ConfigOptions & 0xFFL;
  1294. rc = ScepConfigSystem(
  1295. SystemName,
  1296. InfFileName,
  1297. DatabaseName,
  1298. LogFileName,
  1299. dOptions,
  1300. Area2,
  1301. pCallback,
  1302. hCallbackWnd,
  1303. pdWarning
  1304. );
  1305. ScepSetCallback(NULL, NULL, 0);
  1306. if ( DatabaseName != NULL &&
  1307. !SceIsSystemDatabase(DatabaseName) &&
  1308. !(ConfigOptions & SCE_NO_CONFIG) &&
  1309. (Area2 & AREA_SECURITY_POLICY) ) {
  1310. //
  1311. // private database, should trigger policy propagation
  1312. // delete the last configuration time
  1313. //
  1314. HKEY hKey=NULL;
  1315. if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1316. SCE_ROOT_PATH,
  1317. 0,
  1318. KEY_READ | KEY_WRITE,
  1319. &hKey
  1320. ) == ERROR_SUCCESS ) {
  1321. RegDeleteValue(hKey, TEXT("LastWinlogonConfig"));
  1322. RegCloseKey( hKey );
  1323. }
  1324. HINSTANCE hLoadDll = LoadLibrary(TEXT("userenv.dll"));
  1325. if ( hLoadDll) {
  1326. PFNREFRESHPOLICY pfnRefreshPolicy = (PFNREFRESHPOLICY)GetProcAddress(
  1327. hLoadDll,
  1328. "RefreshPolicy");
  1329. if ( pfnRefreshPolicy ) {
  1330. (*pfnRefreshPolicy )( TRUE );
  1331. }
  1332. FreeLibrary(hLoadDll);
  1333. }
  1334. }
  1335. return(rc);
  1336. }
  1337. SCESTATUS
  1338. ScepConfigSystem(
  1339. IN LPTSTR SystemName OPTIONAL,
  1340. IN PCWSTR InfFileName OPTIONAL,
  1341. IN PCWSTR DatabaseName OPTIONAL,
  1342. IN PCWSTR LogFileName OPTIONAL,
  1343. IN DWORD ConfigOptions,
  1344. IN AREA_INFORMATION Area,
  1345. IN PSCE_AREA_CALLBACK_ROUTINE pCallback OPTIONAL,
  1346. IN HANDLE hCallbackWnd OPTIONAL,
  1347. OUT PDWORD pdWarning OPTIONAL
  1348. )
  1349. /* ++
  1350. Routine Description:
  1351. Routine to configure a system or local system if SystemName is NULL.
  1352. If DatabaseName is NULL, the default databae on the system is used.
  1353. if InfFileName is provided, depending on the ConfigOptions, info in
  1354. the InfFileName is either appended to the database (if exist), or used
  1355. to create/overwrite the database.
  1356. ConfigOptions can contain flags such as verbose log, no log, and overwrite
  1357. /update database. When overwrite is specified, existing database info
  1358. is overwritten by the inf template, and all analysis information is
  1359. cleaned up.
  1360. Callback pointers to the client can be registered as the arguments for
  1361. progress indication.
  1362. A warning code is also returned if there is any warning occurs during the
  1363. operation while the SCESTATUS return code is SCESTATUS_SUCCESS. Examples
  1364. such as ERROR_FILE_NOT_FOUND, or ERROR_ACCESS_DENIED when configuring
  1365. the system won't be counted as error of this operation because the current
  1366. user context may not have proper access to some of the resources specified
  1367. in the template.
  1368. Arguments:
  1369. SystemName - the system name where this operation will run, NULL for local system
  1370. InfFileName - optional inf template name, if NULL, existing info in the SCe
  1371. database is used to configure.
  1372. DatabaseName - the SCE database name. if NULL, the default is used.
  1373. LogFileName - optional log file name for the operation
  1374. ConfigOptions - the options to configure
  1375. SCE_OVERWRITE_DB
  1376. SCE_UPDATE_DB
  1377. SCE_VERBOSE_LOG
  1378. SCE_DISABLE_LOG
  1379. Area - Area to configure
  1380. pCallback - optional client callback routine
  1381. hCallbackWnd - a callback window handle
  1382. pdWarning - the warning code
  1383. Return Value:
  1384. SCE status
  1385. -- */
  1386. {
  1387. SCESTATUS rc;
  1388. handle_t binding_h;
  1389. NTSTATUS NtStatus;
  1390. DWORD dOptions;
  1391. dOptions = ConfigOptions & ~(SCE_CALLBACK_DELTA |
  1392. SCE_CALLBACK_TOTAL |
  1393. SCE_POLBIND_NO_AUTH);
  1394. if ( pCallback ) {
  1395. dOptions |= SCE_CALLBACK_TOTAL;
  1396. }
  1397. //
  1398. // check the input arguments
  1399. //
  1400. LPCTSTR NewInf = NULL;
  1401. LPCTSTR NewDb = NULL;
  1402. LPCTSTR NewLog = NULL;
  1403. __try {
  1404. if ( InfFileName && wcslen(InfFileName) > 0 ) {
  1405. NewInf = InfFileName;
  1406. }
  1407. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1408. }
  1409. __try {
  1410. if ( DatabaseName && wcslen(DatabaseName) > 0 ) {
  1411. NewDb = DatabaseName;
  1412. }
  1413. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1414. }
  1415. __try {
  1416. if ( LogFileName && wcslen(LogFileName) > 0 ) {
  1417. NewLog = LogFileName;
  1418. }
  1419. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1420. }
  1421. /*
  1422. //
  1423. // ANZ hotfix:
  1424. // move the "drop SAM notifications" event-reset into scesrv
  1425. // just before configuring the SAM during policy propagation
  1426. // to reduce the "dropping notifications" window
  1427. //
  1428. if ( (ConfigOptions & SCE_POLICY_TEMPLATE) &&
  1429. !(ConfigOptions & SCE_NO_CONFIG) &&
  1430. (Area & AREA_SECURITY_POLICY) ) {
  1431. //
  1432. // turn off policy filter for SAM notification
  1433. //
  1434. ScepRegSetIntValue(HKEY_LOCAL_MACHINE,
  1435. SCE_ROOT_PATH,
  1436. TEXT("PolicyFilterOffSAM"),
  1437. 1
  1438. );
  1439. }
  1440. */
  1441. //
  1442. // RPC bind to the server
  1443. //
  1444. if ( ConfigOptions & SCE_POLBIND_NO_AUTH ) {
  1445. NtStatus = ScepBindRpc(
  1446. SystemName,
  1447. L"scerpc",
  1448. L"security=impersonation dynamic false",
  1449. &binding_h
  1450. );
  1451. } else {
  1452. NtStatus = ScepBindSecureRpc(
  1453. SystemName,
  1454. L"scerpc",
  1455. L"security=impersonation dynamic false",
  1456. &binding_h
  1457. );
  1458. }
  1459. if (NT_SUCCESS(NtStatus)){
  1460. LPVOID pebClient = GetEnvironmentStrings();
  1461. DWORD ebSize = ScepGetEnvStringSize(pebClient);
  1462. RpcTryExcept {
  1463. DWORD dWarn=0;
  1464. rc = SceRpcConfigureSystem(
  1465. binding_h,
  1466. (wchar_t *)NewInf,
  1467. (wchar_t *)NewDb,
  1468. (wchar_t *)NewLog,
  1469. dOptions,
  1470. (AREAPR)Area,
  1471. ebSize,
  1472. (UCHAR *)pebClient,
  1473. &dWarn
  1474. );
  1475. if ( pdWarning ) {
  1476. *pdWarning = dWarn;
  1477. }
  1478. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1479. //
  1480. // get exception code (DWORD)
  1481. //
  1482. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1483. } RpcEndExcept;
  1484. //
  1485. // Free the binding handle
  1486. //
  1487. RpcpUnbindRpc( binding_h );
  1488. if(pebClient)
  1489. {
  1490. FreeEnvironmentStrings((LPTSTR)pebClient);
  1491. }
  1492. } else {
  1493. rc = ScepDosErrorToSceStatus(
  1494. RtlNtStatusToDosError( NtStatus ));
  1495. }
  1496. /*
  1497. //
  1498. // ANZ hotfix:
  1499. // move the "enable SAM notifications" event-set into scesrv
  1500. // just after configuring the SAM in policy propagation
  1501. // to reduce the "dropping notifications" window
  1502. //
  1503. if ( (ConfigOptions & SCE_POLICY_TEMPLATE) &&
  1504. !(ConfigOptions & SCE_NO_CONFIG) &&
  1505. (Area & AREA_SECURITY_POLICY) ) {
  1506. //
  1507. // delete the value
  1508. //
  1509. dOptions = ScepRegDeleteValue(HKEY_LOCAL_MACHINE,
  1510. SCE_ROOT_PATH,
  1511. TEXT("PolicyFilterOffSAM")
  1512. );
  1513. if ( dOptions != ERROR_SUCCESS &&
  1514. dOptions != ERROR_FILE_NOT_FOUND &&
  1515. dOptions != ERROR_PATH_NOT_FOUND ) {
  1516. ScepRegSetIntValue(HKEY_LOCAL_MACHINE,
  1517. SCE_ROOT_PATH,
  1518. TEXT("PolicyFilterOffSAM"),
  1519. 0
  1520. );
  1521. }
  1522. }
  1523. */
  1524. return(rc);
  1525. }
  1526. SCESTATUS
  1527. WINAPI
  1528. SceAnalyzeSystem(
  1529. IN LPTSTR SystemName OPTIONAL,
  1530. IN PCWSTR InfFileName OPTIONAL,
  1531. IN PCWSTR DatabaseName,
  1532. IN PCWSTR LogFileName OPTIONAL,
  1533. IN DWORD AnalyzeOptions,
  1534. IN AREA_INFORMATION Area,
  1535. IN PSCE_AREA_CALLBACK_ROUTINE pCallback OPTIONAL,
  1536. IN HANDLE hCallbackWnd OPTIONAL,
  1537. OUT PDWORD pdWarning OPTIONAL
  1538. )
  1539. /* ++
  1540. Routine Description:
  1541. Routine to analyze a system or local system if SystemName is NULL.
  1542. If DatabaseName is NULL, the default databae on the system is used.
  1543. if InfFileName is provided with OVERWRITE flag in AnalyzeOptions,
  1544. the database must NOT exist, otherwise, the Inf template is ignored
  1545. and the system is analyzed based on the info in the database. When
  1546. APPEND is specified in the flag, the InfFileName is appended to the
  1547. database (if exist), or used to create the database, then overall
  1548. information in the database is used to analyze the system.
  1549. AnalyzeOptions can contain flags such as verbose log, no log, and overwrite
  1550. /update database.
  1551. Callback pointers to the client can be registered as the arguments for
  1552. progress indication.
  1553. A warning code is also returned if there is any warning occurs during the
  1554. operation while the SCESTATUS return code is SCESTATUS_SUCCESS. Examples
  1555. such as ERROR_FILE_NOT_FOUND, or ERROR_ACCESS_DENIED when configuring
  1556. the system won't be counted as error of this operation because the current
  1557. user context may not have proper access to some of the resources specified
  1558. in the template.
  1559. Arguments:
  1560. SystemName - the system name where this operation will run, NULL for local system
  1561. InfFileName - optional inf template name, if NULL, existing info in the SCe
  1562. database is used to configure.
  1563. DatabaseName - the SCE database name. if NULL, the default is used.
  1564. LogFileName - optional log file name for the operation
  1565. AnalzyeOptions - the options to configure
  1566. SCE_OVERWRITE_DB
  1567. SCE_UPDATE_DB
  1568. SCE_VERBOSE_LOG
  1569. SCE_DISABLE_LOG
  1570. Area - reserved
  1571. pCallback - optional client callback routine
  1572. hCallbackWnd - a callback window handle
  1573. pdWarning - the warning code
  1574. Return Value:
  1575. SCE status
  1576. -- */
  1577. {
  1578. if ( DatabaseName == NULL ||
  1579. SceIsSystemDatabase(DatabaseName) ) {
  1580. //
  1581. // detect if this is system database (admin logon)
  1582. // no configuration is allowed.
  1583. //
  1584. if ( DatabaseName == NULL ) {
  1585. BOOL bAdminLogon=FALSE;
  1586. ScepIsAdminLoggedOn(&bAdminLogon, FALSE);
  1587. if ( bAdminLogon ) {
  1588. return(SCESTATUS_ACCESS_DENIED);
  1589. }
  1590. } else
  1591. return(SCESTATUS_ACCESS_DENIED);
  1592. }
  1593. SCESTATUS rc;
  1594. handle_t binding_h;
  1595. NTSTATUS NtStatus;
  1596. DWORD dOptions;
  1597. ScepSetCallback((PVOID)pCallback, hCallbackWnd, SCE_AREA_CALLBACK);
  1598. //
  1599. // filter out invalid options
  1600. //
  1601. dOptions = AnalyzeOptions & 0xFFL;
  1602. dOptions = dOptions & ~(SCE_CALLBACK_DELTA | SCE_CALLBACK_TOTAL);
  1603. if ( pCallback ) {
  1604. dOptions |= SCE_CALLBACK_TOTAL;
  1605. }
  1606. //
  1607. // check the input arguments
  1608. //
  1609. LPCTSTR NewInf = NULL;
  1610. LPCTSTR NewDb = NULL;
  1611. LPCTSTR NewLog = NULL;
  1612. __try {
  1613. if ( InfFileName && wcslen(InfFileName) > 0 ) {
  1614. NewInf = InfFileName;
  1615. }
  1616. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1617. }
  1618. __try {
  1619. if ( DatabaseName && wcslen(DatabaseName) > 0 ) {
  1620. NewDb = DatabaseName;
  1621. }
  1622. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1623. }
  1624. __try {
  1625. if ( LogFileName && wcslen(LogFileName) > 0 ) {
  1626. NewLog = LogFileName;
  1627. }
  1628. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1629. }
  1630. //
  1631. // RPC bind to the server
  1632. //
  1633. NtStatus = ScepBindSecureRpc(
  1634. SystemName,
  1635. L"scerpc",
  1636. L"security=impersonation dynamic false",
  1637. &binding_h
  1638. );
  1639. if (NT_SUCCESS(NtStatus)){
  1640. LPVOID pebClient = GetEnvironmentStrings();
  1641. DWORD ebSize = ScepGetEnvStringSize(pebClient);
  1642. RpcTryExcept {
  1643. DWORD dwWarn=0;
  1644. rc = SceRpcAnalyzeSystem(
  1645. binding_h,
  1646. (wchar_t *)NewInf,
  1647. (wchar_t *)NewDb,
  1648. (wchar_t *)NewLog,
  1649. (AREAPR)Area,
  1650. dOptions,
  1651. ebSize,
  1652. (UCHAR *)pebClient,
  1653. &dwWarn
  1654. );
  1655. if ( pdWarning ) {
  1656. *pdWarning = dwWarn;
  1657. }
  1658. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1659. //
  1660. // get exception code (DWORD)
  1661. //
  1662. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1663. } RpcEndExcept;
  1664. //
  1665. // Free the binding handle
  1666. //
  1667. RpcpUnbindRpc( binding_h );
  1668. if(pebClient)
  1669. {
  1670. FreeEnvironmentStrings((LPTSTR)pebClient);
  1671. }
  1672. } else {
  1673. rc = ScepDosErrorToSceStatus(
  1674. RtlNtStatusToDosError( NtStatus ));
  1675. }
  1676. ScepSetCallback(NULL, NULL, 0);
  1677. return(rc);
  1678. }
  1679. SCESTATUS
  1680. WINAPI
  1681. SceGenerateRollback(
  1682. IN LPTSTR SystemName OPTIONAL,
  1683. IN PCWSTR InfFileName,
  1684. IN PCWSTR InfRollback,
  1685. IN PCWSTR LogFileName OPTIONAL,
  1686. IN DWORD Options,
  1687. IN AREA_INFORMATION Area,
  1688. OUT PDWORD pdWarning OPTIONAL
  1689. )
  1690. /* ++
  1691. Routine Description:
  1692. Routine to generate a rollback template based on the input configuration
  1693. template. Must be called by admins. System database is used to analyze
  1694. system settings with the confgiuration template and mismatches are saved
  1695. to the rollback template on top of the configuration.
  1696. Options can contain flags such as verbose log and no log
  1697. A warning code is also returned if there is any warning occurs during the
  1698. operation while the SCESTATUS return code is SCESTATUS_SUCCESS. Examples
  1699. such as ERROR_FILE_NOT_FOUND, or ERROR_ACCESS_DENIED when querying
  1700. the system won't be counted as error of this operation
  1701. Arguments:
  1702. SystemName - the system name where this operation will run, NULL for local system
  1703. InfFileName - optional inf template name, if NULL, existing info in the SCe
  1704. database is used to configure.
  1705. InfRollback - the rollback template name
  1706. LogFileName - optional log file name for the operation
  1707. Options - the options to configure
  1708. SCE_VERBOSE_LOG
  1709. SCE_DISABLE_LOG
  1710. Area - reserved
  1711. pdWarning - the warning code
  1712. Return Value:
  1713. SCE status
  1714. -- */
  1715. {
  1716. if ( InfFileName == NULL || InfRollback == NULL )
  1717. return (SCESTATUS_INVALID_PARAMETER);
  1718. SCESTATUS rc;
  1719. handle_t binding_h;
  1720. NTSTATUS NtStatus;
  1721. DWORD dOptions;
  1722. //
  1723. // filter out invalid options
  1724. //
  1725. dOptions = Options & 0xFFL;
  1726. //
  1727. // check the input arguments
  1728. //
  1729. LPCTSTR NewLog = NULL;
  1730. if ( InfFileName[0] == L'\0' ||
  1731. InfRollback[0] == L'\0' ) {
  1732. return(SCESTATUS_INVALID_PARAMETER);
  1733. }
  1734. __try {
  1735. if ( LogFileName && wcslen(LogFileName) > 0 ) {
  1736. NewLog = LogFileName;
  1737. }
  1738. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1739. }
  1740. //
  1741. // RPC bind to the server
  1742. //
  1743. NtStatus = ScepBindSecureRpc(
  1744. SystemName,
  1745. L"scerpc",
  1746. L"security=impersonation dynamic false",
  1747. &binding_h
  1748. );
  1749. if (NT_SUCCESS(NtStatus)){
  1750. LPVOID pebClient = GetEnvironmentStrings();
  1751. DWORD ebSize = ScepGetEnvStringSize(pebClient);
  1752. RpcTryExcept {
  1753. DWORD dwWarn=0;
  1754. rc = SceRpcAnalyzeSystem(
  1755. binding_h,
  1756. (wchar_t *)InfFileName,
  1757. (wchar_t *)InfRollback,
  1758. (wchar_t *)NewLog,
  1759. (AREAPR)Area,
  1760. dOptions | SCE_GENERATE_ROLLBACK,
  1761. ebSize,
  1762. (UCHAR *)pebClient,
  1763. &dwWarn
  1764. );
  1765. if ( pdWarning ) {
  1766. *pdWarning = dwWarn;
  1767. }
  1768. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1769. //
  1770. // get exception code (DWORD)
  1771. //
  1772. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1773. } RpcEndExcept;
  1774. //
  1775. // Free the binding handle
  1776. //
  1777. RpcpUnbindRpc( binding_h );
  1778. if(pebClient)
  1779. {
  1780. FreeEnvironmentStrings((LPTSTR)pebClient);
  1781. }
  1782. } else {
  1783. rc = ScepDosErrorToSceStatus(
  1784. RtlNtStatusToDosError( NtStatus ));
  1785. }
  1786. return(rc);
  1787. }
  1788. SCESTATUS
  1789. WINAPI
  1790. SceUpdateSecurityProfile(
  1791. IN PVOID cxtProfile OPTIONAL,
  1792. IN AREA_INFORMATION Area,
  1793. IN PSCE_PROFILE_INFO pInfo,
  1794. IN DWORD dwMode
  1795. )
  1796. /*
  1797. Routine Description:
  1798. See description in SceRpcUpdateDatabaseInfo
  1799. */
  1800. {
  1801. if ( !pInfo ) {
  1802. return(SCESTATUS_INVALID_PARAMETER);
  1803. }
  1804. if ( !cxtProfile && !(dwMode & SCE_UPDATE_SYSTEM ) ) {
  1805. //
  1806. // if it's not update for system, profile context can't be NULL.
  1807. //
  1808. return(SCESTATUS_INVALID_PARAMETER);
  1809. }
  1810. if ( ( dwMode & (SCE_UPDATE_LOCAL_POLICY | SCE_UPDATE_SYSTEM) ) &&
  1811. ( Area & ~(AREA_SECURITY_POLICY | AREA_PRIVILEGES) ) ) {
  1812. //
  1813. // local policy mode can only take security policy area and
  1814. // privileges area
  1815. //
  1816. return(SCESTATUS_INVALID_PARAMETER);
  1817. }
  1818. SCESTATUS rc=SCESTATUS_SUCCESS;
  1819. PSCE_SERVICES pOldServices=NULL;
  1820. if ( pInfo && pInfo->pServices ) {
  1821. //
  1822. // save the old service structure
  1823. //
  1824. pOldServices = pInfo->pServices;
  1825. }
  1826. if ( Area & AREA_SYSTEM_SERVICE ) {
  1827. //
  1828. // now convert the security descriptor (within PSCE_SERVICES) to self
  1829. // relative format and to the RPC structure.
  1830. //
  1831. rc = ScepConvertServices( (PVOID *)&(pInfo->pServices), FALSE );
  1832. } else {
  1833. //
  1834. // if don't care service area, don't bother to convert the structures
  1835. //
  1836. pInfo->pServices = NULL;
  1837. }
  1838. if ( SCESTATUS_SUCCESS == rc ) {
  1839. RpcTryExcept {
  1840. if ( dwMode & SCE_UPDATE_SYSTEM ) {
  1841. PSCE_ERROR_LOG_INFO pErrTmp=NULL;
  1842. if ( cxtProfile ) {
  1843. rc = SceRpcSetSystemSecurityFromHandle(
  1844. (SCEPR_CONTEXT)cxtProfile,
  1845. (AREAPR)Area,
  1846. 0,
  1847. (PSCEPR_PROFILE_INFO)pInfo,
  1848. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  1849. );
  1850. } else {
  1851. //
  1852. // set system settings
  1853. // for normal user, the local policy database can't be opened.
  1854. //
  1855. // RPC bind to the server
  1856. //
  1857. handle_t binding_h;
  1858. NTSTATUS NtStatus = ScepBindSecureRpc(
  1859. NULL,
  1860. L"scerpc",
  1861. 0,
  1862. &binding_h
  1863. );
  1864. if (NT_SUCCESS(NtStatus)){
  1865. RpcTryExcept {
  1866. rc = SceRpcSetSystemSecurity(
  1867. binding_h,
  1868. (AREAPR)Area,
  1869. 0,
  1870. (PSCEPR_PROFILE_INFO)pInfo,
  1871. (PSCEPR_ERROR_LOG_INFO *)&pErrTmp
  1872. );
  1873. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1874. //
  1875. // get exception code (DWORD)
  1876. //
  1877. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1878. } RpcEndExcept;
  1879. //
  1880. // Free the binding handle
  1881. //
  1882. RpcpUnbindRpc( binding_h );
  1883. } else {
  1884. rc = ScepDosErrorToSceStatus(
  1885. RtlNtStatusToDosError( NtStatus ));
  1886. }
  1887. }
  1888. if ( pErrTmp ) {
  1889. //
  1890. // free this tmp buffer
  1891. //
  1892. ScepFreeErrorLog(pErrTmp);
  1893. }
  1894. } else {
  1895. rc = SceRpcUpdateDatabaseInfo(
  1896. (SCEPR_CONTEXT)cxtProfile,
  1897. (SCEPR_TYPE)(pInfo->Type),
  1898. (AREAPR)Area,
  1899. (PSCEPR_PROFILE_INFO)pInfo,
  1900. dwMode
  1901. );
  1902. }
  1903. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  1904. //
  1905. // get exception code (DWORD)
  1906. //
  1907. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  1908. } RpcEndExcept;
  1909. }
  1910. //
  1911. // should free the new service security descriptor buffer
  1912. //
  1913. ScepFreeConvertedServices( (PVOID)(pInfo->pServices), TRUE );
  1914. //
  1915. // restore the old buffer
  1916. //
  1917. pInfo->pServices = pOldServices;
  1918. return(rc);
  1919. }
  1920. SCESTATUS
  1921. WINAPI
  1922. SceUpdateObjectInfo(
  1923. IN PVOID cxtProfile,
  1924. IN AREA_INFORMATION Area,
  1925. IN PWSTR ObjectName,
  1926. IN DWORD NameLen, // number of characters
  1927. IN BYTE ConfigStatus,
  1928. IN BOOL IsContainer,
  1929. IN PSECURITY_DESCRIPTOR pSD,
  1930. IN SECURITY_INFORMATION SeInfo,
  1931. OUT PBYTE pAnalysisStatus
  1932. )
  1933. /*
  1934. Routine Description:
  1935. See description in SceRpcUpdateObjectInfo
  1936. */
  1937. {
  1938. if ( !cxtProfile || !ObjectName || 0 == Area ) {
  1939. return(SCESTATUS_INVALID_PARAMETER);
  1940. }
  1941. SCESTATUS rc=SCESTATUS_SUCCESS;
  1942. //
  1943. // handle RPC exceptions
  1944. //
  1945. PSCEPR_SR_SECURITY_DESCRIPTOR pNewWrap=NULL;
  1946. PSECURITY_DESCRIPTOR pNewSrSD=NULL;
  1947. //
  1948. // there is a security descriptor, must be self relative
  1949. // if the SD is not self relative, should convert it
  1950. //
  1951. if ( pSD ) {
  1952. if ( !RtlValidSid (pSD) ) {
  1953. return(SCESTATUS_INVALID_PARAMETER);
  1954. }
  1955. SECURITY_DESCRIPTOR_CONTROL ControlBits=0;
  1956. ULONG Revision;
  1957. ULONG nLen=0;
  1958. RtlGetControlSecurityDescriptor ( pSD, &ControlBits, &Revision);
  1959. if ( !(ControlBits & SE_SELF_RELATIVE) ) {
  1960. //
  1961. // if it's absolute format, convert it
  1962. //
  1963. rc = ScepDosErrorToSceStatus(
  1964. ScepMakeSelfRelativeSD( pSD, &pNewSrSD, &nLen ) );
  1965. if ( SCESTATUS_SUCCESS != rc ) {
  1966. return(rc);
  1967. }
  1968. } else {
  1969. //
  1970. // already self relative, just use it
  1971. //
  1972. nLen = RtlLengthSecurityDescriptor (pSD);
  1973. }
  1974. if ( nLen > 0 ) {
  1975. //
  1976. // create a wrapper node to contain the security descriptor
  1977. //
  1978. pNewWrap = (PSCEPR_SR_SECURITY_DESCRIPTOR)ScepAlloc(0, sizeof(SCEPR_SR_SECURITY_DESCRIPTOR));
  1979. if ( pNewWrap ) {
  1980. //
  1981. // assign the wrap to the structure
  1982. //
  1983. if ( ControlBits & SE_SELF_RELATIVE ) {
  1984. pNewWrap->SecurityDescriptor = (UCHAR *)pSD;
  1985. } else {
  1986. pNewWrap->SecurityDescriptor = (UCHAR *)pNewSrSD;
  1987. }
  1988. pNewWrap->Length = nLen;
  1989. } else {
  1990. //
  1991. // no memory is available, but still continue to parse all nodes
  1992. //
  1993. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1994. }
  1995. } else {
  1996. //
  1997. // something is wrong with the SD
  1998. //
  1999. rc = SCESTATUS_INVALID_PARAMETER;
  2000. }
  2001. if ( SCESTATUS_SUCCESS != rc ) {
  2002. if ( pNewSrSD ) {
  2003. ScepFree(pNewSrSD);
  2004. }
  2005. return(rc);
  2006. }
  2007. }
  2008. RpcTryExcept {
  2009. rc = SceRpcUpdateObjectInfo(
  2010. (SCEPR_CONTEXT)cxtProfile,
  2011. (AREAPR)Area,
  2012. (wchar_t *)ObjectName,
  2013. NameLen,
  2014. ConfigStatus,
  2015. IsContainer,
  2016. (SCEPR_SR_SECURITY_DESCRIPTOR *)pNewWrap,
  2017. SeInfo,
  2018. pAnalysisStatus
  2019. );
  2020. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2021. //
  2022. // get exception code (DWORD)
  2023. //
  2024. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2025. } RpcEndExcept;
  2026. if ( pNewSrSD ) {
  2027. ScepFree(pNewSrSD);
  2028. }
  2029. return(rc);
  2030. }
  2031. SCESTATUS
  2032. WINAPI
  2033. SceStartTransaction(
  2034. IN PVOID cxtProfile
  2035. )
  2036. {
  2037. if ( cxtProfile == NULL ) {
  2038. return(SCESTATUS_INVALID_PARAMETER);
  2039. }
  2040. SCESTATUS rc;
  2041. RpcTryExcept {
  2042. rc = SceRpcStartTransaction((SCEPR_CONTEXT)cxtProfile);
  2043. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2044. //
  2045. // get exception code (DWORD)
  2046. //
  2047. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2048. } RpcEndExcept;
  2049. return(rc);
  2050. }
  2051. SCESTATUS
  2052. WINAPI
  2053. SceCommitTransaction(
  2054. IN PVOID cxtProfile
  2055. )
  2056. {
  2057. if ( cxtProfile == NULL ) {
  2058. return(SCESTATUS_INVALID_PARAMETER);
  2059. }
  2060. SCESTATUS rc;
  2061. RpcTryExcept {
  2062. rc = SceRpcCommitTransaction((SCEPR_CONTEXT)cxtProfile);
  2063. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2064. //
  2065. // get exception code (DWORD)
  2066. //
  2067. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2068. } RpcEndExcept;
  2069. return(rc);
  2070. }
  2071. SCESTATUS
  2072. WINAPI
  2073. SceRollbackTransaction(
  2074. IN PVOID cxtProfile
  2075. )
  2076. {
  2077. if ( cxtProfile == NULL ) {
  2078. return(SCESTATUS_INVALID_PARAMETER);
  2079. }
  2080. SCESTATUS rc;
  2081. RpcTryExcept {
  2082. rc = SceRpcRollbackTransaction((SCEPR_CONTEXT)cxtProfile);
  2083. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2084. //
  2085. // get exception code (DWORD)
  2086. //
  2087. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2088. } RpcEndExcept;
  2089. return(rc);
  2090. }
  2091. SCESTATUS
  2092. WINAPI
  2093. SceGetServerProductType(
  2094. IN LPTSTR SystemName OPTIONAL,
  2095. OUT PSCE_SERVER_TYPE pServerType
  2096. )
  2097. /*
  2098. Routine Description:
  2099. Query product type and NT version of the server where SCE server is
  2100. running on
  2101. See description of SceRpcGetServerProductType
  2102. */
  2103. {
  2104. if ( !SystemName ) {
  2105. //
  2106. // the local call
  2107. //
  2108. return(ScepGetProductType(pServerType));
  2109. }
  2110. handle_t binding_h;
  2111. NTSTATUS NtStatus;
  2112. SCESTATUS rc;
  2113. //
  2114. // RPC bind to the server
  2115. //
  2116. NtStatus = ScepBindSecureRpc(
  2117. SystemName,
  2118. L"scerpc",
  2119. 0,
  2120. &binding_h
  2121. );
  2122. if (NT_SUCCESS(NtStatus)){
  2123. //
  2124. // handle RPC exceptions
  2125. //
  2126. RpcTryExcept {
  2127. rc = SceRpcGetServerProductType(
  2128. binding_h,
  2129. (PSCEPR_SERVER_TYPE)pServerType
  2130. );
  2131. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2132. //
  2133. // get exception code (DWORD)
  2134. //
  2135. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2136. } RpcEndExcept;
  2137. //
  2138. // Free the binding handle
  2139. //
  2140. RpcpUnbindRpc( binding_h );
  2141. } else {
  2142. rc = ScepDosErrorToSceStatus(
  2143. RtlNtStatusToDosError( NtStatus ));
  2144. }
  2145. return(rc);
  2146. }
  2147. SCESTATUS
  2148. WINAPI
  2149. SceSvcUpdateInfo(
  2150. IN PVOID hProfile,
  2151. IN PCWSTR ServiceName,
  2152. IN PSCESVC_CONFIGURATION_INFO Info
  2153. )
  2154. /*
  2155. Routine Description:
  2156. Load service's engine dll and pass the Info buffer to service engine's
  2157. update API (SceSvcAttachmentUpdate). Currently security manager engine
  2158. is not doing any processing for the service data.
  2159. This routine triggers the update of configuration database and/or
  2160. analysis information by the service engine. Info may contain the
  2161. modifications only, or the whole configuratio data for the service,
  2162. or partial configuration data, depending on the agreement between service
  2163. extension and service engine.
  2164. This routine does not really write info to security manager database directly,
  2165. instead, it passes the info buffer to the service engine's update interface
  2166. and service engine will determine what and when to write inot the database.
  2167. Arguments:
  2168. hProfile - the security database handle (returned from SCE server)
  2169. ServiceName - The service's name as used by service control manager
  2170. Info - The information modified
  2171. */
  2172. {
  2173. if ( hProfile == NULL || ServiceName == NULL ||
  2174. Info == NULL ) {
  2175. return(SCESTATUS_INVALID_PARAMETER);
  2176. }
  2177. SCESTATUS rc;
  2178. RpcTryExcept {
  2179. //
  2180. // call the RPC interface to update info.
  2181. // the RPC interface loads service engine dll on the server site
  2182. // and passes the info buffer to service engine to process
  2183. //
  2184. rc = SceSvcRpcUpdateInfo(
  2185. (SCEPR_CONTEXT)hProfile,
  2186. (wchar_t *)ServiceName,
  2187. (PSCEPR_SVCINFO)Info
  2188. );
  2189. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2190. //
  2191. // get exception code (DWORD) and convert it into SCESTATUS
  2192. //
  2193. rc = ScepDosErrorToSceStatus(
  2194. RpcExceptionCode());
  2195. } RpcEndExcept;
  2196. return(rc);
  2197. }
  2198. DWORD
  2199. WINAPI
  2200. SceRegisterRegValues(
  2201. IN LPTSTR InfFileName
  2202. )
  2203. /*
  2204. Routine Description:
  2205. Register the registry values from the inf file into reg values location
  2206. under SecEdit key
  2207. This routine can be called from DllRegisterServer, or from the command
  2208. line tool /register
  2209. Arguments:
  2210. InfFileName - the inf file which contains the register values to register
  2211. Return Value:
  2212. Win32 error code
  2213. */
  2214. {
  2215. if ( !InfFileName ) {
  2216. return(ERROR_INVALID_PARAMETER);
  2217. }
  2218. SCESTATUS rc;
  2219. HINF hInf;
  2220. DWORD Win32rc;
  2221. rc = SceInfpOpenProfile(
  2222. InfFileName,
  2223. &hInf
  2224. );
  2225. if ( SCESTATUS_SUCCESS == rc ) {
  2226. INFCONTEXT InfLine;
  2227. HKEY hKeyRoot;
  2228. DWORD dwDisp;
  2229. if(SetupFindFirstLine(hInf,SCE_REGISTER_REGVALUE_SECTION,NULL,&InfLine)) {
  2230. //
  2231. // create the root key first
  2232. //
  2233. Win32rc = RegCreateKeyEx (HKEY_LOCAL_MACHINE,
  2234. SCE_ROOT_REGVALUE_PATH,
  2235. 0,
  2236. NULL,
  2237. REG_OPTION_NON_VOLATILE,
  2238. KEY_READ | KEY_WRITE,
  2239. NULL,
  2240. &hKeyRoot,
  2241. &dwDisp);
  2242. if ( ERROR_SUCCESS == Win32rc ||
  2243. ERROR_ALREADY_EXISTS == Win32rc ) {
  2244. DWORD dSize;
  2245. PWSTR RegKeyName, DisplayName;
  2246. DWORD dType;
  2247. HKEY hKey;
  2248. do {
  2249. //
  2250. // Get key names, value type, diaply name, and display type.
  2251. //
  2252. if(SetupGetStringField(&InfLine,1,NULL,0,&dSize) && dSize > 0) {
  2253. RegKeyName = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR));
  2254. if( RegKeyName == NULL ) {
  2255. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2256. } else {
  2257. RegKeyName[dSize] = L'\0';
  2258. if(SetupGetStringField(&InfLine,1,RegKeyName,dSize, NULL)) {
  2259. //
  2260. // make sure not \\ is specified, if there is
  2261. // change it to /
  2262. //
  2263. ScepConvertMultiSzToDelim(RegKeyName, dSize, L'\\', L'/');
  2264. //
  2265. // get the filed count
  2266. // if count is 1, this key should be deleted
  2267. //
  2268. dwDisp = SetupGetFieldCount( &InfLine );
  2269. if ( dwDisp <= 1 ) {
  2270. //
  2271. // delete this key, don't care error
  2272. //
  2273. RegDeleteKey ( hKeyRoot, RegKeyName );
  2274. Win32rc = ERROR_SUCCESS;
  2275. } else {
  2276. Win32rc = RegCreateKeyEx (hKeyRoot,
  2277. RegKeyName,
  2278. 0,
  2279. NULL,
  2280. REG_OPTION_NON_VOLATILE,
  2281. KEY_WRITE,
  2282. NULL,
  2283. &hKey,
  2284. NULL);
  2285. }
  2286. if ( (dwDisp > 1) &&
  2287. ERROR_SUCCESS == Win32rc ||
  2288. ERROR_ALREADY_EXISTS == Win32rc ) {
  2289. //
  2290. // get registry value type
  2291. //
  2292. dType = REG_DWORD;
  2293. SetupGetIntField( &InfLine, 2, (INT *)&dType );
  2294. RegSetValueEx (hKey,
  2295. SCE_REG_VALUE_TYPE,
  2296. 0,
  2297. REG_DWORD,
  2298. (LPBYTE)&dType,
  2299. sizeof(DWORD));
  2300. //
  2301. // get registry value display type
  2302. //
  2303. dType = SCE_REG_DISPLAY_ENABLE;
  2304. SetupGetIntField( &InfLine, 4, (INT *)&dType );
  2305. RegSetValueEx (hKey,
  2306. SCE_REG_DISPLAY_TYPE,
  2307. 0,
  2308. REG_DWORD,
  2309. (LPBYTE)&dType,
  2310. sizeof(DWORD));
  2311. //
  2312. // get registry display name
  2313. //
  2314. if(SetupGetStringField(&InfLine,3,NULL,0,&dSize) && dSize > 0) {
  2315. DisplayName = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR));
  2316. if( DisplayName == NULL ) {
  2317. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2318. } else {
  2319. DisplayName[dSize] = L'\0';
  2320. if(SetupGetStringField(&InfLine,3,DisplayName,dSize, NULL)) {
  2321. RegSetValueEx (hKey,
  2322. SCE_REG_DISPLAY_NAME,
  2323. 0,
  2324. REG_SZ,
  2325. (LPBYTE)DisplayName,
  2326. dSize*sizeof(TCHAR));
  2327. }
  2328. ScepFree(DisplayName);
  2329. DisplayName = NULL;
  2330. }
  2331. }
  2332. //
  2333. // get registry display unit (optional)
  2334. //
  2335. if ( dType == SCE_REG_DISPLAY_NUMBER ||
  2336. dType == SCE_REG_DISPLAY_CHOICE ||
  2337. dType == SCE_REG_DISPLAY_FLAGS ) {
  2338. if ( SetupGetMultiSzField(&InfLine,5,NULL,0,&dSize) && dSize > 0) {
  2339. DisplayName = (PWSTR)ScepAlloc( 0, (dSize+1)*sizeof(WCHAR));
  2340. if( DisplayName == NULL ) {
  2341. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2342. } else {
  2343. DisplayName[dSize] = L'\0';
  2344. if(SetupGetMultiSzField(&InfLine,5,DisplayName,dSize, NULL)) {
  2345. if ( dType == SCE_REG_DISPLAY_NUMBER ) {
  2346. dSize = wcslen(DisplayName);
  2347. }
  2348. switch (dType) {
  2349. case SCE_REG_DISPLAY_NUMBER:
  2350. RegSetValueEx (hKey,
  2351. SCE_REG_DISPLAY_UNIT,
  2352. 0,
  2353. REG_SZ,
  2354. (LPBYTE)DisplayName,
  2355. dSize*sizeof(TCHAR));
  2356. break;
  2357. case SCE_REG_DISPLAY_CHOICE:
  2358. RegSetValueEx (hKey,
  2359. SCE_REG_DISPLAY_CHOICES,
  2360. 0,
  2361. REG_MULTI_SZ,
  2362. (LPBYTE)DisplayName,
  2363. dSize*sizeof(TCHAR));
  2364. break;
  2365. case SCE_REG_DISPLAY_FLAGS:
  2366. RegSetValueEx (hKey,
  2367. SCE_REG_DISPLAY_FLAGLIST,
  2368. 0,
  2369. REG_MULTI_SZ,
  2370. (LPBYTE)DisplayName,
  2371. dSize*sizeof(TCHAR));
  2372. break;
  2373. default:
  2374. break;
  2375. }
  2376. }
  2377. ScepFree(DisplayName);
  2378. DisplayName = NULL;
  2379. }
  2380. }
  2381. }
  2382. RegCloseKey(hKey);
  2383. hKey = NULL;
  2384. }
  2385. } else {
  2386. Win32rc = GetLastError();
  2387. }
  2388. ScepFree(RegKeyName);
  2389. RegKeyName = NULL;
  2390. }
  2391. } else {
  2392. Win32rc = GetLastError();
  2393. }
  2394. if ( ERROR_SUCCESS != Win32rc ) {
  2395. break;
  2396. }
  2397. } while (SetupFindNextLine(&InfLine,&InfLine));
  2398. RegCloseKey(hKeyRoot);
  2399. }
  2400. } else {
  2401. Win32rc = GetLastError();
  2402. }
  2403. SceInfpCloseProfile(hInf);
  2404. } else {
  2405. Win32rc = ScepSceStatusToDosError(rc);
  2406. }
  2407. return(Win32rc);
  2408. }
  2409. //
  2410. // the RPC callback
  2411. //
  2412. SCEPR_STATUS
  2413. SceClientBrowseCallback(
  2414. IN LONG GpoID,
  2415. IN wchar_t *KeyName OPTIONAL,
  2416. IN wchar_t *GpoName OPTIONAL,
  2417. IN SCEPR_SR_SECURITY_DESCRIPTOR *Value OPTIONAL
  2418. )
  2419. /*
  2420. Routine Description:
  2421. The RPC client callback routine which is called from the server when
  2422. the callback flag is set. This routine is registered in scerpc.idl.
  2423. The callbacks are registered to SCE as arguments when calling from the
  2424. browse API
  2425. Arguments:
  2426. Return Value:
  2427. SCEPR_STATUS
  2428. */
  2429. {
  2430. //
  2431. // the static variables holding callback pointer to client
  2432. //
  2433. if ( theBrowseCallBack != NULL ) {
  2434. //
  2435. // callback to browse progress
  2436. //
  2437. PSCE_BROWSE_CALLBACK_ROUTINE pcb;
  2438. pcb = (PSCE_BROWSE_CALLBACK_ROUTINE)theBrowseCallBack;
  2439. __try {
  2440. //
  2441. // callback
  2442. //
  2443. if ( !((*pcb)(GpoID,
  2444. KeyName,
  2445. GpoName,
  2446. ((Value && Value->Length) ? (PWSTR)(Value->SecurityDescriptor) : NULL),
  2447. Value ? (Value->Length)/sizeof(WCHAR) : 0
  2448. )) ) {
  2449. return SCESTATUS_SERVICE_NOT_SUPPORT;
  2450. }
  2451. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2452. return(SCESTATUS_INVALID_PARAMETER);
  2453. }
  2454. }
  2455. return(SCESTATUS_SUCCESS);
  2456. }
  2457. SCESTATUS
  2458. SceBrowseDatabaseTable(
  2459. IN PWSTR DatabaseName OPTIONAL,
  2460. IN SCETYPE ProfileType,
  2461. IN AREA_INFORMATION Area,
  2462. IN BOOL bDomainPolicyOnly,
  2463. IN PSCE_BROWSE_CALLBACK_ROUTINE pCallback OPTIONAL
  2464. )
  2465. {
  2466. if ( bDomainPolicyOnly &&
  2467. (ProfileType != SCE_ENGINE_SCP) &&
  2468. (ProfileType != SCE_ENGINE_SAP) ) {
  2469. return(SCESTATUS_INVALID_PARAMETER);
  2470. }
  2471. if ( bDomainPolicyOnly && (ProfileType == SCE_ENGINE_SAP) ) {
  2472. /*
  2473. // No, should allow any database for debugging
  2474. //
  2475. // should only work for the system database
  2476. //
  2477. if ( DatabaseName != NULL && !SceIsSystemDatabase(DatabaseName) ) {
  2478. return(SCESTATUS_INVALID_PARAMETER);
  2479. }
  2480. */
  2481. if ( DatabaseName == NULL ) {
  2482. //
  2483. // if it's a normal user logon, should return invalid
  2484. //
  2485. BOOL bAdmin=FALSE;
  2486. if ( ERROR_SUCCESS != ScepIsAdminLoggedOn(&bAdmin, FALSE) || !bAdmin )
  2487. return(SCESTATUS_INVALID_PARAMETER);
  2488. }
  2489. }
  2490. if ( ProfileType != SCE_ENGINE_SCP &&
  2491. ProfileType != SCE_ENGINE_SMP &&
  2492. ProfileType != SCE_ENGINE_SAP ) {
  2493. return(SCESTATUS_INVALID_PARAMETER);
  2494. }
  2495. NTSTATUS NtStatus;
  2496. SCESTATUS rc;
  2497. handle_t binding_h;
  2498. //
  2499. // RPC bind to the server
  2500. //
  2501. NtStatus = ScepBindSecureRpc(
  2502. NULL,
  2503. L"scerpc",
  2504. 0,
  2505. &binding_h
  2506. );
  2507. if (NT_SUCCESS(NtStatus)){
  2508. theBrowseCallBack = (PVOID)pCallback;
  2509. RpcTryExcept {
  2510. rc = SceRpcBrowseDatabaseTable(
  2511. binding_h,
  2512. (wchar_t *)DatabaseName,
  2513. (SCEPR_TYPE)ProfileType,
  2514. (AREAPR)Area,
  2515. bDomainPolicyOnly
  2516. );
  2517. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2518. //
  2519. // get exception code (DWORD)
  2520. //
  2521. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2522. } RpcEndExcept;
  2523. theBrowseCallBack = NULL;
  2524. //
  2525. // Free the binding handle
  2526. //
  2527. RpcpUnbindRpc( binding_h );
  2528. } else {
  2529. rc = ScepDosErrorToSceStatus(
  2530. RtlNtStatusToDosError( NtStatus ));
  2531. }
  2532. return(rc);
  2533. }
  2534. SCESTATUS
  2535. ScepConvertServices(
  2536. IN OUT PVOID *ppServices,
  2537. IN BOOL bSRForm
  2538. )
  2539. {
  2540. if ( !ppServices ) {
  2541. return(SCESTATUS_INVALID_PARAMETER);
  2542. }
  2543. PSCE_SERVICES pTemp = (PSCE_SERVICES)(*ppServices);
  2544. SCESTATUS rc=SCESTATUS_SUCCESS;
  2545. PSCE_SERVICES pNewNode;
  2546. PSCE_SERVICES pNewServices=NULL;
  2547. while ( pTemp ) {
  2548. pNewNode = (PSCE_SERVICES)ScepAlloc(0,sizeof(SCE_SERVICES));
  2549. if ( pNewNode ) {
  2550. pNewNode->ServiceName = pTemp->ServiceName;
  2551. pNewNode->DisplayName = pTemp->DisplayName;
  2552. pNewNode->Status = pTemp->Status;
  2553. pNewNode->Startup = pTemp->Startup;
  2554. pNewNode->SeInfo = pTemp->SeInfo;
  2555. pNewNode->General.pSecurityDescriptor = NULL;
  2556. pNewNode->Next = pNewServices;
  2557. pNewServices = pNewNode;
  2558. if ( bSRForm ) {
  2559. //
  2560. // Service node is in SCEPR_SERVICES structure
  2561. // convert it to SCE_SERVICES structure
  2562. // in this case, just use the self relative security descriptor
  2563. //
  2564. if ( pTemp->General.pSecurityDescriptor) {
  2565. pNewNode->General.pSecurityDescriptor = ((PSCEPR_SERVICES)pTemp)->pSecurityDescriptor->SecurityDescriptor;
  2566. }
  2567. } else {
  2568. //
  2569. // Service node is in SCE_SERVICES strucutre
  2570. // convert it to SCEPR_SERVICES structure
  2571. //
  2572. // make the SD to self relative format and PSCEPR_SR_SECURITY_DESCRIPTOR
  2573. //
  2574. if ( pTemp->General.pSecurityDescriptor ) {
  2575. if ( !RtlValidSid ( pTemp->General.pSecurityDescriptor ) ) {
  2576. rc = SCESTATUS_INVALID_PARAMETER;
  2577. break;
  2578. }
  2579. DWORD nLen = 0;
  2580. PSECURITY_DESCRIPTOR pSD=NULL;
  2581. rc = ScepDosErrorToSceStatus(
  2582. ScepMakeSelfRelativeSD(
  2583. pTemp->General.pSecurityDescriptor,
  2584. &pSD,
  2585. &nLen
  2586. ));
  2587. if ( SCESTATUS_SUCCESS == rc ) {
  2588. //
  2589. // create a wrapper node to contain the security descriptor
  2590. //
  2591. PSCEPR_SR_SECURITY_DESCRIPTOR pNewWrap;
  2592. pNewWrap = (PSCEPR_SR_SECURITY_DESCRIPTOR)ScepAlloc(0, sizeof(SCEPR_SR_SECURITY_DESCRIPTOR));
  2593. if ( pNewWrap ) {
  2594. //
  2595. // assign the wrap to the structure
  2596. //
  2597. pNewWrap->SecurityDescriptor = (UCHAR *)pSD;
  2598. pNewWrap->Length = nLen;
  2599. } else {
  2600. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2601. ScepFree(pSD);
  2602. break;
  2603. }
  2604. //
  2605. // now link the SR_SD to the list
  2606. //
  2607. ((PSCEPR_SERVICES)pNewNode)->pSecurityDescriptor = pNewWrap;
  2608. } else {
  2609. break;
  2610. }
  2611. }
  2612. }
  2613. } else {
  2614. //
  2615. // all allocated buffer are in the list of pNewServices
  2616. //
  2617. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2618. break;
  2619. }
  2620. pTemp = pTemp->Next;
  2621. }
  2622. if ( SCESTATUS_SUCCESS != rc ) {
  2623. //
  2624. // free pNewServices
  2625. //
  2626. ScepFreeConvertedServices( (PVOID)pNewServices, !bSRForm );
  2627. pNewServices = NULL;
  2628. }
  2629. *ppServices = (PVOID)pNewServices;
  2630. return(rc);
  2631. }
  2632. SCESTATUS
  2633. ScepFreeConvertedServices(
  2634. IN PVOID pServices,
  2635. IN BOOL bSRForm
  2636. )
  2637. {
  2638. if ( pServices == NULL ) {
  2639. return(SCESTATUS_SUCCESS);
  2640. }
  2641. PSCEPR_SERVICES pNewNode = (PSCEPR_SERVICES)pServices;
  2642. PSCEPR_SERVICES pTempNode;
  2643. while ( pNewNode ) {
  2644. if ( bSRForm && pNewNode->pSecurityDescriptor ) {
  2645. //
  2646. // free this allocated buffer (PSCEPR_SR_SECURITY_DESCRIPTOR)
  2647. //
  2648. if ( pNewNode->pSecurityDescriptor->SecurityDescriptor ) {
  2649. ScepFree( pNewNode->pSecurityDescriptor->SecurityDescriptor);
  2650. }
  2651. ScepFree(pNewNode->pSecurityDescriptor);
  2652. }
  2653. //
  2654. // also free the PSCEPR_SERVICE node (but not the names referenced by this node)
  2655. //
  2656. pTempNode = pNewNode;
  2657. pNewNode = pNewNode->Next;
  2658. ScepFree(pTempNode);
  2659. }
  2660. return(SCESTATUS_SUCCESS);
  2661. }
  2662. DWORD
  2663. ScepMakeSelfRelativeSD(
  2664. IN PSECURITY_DESCRIPTOR pInSD,
  2665. OUT PSECURITY_DESCRIPTOR *pOutSD,
  2666. OUT PULONG pnLen
  2667. )
  2668. {
  2669. if ( pInSD == NULL ||
  2670. pOutSD == NULL ||
  2671. pnLen == NULL ) {
  2672. return(ERROR_INVALID_PARAMETER);
  2673. }
  2674. //
  2675. // get the length
  2676. //
  2677. RtlMakeSelfRelativeSD( pInSD,
  2678. NULL,
  2679. pnLen
  2680. );
  2681. if ( *pnLen > 0 ) {
  2682. *pOutSD = (PSECURITY_DESCRIPTOR)ScepAlloc(LMEM_ZEROINIT, *pnLen);
  2683. if ( !(*pOutSD) ) {
  2684. return(ERROR_NOT_ENOUGH_MEMORY);
  2685. }
  2686. DWORD NewLen=*pnLen;
  2687. DWORD rc = RtlNtStatusToDosError(
  2688. RtlMakeSelfRelativeSD( pInSD,
  2689. *pOutSD,
  2690. &NewLen
  2691. ) );
  2692. if ( rc != ERROR_SUCCESS ) {
  2693. ScepFree(*pOutSD);
  2694. *pOutSD = NULL;
  2695. *pnLen = 0;
  2696. return(rc);
  2697. }
  2698. } else {
  2699. //
  2700. // something is wrong with the SD
  2701. //
  2702. return(ERROR_INVALID_PARAMETER);
  2703. }
  2704. return(ERROR_SUCCESS);
  2705. }
  2706. SCESTATUS
  2707. WINAPI
  2708. SceGetDatabaseSetting(
  2709. IN PVOID hProfile,
  2710. IN SCETYPE ProfileType,
  2711. IN PWSTR SectionName,
  2712. IN PWSTR KeyName,
  2713. OUT PWSTR *Value,
  2714. OUT DWORD *pnBytes OPTIONAL
  2715. )
  2716. /*
  2717. Routine Descripton:
  2718. Get database setting (from SMP table) for the given key
  2719. Arguments:
  2720. hProfile - the profile handle
  2721. ProfileType - the database type
  2722. SectionName - the section to query data from
  2723. KeyName - the key name
  2724. Value - output buffer for the setting
  2725. ValueLen - the nubmer of bytes to output
  2726. Return Value:
  2727. SCE status
  2728. */
  2729. {
  2730. SCESTATUS rc;
  2731. if ( hProfile == NULL ||
  2732. KeyName == NULL ||
  2733. SectionName == NULL ||
  2734. Value == NULL ) {
  2735. return(SCESTATUS_INVALID_PARAMETER);
  2736. }
  2737. if ( ProfileType != SCE_ENGINE_SMP ) {
  2738. return(SCESTATUS_INVALID_PARAMETER);
  2739. }
  2740. //
  2741. // call rpc interface
  2742. //
  2743. PSCEPR_VALUEINFO ValueInfo=NULL;
  2744. RpcTryExcept {
  2745. rc = SceRpcGetDatabaseSetting(
  2746. (SCEPR_CONTEXT)hProfile,
  2747. (SCEPR_TYPE)ProfileType,
  2748. (wchar_t *)SectionName,
  2749. (wchar_t *)KeyName,
  2750. &ValueInfo
  2751. );
  2752. if ( ValueInfo && ValueInfo->Value ) {
  2753. //
  2754. // output the data
  2755. //
  2756. *Value = (PWSTR)ValueInfo->Value;
  2757. if ( pnBytes )
  2758. *pnBytes = ValueInfo->ValueLen;
  2759. ValueInfo->Value = NULL;
  2760. }
  2761. //
  2762. // free buffer
  2763. if ( ValueInfo ) {
  2764. if ( ValueInfo->Value ) ScepFree(ValueInfo->Value);
  2765. ScepFree(ValueInfo);
  2766. }
  2767. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2768. //
  2769. // get exception code (DWORD)
  2770. //
  2771. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2772. } RpcEndExcept;
  2773. return(rc);
  2774. }
  2775. SCESTATUS
  2776. WINAPI
  2777. SceSetDatabaseSetting(
  2778. IN PVOID hProfile,
  2779. IN SCETYPE ProfileType,
  2780. IN PWSTR SectionName,
  2781. IN PWSTR KeyName,
  2782. IN PWSTR Value OPTIONAL,
  2783. IN DWORD nBytes
  2784. )
  2785. /*
  2786. Routine Descripton:
  2787. Set a setting to the database (SMP table) for the given key
  2788. Arguments:
  2789. hProfile - the profile handle
  2790. ProfileType - the database type
  2791. SectionName - the section name to write to
  2792. KeyName - the key name to write to or delete
  2793. Value - the value to write. If NULL, delete the key
  2794. nBytes - the number of bytes of the input Value buffer
  2795. Return Value:
  2796. SCE status
  2797. */
  2798. {
  2799. SCESTATUS rc;
  2800. if ( hProfile == NULL ||
  2801. SectionName == NULL ||
  2802. KeyName == NULL ) {
  2803. return(SCESTATUS_INVALID_PARAMETER);
  2804. }
  2805. if ( ProfileType != SCE_ENGINE_SMP ) {
  2806. return(SCESTATUS_INVALID_PARAMETER);
  2807. }
  2808. //
  2809. // call rpc interface
  2810. //
  2811. RpcTryExcept {
  2812. SCEPR_VALUEINFO ValueInfo;
  2813. ValueInfo.Value = (byte *)Value;
  2814. ValueInfo.ValueLen = nBytes;
  2815. rc = SceRpcSetDatabaseSetting(
  2816. (SCEPR_CONTEXT)hProfile,
  2817. (SCEPR_TYPE)ProfileType,
  2818. (wchar_t *)SectionName,
  2819. (wchar_t *)KeyName,
  2820. Value ? &ValueInfo : NULL
  2821. );
  2822. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2823. //
  2824. // get exception code (DWORD)
  2825. //
  2826. rc = ScepDosErrorToSceStatus(RpcExceptionCode());
  2827. } RpcEndExcept;
  2828. return(rc);
  2829. }
  2830. DWORD
  2831. ScepControlNotificationQProcess(
  2832. IN PWSTR szLogFileName,
  2833. IN BOOL bThisIsDC,
  2834. IN DWORD ControlFlag
  2835. )
  2836. /*
  2837. Description:
  2838. To suspend or resume policy notification queue processing on DCs
  2839. This routine is used to make sure that the latest group policy is
  2840. being processed in policy proapgation (copied to the cache)
  2841. */
  2842. {
  2843. if ( !bThisIsDC ) return ERROR_SUCCESS;
  2844. handle_t binding_h;
  2845. NTSTATUS NtStatus;
  2846. DWORD rc;
  2847. NtStatus = ScepBindRpc(
  2848. NULL,
  2849. L"scerpc",
  2850. L"security=impersonation dynamic false",
  2851. &binding_h
  2852. );
  2853. rc = RtlNtStatusToDosError( NtStatus );
  2854. if (NT_SUCCESS(NtStatus)){
  2855. RpcTryExcept {
  2856. rc = SceRpcControlNotificationQProcess(
  2857. binding_h,
  2858. ControlFlag
  2859. );
  2860. } RpcExcept( I_RpcExceptionFilter( RpcExceptionCode()) ) {
  2861. //
  2862. // get exception code (DWORD)
  2863. //
  2864. rc = RpcExceptionCode();
  2865. } RpcEndExcept;
  2866. }
  2867. //
  2868. // Free the binding handle
  2869. //
  2870. RpcpUnbindRpc( binding_h );
  2871. //
  2872. // log the operation
  2873. //
  2874. if ( szLogFileName ) {
  2875. LogEventAndReport(MyModuleHandle,
  2876. szLogFileName,
  2877. 1,
  2878. 0,
  2879. IDS_CONTROL_QUEUE,
  2880. rc,
  2881. ControlFlag
  2882. );
  2883. }
  2884. return rc;
  2885. }