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.

3922 lines
122 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. smbsvc.cpp
  5. Abstract:
  6. File sharing security engine attachment for Security Configuration Editor
  7. Author:
  8. Jin Huang (jinhuang) 11-Jul-1997
  9. Revision History:
  10. --*/
  11. #include "smbsvcp.h"
  12. #include "util.h"
  13. #include "smbdllrc.h"
  14. #include <lmapibuf.h>
  15. #pragma hdrstop
  16. #define SMBSVC_BUF_LEN 1024
  17. #define SCESMB_ROOT_PATH SCE_ROOT_SERVICE_PATH TEXT("\\LanManServer")
  18. #define SmbsvcServerKey L"System\\CurrentControlSet\\Services\\LanManServer\\Parameters"
  19. #define SmbsvcRdrKey L"System\\CurrentControlSet\\Services\\MrxSmb\\Parameters"
  20. #define SmbsvcEnableSS L"EnableSecuritySignature"
  21. #define SmbsvcRequireSS L"RequireSecuritySignature"
  22. #define SmbsvcPlainPassword L"EnablePlainTextPassword"
  23. #define SmbsvcRequireECR L"RequireEnhancedChallengeResponse"
  24. #define SmbsvcNTResponse L"SendNTResponseOnly"
  25. #define SmbsvcRestrictNull L"RestrictNullSessAccess"
  26. #define SmbsvcAutoShareServer L"AutoShareServer"
  27. #define SmbsvcAutoShareWks L"AutoShareWks"
  28. #define SmbsvcForcedLogOff L"EnableForcedLogOff"
  29. #define SmbsvcAutoDisconnect L"AutoDisconnect"
  30. #define NUM_COMP 14
  31. #if defined(_NT4BACK_PORT)
  32. HINSTANCE MyModuleHandle = NULL;
  33. #else
  34. /*
  35. #if !defined(Thread)
  36. #define Thread __declspec( thread )
  37. #endif
  38. HINSTANCE Thread MyModuleHandle=NULL;
  39. */
  40. HINSTANCE MyModuleHandle=NULL;
  41. #endif
  42. static NT_PRODUCT_TYPE ProductType;
  43. GENERIC_MAPPING ShareGenMap = {
  44. STANDARD_RIGHTS_READ | SYNCHRONIZE | 0x1,
  45. STANDARD_RIGHTS_WRITE | SYNCHRONIZE | 0x2,
  46. STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | 0x4,
  47. STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF
  48. };
  49. SCESTATUS
  50. SmbsvcpResetInfo(
  51. IN PSMBSVC_SEC_INFO pInfo
  52. );
  53. SCESTATUS
  54. SmbsvcpGetInformation(
  55. IN PSCESVC_CALLBACK_INFO pSceCbInfo,
  56. OUT PSMBSVC_SEC_INFO pSmbInfo
  57. );
  58. SCESTATUS
  59. SmbsvcpAddAShareToList(
  60. OUT PSMBSVC_SHARES *pShareList,
  61. IN PWSTR ShareName,
  62. IN DWORD Status,
  63. IN PSECURITY_DESCRIPTOR pSD
  64. );
  65. SCESTATUS
  66. SmbsvcpFree(
  67. IN PSMBSVC_SEC_INFO pSmbInfo
  68. );
  69. SCESTATUS
  70. SmbsvcpFreeShareList(
  71. PSMBSVC_SHARES pShares
  72. );
  73. SCESTATUS
  74. SmbsvcpWriteError(
  75. IN PFSCE_LOG_INFO pfLogCallback,
  76. IN INT ErrLevel,
  77. IN DWORD ErrCode,
  78. IN PWSTR Mes
  79. );
  80. SCESTATUS
  81. SmbsvcpWriteError2(
  82. IN PFSCE_LOG_INFO pfLogCallback,
  83. IN INT ErrLevel,
  84. IN DWORD ErrCode,
  85. IN UINT nId,
  86. ...
  87. );
  88. SCESTATUS
  89. SmbsvcpConfigureValue(
  90. IN PCWSTR RegKey,
  91. IN PCWSTR ValueName,
  92. IN DWORD Value
  93. );
  94. SCESTATUS
  95. SmbsvcpQueryShareList(
  96. OUT PSMBSVC_SHARES *pShareList,
  97. OUT PDWORD ShareCount
  98. );
  99. SCESTATUS
  100. SmbsvcpAnalyzeValue(
  101. IN PCWSTR RegKey,
  102. IN PCWSTR RegValueName,
  103. IN PCWSTR KeyName,
  104. IN DWORD ConfigValue,
  105. OUT PSCESVC_ANALYSIS_LINE pLineInfo,
  106. IN OUT PDWORD pCount
  107. );
  108. DWORD
  109. SmbsvcpConvertStringToMultiSz(
  110. IN PWSTR theStr,
  111. IN DWORD theLen,
  112. OUT PBYTE *outValue,
  113. OUT PDWORD outLen
  114. );
  115. SCESTATUS
  116. SmbsvcpAnalyzeMultiSzString(
  117. IN PCWSTR RegKey,
  118. IN PCWSTR RegValueName,
  119. IN PWSTR pConfigInfo,
  120. IN DWORD InfoLength,
  121. OUT PSCESVC_ANALYSIS_LINE pLineInfo,
  122. IN OUT PDWORD pCount
  123. );
  124. DWORD
  125. SmbsvcpChangeMultiSzToString(
  126. IN PWSTR Value
  127. );
  128. DWORD
  129. SmbsvcpCompareMultiSzString(
  130. IN PWSTR pConfigInfo,
  131. IN PWSTR Value,
  132. OUT PDWORD pValueLen,
  133. OUT PBOOL pDiff
  134. );
  135. DWORD
  136. SmbsvcpCountComponents(
  137. IN PWSTR Value,
  138. OUT PDWORD ValueLen,
  139. OUT PDWORD Count
  140. );
  141. SCESTATUS
  142. SmbsvcpUpdateMultiSzString(
  143. IN PSCESVC_CALLBACK_INFO pSceCbInfo,
  144. IN SCESVC_CONFIGURATION_LINE NewLine,
  145. IN PSCESVC_CONFIGURATION_INFO pConfigInfo OPTIONAL,
  146. IN PSCESVC_ANALYSIS_INFO pAnaInfo OPTIONAL
  147. );
  148. SCESTATUS
  149. SmbsvcpUpdateShareValue(
  150. IN PSCESVC_CALLBACK_INFO pSceCbInfo,
  151. IN SCESVC_CONFIGURATION_LINE NewLine,
  152. IN PSCESVC_CONFIGURATION_INFO pConfigInfo OPTIONAL,
  153. IN PSCESVC_ANALYSIS_INFO pAnaInfo OPTIONAL
  154. );
  155. SCESTATUS
  156. SmbsvcpEqualSecurityDescriptor(
  157. IN PSECURITY_DESCRIPTOR pSD1,
  158. IN PSECURITY_DESCRIPTOR pSD2,
  159. IN BOOL bExplicitOnly,
  160. OUT PBOOL pbEqual
  161. );
  162. DWORD
  163. SmbsvcEveryoneFullAccess(
  164. IN PACL pAcl,
  165. IN BOOL bExplicit,
  166. OUT PBOOL pbEqual
  167. );
  168. DWORD
  169. SmbsvcpCompareAcl(
  170. IN PACL pAcl1,
  171. IN PACL pAcl2,
  172. IN BOOL bExplicitOnly,
  173. OUT PBOOL pDifferent
  174. );
  175. DWORD
  176. SmbsvcpAnyExplicitAcl(
  177. IN PACL Acl,
  178. IN DWORD Processed,
  179. OUT PBOOL pExist
  180. );
  181. BOOL
  182. SmbsvcpEqualAce(
  183. IN ACE_HEADER *pAce1,
  184. IN ACE_HEADER *pAce2
  185. );
  186. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  187. // Implementation of well-known interfaces
  188. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  189. SCESTATUS
  190. WINAPI
  191. SceSvcAttachmentConfig(
  192. IN PSCESVC_CALLBACK_INFO pSceCbInfo
  193. )
  194. /*
  195. Routine Description:
  196. Arguments:
  197. pSceCbInfo - the callback info structure which contains the database handle,
  198. callback functions to query info, set info, and free info.
  199. All configuration information for SMB server is stored in the storage.
  200. Return Value:
  201. SCESTATUS
  202. */
  203. {
  204. if ( pSceCbInfo == NULL ||
  205. pSceCbInfo->sceHandle == NULL ||
  206. pSceCbInfo->pfQueryInfo == NULL ||
  207. pSceCbInfo->pfSetInfo == NULL ||
  208. pSceCbInfo->pfFreeInfo == NULL ) {
  209. return(SCESTATUS_INVALID_PARAMETER);
  210. }
  211. if ( !RtlGetNtProductType(&ProductType) ) {
  212. return(SmbsvcpDosErrorToSceStatus(GetLastError()));
  213. }
  214. SCESTATUS rc;
  215. SMBSVC_SEC_INFO SmbInfo;
  216. PSMBSVC_SEC_INFO pSmbInfo=&SmbInfo;
  217. SmbsvcpResetInfo(&SmbInfo);
  218. SmbsvcpWriteError2(
  219. pSceCbInfo->pfLogInfo,
  220. SCE_LOG_LEVEL_DETAIL,
  221. 0,
  222. SMBSVC_QUERY_INFO
  223. );
  224. rc = SmbsvcpGetInformation(
  225. pSceCbInfo,
  226. pSmbInfo
  227. );
  228. if ( rc == SCESTATUS_SUCCESS ) {
  229. //
  230. // configure the registry keys first
  231. //
  232. SmbsvcpWriteError2(
  233. pSceCbInfo->pfLogInfo,
  234. SCE_LOG_LEVEL_DETAIL,
  235. 0,
  236. SMBSVC_CONFIGURE_CLIENT_START
  237. );
  238. SCESTATUS rc2;
  239. //
  240. // EnableSecuritySignature for client
  241. //
  242. rc2 = SmbsvcpConfigureValue(
  243. SmbsvcRdrKey,
  244. SmbsvcEnableSS,
  245. pSmbInfo->EnableClientSecuritySignature
  246. );
  247. if ( rc2 != SCESTATUS_SUCCESS ) {
  248. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  249. SCE_LOG_LEVEL_ERROR,
  250. SmbsvcpSceStatusToDosError(rc2),
  251. SMBSVC_ERROR_CONFIGURE,
  252. SmbsvcEnableSS);
  253. if ( rc == SCESTATUS_SUCCESS &&
  254. rc2 != SCESTATUS_PROFILE_NOT_FOUND ) {
  255. rc = rc2;
  256. }
  257. }
  258. //
  259. // RequireSecuritySignature for client
  260. //
  261. rc2 = SmbsvcpConfigureValue(
  262. SmbsvcRdrKey,
  263. SmbsvcRequireSS,
  264. pSmbInfo->RequireClientSecuritySignature
  265. );
  266. if ( rc2 != SCESTATUS_SUCCESS ) {
  267. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  268. SCE_LOG_LEVEL_ERROR,
  269. SmbsvcpSceStatusToDosError(rc2),
  270. SMBSVC_ERROR_CONFIGURE,
  271. SmbsvcRequireSS);
  272. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  273. rc = rc2;
  274. }
  275. //
  276. // EnablePlainTextPassword (client only)
  277. //
  278. rc2 = SmbsvcpConfigureValue(
  279. SmbsvcRdrKey,
  280. SmbsvcPlainPassword,
  281. pSmbInfo->EnablePlainTextPassword
  282. );
  283. if ( rc2 != SCESTATUS_SUCCESS ) {
  284. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  285. SCE_LOG_LEVEL_ERROR,
  286. SmbsvcpSceStatusToDosError(rc2),
  287. SMBSVC_ERROR_CONFIGURE,
  288. SmbsvcPlainPassword);
  289. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  290. rc = rc2;
  291. }
  292. //
  293. // RequireEnhancedChallengeResponse (client only)
  294. //
  295. rc2 = SmbsvcpConfigureValue(
  296. SmbsvcRdrKey,
  297. SmbsvcRequireECR,
  298. pSmbInfo->RequireEnhancedChallengeResponse
  299. );
  300. if ( rc2 != SCESTATUS_SUCCESS ) {
  301. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  302. SCE_LOG_LEVEL_ERROR,
  303. SmbsvcpSceStatusToDosError(rc2),
  304. SMBSVC_ERROR_CONFIGURE,
  305. SmbsvcRequireECR);
  306. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  307. rc = rc2;
  308. }
  309. //
  310. // SendNTResponseOnly (client only)
  311. //
  312. rc2 = SmbsvcpConfigureValue(
  313. SmbsvcRdrKey,
  314. SmbsvcNTResponse,
  315. pSmbInfo->SendNTResponseOnly
  316. );
  317. if ( rc2 != SCESTATUS_SUCCESS ) {
  318. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  319. SCE_LOG_LEVEL_ERROR,
  320. SmbsvcpSceStatusToDosError(rc2),
  321. SMBSVC_ERROR_CONFIGURE,
  322. SmbsvcNTResponse);
  323. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  324. rc = rc2;
  325. }
  326. if ( SCESTATUS_SUCCESS == rc ) {
  327. SmbsvcpWriteError2(
  328. pSceCbInfo->pfLogInfo,
  329. SCE_LOG_LEVEL_DETAIL,
  330. 0,
  331. SMBSVC_CONFIGURE_CLIENT_DONE
  332. );
  333. }
  334. //
  335. // !!!!!!!! server settings !!!!!!!!!
  336. //
  337. SmbsvcpWriteError2(
  338. pSceCbInfo->pfLogInfo,
  339. SCE_LOG_LEVEL_DETAIL,
  340. 0,
  341. SMBSVC_CONFIGURE_SERVER_START
  342. );
  343. SCESTATUS rc3 = rc;
  344. rc = SCESTATUS_SUCCESS;
  345. //
  346. // EnableSecuritySignature for server
  347. //
  348. rc2 = SmbsvcpConfigureValue(
  349. SmbsvcServerKey,
  350. SmbsvcEnableSS,
  351. pSmbInfo->EnableServerSecuritySignature
  352. );
  353. if ( rc2 != SCESTATUS_SUCCESS ) {
  354. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  355. SCE_LOG_LEVEL_ERROR,
  356. SmbsvcpSceStatusToDosError(rc2),
  357. SMBSVC_ERROR_CONFIGURE,
  358. SmbsvcEnableSS);
  359. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  360. rc = rc2;
  361. }
  362. //
  363. // RequireSecuritySignature for server
  364. //
  365. rc2 = SmbsvcpConfigureValue(
  366. SmbsvcServerKey,
  367. SmbsvcRequireSS,
  368. pSmbInfo->RequireServerSecuritySignature
  369. );
  370. if ( rc2 != SCESTATUS_SUCCESS ) {
  371. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  372. SCE_LOG_LEVEL_ERROR,
  373. SmbsvcpSceStatusToDosError(rc2),
  374. SMBSVC_ERROR_CONFIGURE,
  375. SmbsvcRequireSS);
  376. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  377. rc = rc2;
  378. }
  379. //
  380. // RestrictNullSessionAccess
  381. //
  382. rc2 = SmbsvcpConfigureValue(
  383. SmbsvcServerKey,
  384. SmbsvcRestrictNull,
  385. pSmbInfo->RestrictNullSessionAccess
  386. );
  387. if ( rc2 != SCESTATUS_SUCCESS ) {
  388. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  389. SCE_LOG_LEVEL_ERROR,
  390. SmbsvcpSceStatusToDosError(rc2),
  391. SMBSVC_ERROR_CONFIGURE,
  392. SmbsvcRestrictNull);
  393. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  394. rc = rc2;
  395. }
  396. //
  397. // AutoShareServer or AutoShareWks
  398. //
  399. PCWSTR AutoValueName;
  400. if ( ProductType == NtProductLanManNt ||
  401. ProductType == NtProductServer) {
  402. AutoValueName = SmbsvcAutoShareServer;
  403. } else {
  404. AutoValueName = SmbsvcAutoShareWks;
  405. }
  406. rc2 = SmbsvcpConfigureValue(
  407. SmbsvcServerKey,
  408. AutoValueName,
  409. pSmbInfo->EnableAutoShare
  410. );
  411. if ( rc2 != SCESTATUS_SUCCESS ) {
  412. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  413. SCE_LOG_LEVEL_ERROR,
  414. SmbsvcpSceStatusToDosError(rc2),
  415. SMBSVC_ERROR_CONFIGURE,
  416. (PWSTR)AutoValueName);
  417. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  418. rc = rc2;
  419. }
  420. //
  421. // EnableForcedLogOff
  422. //
  423. rc2 = SmbsvcpConfigureValue(
  424. SmbsvcServerKey,
  425. SmbsvcForcedLogOff,
  426. pSmbInfo->EnableForcedLogOff
  427. );
  428. if ( rc2 != SCESTATUS_SUCCESS ) {
  429. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  430. SCE_LOG_LEVEL_ERROR,
  431. SmbsvcpSceStatusToDosError(rc2),
  432. SMBSVC_ERROR_CONFIGURE,
  433. SmbsvcForcedLogOff);
  434. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  435. rc = rc2;
  436. }
  437. //
  438. // AutoDisconnectTime
  439. //
  440. rc2 = SmbsvcpConfigureValue(
  441. SmbsvcServerKey,
  442. SmbsvcAutoDisconnect,
  443. pSmbInfo->AutoDisconnect
  444. );
  445. if ( rc2 != SCESTATUS_SUCCESS ) {
  446. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  447. SCE_LOG_LEVEL_ERROR,
  448. SmbsvcpSceStatusToDosError(rc2),
  449. SMBSVC_ERROR_CONFIGURE,
  450. SmbsvcAutoDisconnect);
  451. if ( rc == SCESTATUS_SUCCESS && rc2 != SCESTATUS_PROFILE_NOT_FOUND )
  452. rc = rc2;
  453. }
  454. //
  455. // configure Null Session Pipes and Shares
  456. //
  457. // buffer NullSessionPipes and NullSessionShares are already in MULTI_SZ format
  458. //
  459. DWORD Win32rc;
  460. PBYTE MultiSzValue=NULL;
  461. DWORD MultiSzLength=0;
  462. if ( pSmbInfo->LengthPipes != SMBSVC_NO_VALUE ) {
  463. Win32rc = SmbsvcpConvertStringToMultiSz(
  464. pSmbInfo->NullSessionPipes,
  465. pSmbInfo->LengthPipes,
  466. &MultiSzValue,
  467. &MultiSzLength
  468. );
  469. if ( Win32rc == ERROR_SUCCESS ) {
  470. Win32rc = SmbsvcpRegSetValue(
  471. HKEY_LOCAL_MACHINE,
  472. SmbsvcServerKey,
  473. L"NullSessionPipes",
  474. REG_MULTI_SZ,
  475. MultiSzValue,
  476. MultiSzLength
  477. );
  478. }
  479. if ( Win32rc != ERROR_SUCCESS ) {
  480. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  481. SCE_LOG_LEVEL_ERROR,
  482. Win32rc,
  483. SMBSVC_ERROR_CONFIGURE,
  484. L"NullSessionPipes");
  485. if ( rc == SCESTATUS_SUCCESS && Win32rc != ERROR_FILE_NOT_FOUND )
  486. rc = SmbsvcpDosErrorToSceStatus(Win32rc);;
  487. }
  488. }
  489. if ( pSmbInfo->LengthShares != SMBSVC_NO_VALUE ) {
  490. Win32rc = SmbsvcpConvertStringToMultiSz(
  491. pSmbInfo->NullSessionShares,
  492. pSmbInfo->LengthShares,
  493. &MultiSzValue,
  494. &MultiSzLength
  495. );
  496. if ( Win32rc == ERROR_SUCCESS ) {
  497. Win32rc = SmbsvcpRegSetValue(
  498. HKEY_LOCAL_MACHINE,
  499. SmbsvcServerKey,
  500. L"NullSessionShares",
  501. REG_MULTI_SZ,
  502. (PBYTE)(pSmbInfo->NullSessionShares),
  503. pSmbInfo->LengthShares
  504. );
  505. }
  506. if ( Win32rc != ERROR_SUCCESS ) {
  507. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  508. SCE_LOG_LEVEL_ERROR,
  509. Win32rc,
  510. SMBSVC_ERROR_CONFIGURE,
  511. L"NullSessionShares");
  512. if ( rc == SCESTATUS_SUCCESS && Win32rc != ERROR_FILE_NOT_FOUND )
  513. rc = SmbsvcpDosErrorToSceStatus(Win32rc);;
  514. }
  515. }
  516. //
  517. // configure security on existing shares
  518. //
  519. SHARE_INFO_1501 ShareInfo;
  520. PSMBSVC_SHARES pTemp;
  521. for ( pTemp=pSmbInfo->pShares; pTemp != NULL;
  522. pTemp = pTemp->Next) {
  523. ShareInfo.shi1501_reserved = 0;
  524. ShareInfo.shi1501_security_descriptor = pTemp->pShareSD;
  525. Win32rc = NetShareSetInfo (
  526. NULL,
  527. pTemp->ShareName,
  528. 1501,
  529. (LPBYTE)&ShareInfo,
  530. NULL
  531. );
  532. if ( Win32rc != ERROR_SUCCESS ) {
  533. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  534. SCE_LOG_LEVEL_ERROR,
  535. Win32rc,
  536. SMBSVC_ERROR_CONFIGURE,
  537. pTemp->ShareName);
  538. if ( rc == SCESTATUS_SUCCESS )
  539. rc = SmbsvcpDosErrorToSceStatus(Win32rc);;
  540. }
  541. //
  542. // continue to configure even if error occurs
  543. //
  544. }
  545. if ( SCESTATUS_SUCCESS == rc ) {
  546. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  547. SCE_LOG_LEVEL_DETAIL,
  548. 0,
  549. SMBSVC_CONFIGURE_SERVER_DONE
  550. );
  551. rc = rc3; // saved status for client configuration
  552. }
  553. //
  554. // free memory
  555. //
  556. SmbsvcpFree(pSmbInfo);
  557. }
  558. return(rc);
  559. }
  560. SCESTATUS
  561. WINAPI
  562. SceSvcAttachmentAnalyze(
  563. IN PSCESVC_CALLBACK_INFO pSceCbInfo
  564. )
  565. /*
  566. Routine Description:
  567. Arguments:
  568. pSceCbInfo - the callback info structure which contains a opaque database handle
  569. and callback function pointers to query info, set info, and free info.
  570. Only mismatched info for SMB server is stored in the storage.
  571. Return Value:
  572. SCESTATUS
  573. */
  574. {
  575. if ( pSceCbInfo == NULL ||
  576. pSceCbInfo->sceHandle == NULL ||
  577. pSceCbInfo->pfQueryInfo == NULL ||
  578. pSceCbInfo->pfSetInfo == NULL ||
  579. pSceCbInfo->pfFreeInfo == NULL ) {
  580. return(SCESTATUS_INVALID_PARAMETER);
  581. }
  582. if ( !RtlGetNtProductType(&ProductType) )
  583. return(SmbsvcpDosErrorToSceStatus(GetLastError()));
  584. SCESTATUS rc, Saverc;
  585. SMBSVC_SEC_INFO SmbInfo;
  586. PSMBSVC_SEC_INFO pSmbInfo=&SmbInfo;
  587. PWSTR ErrPoint=NULL;
  588. WCHAR Errbuf[64];
  589. //
  590. // reset the Smb buffer
  591. //
  592. SmbsvcpResetInfo(&SmbInfo);
  593. SmbsvcpWriteError2(
  594. pSceCbInfo->pfLogInfo,
  595. SCE_LOG_LEVEL_DETAIL,
  596. 0,
  597. SMBSVC_QUERY_INFO
  598. );
  599. //
  600. // get configuration information
  601. //
  602. rc = SmbsvcpGetInformation(
  603. pSceCbInfo,
  604. pSmbInfo
  605. );
  606. if ( rc == SCESTATUS_SUCCESS ) {
  607. // rc == SCESTATUS_RECORD_NOT_FOUND ) {
  608. //
  609. // analyze share information to a buffer
  610. //
  611. PSMBSVC_SHARES pShares=NULL;
  612. DWORD ShareCount=0;
  613. //
  614. // get all shares
  615. //
  616. rc = SmbsvcpQueryShareList(&pShares, &ShareCount);
  617. if ( rc == SCESTATUS_SUCCESS ) {
  618. //
  619. // Allocate PSCESVC_ANALYSIS_INFO buffer
  620. //
  621. PSCESVC_ANALYSIS_INFO pAnaInfo;
  622. DWORD nCount;
  623. pAnaInfo = (PSCESVC_ANALYSIS_INFO)LocalAlloc(LMEM_FIXED, sizeof(SCESVC_ANALYSIS_INFO));
  624. if ( pAnaInfo != NULL ) {
  625. pAnaInfo->Count = 0;
  626. pAnaInfo->Lines = (PSCESVC_ANALYSIS_LINE)LocalAlloc(LMEM_ZEROINIT,
  627. (NUM_COMP+ShareCount)*sizeof(SCESVC_ANALYSIS_LINE));
  628. if ( pAnaInfo->Lines != NULL ) {
  629. nCount = 0;
  630. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  631. SCE_LOG_LEVEL_DETAIL,
  632. 0,
  633. SMBSVC_ANALYZE_CLIENT_START
  634. );
  635. //
  636. // EnableSecuritySignature for client
  637. //
  638. rc = SmbsvcpAnalyzeValue(
  639. SmbsvcRdrKey,
  640. SmbsvcEnableSS,
  641. L"EnableClientSecuritySignature",
  642. pSmbInfo->EnableClientSecuritySignature,
  643. &(pAnaInfo->Lines[nCount]),
  644. &nCount
  645. );
  646. ErrPoint = SmbsvcEnableSS;
  647. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  648. //
  649. // RequireSecuritySignature for client
  650. //
  651. rc = SmbsvcpAnalyzeValue(
  652. SmbsvcRdrKey,
  653. SmbsvcRequireSS,
  654. L"RequireClientSecuritySignature",
  655. pSmbInfo->RequireClientSecuritySignature,
  656. &(pAnaInfo->Lines[nCount]),
  657. &nCount
  658. );
  659. ErrPoint = SmbsvcRequireSS;
  660. }
  661. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  662. //
  663. // EnablePlainTextPassword (client only)
  664. //
  665. rc = SmbsvcpAnalyzeValue(
  666. SmbsvcRdrKey,
  667. SmbsvcPlainPassword,
  668. L"EnablePlainTextPassword",
  669. pSmbInfo->EnablePlainTextPassword,
  670. &(pAnaInfo->Lines[nCount]),
  671. &nCount
  672. );
  673. ErrPoint = SmbsvcPlainPassword;
  674. }
  675. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  676. //
  677. // RequireEnhancedChallengeResponse
  678. //
  679. rc = SmbsvcpAnalyzeValue(
  680. SmbsvcRdrKey,
  681. SmbsvcRequireECR,
  682. L"RequireEnhancedChallengeResponse",
  683. pSmbInfo->RequireEnhancedChallengeResponse,
  684. &(pAnaInfo->Lines[nCount]),
  685. &nCount
  686. );
  687. ErrPoint = SmbsvcRequireECR;
  688. }
  689. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  690. //
  691. // SendNTResponseOnly
  692. //
  693. rc = SmbsvcpAnalyzeValue(
  694. SmbsvcRdrKey,
  695. SmbsvcNTResponse,
  696. L"SendNTResponseOnly",
  697. pSmbInfo->SendNTResponseOnly,
  698. &(pAnaInfo->Lines[nCount]),
  699. &nCount
  700. );
  701. ErrPoint = SmbsvcNTResponse;
  702. }
  703. if ( rc == SCESTATUS_PROFILE_NOT_FOUND ) {
  704. rc = SCESTATUS_SUCCESS;
  705. }
  706. if ( rc == SCESTATUS_SUCCESS ) {
  707. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  708. SCE_LOG_LEVEL_DETAIL,
  709. 0,
  710. SMBSVC_ANALYZE_CLIENT_DONE
  711. );
  712. } else {
  713. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  714. SCE_LOG_LEVEL_ERROR,
  715. SmbsvcpSceStatusToDosError(rc),
  716. SMBSVC_ERROR_ANALYZE,
  717. ErrPoint
  718. );
  719. }
  720. Saverc = rc;
  721. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  722. SCE_LOG_LEVEL_DETAIL,
  723. 0,
  724. SMBSVC_ANALYZE_SERVER_START
  725. );
  726. //
  727. // EnableSecuritySignature for server
  728. //
  729. rc = SmbsvcpAnalyzeValue(
  730. SmbsvcServerKey,
  731. SmbsvcEnableSS,
  732. L"EnableServerSecuritySignature",
  733. pSmbInfo->EnableServerSecuritySignature,
  734. &(pAnaInfo->Lines[nCount]),
  735. &nCount
  736. );
  737. ErrPoint = SmbsvcEnableSS;
  738. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  739. //
  740. // RequireSecuritySignature for server
  741. //
  742. rc = SmbsvcpAnalyzeValue(
  743. SmbsvcServerKey,
  744. SmbsvcRequireSS,
  745. L"RequireServerSecuritySignature",
  746. pSmbInfo->RequireServerSecuritySignature,
  747. &(pAnaInfo->Lines[nCount]),
  748. &nCount
  749. );
  750. ErrPoint = SmbsvcRequireSS;
  751. }
  752. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  753. //
  754. // RestrictNullSessionAccess
  755. //
  756. rc = SmbsvcpAnalyzeValue(
  757. SmbsvcServerKey,
  758. SmbsvcRestrictNull,
  759. L"RestrictNullSessionAccess",
  760. pSmbInfo->RestrictNullSessionAccess,
  761. &(pAnaInfo->Lines[nCount]),
  762. &nCount
  763. );
  764. ErrPoint = SmbsvcRestrictNull;
  765. }
  766. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  767. //
  768. // AutoShareServer or AutoShareWks
  769. //
  770. PCWSTR AutoValueName;
  771. if ( ProductType == NtProductLanManNt ||
  772. ProductType == NtProductServer ) {
  773. AutoValueName = SmbsvcAutoShareServer;
  774. } else {
  775. AutoValueName = SmbsvcAutoShareWks;
  776. }
  777. rc = SmbsvcpAnalyzeValue(
  778. SmbsvcServerKey,
  779. AutoValueName,
  780. L"EnableAutoShare",
  781. pSmbInfo->EnableAutoShare,
  782. &(pAnaInfo->Lines[nCount]),
  783. &nCount
  784. );
  785. ErrPoint = (PWSTR)AutoValueName;
  786. }
  787. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  788. //
  789. // EnableForcedLogOff
  790. //
  791. rc = SmbsvcpAnalyzeValue(
  792. SmbsvcServerKey,
  793. SmbsvcForcedLogOff,
  794. L"EnableForcedLogOff",
  795. pSmbInfo->EnableForcedLogOff,
  796. &(pAnaInfo->Lines[nCount]),
  797. &nCount
  798. );
  799. ErrPoint = SmbsvcForcedLogOff;
  800. }
  801. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_PROFILE_NOT_FOUND) {
  802. //
  803. // AutoDisconnectTime
  804. //
  805. rc = SmbsvcpAnalyzeValue(
  806. SmbsvcServerKey,
  807. SmbsvcAutoDisconnect,
  808. L"AutoDisconnect",
  809. pSmbInfo->AutoDisconnect,
  810. &(pAnaInfo->Lines[nCount]),
  811. &nCount
  812. );
  813. ErrPoint = SmbsvcAutoDisconnect;
  814. }
  815. if ( rc == SCESTATUS_PROFILE_NOT_FOUND ) {
  816. //
  817. // the key does not exist
  818. //
  819. rc = SCESTATUS_SUCCESS;
  820. }
  821. if ( rc == SCESTATUS_SUCCESS ) {
  822. //
  823. // analyze Null Session Pipes and Shares
  824. //
  825. rc = SmbsvcpAnalyzeMultiSzString(
  826. SmbsvcServerKey,
  827. L"NullSessionPipes",
  828. pSmbInfo->NullSessionPipes,
  829. pSmbInfo->LengthPipes,
  830. &(pAnaInfo->Lines[nCount]),
  831. &nCount
  832. );
  833. wcscpy(Errbuf, L"NullSessionPipes");
  834. ErrPoint = Errbuf;
  835. if ( rc == SCESTATUS_SUCCESS ) {
  836. rc = SmbsvcpAnalyzeMultiSzString(
  837. SmbsvcServerKey,
  838. L"NullSessionShares",
  839. pSmbInfo->NullSessionShares,
  840. pSmbInfo->LengthShares,
  841. &(pAnaInfo->Lines[nCount]),
  842. &nCount
  843. );
  844. wcscpy(Errbuf, L"NullSessionShares");
  845. ErrPoint = Errbuf;
  846. }
  847. }
  848. //
  849. // analyze existing shares
  850. //
  851. if ( rc == SCESTATUS_SUCCESS ) {
  852. PSMBSVC_SHARES pTemp, pConfigShare;
  853. //
  854. // process each share
  855. //
  856. for ( pTemp=pShares; pTemp != NULL;
  857. pTemp = pTemp->Next) {
  858. //
  859. // Compare with configuration data
  860. //
  861. for ( pConfigShare=pSmbInfo->pShares;
  862. pConfigShare != NULL; pConfigShare = pConfigShare->Next ) {
  863. if ( _wcsicmp(pTemp->ShareName, pConfigShare->ShareName) == 0 ) {
  864. //
  865. // find the share in configuation data, compare security descriptor
  866. //
  867. break;
  868. }
  869. }
  870. BOOL bEqual = FALSE;
  871. DWORD Status;
  872. if ( pConfigShare != NULL ) {
  873. rc = SmbsvcpEqualSecurityDescriptor(
  874. pTemp->pShareSD,
  875. pConfigShare->pShareSD,
  876. FALSE,
  877. &bEqual
  878. );
  879. wcscpy(Errbuf, pTemp->ShareName);
  880. ErrPoint = Errbuf;
  881. Status = SMBSVC_STATUS_MISMATCH;
  882. } else
  883. Status = SMBSVC_STATUS_NOT_CONFIGURED;
  884. if ( rc == SCESTATUS_SUCCESS && !bEqual ) {
  885. //
  886. // different, save this share
  887. //
  888. if ( pSmbInfo->pShares == NULL ) {
  889. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  890. SCE_LOG_LEVEL_DETAIL,
  891. 0,
  892. SMBSVC_NOT_CONFIGURED,
  893. pTemp->ShareName
  894. );
  895. } else {
  896. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  897. SCE_LOG_LEVEL_DETAIL,
  898. 0,
  899. SMBSVC_MISMATCH,
  900. pTemp->ShareName
  901. );
  902. }
  903. PWSTR TextSD=NULL;
  904. DWORD SDsize=0;
  905. if ( pTemp->pShareSD != NULL ) {
  906. #if defined(_NT4BACK_PORT)
  907. rc = SceSvcConvertSDToText(
  908. pTemp->pShareSD,
  909. DACL_SECURITY_INFORMATION,
  910. &TextSD,
  911. &SDsize
  912. );
  913. rc = SmbsvcpDosErrorToSceStatus(rc);
  914. #else
  915. if ( !ConvertSecurityDescriptorToStringSecurityDescriptor(
  916. pTemp->pShareSD,
  917. SDDL_REVISION,
  918. DACL_SECURITY_INFORMATION,
  919. &TextSD,
  920. &SDsize
  921. ) ) {
  922. rc = SmbsvcpDosErrorToSceStatus(GetLastError());
  923. } else {
  924. rc = SCESTATUS_SUCCESS;
  925. }
  926. #endif
  927. wcscpy(Errbuf, pTemp->ShareName);
  928. ErrPoint = Errbuf;
  929. }
  930. PWSTR Value;
  931. Value = (PWSTR)LocalAlloc(LMEM_FIXED, (SDsize+9)*sizeof(WCHAR));
  932. if ( Value != NULL ) {
  933. if ( TextSD != NULL )
  934. swprintf(Value, L"Share,%1d,%s", Status, TextSD);
  935. else
  936. swprintf(Value, L"Share,%1d,", Status);
  937. Value[SDsize+8] = L'\0';
  938. pAnaInfo->Lines[nCount].Key = pTemp->ShareName;
  939. pAnaInfo->Lines[nCount].Value = (PBYTE)Value;
  940. pAnaInfo->Lines[nCount].ValueLen = (SDsize+8)*sizeof(WCHAR);
  941. pTemp->ShareName = NULL;
  942. nCount++;
  943. } else {
  944. wcscpy(Errbuf, pTemp->ShareName);
  945. ErrPoint = Errbuf;
  946. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  947. }
  948. if ( TextSD != NULL )
  949. LocalFree(TextSD);
  950. TextSD = NULL;
  951. } else {
  952. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  953. SCE_LOG_LEVEL_DETAIL,
  954. 0,
  955. SMBSVC_MATCH,
  956. pTemp->ShareName
  957. );
  958. }
  959. if ( rc != SCESTATUS_SUCCESS ) {
  960. break;
  961. }
  962. }
  963. }
  964. if ( rc == SCESTATUS_SUCCESS ) {
  965. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  966. SCE_LOG_LEVEL_DETAIL,
  967. 0,
  968. SMBSVC_ANALYZE_SERVER_DONE
  969. );
  970. rc = Saverc; // saved status for client analysis
  971. } else {
  972. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  973. SCE_LOG_LEVEL_ERROR,
  974. SmbsvcpSceStatusToDosError(rc),
  975. SMBSVC_ERROR_ANALYZE,
  976. ErrPoint
  977. );
  978. }
  979. //
  980. // Now save the information to the database
  981. //
  982. if ( rc == SCESTATUS_SUCCESS ) {
  983. SmbsvcpWriteError2(
  984. pSceCbInfo->pfLogInfo,
  985. SCE_LOG_LEVEL_DETAIL,
  986. 0,
  987. SMBSVC_SAVE_INFO
  988. );
  989. pAnaInfo->Count = nCount;
  990. __try {
  991. rc = (*(pSceCbInfo->pfSetInfo))(
  992. pSceCbInfo->sceHandle,
  993. SceSvcAnalysisInfo,
  994. NULL,
  995. FALSE,
  996. (PVOID)pAnaInfo
  997. );
  998. } __except (EXCEPTION_EXECUTE_HANDLER) {
  999. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1000. }
  1001. if ( SCESTATUS_SUCCESS != rc ) {
  1002. SmbsvcpWriteError2(
  1003. pSceCbInfo->pfLogInfo,
  1004. SCE_LOG_LEVEL_ERROR,
  1005. SmbsvcpSceStatusToDosError(rc),
  1006. SMBSVC_ERROR_SAVE_INFO
  1007. );
  1008. }
  1009. }
  1010. //
  1011. // free pAnaInfo
  1012. //
  1013. __try {
  1014. (*(pSceCbInfo->pfFreeInfo))((PVOID)pAnaInfo);
  1015. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1016. //
  1017. // BUGBUG: buffer is not freed ??
  1018. //
  1019. }
  1020. } else {
  1021. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1022. LocalFree(pAnaInfo);
  1023. }
  1024. } else
  1025. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1026. SmbsvcpFreeShareList(pShares);
  1027. } else {
  1028. SmbsvcpWriteError2(
  1029. pSceCbInfo->pfLogInfo,
  1030. SCE_LOG_LEVEL_ERROR,
  1031. SmbsvcpSceStatusToDosError(rc),
  1032. SMBSVC_ERROR_ENUM_SHARE
  1033. );
  1034. }
  1035. //
  1036. // free memory
  1037. //
  1038. SmbsvcpFree(pSmbInfo);
  1039. }
  1040. return(rc);
  1041. }
  1042. SCESTATUS
  1043. WINAPI
  1044. SceSvcAttachmentUpdate(
  1045. IN PSCESVC_CALLBACK_INFO pSceCbInfo,
  1046. IN SCESVC_CONFIGURATION_INFO *ServiceInfo
  1047. )
  1048. /*
  1049. Routine Description:
  1050. Arguments:
  1051. pSceCbInfo - the callback handle and function pointers to SCE.
  1052. ServiceInfo - The update configuration information for SMB server to process.
  1053. Return Value:
  1054. SCESTATUS
  1055. */
  1056. {
  1057. if ( pSceCbInfo == NULL ||
  1058. pSceCbInfo->sceHandle == NULL ||
  1059. pSceCbInfo->pfQueryInfo == NULL ||
  1060. pSceCbInfo->pfSetInfo == NULL ||
  1061. pSceCbInfo->pfFreeInfo == NULL ||
  1062. ServiceInfo == NULL ) {
  1063. return(SCESTATUS_INVALID_PARAMETER);
  1064. }
  1065. SCESTATUS rc=SCESTATUS_SUCCESS;
  1066. PSCESVC_CONFIGURATION_INFO pConfigInfo=NULL;
  1067. SCE_ENUMERATION_CONTEXT EnumHandle;
  1068. PSCESVC_ANALYSIS_INFO pAnaInfo=NULL;
  1069. //
  1070. // prepare two buffers for update
  1071. //
  1072. SCESVC_ANALYSIS_INFO UpdtAnaInfo;
  1073. SCESVC_ANALYSIS_LINE UpdtAnaLine;
  1074. SCESVC_CONFIGURATION_INFO UpdtConfigInfo;
  1075. SCESVC_CONFIGURATION_LINE UpdtConfigLine;
  1076. UpdtAnaInfo.Count = 1;
  1077. UpdtAnaInfo.Lines = &UpdtAnaLine;
  1078. UpdtConfigInfo.Count = 1;
  1079. UpdtConfigInfo.Lines = &UpdtConfigLine;
  1080. //
  1081. // process each line
  1082. //
  1083. for ( DWORD i=0; i<ServiceInfo->Count; i++ ) {
  1084. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  1085. SCE_LOG_LEVEL_DETAIL,
  1086. 0,
  1087. SMBSVC_UPDATE_INFO,
  1088. ServiceInfo->Lines[i].Key
  1089. );
  1090. //
  1091. // query the configuration setting
  1092. //
  1093. EnumHandle = 0;
  1094. __try {
  1095. rc = (*(pSceCbInfo->pfQueryInfo))(
  1096. pSceCbInfo->sceHandle,
  1097. SceSvcConfigurationInfo,
  1098. ServiceInfo->Lines[i].Key,
  1099. TRUE,
  1100. (PVOID *)&pConfigInfo,
  1101. &EnumHandle
  1102. );
  1103. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1104. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1105. }
  1106. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1107. // if ( ServiceInfo->Lines[i].Value == NULL ) {
  1108. if ( ServiceInfo->Lines[i].ValueLen == SMBSVC_NO_VALUE ) {
  1109. //
  1110. // delete is requested
  1111. //
  1112. if ( rc == SCESTATUS_SUCCESS ) {
  1113. //
  1114. // delete the configuration, but make sure analysis is ok
  1115. //
  1116. EnumHandle = 0;
  1117. __try {
  1118. rc = (*(pSceCbInfo->pfQueryInfo))(
  1119. pSceCbInfo->sceHandle,
  1120. SceSvcAnalysisInfo,
  1121. ServiceInfo->Lines[i].Key,
  1122. TRUE,
  1123. (PVOID *)&pAnaInfo,
  1124. &EnumHandle
  1125. );
  1126. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1127. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1128. }
  1129. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1130. //
  1131. // analysis info does not exist, matched.
  1132. // should save configuration info as analysis
  1133. //
  1134. UpdtAnaLine.Key = ServiceInfo->Lines[i].Key;
  1135. UpdtAnaLine.Value = (PBYTE)(pConfigInfo->Lines[0].Value);
  1136. UpdtAnaLine.ValueLen = pConfigInfo->Lines[0].ValueLen;
  1137. if ( pConfigInfo->Lines[0].ValueLen > 14 &&
  1138. pConfigInfo->Lines[0].Value != NULL &&
  1139. _wcsnicmp(L"Share,", pConfigInfo->Lines[0].Value, 6) == 0 ) {
  1140. //
  1141. // this is a share, needs to update status
  1142. //
  1143. *(pConfigInfo->Lines[0].Value+6) = L'2';
  1144. }
  1145. __try {
  1146. rc = (*(pSceCbInfo->pfSetInfo))(
  1147. pSceCbInfo->sceHandle,
  1148. SceSvcAnalysisInfo,
  1149. NULL,
  1150. TRUE,
  1151. (PVOID)&UpdtAnaInfo
  1152. );
  1153. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1154. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1155. }
  1156. }
  1157. if ( rc == SCESTATUS_SUCCESS ) {
  1158. //
  1159. // delete the configuration info
  1160. //
  1161. __try {
  1162. rc = (*(pSceCbInfo->pfSetInfo))(
  1163. pSceCbInfo->sceHandle,
  1164. SceSvcConfigurationInfo,
  1165. ServiceInfo->Lines[i].Key,
  1166. TRUE,
  1167. NULL
  1168. );
  1169. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1170. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1171. }
  1172. }
  1173. } // if configuration is not found, just continue
  1174. } else {
  1175. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1176. //
  1177. // no configuration setting for this one,
  1178. // either a new added share, or other configuration settings.
  1179. // BUGBUG: need to validate the key for other settings.
  1180. //
  1181. // if not valid, break out here
  1182. }
  1183. //
  1184. // query the analysis setting
  1185. //
  1186. EnumHandle = 0;
  1187. __try {
  1188. rc = (*(pSceCbInfo->pfQueryInfo))(
  1189. pSceCbInfo->sceHandle,
  1190. SceSvcAnalysisInfo,
  1191. ServiceInfo->Lines[i].Key,
  1192. TRUE,
  1193. (PVOID *)&pAnaInfo,
  1194. &EnumHandle
  1195. );
  1196. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1197. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1198. }
  1199. if ( rc == SCESTATUS_SUCCESS || rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1200. //
  1201. // mismatch is found for this one, or a matched item
  1202. //
  1203. if ( _wcsicmp(L"NullSessionShares", ServiceInfo->Lines[i].Key ) == 0 ||
  1204. _wcsicmp(L"NullSessionPipes", ServiceInfo->Lines[i].Key ) == 0 ) {
  1205. rc = SmbsvcpUpdateMultiSzString(
  1206. pSceCbInfo,
  1207. ServiceInfo->Lines[i],
  1208. pConfigInfo,
  1209. pAnaInfo
  1210. );
  1211. } else if ( ServiceInfo->Lines[i].ValueLen > 14 &&
  1212. ServiceInfo->Lines[i].Value != NULL &&
  1213. _wcsnicmp(L"Share,", ServiceInfo->Lines[i].Value, 6) == 0 ) {
  1214. //
  1215. // shares
  1216. //
  1217. rc = SmbsvcpUpdateShareValue(pSceCbInfo,
  1218. ServiceInfo->Lines[i],
  1219. pConfigInfo,
  1220. pAnaInfo
  1221. );
  1222. } else {
  1223. //
  1224. // other BYTE or DWORD type fields
  1225. //
  1226. DWORD NewValue = SMBSVC_NO_VALUE;
  1227. if ( swscanf(ServiceInfo->Lines[i].Value, L"%d", &NewValue) != EOF ) {
  1228. DWORD ConfigValue = SMBSVC_NO_VALUE;
  1229. DWORD AnaValue = SMBSVC_NO_VALUE;
  1230. if ( pConfigInfo != NULL && pConfigInfo->Lines != NULL )
  1231. swscanf(pConfigInfo->Lines[0].Value, L"%d", &ConfigValue);
  1232. if ( pAnaInfo != NULL && pAnaInfo->Lines != NULL ) {
  1233. swscanf((PWSTR)(pAnaInfo->Lines[0].Value), L"%d", &AnaValue);
  1234. }
  1235. if ( AnaValue != SMBSVC_NO_VALUE ) {
  1236. //
  1237. // old status is mismatch for this item
  1238. //
  1239. if ( NewValue == AnaValue ) {
  1240. //
  1241. // now it is matched, delete the analysis entry
  1242. //
  1243. SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
  1244. SCE_LOG_LEVEL_DEBUG,
  1245. 0,
  1246. L"mismatch->match"
  1247. );
  1248. __try {
  1249. rc = (*(pSceCbInfo->pfSetInfo))(
  1250. pSceCbInfo->sceHandle,
  1251. SceSvcAnalysisInfo,
  1252. ServiceInfo->Lines[i].Key,
  1253. TRUE,
  1254. NULL
  1255. );
  1256. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1257. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1258. }
  1259. }
  1260. if ( NewValue != ConfigValue ) {
  1261. //
  1262. // update the configuration setting
  1263. //
  1264. UpdtConfigLine.Key = ServiceInfo->Lines[i].Key;
  1265. UpdtConfigLine.Value = ServiceInfo->Lines[i].Value;
  1266. UpdtConfigLine.ValueLen = ServiceInfo->Lines[i].ValueLen;
  1267. __try {
  1268. rc = (*(pSceCbInfo->pfSetInfo))(
  1269. pSceCbInfo->sceHandle,
  1270. SceSvcConfigurationInfo,
  1271. NULL,
  1272. TRUE,
  1273. (PVOID)&UpdtConfigInfo
  1274. );
  1275. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1276. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1277. }
  1278. }
  1279. } else {
  1280. //
  1281. // old status is match, or a new added configuration key
  1282. //
  1283. if ( NewValue != ConfigValue ) {
  1284. SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
  1285. SCE_LOG_LEVEL_DEBUG,
  1286. 0,
  1287. L"match->mismatch"
  1288. );
  1289. //
  1290. // mismatch should be raised with ConfigValue
  1291. //
  1292. UpdtAnaLine.Key = ServiceInfo->Lines[i].Key;
  1293. UpdtAnaLine.Value = ( pConfigInfo != NULL ) ? (PBYTE)(pConfigInfo->Lines[0].Value) : NULL ;
  1294. UpdtAnaLine.ValueLen = ( pConfigInfo != NULL ) ? pConfigInfo->Lines[0].ValueLen : 0;
  1295. __try {
  1296. rc = (*(pSceCbInfo->pfSetInfo))(
  1297. pSceCbInfo->sceHandle,
  1298. SceSvcAnalysisInfo,
  1299. NULL,
  1300. TRUE,
  1301. (PVOID)&UpdtAnaInfo
  1302. );
  1303. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1304. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1305. }
  1306. if ( rc == SCESTATUS_SUCCESS ) {
  1307. if ( NewValue == SMBSVC_NO_VALUE ) {
  1308. SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
  1309. SCE_LOG_LEVEL_DEBUG,
  1310. 0,
  1311. L"delelte base setting"
  1312. );
  1313. //
  1314. // delete configuration setting
  1315. //
  1316. __try {
  1317. rc = (*(pSceCbInfo->pfSetInfo))(
  1318. pSceCbInfo->sceHandle,
  1319. SceSvcConfigurationInfo,
  1320. ServiceInfo->Lines[i].Key,
  1321. TRUE,
  1322. NULL
  1323. );
  1324. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1325. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1326. }
  1327. } else {
  1328. //
  1329. // update configuration setting with NewValue
  1330. //
  1331. UpdtConfigLine.Key = ServiceInfo->Lines[i].Key;
  1332. UpdtConfigLine.Value = ServiceInfo->Lines[i].Value;
  1333. UpdtConfigLine.ValueLen = ServiceInfo->Lines[i].ValueLen;
  1334. __try {
  1335. rc = (*(pSceCbInfo->pfSetInfo))(
  1336. pSceCbInfo->sceHandle,
  1337. SceSvcConfigurationInfo,
  1338. NULL,
  1339. TRUE,
  1340. (PVOID)&UpdtConfigInfo
  1341. );
  1342. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1343. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1344. }
  1345. }
  1346. }
  1347. }
  1348. }
  1349. } else
  1350. rc = SCESTATUS_INVALID_DATA;
  1351. }
  1352. if ( pAnaInfo != NULL ) {
  1353. __try {
  1354. (*(pSceCbInfo->pfFreeInfo))((PVOID)pAnaInfo);
  1355. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1356. }
  1357. }
  1358. pAnaInfo = NULL;
  1359. }
  1360. }
  1361. if ( pConfigInfo != NULL ) {
  1362. __try {
  1363. (*(pSceCbInfo->pfFreeInfo))((PVOID)pConfigInfo);
  1364. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1365. }
  1366. }
  1367. pConfigInfo = NULL;
  1368. }
  1369. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1370. rc = SCESTATUS_SUCCESS;
  1371. }
  1372. if ( rc != SCESTATUS_SUCCESS ) {
  1373. break;
  1374. }
  1375. }
  1376. return(rc);
  1377. }
  1378. SCESTATUS
  1379. SmbsvcpResetInfo(
  1380. IN PSMBSVC_SEC_INFO pInfo
  1381. )
  1382. /*
  1383. Routine Description:
  1384. This routine resets or initializes the buffer. All BYTE and DWORD
  1385. type fields are set to SMBSVC_NO_VALUE and all othe pointers are
  1386. set to NULL
  1387. Arguments:
  1388. pInfo - the buffer to reset.
  1389. Return Value:
  1390. SCESTATUS
  1391. */
  1392. {
  1393. if ( pInfo == NULL ) {
  1394. return(SCESTATUS_INVALID_PARAMETER);
  1395. }
  1396. pInfo->EnableClientSecuritySignature = SMBSVC_NO_VALUE;
  1397. pInfo->RequireClientSecuritySignature = SMBSVC_NO_VALUE;
  1398. pInfo->EnablePlainTextPassword = SMBSVC_NO_VALUE;
  1399. pInfo->RequireEnhancedChallengeResponse = SMBSVC_NO_VALUE;
  1400. pInfo->SendNTResponseOnly = SMBSVC_NO_VALUE;
  1401. pInfo->EnableAutoShare = SMBSVC_NO_VALUE;
  1402. pInfo->EnableServerSecuritySignature = SMBSVC_NO_VALUE;
  1403. pInfo->RequireServerSecuritySignature = SMBSVC_NO_VALUE;
  1404. pInfo->RestrictNullSessionAccess = SMBSVC_NO_VALUE;
  1405. pInfo->EnableForcedLogOff = SMBSVC_NO_VALUE;
  1406. pInfo->AutoDisconnect = SMBSVC_NO_VALUE;
  1407. pInfo->NullSessionShares = NULL;
  1408. pInfo->LengthShares = SMBSVC_NO_VALUE;
  1409. pInfo->NullSessionPipes = NULL;
  1410. pInfo->LengthPipes = SMBSVC_NO_VALUE;
  1411. pInfo->pShares=NULL;
  1412. return(SCESTATUS_SUCCESS);
  1413. }
  1414. SCESTATUS
  1415. SmbsvcpGetInformation(
  1416. IN PSCESVC_CALLBACK_INFO pSceCbInfo,
  1417. OUT PSMBSVC_SEC_INFO pSmbInfo
  1418. )
  1419. /*
  1420. Routine Description:
  1421. This routine queries information from the storage pointed by sceHandle.
  1422. Infomration is loaded into each field in the buffer pSmbInfo. Type argument
  1423. indicates configuration information or analysis information to query.
  1424. Arguments:
  1425. pSceCbInfo - the callback info structure
  1426. Type - SceSvcConfigurationInfo or SceSvcAnalysisInfo
  1427. pSmbInfo - the buffer to hold information. Note, this buffer must be allocated
  1428. before this call
  1429. Return Value:
  1430. SCESTATUS
  1431. */
  1432. {
  1433. if ( pSceCbInfo == NULL ||
  1434. pSceCbInfo->sceHandle == NULL ||
  1435. pSceCbInfo->pfQueryInfo == NULL ||
  1436. pSmbInfo == NULL ) {
  1437. return(SCESTATUS_INVALID_PARAMETER);
  1438. }
  1439. SCESTATUS rc;
  1440. SCE_ENUMERATION_CONTEXT EnumHandle=0;
  1441. PSCESVC_CONFIGURATION_INFO pConfigInfo=NULL;
  1442. SMBSVC_KEY_LOOKUP LookupKeys[] = {
  1443. {(PWSTR)TEXT("EnableForcedLogOff"), offsetof(struct _SMBSVC_SEC_INFO_, EnableForcedLogOff), 'B'},
  1444. {(PWSTR)TEXT("AutoDisconnect"), offsetof(struct _SMBSVC_SEC_INFO_, AutoDisconnect),'D'},
  1445. {(PWSTR)TEXT("EnableAutoShare"), offsetof(struct _SMBSVC_SEC_INFO_, EnableAutoShare), 'B'},
  1446. {(PWSTR)TEXT("EnableServerSecuritySignature"),offsetof(struct _SMBSVC_SEC_INFO_, EnableServerSecuritySignature),'B'},
  1447. {(PWSTR)TEXT("RequireServerSecuritySignature"),offsetof(struct _SMBSVC_SEC_INFO_, RequireServerSecuritySignature), 'B'},
  1448. {(PWSTR)TEXT("RestrictNullSessionAccess"), offsetof(struct _SMBSVC_SEC_INFO_, RestrictNullSessionAccess), 'B'},
  1449. {(PWSTR)TEXT("EnableClientSecuritySignature"),offsetof(struct _SMBSVC_SEC_INFO_, EnableClientSecuritySignature),'B'},
  1450. {(PWSTR)TEXT("RequireClientSecuritySignature"),offsetof(struct _SMBSVC_SEC_INFO_, RequireClientSecuritySignature), 'B'},
  1451. {(PWSTR)TEXT("EnablePlainTextPassword"), offsetof(struct _SMBSVC_SEC_INFO_, EnablePlainTextPassword), 'B'},
  1452. {(PWSTR)TEXT("RequireEnhancedChallengeResponse"),offsetof(struct _SMBSVC_SEC_INFO_, RequireEnhancedChallengeResponse),'B'},
  1453. {(PWSTR)TEXT("SendNTResponseOnly"),offsetof(struct _SMBSVC_SEC_INFO_, SendNTResponseOnly), 'B'},
  1454. {(PWSTR)TEXT("NullSessionPipes"), offsetof(struct _SMBSVC_SEC_INFO_, NullSessionPipes), 'M'},
  1455. {(PWSTR)TEXT("NullSessionShares"), offsetof(struct _SMBSVC_SEC_INFO_, NullSessionShares), 'M'}
  1456. };
  1457. DWORD cKeys = sizeof(LookupKeys) / sizeof(SMBSVC_KEY_LOOKUP);
  1458. DWORD CountReturned;
  1459. PSMBSVC_SHARES pShareList=NULL;
  1460. //
  1461. // read configuration information for smb server
  1462. //
  1463. do {
  1464. CountReturned = 0;
  1465. __try {
  1466. rc = (*(pSceCbInfo->pfQueryInfo))(
  1467. pSceCbInfo->sceHandle,
  1468. SceSvcConfigurationInfo,
  1469. NULL,
  1470. FALSE,
  1471. (PVOID *)&pConfigInfo,
  1472. &EnumHandle
  1473. );
  1474. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1475. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1476. }
  1477. if ( rc == SCESTATUS_SUCCESS && pConfigInfo != NULL &&
  1478. pConfigInfo->Count > 0 ) {
  1479. //
  1480. // got something
  1481. //
  1482. CountReturned = pConfigInfo->Count;
  1483. DWORD i, j;
  1484. PSECURITY_DESCRIPTOR pTempSD=NULL;
  1485. DWORD KeyValue, ValueLen, k;
  1486. PCHAR StrValue=NULL;
  1487. for ( i=0; i<pConfigInfo->Count; i++ ) {
  1488. if ( pConfigInfo->Lines[i].Key == NULL )
  1489. continue;
  1490. for (j=0; j<cKeys; j++) {
  1491. if ( _wcsicmp( pConfigInfo->Lines[i].Key, LookupKeys[j].KeyString) == 0 ) {
  1492. //
  1493. // find the matched string
  1494. //
  1495. switch ( LookupKeys[j].BufferType ) {
  1496. case 'B':
  1497. if ( pConfigInfo->Lines[i].Value != NULL ) {
  1498. KeyValue = _wtoi(pConfigInfo->Lines[i].Value);
  1499. *((BYTE *)pSmbInfo+LookupKeys[j].Offset) = (BYTE)KeyValue;
  1500. }
  1501. break;
  1502. case 'D':
  1503. if ( pConfigInfo->Lines[i].Value != NULL ) {
  1504. KeyValue = _wtol(pConfigInfo->Lines[i].Value);
  1505. *((DWORD *)((BYTE *)pSmbInfo+LookupKeys[j].Offset)) = KeyValue;
  1506. }
  1507. break;
  1508. case 'M':
  1509. // comma separated strings,
  1510. ValueLen = pConfigInfo->Lines[i].ValueLen;
  1511. if ( pConfigInfo->Lines[i].Value != NULL ) {
  1512. StrValue = (PCHAR)LocalAlloc(LMEM_FIXED, ValueLen + 4 );
  1513. if ( StrValue != NULL ) {
  1514. memcpy((PVOID)StrValue, (PVOID)(pConfigInfo->Lines[i].Value),
  1515. ValueLen);
  1516. //
  1517. // terminate the buffer by two L'\0's
  1518. //
  1519. *((WCHAR *)(StrValue+ValueLen)) = L'\0';
  1520. *((WCHAR *)(StrValue+ValueLen+2)) = L'\0';
  1521. /*
  1522. //
  1523. // replace ',' with '\0's
  1524. //
  1525. for ( k=0; k<ValueLen; k++ ) {
  1526. if ( StrValue[k] == ',' ) {
  1527. StrValue[k] = '\0';
  1528. }
  1529. }
  1530. */
  1531. *((PVOID *)((BYTE *)pSmbInfo+LookupKeys[j].Offset)) = (PVOID)StrValue;
  1532. StrValue = NULL;
  1533. *((DWORD *)((BYTE *)pSmbInfo+LookupKeys[j].Offset+sizeof(PVOID))) = ValueLen;
  1534. } else {
  1535. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1536. }
  1537. }
  1538. break;
  1539. default:
  1540. //
  1541. // unknown type, should not occur, ignore!!!
  1542. //
  1543. break;
  1544. }
  1545. break;
  1546. }
  1547. }
  1548. if ( j >= cKeys && rc == SCESTATUS_SUCCESS ) {
  1549. //
  1550. // did not find a match for pre-defined keywords
  1551. //
  1552. if ( pConfigInfo->Lines[i].Value != NULL && pConfigInfo->Lines[i].ValueLen > 14 &&
  1553. _wcsnicmp(L"Share,", pConfigInfo->Lines[i].Value, 6) == 0 ) {
  1554. //
  1555. // shares and security
  1556. //
  1557. if ( wcslen(pConfigInfo->Lines[i].Value) > 8) {
  1558. #if defined(_NT4BACK_PORT)
  1559. DWORD SDsize;
  1560. SECURITY_INFORMATION SeInfo;
  1561. rc = SceSvcConvertTextToSD(
  1562. pConfigInfo->Lines[i].Value+8,
  1563. &pTempSD,
  1564. &SDsize,
  1565. &SeInfo
  1566. );
  1567. rc = SmbsvcpDosErrorToSceStatus(rc);
  1568. #else
  1569. if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
  1570. (PCWSTR)(pConfigInfo->Lines[i].Value+8),
  1571. SDDL_REVISION,
  1572. &pTempSD,
  1573. NULL
  1574. ) ) {
  1575. rc = SmbsvcpDosErrorToSceStatus(GetLastError());
  1576. }
  1577. #endif
  1578. } else {
  1579. pTempSD = NULL;
  1580. }
  1581. DWORD Status = *(pConfigInfo->Lines[i].Value+6)-L'0';
  1582. if ( rc == SCESTATUS_SUCCESS ) {
  1583. rc = SmbsvcpAddAShareToList(&pShareList,
  1584. pConfigInfo->Lines[i].Key,
  1585. Status,
  1586. pTempSD
  1587. );
  1588. if ( rc != SCESTATUS_SUCCESS && pTempSD != NULL ) {
  1589. LocalFree(pTempSD);
  1590. }
  1591. }
  1592. if ( rc != SCESTATUS_SUCCESS && pSceCbInfo->pfLogInfo != NULL ) {
  1593. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  1594. SCE_LOG_LEVEL_ERROR,
  1595. SmbsvcpSceStatusToDosError(rc),
  1596. SMBSVC_ERROR_QUERY,
  1597. pConfigInfo->Lines[i]
  1598. );
  1599. }
  1600. } else if (pSceCbInfo->pfLogInfo != NULL ) {
  1601. //
  1602. // did not find a match
  1603. // warning for unknown data, but return success
  1604. //
  1605. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  1606. SCE_LOG_LEVEL_ERROR,
  1607. 0,
  1608. SMBSVC_UNKNOWN_KEYWORD,
  1609. pConfigInfo->Lines[i].Key
  1610. );
  1611. }
  1612. } else if ( rc != SCESTATUS_SUCCESS &&
  1613. pSceCbInfo->pfLogInfo != NULL ) {
  1614. SmbsvcpWriteError2(pSceCbInfo->pfLogInfo,
  1615. SCE_LOG_LEVEL_ERROR,
  1616. SmbsvcpSceStatusToDosError(rc),
  1617. SMBSVC_ERROR_QUERY,
  1618. pConfigInfo->Lines[i]
  1619. );
  1620. }
  1621. if ( rc != SCESTATUS_SUCCESS )
  1622. break;
  1623. }
  1624. __try {
  1625. (*(pSceCbInfo->pfFreeInfo))((PVOID)pConfigInfo);
  1626. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1627. }
  1628. pConfigInfo = NULL;
  1629. }
  1630. } while ( rc == SCESTATUS_SUCCESS && CountReturned >= SCESVC_ENUMERATION_MAX ); //0
  1631. if ( pShareList != NULL ) {
  1632. pSmbInfo->pShares = pShareList;
  1633. }
  1634. if ( rc != SCESTATUS_SUCCESS ) {
  1635. //
  1636. // free memory
  1637. //
  1638. SmbsvcpFree(pSmbInfo);
  1639. }
  1640. return(rc);
  1641. }
  1642. SCESTATUS
  1643. SmbsvcpAddAShareToList(
  1644. OUT PSMBSVC_SHARES *pShareList,
  1645. IN PWSTR ShareName,
  1646. IN DWORD Status,
  1647. IN PSECURITY_DESCRIPTOR pSD
  1648. )
  1649. /*
  1650. Routine Description:
  1651. This routine adds a share's information (Name, Security descriptor, and
  1652. security information) to the list of shares. Memory allocated for the
  1653. share node must be freed using LocalFree
  1654. Arguments:
  1655. pShareList - The ouput list of shares
  1656. ShareName - The name of the share
  1657. pSD - The security descriptor of the share object
  1658. Return Value:
  1659. SCESTATUS
  1660. */
  1661. {
  1662. if ( pShareList == NULL || ShareName == NULL ) {
  1663. return(SCESTATUS_INVALID_PARAMETER);
  1664. }
  1665. PSMBSVC_SHARES pTempShare;
  1666. pTempShare = (PSMBSVC_SHARES)LocalAlloc(LMEM_FIXED, sizeof(SMBSVC_SHARES));
  1667. if ( pTempShare == NULL ) {
  1668. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  1669. } else {
  1670. SCESTATUS rc=SCESTATUS_SUCCESS;
  1671. pTempShare->ShareName = (PWSTR)LocalAlloc(LMEM_FIXED, (wcslen(ShareName)+1)*sizeof(WCHAR));
  1672. if ( pTempShare->ShareName == NULL ) {
  1673. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1674. } else {
  1675. wcscpy(pTempShare->ShareName, ShareName);
  1676. pTempShare->pShareSD = pSD;
  1677. pTempShare->Status = Status;
  1678. pTempShare->Next = *pShareList;
  1679. *pShareList = pTempShare;
  1680. }
  1681. if ( rc != SCESTATUS_SUCCESS ) {
  1682. LocalFree(pTempShare);
  1683. }
  1684. return(rc);
  1685. }
  1686. }
  1687. SCESTATUS
  1688. SmbsvcpFree(
  1689. IN PSMBSVC_SEC_INFO pSmbInfo
  1690. )
  1691. /*
  1692. Routine Description:
  1693. This routine frees the memory allocated for the components in the buffer.
  1694. Arguments:
  1695. pSmbInfo - the buffer to free.
  1696. Return Value:
  1697. SCESTATUS
  1698. */
  1699. {
  1700. if ( pSmbInfo == NULL ) {
  1701. return(SCESTATUS_SUCCESS);
  1702. }
  1703. if ( pSmbInfo->NullSessionPipes != NULL ) {
  1704. LocalFree(pSmbInfo->NullSessionPipes);
  1705. }
  1706. if ( pSmbInfo->NullSessionShares != NULL ) {
  1707. LocalFree(pSmbInfo->NullSessionShares);
  1708. }
  1709. SmbsvcpFreeShareList(pSmbInfo->pShares);
  1710. return( SmbsvcpResetInfo( pSmbInfo ) );
  1711. }
  1712. SCESTATUS
  1713. SmbsvcpFreeShareList(
  1714. PSMBSVC_SHARES pShares
  1715. )
  1716. {
  1717. PSMBSVC_SHARES pTemp, pTemp2;
  1718. pTemp = pShares;
  1719. while (pTemp != NULL ) {
  1720. if ( pTemp->ShareName != NULL )
  1721. LocalFree(pTemp->ShareName);
  1722. if (pTemp->pShareSD != NULL )
  1723. LocalFree(pTemp->pShareSD);
  1724. pTemp2 = pTemp;
  1725. pTemp = pTemp->Next;
  1726. LocalFree(pTemp2);
  1727. }
  1728. return(SCESTATUS_SUCCESS);
  1729. }
  1730. SCESTATUS
  1731. SmbsvcpWriteError(
  1732. IN PFSCE_LOG_INFO pfLogCallback,
  1733. IN INT ErrLevel,
  1734. IN DWORD ErrCode,
  1735. IN PWSTR Mes
  1736. )
  1737. {
  1738. if ( Mes == NULL || pfLogCallback == NULL ) {
  1739. return(SCESTATUS_SUCCESS);
  1740. }
  1741. SCESTATUS rc;
  1742. __try {
  1743. rc = (*pfLogCallback)(ErrLevel,
  1744. ErrCode,
  1745. Mes);
  1746. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1747. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  1748. }
  1749. return(rc);
  1750. }
  1751. SCESTATUS
  1752. SmbsvcpWriteError2(
  1753. IN PFSCE_LOG_INFO pfLogCallback,
  1754. IN INT ErrLevel,
  1755. IN DWORD ErrCode,
  1756. IN UINT nId,
  1757. ...
  1758. )
  1759. {
  1760. WCHAR szTempString[256];
  1761. TCHAR buf[SMBSVC_BUF_LEN];
  1762. va_list args;
  1763. if ( nId > 0 && pfLogCallback ) {
  1764. szTempString[0] = L'\0';
  1765. if ( MyModuleHandle != NULL ) {
  1766. LoadString( MyModuleHandle,
  1767. nId,
  1768. szTempString,
  1769. 256
  1770. );
  1771. }
  1772. //
  1773. // check arguments
  1774. //
  1775. va_start( args, nId );
  1776. vswprintf( buf, szTempString, args );
  1777. va_end( args );
  1778. return ( SmbsvcpWriteError(pfLogCallback,
  1779. ErrLevel,
  1780. ErrCode,
  1781. buf) );
  1782. }
  1783. return(SCESTATUS_SUCCESS);
  1784. }
  1785. SCESTATUS
  1786. SmbsvcpConfigureValue(
  1787. IN PCWSTR RegKey,
  1788. IN PCWSTR ValueName,
  1789. IN DWORD Value
  1790. )
  1791. {
  1792. if ( Value == (DWORD)SMBSVC_NO_VALUE ||
  1793. (BYTE)Value == (BYTE)SMBSVC_NO_VALUE ) {
  1794. return(SCESTATUS_SUCCESS);
  1795. }
  1796. DWORD Win32rc;
  1797. Win32rc = SmbsvcpRegSetIntValue(
  1798. HKEY_LOCAL_MACHINE,
  1799. (PWSTR)RegKey,
  1800. (PWSTR)ValueName,
  1801. Value
  1802. );
  1803. return(SmbsvcpDosErrorToSceStatus(Win32rc));
  1804. }
  1805. SCESTATUS
  1806. SmbsvcpQueryShareList(
  1807. OUT PSMBSVC_SHARES *pShareList,
  1808. OUT PDWORD ShareCount
  1809. )
  1810. {
  1811. if ( pShareList == NULL || ShareCount == NULL ) {
  1812. return(SCESTATUS_INVALID_PARAMETER);
  1813. }
  1814. LPSHARE_INFO_502 pShareInfo=NULL;
  1815. DWORD EntriesRead, TotalEntries, ResumeHandle=0;
  1816. SCESTATUS rc=SCESTATUS_SUCCESS;
  1817. DWORD Win32rc;
  1818. DWORD nCount=0;
  1819. *ShareCount = 0;
  1820. do {
  1821. Win32rc = NetShareEnum (
  1822. NULL,
  1823. 502,
  1824. (LPBYTE *)&pShareInfo,
  1825. 0xFFFFFFFF,
  1826. &EntriesRead,
  1827. &TotalEntries,
  1828. &ResumeHandle
  1829. );
  1830. if ( Win32rc == ERROR_SUCCESS ) {
  1831. nCount += EntriesRead;
  1832. for( DWORD i=0; i < EntriesRead; i++ ) {
  1833. if( (pShareInfo + i)->shi502_type == STYPE_DISKTREE )
  1834. {
  1835. PSECURITY_DESCRIPTOR pSD=NULL;
  1836. if ( (pShareInfo + i)->shi502_security_descriptor != NULL ) {
  1837. NTSTATUS status;
  1838. DWORD RequireLength=0;
  1839. status = RtlMakeSelfRelativeSD(
  1840. (pShareInfo + i)->shi502_security_descriptor,
  1841. NULL,
  1842. &RequireLength
  1843. );
  1844. if ( status == STATUS_BUFFER_TOO_SMALL ) {
  1845. pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, RequireLength+1);
  1846. status = RtlMakeSelfRelativeSD(
  1847. (pShareInfo + i)->shi502_security_descriptor,
  1848. pSD,
  1849. &RequireLength
  1850. );
  1851. }
  1852. rc = SmbsvcpDosErrorToSceStatus(RtlNtStatusToDosError(status));
  1853. }
  1854. if ( rc == SCESTATUS_SUCCESS ) {
  1855. rc = SmbsvcpAddAShareToList(pShareList,
  1856. (pShareInfo + i)->shi502_netname,
  1857. 0,
  1858. pSD
  1859. );
  1860. if ( rc == SCESTATUS_SUCCESS ) {
  1861. (*ShareCount)++;
  1862. } else if ( pSD != NULL ) {
  1863. LocalFree(pSD);
  1864. pSD = NULL;
  1865. }
  1866. }
  1867. if ( rc != SCESTATUS_SUCCESS ) {
  1868. break;
  1869. }
  1870. }
  1871. }
  1872. //
  1873. // free the buffer
  1874. //
  1875. NetApiBufferFree(pShareInfo);
  1876. pShareInfo = NULL;
  1877. } else
  1878. rc = SmbsvcpDosErrorToSceStatus(Win32rc);
  1879. } while ( rc == SCESTATUS_SUCCESS && nCount < TotalEntries );
  1880. if ( rc != SCESTATUS_SUCCESS && *pShareList != NULL ) {
  1881. SmbsvcpFreeShareList(*pShareList);
  1882. *pShareList = NULL;
  1883. *ShareCount = 0;
  1884. }
  1885. return(rc);
  1886. }
  1887. SCESTATUS
  1888. SmbsvcpAnalyzeValue(
  1889. IN PCWSTR RegKey,
  1890. IN PCWSTR RegValueName,
  1891. IN PCWSTR KeyName,
  1892. IN DWORD ConfigValue,
  1893. OUT PSCESVC_ANALYSIS_LINE pLineInfo,
  1894. IN OUT PDWORD pCount
  1895. )
  1896. {
  1897. if ( RegKey == NULL || RegValueName == NULL ||
  1898. KeyName == NULL || pLineInfo == NULL || pCount == NULL ) {
  1899. return(SCESTATUS_INVALID_PARAMETER);
  1900. }
  1901. if ( ConfigValue == (DWORD)SMBSVC_NO_VALUE ||
  1902. (BYTE)ConfigValue == (BYTE)SMBSVC_NO_VALUE ) {
  1903. return(SCESTATUS_SUCCESS);
  1904. }
  1905. //
  1906. // query the registry value
  1907. //
  1908. DWORD Value=0;
  1909. DWORD Win32rc = SmbsvcpRegQueryIntValue(
  1910. HKEY_LOCAL_MACHINE,
  1911. (PWSTR)RegKey,
  1912. (PWSTR)RegValueName,
  1913. &Value
  1914. );
  1915. if ( Win32rc == ERROR_SUCCESS || Win32rc == ERROR_FILE_NOT_FOUND ) {
  1916. Win32rc = ERROR_SUCCESS;
  1917. if ( ConfigValue != Value ) {
  1918. //
  1919. // mismatched
  1920. //
  1921. PWSTR Key, StrValue;
  1922. DWORD ValueLen;
  1923. //
  1924. // allocate buffer for key and value
  1925. //
  1926. Key = (PWSTR)LocalAlloc(LMEM_FIXED, (wcslen(KeyName)+1)*sizeof(WCHAR));
  1927. if ( Key != NULL ) {
  1928. WCHAR TempBuf[16];
  1929. memset(TempBuf, '\0', 32);
  1930. swprintf(TempBuf, L"%d", Value);
  1931. DWORD Len = wcslen(TempBuf);
  1932. StrValue = (PWSTR)LocalAlloc(LMEM_FIXED, (Len+1)*sizeof(WCHAR));
  1933. if ( StrValue != NULL ) {
  1934. //
  1935. // assign to the line buffer and increment the count
  1936. //
  1937. wcsncpy(StrValue, TempBuf, Len);
  1938. StrValue[Len] = L'\0';
  1939. wcscpy(Key, KeyName);
  1940. pLineInfo->Key = Key;
  1941. pLineInfo->Value = (PBYTE)StrValue;
  1942. pLineInfo->ValueLen = Len*sizeof(WCHAR);
  1943. (*pCount)++;
  1944. } else {
  1945. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  1946. LocalFree(Key);
  1947. }
  1948. } else
  1949. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  1950. }
  1951. }
  1952. return(SmbsvcpDosErrorToSceStatus(Win32rc));
  1953. }
  1954. DWORD
  1955. SmbsvcpConvertStringToMultiSz(
  1956. IN PWSTR theStr,
  1957. IN DWORD theLen,
  1958. OUT PBYTE *outValue,
  1959. OUT PDWORD outLen
  1960. )
  1961. {
  1962. if ( outValue == NULL || outLen == NULL ) {
  1963. return(ERROR_INVALID_PARAMETER);
  1964. }
  1965. *outValue = NULL;
  1966. *outLen = 0;
  1967. if ( theStr == NULL || theLen == 0 || theLen == SMBSVC_NO_VALUE ) {
  1968. return ERROR_SUCCESS;
  1969. }
  1970. *outValue = (PBYTE)LocalAlloc(0, theLen+4);
  1971. if ( *outValue != NULL ) {
  1972. wcscpy((PWSTR)(*outValue), theStr);
  1973. // terminate the last w-char with 0 for Multi-Sz format
  1974. *((PWSTR)(*outValue+theLen+2)) = L'\0';
  1975. // replace ',' with '\0'
  1976. PWSTR pTemp = (PWSTR)(*outValue);
  1977. while ( pTemp != NULL ) {
  1978. pTemp = wcschr(pTemp, L',');
  1979. if ( pTemp != NULL ) {
  1980. *pTemp = L'\0';
  1981. pTemp++;
  1982. }
  1983. }
  1984. return ERROR_SUCCESS;
  1985. } else
  1986. return ERROR_NOT_ENOUGH_MEMORY;
  1987. }
  1988. SCESTATUS
  1989. SmbsvcpAnalyzeMultiSzString(
  1990. IN PCWSTR RegKey,
  1991. IN PCWSTR RegValueName,
  1992. IN PWSTR pConfigInfo,
  1993. IN DWORD InfoLength,
  1994. OUT PSCESVC_ANALYSIS_LINE pLineInfo,
  1995. IN OUT PDWORD pCount
  1996. )
  1997. {
  1998. if ( RegKey == NULL || RegValueName == NULL ||
  1999. pLineInfo == NULL || pCount == NULL ) {
  2000. return(SCESTATUS_INVALID_PARAMETER);
  2001. }
  2002. if ( InfoLength == SMBSVC_NO_VALUE ) {
  2003. // do not configure
  2004. return(SCESTATUS_SUCCESS);
  2005. }
  2006. //
  2007. // query the registry value
  2008. //
  2009. DWORD RegType;
  2010. PWSTR Value=NULL;
  2011. DWORD Win32rc = SmbsvcpRegQueryValue(
  2012. HKEY_LOCAL_MACHINE,
  2013. (PWSTR)RegKey,
  2014. (PWSTR)RegValueName,
  2015. (PVOID *)&Value,
  2016. &RegType
  2017. );
  2018. if ( Win32rc == ERROR_SUCCESS || Win32rc == ERROR_FILE_NOT_FOUND ) {
  2019. BOOL Diff;
  2020. DWORD ValueLen;
  2021. //
  2022. // change multi-sz to comma separated strings IN PLACE
  2023. //
  2024. SmbsvcpChangeMultiSzToString(Value);
  2025. Win32rc = SmbsvcpCompareMultiSzString(pConfigInfo, Value, &ValueLen, &Diff);
  2026. if (Win32rc == ERROR_SUCCESS && Diff ) {
  2027. //
  2028. // mismatched
  2029. //
  2030. PWSTR Key;
  2031. //
  2032. // allocate buffer for key and value
  2033. //
  2034. Key = (PWSTR)LocalAlloc(LMEM_FIXED, (wcslen(RegValueName)+1)*sizeof(WCHAR));
  2035. if ( Key != NULL ) {
  2036. //
  2037. // assign to the line buffer and increment the count
  2038. //
  2039. wcscpy(Key, RegValueName);
  2040. pLineInfo->Key = Key;
  2041. pLineInfo->Value = (PBYTE)Value;
  2042. pLineInfo->ValueLen = ValueLen*sizeof(WCHAR);
  2043. (*pCount)++;
  2044. Value = NULL;
  2045. } else
  2046. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2047. }
  2048. //
  2049. // free Value is not NULL
  2050. //
  2051. if ( Value != NULL ) {
  2052. LocalFree(Value);
  2053. }
  2054. }
  2055. return(SmbsvcpDosErrorToSceStatus(Win32rc));
  2056. }
  2057. DWORD
  2058. SmbsvcpChangeMultiSzToString(
  2059. IN PWSTR Value
  2060. )
  2061. {
  2062. if ( Value == NULL )
  2063. return ERROR_SUCCESS;
  2064. //
  2065. // replace '\0' with ','s
  2066. //
  2067. PWSTR pTemp=Value;
  2068. while ( pTemp ) {
  2069. if ( *pTemp == L'\0' ) {
  2070. if ( *(pTemp+1) != L'\0' )
  2071. *pTemp = L',';
  2072. else
  2073. break;
  2074. }
  2075. pTemp++;
  2076. }
  2077. return ERROR_SUCCESS;
  2078. }
  2079. DWORD
  2080. SmbsvcpCompareMultiSzString(
  2081. IN PWSTR pConfigInfo,
  2082. IN PWSTR Value,
  2083. OUT PDWORD pValueLen,
  2084. OUT PBOOL pDiff
  2085. )
  2086. {
  2087. if ( pDiff == NULL || pValueLen == NULL ) {
  2088. return(ERROR_INVALID_PARAMETER);
  2089. }
  2090. *pDiff = FALSE;
  2091. *pValueLen = 0;
  2092. if ( pConfigInfo == NULL && Value == NULL ) {
  2093. return(ERROR_SUCCESS);
  2094. }
  2095. if ( (pConfigInfo == NULL && Value != NULL) ||
  2096. (pConfigInfo != NULL && Value == NULL) ) {
  2097. *pDiff = TRUE;
  2098. return ERROR_SUCCESS;
  2099. }
  2100. DWORD CountValue=0, ValueLen=0;
  2101. DWORD ConfigLen=0, CountConfig=0;
  2102. DWORD Win32rc;
  2103. Win32rc = SmbsvcpCountComponents(Value, &ValueLen, &CountValue);
  2104. //
  2105. // both pConfigInfo and Value are not NULL
  2106. //
  2107. if ( Win32rc == ERROR_SUCCESS ) {
  2108. *pValueLen = ValueLen;
  2109. Win32rc = SmbsvcpCountComponents(pConfigInfo, &ConfigLen, &CountConfig);
  2110. }
  2111. if ( Win32rc == ERROR_SUCCESS ) {
  2112. if ( ConfigLen != ValueLen ||
  2113. CountConfig != CountValue ) {
  2114. *pDiff = TRUE;
  2115. return(Win32rc);
  2116. }
  2117. if ( CountConfig == 0 ) {
  2118. //
  2119. // No component, return FALSE for *pDiff
  2120. //
  2121. return(Win32rc);
  2122. }
  2123. //
  2124. // both value are not empty, have the same count and same length
  2125. // build the pointers into array to compare
  2126. //
  2127. PWSTR *ConfigPtr;
  2128. PWSTR *ValuePtr;
  2129. ConfigPtr = (PWSTR *)LocalAlloc(LMEM_FIXED, CountConfig*sizeof(PWSTR));
  2130. if ( ConfigPtr != NULL ) {
  2131. ValuePtr = (PWSTR *)LocalAlloc(LMEM_FIXED, CountValue*2*sizeof(PWSTR));
  2132. if ( ValuePtr != NULL ) {
  2133. PWSTR pTemp = (PWSTR)pConfigInfo;
  2134. DWORD i = 0;
  2135. //
  2136. // build the pointers from pConfigInfo into ConfigPtr
  2137. //
  2138. do {
  2139. ConfigPtr[i++] = pTemp;
  2140. pTemp = wcschr(pTemp, L',');
  2141. if ( pTemp != NULL ) {
  2142. pTemp++;
  2143. }
  2144. } while ( pTemp != NULL );
  2145. pTemp = (PWSTR)Value;
  2146. i = 0;
  2147. //
  2148. // build the pointers from Value into ValuePtr
  2149. //
  2150. do {
  2151. ValuePtr[i++] = pTemp;
  2152. pTemp = wcschr(pTemp, L',');
  2153. if ( pTemp != NULL ) {
  2154. ValuePtr[i] = (PWSTR)((DWORD_PTR)pTemp-(DWORD_PTR)(ValuePtr[i-1]));
  2155. i++;
  2156. pTemp++;
  2157. } else {
  2158. ValuePtr[i] = (PWSTR)(wcslen(ValuePtr[i-1]));
  2159. i++;
  2160. }
  2161. } while ( pTemp != NULL );
  2162. DWORD j, nLen;
  2163. //
  2164. // compare two pointer arrays. if a match is found, the pointer element is set to NULL
  2165. // so next time it won't be compared again.
  2166. //
  2167. for ( i=0; i<CountConfig; i++ ) {
  2168. if ( i == CountConfig-1 )
  2169. // the last one
  2170. nLen = wcslen(ConfigPtr[i]);
  2171. else
  2172. nLen = (DWORD)(ConfigPtr[i+1]-ConfigPtr[i]-1);
  2173. for ( j=0; j<CountValue*2; j+=2) {
  2174. if ( ValuePtr[j] != NULL ) {
  2175. if ( (DWORD_PTR)(ValuePtr[j+1]) == nLen &&
  2176. _wcsnicmp(ConfigPtr[i], ValuePtr[j], nLen) == 0 ) {
  2177. ValuePtr[j] = NULL;
  2178. break;
  2179. }
  2180. }
  2181. }
  2182. if ( j >= CountValue*2 ) {
  2183. //
  2184. // did not find a match
  2185. //
  2186. *pDiff = TRUE;
  2187. break;
  2188. }
  2189. }
  2190. for ( j=0; j < CountValue*2; j+=2 ) {
  2191. if ( ValuePtr[j] != NULL ) {
  2192. *pDiff = TRUE;
  2193. break;
  2194. }
  2195. }
  2196. LocalFree(ValuePtr);
  2197. } else
  2198. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2199. LocalFree(ConfigPtr);
  2200. } else
  2201. Win32rc = ERROR_NOT_ENOUGH_MEMORY;
  2202. }
  2203. return(Win32rc);
  2204. }
  2205. DWORD
  2206. SmbsvcpCountComponents(
  2207. IN PWSTR Value,
  2208. OUT PDWORD ValueLen,
  2209. OUT PDWORD Count
  2210. )
  2211. {
  2212. if ( ValueLen == NULL ||
  2213. Count == NULL ) {
  2214. return(ERROR_INVALID_PARAMETER);
  2215. }
  2216. if ( Value == NULL ) {
  2217. *ValueLen = 0;
  2218. *Count = 0;
  2219. return(ERROR_SUCCESS);
  2220. }
  2221. PWSTR pTemp = (PWSTR)Value;
  2222. DWORD Len = 0;
  2223. *Count = 0;
  2224. *ValueLen = wcslen(pTemp);
  2225. do {
  2226. (*Count)++;
  2227. pTemp = wcschr(pTemp, L',');
  2228. if ( pTemp != NULL ) {
  2229. pTemp++;
  2230. }
  2231. } while ( pTemp != NULL );
  2232. return(ERROR_SUCCESS);
  2233. }
  2234. SCESTATUS
  2235. SmbsvcpUpdateMultiSzString(
  2236. IN PSCESVC_CALLBACK_INFO pSceCbInfo,
  2237. IN SCESVC_CONFIGURATION_LINE NewLine,
  2238. IN PSCESVC_CONFIGURATION_INFO pConfigInfo OPTIONAL,
  2239. IN PSCESVC_ANALYSIS_INFO pAnaInfo OPTIONAL
  2240. )
  2241. {
  2242. //
  2243. // the value in the structure is Multi-Sz
  2244. //
  2245. if ( pSceCbInfo == NULL ||
  2246. pSceCbInfo->sceHandle == NULL ||
  2247. pSceCbInfo->pfSetInfo == NULL ) {
  2248. return(SCESTATUS_INVALID_PARAMETER);
  2249. }
  2250. SCESTATUS rc=SCESTATUS_SUCCESS;
  2251. DWORD Win32rc;
  2252. BOOL bDiff, bDiff2;
  2253. DWORD ValueLen;
  2254. //
  2255. // prepare an update buffer
  2256. //
  2257. SCESVC_ANALYSIS_INFO UpdtAnaInfo;
  2258. SCESVC_ANALYSIS_LINE UpdtAnaLine;
  2259. UpdtAnaInfo.Count = 1;
  2260. UpdtAnaInfo.Lines = &UpdtAnaLine;
  2261. SCESVC_CONFIGURATION_INFO UpdtConfigInfo;
  2262. SCESVC_CONFIGURATION_LINE UpdtConfigLine;
  2263. UpdtConfigInfo.Count = 1;
  2264. UpdtConfigInfo.Lines = &UpdtConfigLine;
  2265. if ( pAnaInfo == NULL ) {
  2266. //
  2267. // old status is match, or new added configuration key
  2268. //
  2269. if ( pConfigInfo != NULL && pConfigInfo->Lines != NULL ) {
  2270. // match item
  2271. Win32rc = SmbsvcpCompareMultiSzString(
  2272. NewLine.Value,
  2273. pConfigInfo->Lines[0].Value,
  2274. &ValueLen,
  2275. &bDiff
  2276. );
  2277. if ( Win32rc != ERROR_SUCCESS ) {
  2278. return(SmbsvcpDosErrorToSceStatus(Win32rc));
  2279. }
  2280. } else {
  2281. // new add
  2282. bDiff = TRUE;
  2283. ValueLen = 0;
  2284. }
  2285. if ( bDiff ) {
  2286. SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
  2287. SCE_LOG_LEVEL_DEBUG,
  2288. 0,
  2289. L"match->mismatch"
  2290. );
  2291. //
  2292. // mismatch should be raised with ConfigValue
  2293. //
  2294. UpdtAnaLine.Key = NewLine.Key;
  2295. UpdtAnaLine.Value = ( pConfigInfo != NULL ) ? (PBYTE)(pConfigInfo->Lines[0].Value) : NULL;
  2296. UpdtAnaLine.ValueLen = ( pConfigInfo != NULL ) ? pConfigInfo->Lines[0].ValueLen : 0;
  2297. __try {
  2298. rc = (*(pSceCbInfo->pfSetInfo))(
  2299. pSceCbInfo->sceHandle,
  2300. SceSvcAnalysisInfo,
  2301. NULL,
  2302. TRUE,
  2303. (PVOID)&UpdtAnaInfo
  2304. );
  2305. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2306. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2307. }
  2308. if ( rc == SCESTATUS_SUCCESS ) {
  2309. //
  2310. // update configuration setting with NewValue
  2311. //
  2312. UpdtConfigLine.Key = NewLine.Key;
  2313. UpdtConfigLine.Value = NewLine.Value;
  2314. UpdtConfigLine.ValueLen = NewLine.ValueLen;
  2315. __try {
  2316. rc = (*(pSceCbInfo->pfSetInfo))(
  2317. pSceCbInfo->sceHandle,
  2318. SceSvcConfigurationInfo,
  2319. NULL,
  2320. TRUE,
  2321. (PVOID)&UpdtConfigInfo
  2322. );
  2323. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2324. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2325. }
  2326. }
  2327. }
  2328. } else {
  2329. //
  2330. // old status is mismatch for this item
  2331. //
  2332. Win32rc = SmbsvcpCompareMultiSzString(
  2333. NewLine.Value,
  2334. (PWSTR)(pAnaInfo->Lines[0].Value),
  2335. &ValueLen,
  2336. &bDiff
  2337. );
  2338. if ( Win32rc == ERROR_SUCCESS ) {
  2339. if (pConfigInfo != NULL && pConfigInfo->Lines != NULL ) {
  2340. Win32rc = SmbsvcpCompareMultiSzString(
  2341. NewLine.Value,
  2342. pConfigInfo->Lines[0].Value,
  2343. &ValueLen,
  2344. &bDiff2
  2345. );
  2346. } else {
  2347. bDiff2 = TRUE;
  2348. ValueLen = 0;
  2349. }
  2350. }
  2351. if ( Win32rc != ERROR_SUCCESS ) {
  2352. return(SmbsvcpDosErrorToSceStatus(Win32rc));
  2353. }
  2354. if ( !bDiff ) {
  2355. SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
  2356. SCE_LOG_LEVEL_DEBUG,
  2357. 0,
  2358. L"mismatch->match"
  2359. );
  2360. //
  2361. // now it is matched, delete the analysis entry
  2362. //
  2363. __try {
  2364. rc = (*(pSceCbInfo->pfSetInfo))(
  2365. pSceCbInfo->sceHandle,
  2366. SceSvcAnalysisInfo,
  2367. NewLine.Key,
  2368. TRUE,
  2369. NULL
  2370. );
  2371. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2372. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2373. }
  2374. }
  2375. if ( bDiff2 ) {
  2376. //
  2377. // update the configuration setting
  2378. //
  2379. UpdtConfigLine.Key = NewLine.Key;
  2380. UpdtConfigLine.Value = NewLine.Value;
  2381. UpdtConfigLine.ValueLen = NewLine.ValueLen;
  2382. __try {
  2383. rc = (*(pSceCbInfo->pfSetInfo))(
  2384. pSceCbInfo->sceHandle,
  2385. SceSvcConfigurationInfo,
  2386. NULL,
  2387. TRUE,
  2388. (PVOID)&UpdtConfigInfo
  2389. );
  2390. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2391. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2392. }
  2393. }
  2394. }
  2395. return(rc);
  2396. }
  2397. SCESTATUS
  2398. SmbsvcpUpdateShareValue(
  2399. IN PSCESVC_CALLBACK_INFO pSceCbInfo,
  2400. IN SCESVC_CONFIGURATION_LINE NewLine,
  2401. IN PSCESVC_CONFIGURATION_INFO pConfigInfo OPTIONAL,
  2402. IN PSCESVC_ANALYSIS_INFO pAnaInfo OPTIONAL
  2403. )
  2404. {
  2405. //
  2406. // the value in the structure is "Share," followed by a security descriptor text
  2407. //
  2408. if ( pSceCbInfo == NULL ||
  2409. pSceCbInfo->sceHandle == NULL ||
  2410. pSceCbInfo->pfSetInfo == NULL ) {
  2411. return(SCESTATUS_INVALID_PARAMETER);
  2412. }
  2413. SCESTATUS rc=SCESTATUS_SUCCESS;
  2414. //
  2415. // prepare an update buffer
  2416. //
  2417. SCESVC_ANALYSIS_INFO UpdtAnaInfo;
  2418. SCESVC_ANALYSIS_LINE UpdtAnaLine;
  2419. UpdtAnaInfo.Count = 1;
  2420. UpdtAnaInfo.Lines = &UpdtAnaLine;
  2421. SCESVC_CONFIGURATION_INFO UpdtConfigInfo;
  2422. SCESVC_CONFIGURATION_LINE UpdtConfigLine;
  2423. UpdtConfigInfo.Count = 1;
  2424. UpdtConfigInfo.Lines = &UpdtConfigLine;
  2425. PSECURITY_DESCRIPTOR pSD1=NULL, pSD2=NULL;
  2426. DWORD SDsize;
  2427. BOOL bEqual;
  2428. if ( pAnaInfo == NULL ) {
  2429. //
  2430. // old status is match, or a new added share
  2431. //
  2432. if ( pConfigInfo == NULL ) {
  2433. //
  2434. // a new share, query the current setting in the system
  2435. //
  2436. PSHARE_INFO_1501 ShareInfo=NULL;
  2437. DWORD Win32rc;
  2438. Win32rc = NetShareGetInfo (
  2439. NULL,
  2440. NewLine.Key,
  2441. 1501,
  2442. (LPBYTE *)&ShareInfo
  2443. );
  2444. if ( Win32rc == ERROR_SUCCESS ) {
  2445. PWSTR TextSD=NULL;
  2446. DWORD SDsize=0;
  2447. if ( ShareInfo->shi1501_security_descriptor != NULL ) {
  2448. #if defined(_NT4BACK_PORT)
  2449. rc = SceSvcConvertSDToText(
  2450. ShareInfo->shi1501_security_descriptor,
  2451. DACL_SECURITY_INFORMATION,
  2452. &TextSD,
  2453. &SDsize
  2454. );
  2455. rc = SmbsvcpDosErrorToSceStatus(rc);
  2456. #else
  2457. if ( !ConvertSecurityDescriptorToStringSecurityDescriptor(
  2458. ShareInfo->shi1501_security_descriptor,
  2459. SDDL_REVISION,
  2460. DACL_SECURITY_INFORMATION,
  2461. &TextSD,
  2462. &SDsize
  2463. ) ) {
  2464. rc = SmbsvcpDosErrorToSceStatus(GetLastError());
  2465. } else {
  2466. rc = SCESTATUS_SUCCESS;
  2467. }
  2468. #endif
  2469. }
  2470. if ( rc == SCESTATUS_SUCCESS ) {
  2471. PWSTR Value;
  2472. Value = (PWSTR)LocalAlloc(LMEM_FIXED, (SDsize+9)*sizeof(WCHAR));
  2473. if ( Value != NULL ) {
  2474. if ( TextSD != NULL )
  2475. swprintf(Value, L"Share,%1d,%s", SMBSVC_STATUS_NOT_CONFIGURED, TextSD );
  2476. else
  2477. swprintf(Value, L"Share,%1d,",SMBSVC_STATUS_NOT_CONFIGURED);
  2478. Value[SDsize+8] = L'\0';
  2479. UpdtAnaLine.Key = NewLine.Key;
  2480. UpdtAnaLine.Value = (PBYTE)Value;
  2481. UpdtAnaLine.ValueLen = (SDsize+8)*sizeof(WCHAR);
  2482. __try {
  2483. rc = (*(pSceCbInfo->pfSetInfo))(
  2484. pSceCbInfo->sceHandle,
  2485. SceSvcAnalysisInfo,
  2486. NULL,
  2487. TRUE,
  2488. (PVOID)&UpdtAnaInfo
  2489. );
  2490. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2491. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2492. }
  2493. LocalFree(Value);
  2494. } else
  2495. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2496. }
  2497. NetApiBufferFree(ShareInfo);
  2498. } else
  2499. rc = SmbsvcpDosErrorToSceStatus(Win32rc);
  2500. } else {
  2501. //
  2502. // matched item.
  2503. //
  2504. bEqual = FALSE;
  2505. SECURITY_INFORMATION SeInfo;
  2506. if ( NewLine.ValueLen > 14 &&
  2507. NewLine.Value != NULL &&
  2508. NewLine.Value[8] != L'\0' ) {
  2509. #if defined(_NT4BACK_PORT)
  2510. rc = SceSvcConvertTextToSD(
  2511. NewLine.Value+8,
  2512. &pSD1,
  2513. &SDsize,
  2514. &SeInfo
  2515. );
  2516. rc = SmbsvcpDosErrorToSceStatus(rc);
  2517. #else
  2518. if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
  2519. (PCWSTR)(NewLine.Value+8),
  2520. SDDL_REVISION,
  2521. &pSD1,
  2522. NULL
  2523. ) ) {
  2524. rc = SmbsvcpDosErrorToSceStatus(GetLastError());
  2525. } else {
  2526. rc = SCESTATUS_SUCCESS;
  2527. }
  2528. #endif
  2529. }
  2530. if ( rc == SCESTATUS_SUCCESS && pConfigInfo->Lines != NULL &&
  2531. pConfigInfo->Lines[0].ValueLen > 14 &&
  2532. pConfigInfo->Lines[0].Value != NULL &&
  2533. pConfigInfo->Lines[0].Value[8] != L'\0' ) {
  2534. #if defined(_NT4BACK_PORT)
  2535. rc = SceSvcConvertTextToSD(
  2536. pConfigInfo->Lines[0].Value+8,
  2537. &pSD2,
  2538. &SDsize,
  2539. &SeInfo
  2540. );
  2541. rc = SmbsvcpDosErrorToSceStatus(rc);
  2542. #else
  2543. if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
  2544. (PCWSTR)(pConfigInfo->Lines[0].Value+8),
  2545. SDDL_REVISION,
  2546. &pSD2,
  2547. NULL
  2548. ) ) {
  2549. rc = SmbsvcpDosErrorToSceStatus(GetLastError());
  2550. }
  2551. #endif
  2552. }
  2553. if ( rc == SCESTATUS_SUCCESS ) {
  2554. rc = SmbsvcpEqualSecurityDescriptor(
  2555. pSD1,
  2556. pSD2,
  2557. FALSE,
  2558. &bEqual
  2559. );
  2560. }
  2561. if ( rc == SCESTATUS_SUCCESS && !bEqual ) {
  2562. SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
  2563. SCE_LOG_LEVEL_DEBUG,
  2564. 0,
  2565. L"match->mismatch"
  2566. );
  2567. //
  2568. // mismatch should be raised with ConfigValue
  2569. //
  2570. UpdtAnaLine.Key = NewLine.Key;
  2571. UpdtAnaLine.Value = (PBYTE)(pConfigInfo->Lines[0].Value);
  2572. UpdtAnaLine.ValueLen = pConfigInfo->Lines[0].ValueLen;
  2573. __try {
  2574. rc = (*(pSceCbInfo->pfSetInfo))(
  2575. pSceCbInfo->sceHandle,
  2576. SceSvcAnalysisInfo,
  2577. NULL,
  2578. TRUE,
  2579. (PVOID)&UpdtAnaInfo
  2580. );
  2581. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2582. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2583. }
  2584. }
  2585. }
  2586. if ( rc == SCESTATUS_SUCCESS ) {
  2587. //
  2588. // update configuration setting with NewValue
  2589. //
  2590. UpdtConfigLine.Key = NewLine.Key;
  2591. UpdtConfigLine.Value = NewLine.Value;
  2592. UpdtConfigLine.ValueLen = NewLine.ValueLen;
  2593. __try {
  2594. rc = (*(pSceCbInfo->pfSetInfo))(
  2595. pSceCbInfo->sceHandle,
  2596. SceSvcConfigurationInfo,
  2597. NULL,
  2598. TRUE,
  2599. (PVOID)&UpdtConfigInfo
  2600. );
  2601. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2602. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2603. }
  2604. }
  2605. } else {
  2606. //
  2607. // old status is mismatch for this item
  2608. //
  2609. bEqual = FALSE;
  2610. if ( NewLine.ValueLen > 14 &&
  2611. NewLine.Value != NULL &&
  2612. NewLine.Value[8] != L'\0' ) {
  2613. #if defined(_NT4BACK_PORT)
  2614. SECURITY_INFORMATION SeInfo;
  2615. rc = SceSvcConvertTextToSD(
  2616. NewLine.Value+8,
  2617. &pSD1,
  2618. &SDsize,
  2619. &SeInfo
  2620. );
  2621. rc = SmbsvcpDosErrorToSceStatus(rc);
  2622. #else
  2623. if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
  2624. (PCWSTR)(NewLine.Value+8),
  2625. SDDL_REVISION,
  2626. &pSD1,
  2627. NULL
  2628. ) ) {
  2629. rc = SmbsvcpDosErrorToSceStatus(GetLastError());
  2630. } else {
  2631. rc = SCESTATUS_SUCCESS;
  2632. }
  2633. #endif
  2634. }
  2635. if ( rc == SCESTATUS_SUCCESS && pAnaInfo->Lines != NULL &&
  2636. pAnaInfo->Lines[0].ValueLen > 14 &&
  2637. pAnaInfo->Lines[0].Value != NULL &&
  2638. ((PWSTR)(pAnaInfo->Lines[0].Value))[8] != L'\0' ) {
  2639. #if defined(_NT4BACK_PORT)
  2640. SECURITY_INFORMATION SeInfo;
  2641. rc = SceSvcConvertTextToSD(
  2642. (PWSTR)(pAnaInfo->Lines[0].Value+8),
  2643. &pSD2,
  2644. &SDsize,
  2645. &SeInfo
  2646. );
  2647. rc = SmbsvcpDosErrorToSceStatus(rc);
  2648. #else
  2649. if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(
  2650. (PCWSTR)(pAnaInfo->Lines[0].Value+8),
  2651. SDDL_REVISION,
  2652. &pSD2,
  2653. NULL
  2654. ) ) {
  2655. rc = SmbsvcpDosErrorToSceStatus(GetLastError());
  2656. } else {
  2657. rc = SCESTATUS_SUCCESS;
  2658. }
  2659. #endif
  2660. }
  2661. if ( rc == SCESTATUS_SUCCESS ) {
  2662. rc = SmbsvcpEqualSecurityDescriptor(
  2663. pSD1,
  2664. pSD2,
  2665. FALSE,
  2666. &bEqual
  2667. );
  2668. }
  2669. if ( rc == SCESTATUS_SUCCESS && bEqual ) {
  2670. SmbsvcpWriteError(pSceCbInfo->pfLogInfo,
  2671. SCE_LOG_LEVEL_DEBUG,
  2672. 0,
  2673. L"mismatch->match"
  2674. );
  2675. //
  2676. // now it is matched, delete the analysis entry
  2677. //
  2678. __try {
  2679. rc = (*(pSceCbInfo->pfSetInfo))(
  2680. pSceCbInfo->sceHandle,
  2681. SceSvcAnalysisInfo,
  2682. NewLine.Key,
  2683. TRUE,
  2684. NULL
  2685. );
  2686. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2687. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2688. }
  2689. }
  2690. if ( rc == SCESTATUS_SUCCESS ) {
  2691. //
  2692. // update the configuration setting
  2693. //
  2694. UpdtConfigLine.Key = NewLine.Key;
  2695. UpdtConfigLine.Value = NewLine.Value;
  2696. UpdtConfigLine.ValueLen = NewLine.ValueLen;
  2697. __try {
  2698. rc = (*(pSceCbInfo->pfSetInfo))(
  2699. pSceCbInfo->sceHandle,
  2700. SceSvcConfigurationInfo,
  2701. NULL,
  2702. TRUE,
  2703. (PVOID)&UpdtConfigInfo
  2704. );
  2705. } __except (EXCEPTION_EXECUTE_HANDLER) {
  2706. rc = SCESTATUS_SERVICE_NOT_SUPPORT;
  2707. }
  2708. }
  2709. }
  2710. if ( pSD1 != NULL ) {
  2711. LocalFree(pSD1);
  2712. }
  2713. if ( pSD2 != NULL ) {
  2714. LocalFree(pSD2);
  2715. }
  2716. return(rc);
  2717. }
  2718. SCESTATUS
  2719. SmbsvcpEqualSecurityDescriptor(
  2720. IN PSECURITY_DESCRIPTOR pSD1,
  2721. IN PSECURITY_DESCRIPTOR pSD2,
  2722. IN BOOL bExplicitOnly,
  2723. OUT PBOOL pbEqual
  2724. )
  2725. {
  2726. if ( pbEqual == NULL ) {
  2727. return(SCESTATUS_INVALID_PARAMETER);
  2728. }
  2729. *pbEqual = TRUE;
  2730. if ( pSD1 == NULL && pSD2 == NULL )
  2731. return(SCESTATUS_SUCCESS);
  2732. BOOLEAN aclPresent, tFlag;
  2733. PACL pAcl1=NULL, pAcl2=NULL;
  2734. //
  2735. // get the DACL in each SD
  2736. //
  2737. if ( pSD1 == NULL ||
  2738. !NT_SUCCESS( RtlGetDaclSecurityDescriptor(
  2739. pSD1,
  2740. &aclPresent,
  2741. &pAcl1,
  2742. &tFlag)
  2743. ) ) {
  2744. pAcl1 = NULL;
  2745. } else if ( !aclPresent )
  2746. pAcl1 = NULL;
  2747. if ( pSD2 == NULL ||
  2748. !NT_SUCCESS( RtlGetDaclSecurityDescriptor(
  2749. pSD2,
  2750. &aclPresent,
  2751. &pAcl2,
  2752. &tFlag)
  2753. ) ) {
  2754. pAcl2 = NULL;
  2755. } else if ( !aclPresent )
  2756. pAcl2 = NULL;
  2757. //
  2758. // NOTE:
  2759. // if SD is NULL, it is Everyone Full Control
  2760. //
  2761. if ( pSD1 == NULL ) {
  2762. //
  2763. // check if pAcl2 has only Everyone Full Access
  2764. //
  2765. return( SmbsvcpDosErrorToSceStatus(
  2766. SmbsvcEveryoneFullAccess(pAcl2, bExplicitOnly, pbEqual) ));
  2767. }
  2768. if ( pSD2 == NULL ) {
  2769. //
  2770. // check if pAcl1 has only Everyone Full Access
  2771. //
  2772. return(SmbsvcpDosErrorToSceStatus(
  2773. SmbsvcEveryoneFullAccess(pAcl1, bExplicitOnly, pbEqual) ));
  2774. }
  2775. if ( pAcl1 == NULL && pAcl2 == NULL ) {
  2776. return(SCESTATUS_SUCCESS);
  2777. }
  2778. // if DACL is NULL, it is deny everyone access
  2779. if ( !bExplicitOnly) {
  2780. //
  2781. // if all aces are checked, they are different when one is NULL
  2782. //
  2783. if ( (pAcl1 == NULL && pAcl2 != NULL) ||
  2784. (pAcl1 != NULL && pAcl2 == NULL) ) {
  2785. *pbEqual = FALSE;
  2786. return(SCESTATUS_SUCCESS);
  2787. }
  2788. }
  2789. //
  2790. // compare two ACLs
  2791. //
  2792. BOOL bDifferent = FALSE;
  2793. DWORD rc;
  2794. rc = SmbsvcpCompareAcl( pAcl1, pAcl2, bExplicitOnly, &bDifferent );
  2795. if ( rc == ERROR_SUCCESS ) {
  2796. if (bDifferent )
  2797. *pbEqual = FALSE;
  2798. } else
  2799. *pbEqual = FALSE;
  2800. return(SmbsvcpDosErrorToSceStatus(rc));
  2801. }
  2802. DWORD
  2803. SmbsvcEveryoneFullAccess(
  2804. IN PACL pAcl,
  2805. IN BOOL bExplicit,
  2806. OUT PBOOL pbEqual
  2807. )
  2808. {
  2809. if ( pbEqual == NULL ) {
  2810. return(ERROR_INVALID_PARAMETER);
  2811. }
  2812. *pbEqual = FALSE;
  2813. if ( pAcl == NULL ) {
  2814. return(ERROR_SUCCESS);
  2815. }
  2816. NTSTATUS NtStatus;
  2817. PSID pSidEveryone=NULL;
  2818. SID_IDENTIFIER_AUTHORITY IdentifierAuthority=SECURITY_WORLD_SID_AUTHORITY;
  2819. //
  2820. // build everyone sid
  2821. //
  2822. pSidEveryone = (PSID) LocalAlloc(LMEM_FIXED, RtlLengthRequiredSid(1));
  2823. if (NULL == pSidEveryone )
  2824. return(ERROR_NOT_ENOUGH_MEMORY);
  2825. NtStatus = RtlInitializeSid(pSidEveryone, &IdentifierAuthority, (UCHAR)1);
  2826. if ( !NT_SUCCESS(NtStatus) ) {
  2827. LocalFree(pSidEveryone);
  2828. return(RtlNtStatusToDosError(NtStatus));
  2829. }
  2830. *(RtlSubAuthoritySid(pSidEveryone, 0)) = SECURITY_WORLD_RID;
  2831. ACE_HEADER *pAce=NULL;
  2832. PSID pSid;
  2833. ACCESS_MASK Access;
  2834. DWORD nAceCount, j;
  2835. for ( j=0, nAceCount=0; j<pAcl->AceCount; j++ ) {
  2836. NtStatus = RtlGetAce(pAcl, j, (PVOID *)&pAce);
  2837. if ( !NT_SUCCESS(NtStatus) )
  2838. break;
  2839. if ( pAce == NULL )
  2840. continue;
  2841. if ( bExplicit && (pAce->AceFlags & INHERITED_ACE) ) {
  2842. //
  2843. // find a inherit Ace in Acl
  2844. //
  2845. continue;
  2846. }
  2847. nAceCount++;
  2848. if ( nAceCount == 1 && pAce->AceType == ACCESS_ALLOWED_ACE_TYPE ) {
  2849. pSid = (PSID)&((PACCESS_ALLOWED_ACE)pAce)->SidStart;
  2850. Access = ((PACCESS_ALLOWED_ACE)pAce)->Mask;
  2851. if ( pSid != NULL ) {
  2852. if ( Access == FILE_ALL_ACCESS || Access == GENERIC_ALL ) {
  2853. if ( EqualSid(pSid, pSidEveryone) )
  2854. *pbEqual = TRUE;
  2855. }
  2856. }
  2857. }
  2858. if ( !*pbEqual)
  2859. break;
  2860. if ( nAceCount > 1 ) { // should only allow one ace
  2861. *pbEqual = FALSE;
  2862. break;
  2863. }
  2864. }
  2865. LocalFree(pSidEveryone);
  2866. return(RtlNtStatusToDosError(NtStatus));
  2867. }
  2868. DWORD
  2869. SmbsvcpCompareAcl(
  2870. IN PACL pAcl1,
  2871. IN PACL pAcl2,
  2872. IN BOOL bExplicitOnly,
  2873. OUT PBOOL pDifferent
  2874. )
  2875. /*
  2876. Routine Description:
  2877. This routine compares explicit aces of two ACLs for exact match. Exact
  2878. match means: same access type, same inheritance flag, same access mask,
  2879. same GUID/Object GUID (if available), and same SID.
  2880. Inherited aces (INHERITED_ACE is set) are ignored.
  2881. Arguments:
  2882. pAcl1 - The first ACL
  2883. pAcl2 - The 2nd ACL
  2884. pDifferent - The output flag to indicate different
  2885. Return Value:
  2886. Win32 error codes
  2887. */
  2888. {
  2889. NTSTATUS NtStatus=STATUS_SUCCESS;
  2890. DWORD i, j;
  2891. ACE_HEADER *pAce1=NULL;
  2892. ACE_HEADER *pAce2=NULL;
  2893. DWORD ProcessAce=0;
  2894. *pDifferent = FALSE;
  2895. //
  2896. // if pAcl1 is NULL, pAcl2 should have 0 explicit Ace
  2897. //
  2898. if ( pAcl1 == NULL ) {
  2899. return( SmbsvcpAnyExplicitAcl( pAcl2, 0, pDifferent ) );
  2900. }
  2901. //
  2902. // if pAcl2 is NULL, pAcl1 should have 0 explicit Ace
  2903. //
  2904. if ( pAcl2 == NULL ) {
  2905. return( SmbsvcpAnyExplicitAcl( pAcl1, 0, pDifferent ) );
  2906. }
  2907. //
  2908. // both ACLs are not NULL
  2909. // BUGBUG: note there is a limit of AceCount because of DWORD (32 bits)
  2910. //
  2911. for ( i=0; i<pAcl1->AceCount; i++) {
  2912. NtStatus = RtlGetAce(pAcl1, i, (PVOID *)&pAce1);
  2913. if ( !NT_SUCCESS(NtStatus) )
  2914. goto Done;
  2915. //
  2916. // ignore inherited Aces
  2917. //
  2918. if ( bExplicitOnly && (pAce1->AceFlags & INHERITED_ACE) )
  2919. continue;
  2920. //
  2921. // try to find a match in pAcl2
  2922. //
  2923. for ( j=0; j<pAcl2->AceCount; j++ ) {
  2924. if ( ProcessAce & (1 << j) )
  2925. // this one is already processed
  2926. continue;
  2927. NtStatus = RtlGetAce(pAcl2, j, (PVOID *)&pAce2);
  2928. if ( !NT_SUCCESS(NtStatus) )
  2929. goto Done;
  2930. //
  2931. // ignore inherited Aces too
  2932. //
  2933. if ( bExplicitOnly && (pAce2->AceFlags & INHERITED_ACE) ) {
  2934. ProcessAce |= (1 << j);
  2935. continue;
  2936. }
  2937. //
  2938. // compare two Aces (pAce1 and pAce2)
  2939. //
  2940. if ( SmbsvcpEqualAce(pAce1, pAce2) ) {
  2941. //
  2942. // find a match
  2943. //
  2944. ProcessAce |= (1 << j);
  2945. break;
  2946. }
  2947. }
  2948. if ( j >= pAcl2->AceCount ) {
  2949. //
  2950. // did not find a match for pAce1
  2951. //
  2952. *pDifferent = TRUE;
  2953. return(ERROR_SUCCESS);
  2954. }
  2955. }
  2956. if ( i >= pAcl1->AceCount ) {
  2957. //
  2958. // every Ace in pAcl1 finds a match in pAcl2
  2959. // see if every Ace in pAcl2 has a match
  2960. //
  2961. return( SmbsvcpAnyExplicitAcl( pAcl2, ProcessAce, pDifferent ) );
  2962. }
  2963. Done:
  2964. return(RtlNtStatusToDosError(NtStatus));
  2965. }
  2966. DWORD
  2967. SmbsvcpAnyExplicitAcl(
  2968. IN PACL Acl,
  2969. IN DWORD Processed,
  2970. OUT PBOOL pExist
  2971. )
  2972. /*
  2973. Routine Description:
  2974. This routine detects if there is any explicit ace in the Acl. The DWORD
  2975. Processed is a bit mask of the aces already checked.
  2976. Arguments:
  2977. Acl - The Acl
  2978. Processed - The bit mask for the processed aces (so it won't be checked again)
  2979. pExist - The output flag to indicate if there is any explicit ace
  2980. Return Value:
  2981. win32 error codes
  2982. */
  2983. {
  2984. NTSTATUS NtStatus=STATUS_SUCCESS;
  2985. DWORD j;
  2986. ACE_HEADER *pAce=NULL;
  2987. //
  2988. // check output argument
  2989. //
  2990. if ( pExist == NULL )
  2991. return(ERROR_INVALID_PARAMETER);
  2992. *pExist = FALSE;
  2993. if ( Acl == NULL )
  2994. return(ERROR_SUCCESS);
  2995. for ( j=0; j<Acl->AceCount; j++ ) {
  2996. if ( Processed & (1 << j) )
  2997. continue;
  2998. NtStatus = RtlGetAce(Acl, j, (PVOID *)&pAce);
  2999. if ( !NT_SUCCESS(NtStatus) )
  3000. return(RtlNtStatusToDosError(NtStatus));
  3001. if ( pAce == NULL )
  3002. continue;
  3003. if ( !(pAce->AceFlags & INHERITED_ACE) ) {
  3004. //
  3005. // find a explicit Ace in Acl
  3006. //
  3007. *pExist = TRUE;
  3008. break;
  3009. }
  3010. }
  3011. return(RtlNtStatusToDosError(NtStatus));
  3012. }
  3013. BOOL
  3014. SmbsvcpEqualAce(
  3015. IN ACE_HEADER *pAce1,
  3016. IN ACE_HEADER *pAce2
  3017. )
  3018. // compare two aces for exact match. The return BOOL value indicates the
  3019. // match or not
  3020. {
  3021. PSID pSid1=NULL, pSid2=NULL;
  3022. ACCESS_MASK Access1=0, Access2=0;
  3023. if ( pAce1 == NULL && pAce2 == NULL )
  3024. return(TRUE);
  3025. if ( pAce1 == NULL || pAce2 == NULL )
  3026. return(FALSE);
  3027. //
  3028. // compare ace access type
  3029. //
  3030. if ( pAce1->AceType != pAce2->AceType )
  3031. return(FALSE);
  3032. //
  3033. // compare ace inheritance flag
  3034. //
  3035. if ( pAce1->AceFlags != pAce2->AceFlags )
  3036. return(FALSE);
  3037. switch ( pAce1->AceType ) {
  3038. case ACCESS_ALLOWED_ACE_TYPE:
  3039. case ACCESS_DENIED_ACE_TYPE:
  3040. case SYSTEM_AUDIT_ACE_TYPE:
  3041. case SYSTEM_ALARM_ACE_TYPE:
  3042. pSid1 = (PSID)&((PACCESS_ALLOWED_ACE)pAce1)->SidStart;
  3043. pSid2 = (PSID)&((PACCESS_ALLOWED_ACE)pAce2)->SidStart;
  3044. Access1 = ((PACCESS_ALLOWED_ACE)pAce1)->Mask;
  3045. Access2 = ((PACCESS_ALLOWED_ACE)pAce2)->Mask;
  3046. break;
  3047. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  3048. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  3049. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  3050. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  3051. pSid1 = (PSID)&((PACCESS_ALLOWED_OBJECT_ACE)pAce1)->SidStart;
  3052. pSid2 = (PSID)&((PACCESS_ALLOWED_OBJECT_ACE)pAce2)->SidStart;
  3053. Access1 = ((PACCESS_ALLOWED_OBJECT_ACE)pAce1)->Mask;
  3054. Access2 = ((PACCESS_ALLOWED_OBJECT_ACE)pAce2)->Mask;
  3055. //
  3056. // ignore the guids
  3057. //
  3058. break;
  3059. default:
  3060. return(FALSE); // not recognized Ace type
  3061. }
  3062. if ( pSid1 == NULL || pSid2 == NULL )
  3063. //
  3064. // no Sid, ignore the Ace
  3065. //
  3066. return(FALSE);
  3067. //
  3068. // compare the sids
  3069. //
  3070. if ( !EqualSid(pSid1, pSid2) )
  3071. return(FALSE);
  3072. //
  3073. // access mask
  3074. //
  3075. // Translation is already done when calculating security descriptor
  3076. // for file objects and registry objects
  3077. //
  3078. if ( Access1 != Access2 ) {
  3079. RtlMapGenericMask (
  3080. &Access2,
  3081. &ShareGenMap
  3082. );
  3083. if ( Access1 != Access2)
  3084. return(FALSE);
  3085. }
  3086. return(TRUE);
  3087. }
  3088. /*=============================================================================
  3089. ** Procedure Name: DllMain
  3090. **
  3091. ** Arguments:
  3092. **
  3093. **
  3094. **
  3095. ** Returns: 0 = SUCCESS
  3096. ** !0 = ERROR
  3097. **
  3098. ** Abstract:
  3099. **
  3100. ** Notes:
  3101. **
  3102. **===========================================================================*/
  3103. BOOL WINAPI DllMain(
  3104. IN HANDLE DllHandle,
  3105. IN ULONG ulReason,
  3106. IN LPVOID Reserved )
  3107. {
  3108. switch(ulReason) {
  3109. case DLL_PROCESS_ATTACH:
  3110. MyModuleHandle = (HINSTANCE)DllHandle;
  3111. //
  3112. // Fall through to process first thread
  3113. //
  3114. case DLL_THREAD_ATTACH:
  3115. break;
  3116. case DLL_PROCESS_DETACH:
  3117. break;
  3118. case DLL_THREAD_DETACH:
  3119. break;
  3120. }
  3121. return TRUE;
  3122. }
  3123. /////////////////////////////////////////////////////////////////////////////
  3124. // DllRegisterServer - Adds entries to the system registry
  3125. STDAPI DllRegisterServer(void)
  3126. {
  3127. HKEY hKey;
  3128. LONG lResult;
  3129. DWORD dwDisp;
  3130. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, SCESMB_ROOT_PATH, 0, NULL,
  3131. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  3132. &hKey, &dwDisp);
  3133. if (lResult != ERROR_SUCCESS)
  3134. {
  3135. return lResult;
  3136. }
  3137. RegSetValueEx (hKey, TEXT("ServiceAttachmentPath"), 0, REG_SZ, (LPBYTE)TEXT("seFilShr.dll"),
  3138. (lstrlen(TEXT("seFilShr.dll")) + 1) * sizeof(TCHAR));
  3139. RegCloseKey (hKey);
  3140. return S_OK;
  3141. }
  3142. /////////////////////////////////////////////////////////////////////////////
  3143. // DllUnregisterServer - Removes entries from the system registry
  3144. STDAPI DllUnregisterServer(void)
  3145. {
  3146. RegDeleteKey (HKEY_LOCAL_MACHINE, SCESMB_ROOT_PATH);
  3147. return S_OK;
  3148. }