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.

1534 lines
41 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. security.c
  5. Abstract:
  6. This module provides security for the service.
  7. Author:
  8. Oded Sacher (OdedS) 13-Feb-2000
  9. Revision History:
  10. --*/
  11. #include "faxsvc.h"
  12. #include <aclapi.h>
  13. #define ATLASSERT Assert
  14. #include <smartptr.h>
  15. #pragma hdrstop
  16. //
  17. // defined in ntrtl.h.
  18. // do this to avoid dragging in ntrtl.h since we already include some stuff
  19. // from ntrtl.h
  20. //
  21. extern "C"
  22. NTSYSAPI
  23. BOOLEAN
  24. NTAPI
  25. RtlValidRelativeSecurityDescriptor (
  26. IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
  27. IN ULONG SecurityDescriptorLength,
  28. IN SECURITY_INFORMATION RequiredInformation
  29. );
  30. //
  31. // Global Fax Service Security Descriptor
  32. //
  33. PSECURITY_DESCRIPTOR g_pFaxSD;
  34. CFaxCriticalSection g_CsSecurity;
  35. const GENERIC_MAPPING gc_FaxGenericMapping =
  36. {
  37. (STANDARD_RIGHTS_READ | FAX_GENERIC_READ),
  38. (STANDARD_RIGHTS_WRITE | FAX_GENERIC_WRITE),
  39. (STANDARD_RIGHTS_EXECUTE | FAX_GENERIC_EXECUTE),
  40. (READ_CONTROL | WRITE_DAC | WRITE_OWNER | FAX_GENERIC_ALL)
  41. };
  42. DWORD
  43. FaxSvcAccessCheck(
  44. IN ACCESS_MASK DesiredAccess,
  45. OUT BOOL* lpbAccessStatus,
  46. OUT LPDWORD lpdwGrantedAccess
  47. )
  48. /*++
  49. Routine name : FaxSvcAccessCheck
  50. Routine description:
  51. Performs an access check against the fax service security descriptor
  52. Author:
  53. Oded Sacher (OdedS), Feb, 2000
  54. Arguments:
  55. DesiredAccess [in ] - Desired access
  56. lpbAccessStatus [out ] - Address of a BOOL to receive the access check result (TRUE is access allowed)
  57. lpdwGrantedAccess [out ] - Optional., Address of a DWORD to receive the maximum access allowed. Desired Access should be MAXIMUM_ALLOWED
  58. Return Value:
  59. Standard Win32 error code
  60. --*/
  61. {
  62. DWORD rc;
  63. DWORD GrantedAccess;
  64. DWORD dwRes;
  65. BOOL fGenerateOnClose;
  66. DEBUG_FUNCTION_NAME(TEXT("FaxSvcAccessCheck"));
  67. Assert (lpbAccessStatus);
  68. //
  69. // Impersonate the client.
  70. //
  71. if ((rc = RpcImpersonateClient(NULL)) != RPC_S_OK)
  72. {
  73. DebugPrintEx(
  74. DEBUG_ERR,
  75. TEXT("RpcImpersonateClient() failed. (ec: %ld)"),
  76. rc);
  77. goto exit;
  78. }
  79. EnterCriticalSection( &g_CsSecurity );
  80. //
  81. // purify the access mask - get rid of generic access bits
  82. //
  83. MapGenericMask( &DesiredAccess, const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping) );
  84. //
  85. // Check if the client has the required access.
  86. //
  87. if (!AccessCheckAndAuditAlarm(
  88. FAX_SERVICE_NAME, // subsystem name
  89. NULL, // handle to object
  90. NULL, // type of object
  91. NULL, // name of object
  92. g_pFaxSD, // SD
  93. DesiredAccess, // requested access rights
  94. const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping), // mapping
  95. FALSE, // creation status
  96. &GrantedAccess, // granted access rights
  97. lpbAccessStatus, // result of access check
  98. &fGenerateOnClose // audit generation option
  99. ))
  100. {
  101. rc = GetLastError();
  102. DebugPrintEx(
  103. DEBUG_ERR,
  104. TEXT("AccessCheck() failed. (ec: %ld)"),
  105. rc);
  106. LeaveCriticalSection( &g_CsSecurity );
  107. goto exit;
  108. }
  109. if (lpdwGrantedAccess)
  110. {
  111. *lpdwGrantedAccess = GrantedAccess;
  112. }
  113. LeaveCriticalSection( &g_CsSecurity );
  114. Assert (ERROR_SUCCESS == rc);
  115. exit:
  116. dwRes=RpcRevertToSelf();
  117. if (RPC_S_OK != dwRes)
  118. {
  119. DebugPrintEx(
  120. DEBUG_ERR,
  121. TEXT("RpcRevertToSelf() failed (ec: %ld)"),
  122. dwRes);
  123. Assert(FALSE);
  124. }
  125. return rc;
  126. }
  127. DWORD
  128. SaveSecurityDescriptor(
  129. PSECURITY_DESCRIPTOR pSD
  130. )
  131. /*++
  132. Routine name : SaveSecurityDescriptor
  133. Routine description:
  134. Saves the Fax Service SD to the registry
  135. Author:
  136. Oded Sacher (OdedS), Feb, 2000
  137. Arguments:
  138. pSD [in ] - Pointer to a SD to be saved
  139. Return Value:
  140. DWORD
  141. --*/
  142. {
  143. DWORD rc = ERROR_SUCCESS;
  144. DWORD dwSize;
  145. PSECURITY_DESCRIPTOR pSDSelfRelative = NULL;
  146. HKEY hKey = NULL;
  147. DWORD Disposition;
  148. SECURITY_DESCRIPTOR_CONTROL Control = SE_SELF_RELATIVE;
  149. DWORD dwRevision;
  150. DEBUG_FUNCTION_NAME(TEXT("SaveSecurityDescriptor"));
  151. Assert (pSD);
  152. rc = RegCreateKeyEx(
  153. HKEY_LOCAL_MACHINE,
  154. REGKEY_FAX_SECURITY,
  155. 0,
  156. TEXT(""),
  157. 0,
  158. KEY_WRITE,
  159. NULL,
  160. &hKey,
  161. &Disposition
  162. );
  163. if (rc != ERROR_SUCCESS)
  164. {
  165. DebugPrintEx(
  166. DEBUG_ERR,
  167. TEXT("RegCreateKeyEx() failed (ec: %ld)"),
  168. rc);
  169. return rc;
  170. }
  171. if (!IsValidSecurityDescriptor(pSD))
  172. {
  173. rc = ERROR_INVALID_SECURITY_DESCR;
  174. DebugPrintEx(
  175. DEBUG_ERR,
  176. TEXT("IsValidSecurityDescriptor() failed."));
  177. goto exit;
  178. }
  179. //
  180. // Check if the security descriptor is absolute or self relative.
  181. //
  182. if (!GetSecurityDescriptorControl( pSD, &Control, &dwRevision))
  183. {
  184. rc = GetLastError();
  185. DebugPrintEx(
  186. DEBUG_ERR,
  187. TEXT("GetSecurityDescriptorControl() failed (ec: %ld)"),
  188. rc);
  189. goto exit;
  190. }
  191. //
  192. // store the security descriptor in the registry
  193. //
  194. dwSize = GetSecurityDescriptorLength( pSD );
  195. if (SE_SELF_RELATIVE & Control)
  196. {
  197. //
  198. // store the security descriptor in the registry use absolute SD
  199. //
  200. rc = RegSetValueEx(
  201. hKey,
  202. REGVAL_DESCRIPTOR,
  203. 0,
  204. REG_BINARY,
  205. (LPBYTE) pSD,
  206. dwSize
  207. );
  208. if (ERROR_SUCCESS != rc)
  209. {
  210. DebugPrintEx(
  211. DEBUG_ERR,
  212. TEXT("RegSetValueEx() failed (ec: %ld)"),
  213. rc);
  214. goto exit;
  215. }
  216. }
  217. else
  218. {
  219. //
  220. // Convert the absolute SD to self relative
  221. //
  222. pSDSelfRelative = (PSECURITY_DESCRIPTOR) MemAlloc( dwSize );
  223. if (NULL == pSDSelfRelative)
  224. {
  225. rc = ERROR_NOT_ENOUGH_MEMORY;
  226. DebugPrintEx(
  227. DEBUG_ERR,
  228. TEXT("Error Allocating security descriptor"));
  229. goto exit;
  230. }
  231. //
  232. // make the security descriptor self relative
  233. //
  234. if (!MakeSelfRelativeSD( pSD, pSDSelfRelative, &dwSize))
  235. {
  236. rc = GetLastError();
  237. DebugPrintEx(
  238. DEBUG_ERR,
  239. TEXT("MakeSelfRelativeSD() failed (ec: %ld)"),
  240. rc);
  241. goto exit;
  242. }
  243. //
  244. // store the security descriptor in the registry use self relative SD
  245. //
  246. rc = RegSetValueEx(
  247. hKey,
  248. REGVAL_DESCRIPTOR,
  249. 0,
  250. REG_BINARY,
  251. (LPBYTE) pSDSelfRelative,
  252. dwSize
  253. );
  254. if (ERROR_SUCCESS != rc)
  255. {
  256. DebugPrintEx(
  257. DEBUG_ERR,
  258. TEXT("RegSetValueEx() failed (ec: %ld)"),
  259. rc);
  260. goto exit;
  261. }
  262. }
  263. Assert (ERROR_SUCCESS == rc);
  264. exit:
  265. if (NULL != hKey)
  266. {
  267. RegCloseKey (hKey);
  268. }
  269. if (NULL != pSDSelfRelative)
  270. {
  271. MemFree (pSDSelfRelative);
  272. }
  273. return rc;
  274. }
  275. #define FAX_OWNER_SID TEXT("O:NS") // Owner sid : Network Service
  276. #define FAX_GROUP_SID TEXT("G:NS") // Group sid : Network Service
  277. #define FAX_DACL TEXT("D:")
  278. #define FAX_BA_ALLOW_ACE TEXT("(A;;0xe07ff;;;BA)") // Allow Built-in administrators (BA) -
  279. // Access mask : 0xe07ff == FAX_GENERIC_ALL |
  280. // WRITE_OWNER |
  281. // WRITE_DAC |
  282. // READ_CONTROL
  283. #define FAX_WD_ALLOW_ACE TEXT("(A;;0x20003;;;WD)") // Allow Everyone (WD) -
  284. // Access mask : 0x20003 == FAX_ACCESS_SUBMIT |
  285. // FAX_ACCESS_SUBMIT_NORMAL |
  286. // READ_CONTROL
  287. #define FAX_IU_ALLOW_ACE TEXT("(A;;0x202BF;;;IU)") // Allow Interactive users (IU) -
  288. // Access mask : 0x202BF == FAX_ACCESS_SUBMIT |
  289. // FAX_ACCESS_SUBMIT_NORMAL |
  290. // FAX_ACCESS_SUBMIT_HIGH |
  291. // FAX_ACCESS_QUERY_JOBS |
  292. // FAX_ACCESS_MANAGE_JOBS |
  293. // FAX_ACCESS_QUERY_CONFIG |
  294. // FAX_ACCESS_QUERY_OUT_ARCHIVE |
  295. // FAX_ACCESS_QUERY_IN_ARCHIVE |
  296. // READ_CONTROL
  297. #define FAX_DESKTOP_SKU_SD (FAX_OWNER_SID FAX_GROUP_SID FAX_DACL FAX_BA_ALLOW_ACE FAX_WD_ALLOW_ACE FAX_IU_ALLOW_ACE) // SD for per/pro SKU
  298. #define FAX_SERVER_SKU_SD (FAX_OWNER_SID FAX_GROUP_SID FAX_DACL FAX_BA_ALLOW_ACE FAX_WD_ALLOW_ACE) // SD for server SKU
  299. DWORD
  300. CreateDefaultSecurityDescriptor(
  301. VOID
  302. )
  303. /*++
  304. Routine name : CreateDefaultSecurityDescriptor
  305. Routine description:
  306. Creates the default security descriptor
  307. Author:
  308. Oded Sacher (OdedS), Feb, 2000
  309. Caliv Nir (t-nicali) Mar, 2002 - changed to use SDDL, while moving Fax service
  310. to run under "Network service"
  311. Arguments:
  312. None.
  313. Return Value:
  314. Standard Win32 error code.
  315. --*/
  316. {
  317. DWORD dwRet = ERROR_SUCCESS;
  318. BOOL bRet;
  319. PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  320. PSECURITY_DESCRIPTOR pPrivateObjectSD = NULL;
  321. ULONG SecurityDescriptorSize = 0;
  322. HANDLE hFaxServiceToken = NULL;
  323. BOOL bDesktopSKU = FALSE;
  324. TCHAR* ptstrSD = NULL;
  325. DEBUG_FUNCTION_NAME(TEXT("CreateDefaultSecurityDescriptor"));
  326. //
  327. // If this is PERSONAL SKU, then add Interactive Users SID
  328. //
  329. bDesktopSKU = IsDesktopSKU();
  330. ptstrSD = bDesktopSKU ? FAX_DESKTOP_SKU_SD : FAX_SERVER_SKU_SD;
  331. bRet = ConvertStringSecurityDescriptorToSecurityDescriptor(
  332. ptstrSD, // security descriptor string
  333. SDDL_REVISION_1, // revision level
  334. &pSecurityDescriptor, // SD
  335. &SecurityDescriptorSize // SD size
  336. );
  337. if(!bRet)
  338. {
  339. dwRet = GetLastError();
  340. DebugPrintEx(
  341. DEBUG_ERR,
  342. TEXT("ConvertStringSecurityDescriptorToSecurityDescriptor() failed (ec: %lu)"),
  343. dwRet);
  344. goto exit;
  345. }
  346. //
  347. // Get the Fax Service Token
  348. //
  349. if (!OpenProcessToken( GetCurrentProcess(), // handle to process
  350. TOKEN_QUERY, // desired access to process
  351. &hFaxServiceToken // handle to open access token
  352. ))
  353. {
  354. dwRet = GetLastError();
  355. DebugPrintEx(
  356. DEBUG_ERR,
  357. TEXT("OpenThreadToken failed. (ec: %ld)"),
  358. dwRet);
  359. goto exit;
  360. }
  361. //
  362. // Create a private object SD
  363. //
  364. if (!CreatePrivateObjectSecurity( NULL, // parent directory SD
  365. pSecurityDescriptor, // creator SD
  366. &pPrivateObjectSD, // new SD
  367. FALSE, // container
  368. hFaxServiceToken, // handle to access token
  369. const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping) // mapping
  370. ))
  371. {
  372. dwRet = GetLastError();
  373. DebugPrintEx(
  374. DEBUG_ERR,
  375. TEXT("CreatePrivateObjectSecurity() failed (ec: %ld)"),
  376. dwRet);
  377. goto exit;
  378. }
  379. //
  380. // store the security descriptor in the registry
  381. //
  382. dwRet = SaveSecurityDescriptor (pPrivateObjectSD);
  383. if (ERROR_SUCCESS != dwRet)
  384. {
  385. DebugPrintEx(
  386. DEBUG_ERR,
  387. TEXT("SaveSecurityDescriptor() failed (ec: %ld)"),
  388. dwRet);
  389. goto exit;
  390. }
  391. //
  392. // All done! Set the global fax service security descriptor
  393. //
  394. g_pFaxSD = pPrivateObjectSD;
  395. pPrivateObjectSD = NULL;
  396. Assert (ERROR_SUCCESS == dwRet);
  397. exit:
  398. if(NULL != pSecurityDescriptor)
  399. {
  400. LocalFree(pSecurityDescriptor);
  401. }
  402. if (NULL != hFaxServiceToken)
  403. {
  404. if (!CloseHandle(hFaxServiceToken))
  405. {
  406. DebugPrintEx(
  407. DEBUG_ERR,
  408. TEXT("CloseHandle() failed. (ec: %ld)"),
  409. GetLastError());
  410. }
  411. }
  412. if (NULL != pPrivateObjectSD)
  413. {
  414. //
  415. // in case of failure in creating the SD destroy the private object SD.
  416. //
  417. if (!DestroyPrivateObjectSecurity (&pPrivateObjectSD))
  418. {
  419. DebugPrintEx(
  420. DEBUG_ERR,
  421. TEXT("DestroyPrivateObjectSecurity() failed. (ec: %ld)"),
  422. GetLastError());
  423. }
  424. }
  425. return dwRet;
  426. } // CreateDefaultSecurityDescriptor
  427. DWORD
  428. LoadSecurityDescriptor(
  429. VOID
  430. )
  431. /*++
  432. Routine name : LoadSecurityDescriptor
  433. Routine description:
  434. Loads the Fax Service security descriptor from the registry
  435. Author:
  436. Oded Sacher (OdedS), Feb, 2000
  437. Arguments:
  438. None
  439. Return Value:
  440. Standard Win32 error code
  441. --*/
  442. {
  443. DWORD rc = ERROR_SUCCESS;
  444. DWORD dwSize;
  445. HKEY hKey = NULL;
  446. DWORD Disposition;
  447. DWORD dwType;
  448. PSECURITY_DESCRIPTOR pRelativeSD = NULL;
  449. DEBUG_FUNCTION_NAME(TEXT("LoadSecurityDescriptor"));
  450. rc = RegCreateKeyEx(
  451. HKEY_LOCAL_MACHINE,
  452. REGKEY_FAX_SECURITY,
  453. 0,
  454. TEXT(""),
  455. 0,
  456. KEY_READ,
  457. NULL,
  458. &hKey,
  459. &Disposition
  460. );
  461. if (rc != ERROR_SUCCESS)
  462. {
  463. DebugPrintEx(
  464. DEBUG_ERR,
  465. TEXT("RegCreateKeyEx() failed (ec: %ld)"),
  466. rc);
  467. goto exit;
  468. }
  469. rc = RegQueryValueEx(
  470. hKey,
  471. REGVAL_DESCRIPTOR,
  472. NULL,
  473. &dwType,
  474. NULL,
  475. &dwSize
  476. );
  477. if (ERROR_SUCCESS != rc)
  478. {
  479. DebugPrintEx(
  480. DEBUG_ERR,
  481. TEXT("RegQueryValueEx failed with %ld"),
  482. rc);
  483. goto exit;
  484. }
  485. //
  486. // We opened an existing registry value
  487. //
  488. if (REG_BINARY != dwType ||
  489. 0 == dwSize)
  490. {
  491. //
  492. // We expect only binary data here
  493. //
  494. DebugPrintEx(
  495. DEBUG_ERR,
  496. TEXT("Error reading security descriptor from the registry, not a binary type, or size is 0"));
  497. rc = ERROR_BADDB; // The configuration registry database is corrupt.
  498. goto exit;
  499. }
  500. //
  501. // Allocate required buffer
  502. // The buffer must be allocated using HeapAlloc (GetProcessHeap()...) because this is the way CreatePrivateObjectSecurity() allocates memory
  503. // This is a result of a bad design of private object security APIs, see Windows Bugs #324906.
  504. //
  505. pRelativeSD = (PSECURITY_DESCRIPTOR) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize );
  506. if (!pRelativeSD)
  507. {
  508. rc = ERROR_NOT_ENOUGH_MEMORY;
  509. DebugPrintEx(
  510. DEBUG_ERR,
  511. TEXT("Failed to allocate security descriptor buffer"));
  512. goto exit;
  513. }
  514. //
  515. // Read the data
  516. //
  517. rc = RegQueryValueEx(
  518. hKey,
  519. REGVAL_DESCRIPTOR,
  520. NULL,
  521. &dwType,
  522. (LPBYTE)pRelativeSD,
  523. &dwSize
  524. );
  525. if (ERROR_SUCCESS != rc)
  526. {
  527. DebugPrintEx(
  528. DEBUG_ERR,
  529. TEXT("RegQueryValueEx failed with %ld"),
  530. rc);
  531. goto exit;
  532. }
  533. if (!IsValidSecurityDescriptor(pRelativeSD))
  534. {
  535. rc = ERROR_INVALID_SECURITY_DESCR;
  536. DebugPrintEx(
  537. DEBUG_ERR,
  538. TEXT("IsValidSecurityDescriptor() failed."));
  539. goto exit;
  540. }
  541. g_pFaxSD = pRelativeSD;
  542. pRelativeSD = NULL;
  543. Assert (ERROR_SUCCESS == rc);
  544. exit:
  545. if (hKey)
  546. {
  547. RegCloseKey( hKey );
  548. }
  549. if (NULL != pRelativeSD)
  550. {
  551. if (!HeapFree(GetProcessHeap(), 0, pRelativeSD))
  552. {
  553. DebugPrintEx(
  554. DEBUG_ERR,
  555. TEXT("pRelativeSD() failed. (ec: %ld)"),
  556. GetLastError());
  557. }
  558. }
  559. return rc;
  560. }
  561. DWORD
  562. InitializeServerSecurity(
  563. VOID
  564. )
  565. /*++
  566. Routine name : InitializeServerSecurity
  567. Routine description:
  568. Initializes the Fax Service security
  569. Author:
  570. Oded Sacher (OdedS), Feb, 2000
  571. Arguments:
  572. None
  573. Return Value:
  574. Standard Win32 error code
  575. --*/
  576. {
  577. DWORD rc = ERROR_SUCCESS;
  578. DEBUG_FUNCTION_NAME(TEXT("InitializeServerSecurity"));
  579. rc = LoadSecurityDescriptor();
  580. if (ERROR_SUCCESS != rc)
  581. {
  582. DebugPrintEx(
  583. DEBUG_ERR,
  584. TEXT("LoadSecurityDescriptor() failed (ec: %ld), Create default security descriptor"),
  585. rc);
  586. }
  587. else
  588. {
  589. //success
  590. return rc;
  591. }
  592. //
  593. // We failed to load the security descriptor
  594. //
  595. if (ERROR_NOT_ENOUGH_MEMORY == rc)
  596. {
  597. //
  598. // Do not let the service start
  599. //
  600. return rc;
  601. }
  602. //
  603. // The registry is corrupted - create the default security descriptor
  604. //
  605. rc = CreateDefaultSecurityDescriptor();
  606. if (ERROR_SUCCESS != rc)
  607. {
  608. DebugPrintEx(
  609. DEBUG_ERR,
  610. TEXT("CreateDefaultSecurityDescriptor() failed (ec: %ld)"),
  611. rc);
  612. }
  613. return rc;
  614. }
  615. //*********************************************************************************
  616. //* Name:GetClientUserName()
  617. //* Author: Ronen Barenboim
  618. //* Date: May 02, 1999
  619. //*********************************************************************************
  620. //* DESCRIPTION:
  621. //* Returns the OS User Name of the connected RPC client.
  622. //* PARAMETERS:
  623. //* None.
  624. //* RETURN VALUE:
  625. //* A pointer to a newly allocated string holding the user name.
  626. //* The caller must free this string using MemFree().
  627. //* Returns NULL if an error occures.
  628. //* To get extended error information, call GetLastError.
  629. //*********************************************************************************
  630. LPWSTR
  631. GetClientUserName(
  632. VOID
  633. )
  634. {
  635. RPC_STATUS dwRes;
  636. LPWSTR lpwstrUserName = NULL;
  637. HANDLE hToken = NULL;
  638. PSID pUserSid;
  639. WCHAR szShortUserName[64];
  640. WCHAR szShortDomainName[64];
  641. DWORD dwUserNameLen = sizeof(szShortUserName) / sizeof(WCHAR);
  642. DWORD dwDomainNameLen = sizeof(szShortDomainName) / sizeof(WCHAR);
  643. LPWSTR szUserName = szShortUserName; // first point to short on stack buffers
  644. LPWSTR szDomainName = szShortDomainName;
  645. SID_NAME_USE SidNameUse;
  646. LPWSTR szLongUserName = NULL;
  647. LPWSTR szLongDomainName = NULL;
  648. DEBUG_FUNCTION_NAME(TEXT("GetClientUserName"));
  649. //
  650. // Impersonate the user.
  651. //
  652. dwRes=RpcImpersonateClient(NULL);
  653. if (dwRes != RPC_S_OK)
  654. {
  655. DebugPrintEx(
  656. DEBUG_ERR,
  657. TEXT("RpcImpersonateClient(NULL) failed. (ec: %ld)"),
  658. dwRes);
  659. SetLastError (dwRes);
  660. return NULL;
  661. }
  662. //
  663. // Open the thread token. We're in an RPC thread, not the main thread.
  664. //
  665. if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
  666. {
  667. dwRes = GetLastError();
  668. DebugPrintEx(
  669. DEBUG_ERR,
  670. TEXT("OpenThreadToken failed. (ec: %ld)"),
  671. dwRes);
  672. goto exit;
  673. }
  674. //
  675. // Get the user's SID. A 128 byte long buffer should always suffice since
  676. // a SID length is limited to +/- 80 bytes at most.
  677. //
  678. BYTE abTokenUser[128];
  679. DWORD dwReqSize;
  680. if (!GetTokenInformation(hToken,
  681. TokenUser,
  682. (LPVOID)abTokenUser,
  683. sizeof(abTokenUser),
  684. &dwReqSize))
  685. {
  686. dwRes = GetLastError();
  687. DebugPrintEx(
  688. DEBUG_ERR,
  689. TEXT("GetTokenInformation failed. (ec: %ld)"),
  690. dwRes);
  691. goto exit;
  692. }
  693. //
  694. // Get the user name and domain.
  695. //
  696. pUserSid = ((TOKEN_USER *)abTokenUser)->User.Sid;
  697. //
  698. // Try to get account Sid - with small on stack buffers
  699. //
  700. if (!LookupAccountSid(NULL,
  701. pUserSid,
  702. szShortUserName,
  703. &dwUserNameLen,
  704. szShortDomainName,
  705. &dwDomainNameLen,
  706. &SidNameUse))
  707. {
  708. dwRes = GetLastError();
  709. if (dwRes == ERROR_INSUFFICIENT_BUFFER)
  710. {
  711. //
  712. // At least one of buffer were too small.
  713. //
  714. if (dwUserNameLen > sizeof(szShortUserName) / sizeof(WCHAR))
  715. {
  716. //
  717. // Allocate a buffer for the user name.
  718. //
  719. szLongUserName = new (std::nothrow) WCHAR[dwUserNameLen];
  720. if (!szLongUserName)
  721. {
  722. DebugPrintEx(
  723. DEBUG_ERR,
  724. TEXT("Failed to allocate user name buffer (%d bytes)"),
  725. dwUserNameLen);
  726. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  727. goto exit;
  728. }
  729. //
  730. // Update szUserName to point to longer buffers
  731. //
  732. szUserName = szLongUserName;
  733. }
  734. if (dwDomainNameLen > sizeof(szShortDomainName) / sizeof(WCHAR))
  735. {
  736. //
  737. // Allocate a buffer for the domain name.
  738. //
  739. szLongDomainName = new (std::nothrow) WCHAR[dwDomainNameLen];
  740. if (!szLongDomainName)
  741. {
  742. DebugPrintEx(
  743. DEBUG_ERR,
  744. TEXT("Failed to allocate domain name buffer (%d bytes)"),
  745. dwDomainNameLen);
  746. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  747. goto exit;
  748. }
  749. //
  750. // Update szDomainName to point to longer buffers
  751. //
  752. szDomainName = szLongDomainName;
  753. }
  754. }
  755. else
  756. {
  757. DebugPrintEx(
  758. DEBUG_ERR,
  759. TEXT("LookupAccountSid(1) failed. (ec: %ld)"),
  760. dwRes);
  761. goto exit;
  762. }
  763. //
  764. // Try now with larger buffers.
  765. //
  766. if (!LookupAccountSid(NULL,
  767. pUserSid,
  768. szUserName,
  769. &dwUserNameLen,
  770. szDomainName,
  771. &dwDomainNameLen,
  772. &SidNameUse))
  773. {
  774. dwRes = GetLastError();
  775. DebugPrintEx(
  776. DEBUG_ERR,
  777. TEXT("LookupAccountSid(2) failed. (ec: %ld)"),
  778. dwRes);
  779. goto exit;
  780. }
  781. }
  782. //
  783. // Allocate a buffer for the combined string - domain\user
  784. //
  785. dwUserNameLen = wcslen(szUserName);
  786. dwDomainNameLen = wcslen(szDomainName);
  787. lpwstrUserName = (LPWSTR)MemAlloc(sizeof(WCHAR) * (dwUserNameLen + dwDomainNameLen + 2));
  788. if (!lpwstrUserName)
  789. {
  790. DebugPrintEx(
  791. DEBUG_ERR,
  792. TEXT("Failed to allocate user and domain name buffer (%d bytes)"),
  793. sizeof(WCHAR) * (dwUserNameLen + dwDomainNameLen + 2));
  794. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  795. goto exit;
  796. }
  797. //
  798. // Construct the combined string
  799. //
  800. memcpy(lpwstrUserName,
  801. szDomainName,
  802. sizeof(WCHAR) * dwDomainNameLen);
  803. lpwstrUserName[dwDomainNameLen] = L'\\';
  804. memcpy(lpwstrUserName + dwDomainNameLen + 1,
  805. szUserName,
  806. sizeof(WCHAR) * (dwUserNameLen + 1));
  807. exit:
  808. DWORD dwErr = RpcRevertToSelf();
  809. if (RPC_S_OK != dwErr)
  810. {
  811. DebugPrintEx(
  812. DEBUG_ERR,
  813. TEXT("RpcRevertToSelf() failed. (ec: %ld)"),
  814. dwRes);
  815. Assert(dwErr == RPC_S_OK); // Assert(FALSE)
  816. }
  817. if (NULL != szLongUserName)
  818. {
  819. delete[] szLongUserName;
  820. }
  821. if (NULL != szLongDomainName)
  822. {
  823. delete[] szLongDomainName;
  824. }
  825. if (hToken)
  826. {
  827. CloseHandle(hToken);
  828. }
  829. if (dwRes != ERROR_SUCCESS)
  830. {
  831. Assert (NULL == lpwstrUserName);
  832. SetLastError (dwRes);
  833. }
  834. return lpwstrUserName;
  835. }
  836. error_status_t
  837. FAX_SetSecurity (
  838. IN handle_t hFaxHandle,
  839. IN SECURITY_INFORMATION SecurityInformation,
  840. IN const LPBYTE lpBuffer,
  841. IN DWORD dwBufferSize
  842. )
  843. /*++
  844. Routine name : FAX_SetSecurity
  845. Routine description:
  846. RPC implementation of FaxSetSecurity
  847. Author:
  848. Eran Yariv (EranY), Nov, 1999
  849. Arguments:
  850. hFaxHandle [in] - Unused
  851. SecurityInformation [in] - Defines the valid entries in the security descriptor (Bit wise OR )
  852. lpBuffer [in] - Pointer to new security descriptor
  853. dwBufferSize [in] - Buffer size
  854. Return Value:
  855. Standard RPC error codes
  856. --*/
  857. {
  858. DWORD rVal = ERROR_SUCCESS;
  859. DWORD rVal2;
  860. BOOL fAccess;
  861. ACCESS_MASK AccessMask = 0;
  862. HANDLE hClientToken = NULL;
  863. DEBUG_FUNCTION_NAME(TEXT("FAX_SetSecurity"));
  864. Assert (g_pFaxSD);
  865. Assert (IsValidSecurityDescriptor(g_pFaxSD));
  866. if (!lpBuffer || !dwBufferSize)
  867. {
  868. DebugPrintEx(
  869. DEBUG_ERR,
  870. TEXT("'Error Null buffer"));
  871. return ERROR_INVALID_PARAMETER;
  872. }
  873. //
  874. // Must validate the RPC blob before calling IsValidSecurityDescriptor();
  875. //
  876. if (!RtlValidRelativeSecurityDescriptor( (PSECURITY_DESCRIPTOR)lpBuffer,
  877. dwBufferSize,
  878. SecurityInformation))
  879. {
  880. DebugPrintEx(
  881. DEBUG_ERR,
  882. TEXT("RtlValidRelativeSecurityDescriptor failed"));
  883. return ERROR_INVALID_DATA;
  884. }
  885. //
  886. // Access check
  887. //
  888. if (SecurityInformation & OWNER_SECURITY_INFORMATION)
  889. {
  890. AccessMask |= WRITE_OWNER;
  891. }
  892. if (SecurityInformation & (GROUP_SECURITY_INFORMATION |
  893. DACL_SECURITY_INFORMATION) )
  894. {
  895. AccessMask |= WRITE_DAC;
  896. }
  897. if (SecurityInformation & SACL_SECURITY_INFORMATION)
  898. {
  899. AccessMask |= ACCESS_SYSTEM_SECURITY;
  900. }
  901. //
  902. // Block other threads from changing the SD
  903. //
  904. EnterCriticalSection (&g_CsSecurity);
  905. rVal = FaxSvcAccessCheck (AccessMask, &fAccess, NULL);
  906. if (ERROR_SUCCESS != rVal)
  907. {
  908. DebugPrintEx(DEBUG_ERR,
  909. TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
  910. rVal);
  911. goto exit;
  912. }
  913. if (FALSE == fAccess)
  914. {
  915. DebugPrintEx(DEBUG_ERR,
  916. TEXT("The user does not have the needed rights to change the security descriptor"));
  917. rVal = ERROR_ACCESS_DENIED;
  918. goto exit;
  919. }
  920. //
  921. // Get the calling client access token
  922. //
  923. // Impersonate the user.
  924. //
  925. rVal = RpcImpersonateClient(NULL);
  926. if (rVal != RPC_S_OK)
  927. {
  928. DebugPrintEx(
  929. DEBUG_ERR,
  930. TEXT("RpcImpersonateClient(NULL) failed. (ec: %ld)"),
  931. rVal);
  932. goto exit;
  933. }
  934. //
  935. // Open the thread token. We're in an RPC thread, not the main thread.
  936. //
  937. if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hClientToken))
  938. {
  939. rVal = GetLastError();
  940. DebugPrintEx(
  941. DEBUG_ERR,
  942. TEXT("OpenThreadToken failed. (ec: %ld)"),
  943. rVal);
  944. DWORD dwErr = RpcRevertToSelf();
  945. if (RPC_S_OK != dwErr)
  946. {
  947. DebugPrintEx(
  948. DEBUG_ERR,
  949. TEXT("RpcRevertToSelf() failed. (ec: %ld)"),
  950. dwErr);
  951. }
  952. goto exit;
  953. }
  954. //
  955. // The calling process (SetPrivateObjectSecurity()) must not impersonate the client
  956. //
  957. rVal = RpcRevertToSelf();
  958. if (RPC_S_OK != rVal)
  959. {
  960. DebugPrintEx(
  961. DEBUG_ERR,
  962. TEXT("RpcRevertToSelf() failed. (ec: %ld)"),
  963. rVal);
  964. goto exit;
  965. }
  966. //
  967. // Get a new (Mereged) Fax service private object SD
  968. //
  969. if (!SetPrivateObjectSecurity ( SecurityInformation,
  970. (PSECURITY_DESCRIPTOR)lpBuffer,
  971. &g_pFaxSD,
  972. const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping),
  973. hClientToken))
  974. {
  975. rVal = GetLastError();
  976. DebugPrintEx(
  977. DEBUG_ERR,
  978. TEXT("SetPrivateObjectSecurity failed. (ec: %ld)"),
  979. rVal);
  980. goto exit;
  981. }
  982. Assert (IsValidSecurityDescriptor(g_pFaxSD));
  983. //
  984. // Save the new SD
  985. //
  986. rVal = SaveSecurityDescriptor(g_pFaxSD);
  987. if (rVal != ERROR_SUCCESS)
  988. {
  989. DebugPrintEx(
  990. DEBUG_ERR,
  991. TEXT("Error in SaveSecurityDescriptor (%ld)"),
  992. rVal);
  993. rVal = ERROR_REGISTRY_CORRUPT;
  994. goto exit;
  995. }
  996. rVal2 = CreateConfigEvent (FAX_CONFIG_TYPE_SECURITY);
  997. if (ERROR_SUCCESS != rVal2)
  998. {
  999. DebugPrintEx(
  1000. DEBUG_ERR,
  1001. TEXT("CreateConfigEvent(FAX_CONFIG_TYPE_SECURITY) (ec: %lc)"),
  1002. rVal2);
  1003. }
  1004. Assert (ERROR_SUCCESS == rVal);
  1005. exit:
  1006. LeaveCriticalSection (&g_CsSecurity);
  1007. if (NULL != hClientToken)
  1008. {
  1009. if (!CloseHandle(hClientToken))
  1010. {
  1011. DebugPrintEx(
  1012. DEBUG_ERR,
  1013. TEXT("CloseHandle() failed. (ec: %ld)"),
  1014. GetLastError());
  1015. }
  1016. }
  1017. return GetServerErrorCode(rVal);
  1018. UNREFERENCED_PARAMETER (hFaxHandle);
  1019. } // FAX_SetSecurity
  1020. error_status_t
  1021. FAX_GetSecurityEx(
  1022. IN handle_t hFaxHandle,
  1023. IN SECURITY_INFORMATION SecurityInformation,
  1024. OUT LPBYTE *lpBuffer,
  1025. OUT LPDWORD lpdwBufferSize
  1026. )
  1027. /*++
  1028. Routine Description:
  1029. Retrieves the FAX security descriptor from the FAX server.
  1030. Arguments:
  1031. hFaxHandle - FAX handle obtained from FaxConnectFaxServer.
  1032. SecurityInformation - Defines the desired entries in the security descriptor (Bit wise OR )
  1033. lpBuffer - Pointer to a SECURITY_DESCRIPTOR structure.
  1034. lpdwBufferSize - Size of lpBuffer
  1035. Return Value:
  1036. TRUE - Success
  1037. FALSE - Failure, call GetLastError() for more error information.
  1038. --*/
  1039. {
  1040. error_status_t rVal = ERROR_SUCCESS;
  1041. DWORD dwDescLength = 0;
  1042. DEBUG_FUNCTION_NAME(TEXT("FAX_GetSecurityEx"));
  1043. BOOL fAccess;
  1044. ACCESS_MASK AccessMask = 0;
  1045. PSECURITY_DESCRIPTOR pSDPrivateObject = NULL;
  1046. Assert (g_pFaxSD);
  1047. Assert (IsValidSecurityDescriptor(g_pFaxSD));
  1048. Assert (lpdwBufferSize); // ref pointer in idl
  1049. if (!lpBuffer) // unique pointer in idl
  1050. {
  1051. return ERROR_INVALID_PARAMETER;
  1052. }
  1053. *lpBuffer = NULL;
  1054. *lpdwBufferSize = 0;
  1055. //
  1056. // Block other threads from changing the SD
  1057. //
  1058. EnterCriticalSection (&g_CsSecurity);
  1059. //
  1060. // Access check
  1061. //
  1062. if (SecurityInformation & (GROUP_SECURITY_INFORMATION |
  1063. DACL_SECURITY_INFORMATION |
  1064. OWNER_SECURITY_INFORMATION) )
  1065. {
  1066. AccessMask |= READ_CONTROL;
  1067. }
  1068. if (SecurityInformation & SACL_SECURITY_INFORMATION)
  1069. {
  1070. AccessMask |= ACCESS_SYSTEM_SECURITY;
  1071. }
  1072. rVal = FaxSvcAccessCheck (AccessMask, &fAccess, NULL);
  1073. if (ERROR_SUCCESS != rVal)
  1074. {
  1075. DebugPrintEx(DEBUG_ERR,
  1076. TEXT("FaxSvcAccessCheck Failed, Error : %ld"),
  1077. rVal);
  1078. goto exit;
  1079. }
  1080. if (FALSE == fAccess)
  1081. {
  1082. DebugPrintEx(DEBUG_ERR,
  1083. TEXT("The user does not have the READ_CONTROL or ACCESS_SYSTEM_SECURITY"));
  1084. rVal = ERROR_ACCESS_DENIED;;
  1085. goto exit;
  1086. }
  1087. if (!IsValidSecurityDescriptor( g_pFaxSD ))
  1088. {
  1089. rVal = ERROR_INVALID_SECURITY_DESCR;
  1090. DebugPrintEx(
  1091. DEBUG_ERR,
  1092. TEXT("IsValidSecurityDescriptor() failed. Got invalid SD"));
  1093. ASSERT_FALSE;
  1094. goto exit;
  1095. }
  1096. //
  1097. // Get the required buffer size
  1098. //
  1099. GetPrivateObjectSecurity( g_pFaxSD, // SD
  1100. SecurityInformation, // requested info type
  1101. NULL, // requested SD info
  1102. 0, // size of SD buffer
  1103. &dwDescLength // required buffer size
  1104. );
  1105. //
  1106. // Allocate returned security descriptor buffer
  1107. //
  1108. Assert(dwDescLength);
  1109. *lpBuffer = (LPBYTE)MemAlloc(dwDescLength);
  1110. if (NULL == *lpBuffer)
  1111. {
  1112. rVal = ERROR_NOT_ENOUGH_MEMORY;
  1113. DebugPrintEx(
  1114. DEBUG_ERR,
  1115. TEXT("Failed to allocate SD"));
  1116. goto exit;
  1117. }
  1118. if (!GetPrivateObjectSecurity( g_pFaxSD, // SD
  1119. SecurityInformation, // requested info type
  1120. (PSECURITY_DESCRIPTOR)*lpBuffer, // requested SD info
  1121. dwDescLength, // size of SD buffer
  1122. &dwDescLength // required buffer size
  1123. ))
  1124. {
  1125. rVal = GetLastError();
  1126. DebugPrintEx(
  1127. DEBUG_ERR,
  1128. TEXT("GetPrivateObjectSecurity() failed. (ec: %ld)"),
  1129. rVal);
  1130. goto exit;
  1131. }
  1132. *lpdwBufferSize = dwDescLength;
  1133. Assert (ERROR_SUCCESS == rVal);
  1134. exit:
  1135. LeaveCriticalSection (&g_CsSecurity);
  1136. if (ERROR_SUCCESS != rVal)
  1137. {
  1138. MemFree (*lpBuffer);
  1139. *lpBuffer = NULL;
  1140. *lpdwBufferSize = 0;
  1141. }
  1142. return GetServerErrorCode(rVal);
  1143. UNREFERENCED_PARAMETER (hFaxHandle);
  1144. } // FAX_GetSecurityEx
  1145. error_status_t
  1146. FAX_GetSecurity(
  1147. IN handle_t hFaxHandle,
  1148. OUT LPBYTE *lpBuffer,
  1149. OUT LPDWORD lpdwBufferSize
  1150. )
  1151. /*++
  1152. Routine Description:
  1153. Retrieves the FAX security descriptor from the FAX server.
  1154. Arguments:
  1155. hFaxHandle - FAX handle obtained from FaxConnectFaxServer.
  1156. lpBuffer - Pointer to a SECURITY_DESCRIPTOR structure.
  1157. lpdwBufferSize - Size of lpBuffer
  1158. Return Value:
  1159. TRUE - Success
  1160. FALSE - Failure, call GetLastError() for more error information.
  1161. --*/
  1162. {
  1163. error_status_t rVal = ERROR_SUCCESS;
  1164. DEBUG_FUNCTION_NAME(TEXT("FAX_GetSecurity"));
  1165. rVal = FAX_GetSecurityEx (hFaxHandle,
  1166. DACL_SECURITY_INFORMATION | // Read DACL
  1167. GROUP_SECURITY_INFORMATION | // Read group
  1168. OWNER_SECURITY_INFORMATION | // Read owner
  1169. SACL_SECURITY_INFORMATION, // Read SACL
  1170. lpBuffer,
  1171. lpdwBufferSize);
  1172. if (ERROR_ACCESS_DENIED == rVal)
  1173. {
  1174. //
  1175. // Let's try without the SACL
  1176. //
  1177. rVal = FAX_GetSecurityEx (hFaxHandle,
  1178. DACL_SECURITY_INFORMATION | // Read DACL
  1179. GROUP_SECURITY_INFORMATION | // Read group
  1180. OWNER_SECURITY_INFORMATION, // Read owner
  1181. lpBuffer,
  1182. lpdwBufferSize);
  1183. }
  1184. return rVal;
  1185. } // FAX_GetSecurity
  1186. error_status_t
  1187. FAX_AccessCheck(
  1188. IN handle_t hBinding,
  1189. IN DWORD dwAccessMask,
  1190. OUT BOOL* pfAccess,
  1191. OUT LPDWORD lpdwRights
  1192. )
  1193. /*++
  1194. Routine name : FAX_AccessCheck
  1195. Routine description:
  1196. Performs an access check against the fax service security descriptor
  1197. Author:
  1198. Oded Sacher (OdedS), Feb, 2000
  1199. Arguments:
  1200. hBinding [in ] - Handle to the Fax Server obtained from FaxConnectFaxServer()
  1201. dwAccessMask [in ] - Desired access
  1202. pfAccess [out] - Address of a BOOL to receive the access check return value (TRUE - access allowed).
  1203. lpdwRights [out] - Optional, Address of a DWORD to receive the access rights bit wise OR.
  1204. To get the access rights, set dwAccessMask to MAXIMUM_ALLOWED
  1205. Return Value:
  1206. Standard Win32 error code.
  1207. --*/
  1208. {
  1209. error_status_t Rval = ERROR_SUCCESS;
  1210. DEBUG_FUNCTION_NAME(TEXT("FAX_AccessCheck"));
  1211. if (!pfAccess)
  1212. {
  1213. DebugPrintEx(
  1214. DEBUG_ERR,
  1215. TEXT("fAccess is NULL "));
  1216. return ERROR_INVALID_PARAMETER;
  1217. }
  1218. Rval = FaxSvcAccessCheck (dwAccessMask, pfAccess, lpdwRights);
  1219. if (ERROR_SUCCESS != Rval)
  1220. {
  1221. DebugPrintEx(
  1222. DEBUG_ERR,
  1223. TEXT("FaxSvcAccessCheck failed with error (%ld)"),
  1224. Rval);
  1225. }
  1226. return GetServerErrorCode(Rval);
  1227. } // FAX_AccessCheck
  1228. //*********************************************************************************
  1229. //* Name:GetClientUserSID()
  1230. //* Author: Oded Sacher
  1231. //* Date: Oct 26, 1999
  1232. //*********************************************************************************
  1233. //* DESCRIPTION:
  1234. //* Returns the SID of the connected RPC client.
  1235. //* PARAMETERS:
  1236. //* None.
  1237. //* RETURN VALUE:
  1238. //* A pointer to a newly allocated SID buffer.
  1239. //* The caller must free this buffer using MemFree().
  1240. //* Returns NULL if an error occures.
  1241. //* To get extended error information, call GetLastError.
  1242. //*********************************************************************************
  1243. PSID
  1244. GetClientUserSID(
  1245. VOID
  1246. )
  1247. {
  1248. RPC_STATUS dwRes;
  1249. PSID pUserSid;
  1250. DEBUG_FUNCTION_NAME(TEXT("GetClientUserSID"));
  1251. //
  1252. // Impersonate the user.
  1253. //
  1254. dwRes=RpcImpersonateClient(NULL);
  1255. if (dwRes != RPC_S_OK)
  1256. {
  1257. DebugPrintEx(
  1258. DEBUG_ERR,
  1259. TEXT("RpcImpersonateClient(NULL) failed. (ec: %ld)"),
  1260. dwRes);
  1261. SetLastError( dwRes);
  1262. return NULL;
  1263. }
  1264. //
  1265. // Get SID of (impersonated) thread
  1266. //
  1267. pUserSid = GetCurrentThreadSID ();
  1268. if (!pUserSid)
  1269. {
  1270. dwRes = GetLastError ();
  1271. DebugPrintEx(
  1272. DEBUG_ERR,
  1273. TEXT("GetCurrentThreadSID failed. (ec: %ld)"),
  1274. dwRes);
  1275. }
  1276. dwRes = RpcRevertToSelf();
  1277. if (RPC_S_OK != dwRes)
  1278. {
  1279. DebugPrintEx(
  1280. DEBUG_ERR,
  1281. TEXT("RpcRevertToSelf() failed. (ec: %ld)"),
  1282. dwRes);
  1283. ASSERT_FALSE;
  1284. //
  1285. // Free SID (if exists)
  1286. MemFree (pUserSid);
  1287. SetLastError (dwRes);
  1288. return NULL;
  1289. }
  1290. return pUserSid;
  1291. }