Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

473 lines
15 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1996.
  5. //
  6. // File: service.cxx
  7. //
  8. // Contents: Service support functions
  9. //
  10. // History: 8/94 davemont Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <aclpch.hxx>
  14. #pragma hdrstop
  15. //+---------------------------------------------------------------------------
  16. //
  17. // Function: OpenServiceObject
  18. //
  19. // Synopsis: Opens the specified service object
  20. //
  21. // Arguments: [IN pwszService] -- The name of the service to
  22. // open
  23. // [IN AccessMask] -- Flags indicating if the object
  24. // is to be opened to read or write
  25. // the DACL
  26. // [OUT pHandle] -- Where the open handle is
  27. // returned
  28. //
  29. // Returns: ERROR_SUCCESS -- Success
  30. // ERROR_NOT_ENOUGH_MEMORY -- A memory allocation failed
  31. // ERROR_INVALID_PARAMETER -- A bad name was given
  32. //
  33. //----------------------------------------------------------------------------
  34. DWORD
  35. OpenServiceObject(IN LPWSTR pwszService,
  36. IN ACCESS_MASK AccessMask,
  37. OUT SC_HANDLE *pHandle)
  38. {
  39. acDebugOut((DEB_TRACE, "in OpenServiceObject \n"));
  40. DWORD dwErr;
  41. //
  42. // Make sure the service functions are loaded
  43. //
  44. dwErr = LoadDLLFuncTable();
  45. if(dwErr != ERROR_SUCCESS)
  46. {
  47. return(dwErr);
  48. }
  49. if(pwszService != NULL)
  50. {
  51. WCHAR wszName[MAX_PATH + 1];
  52. PWSTR pwszName;
  53. //
  54. // save the object since we must crack it to go to remote machines
  55. //
  56. dwErr = AccGetBufferOfSizeW(pwszService,
  57. wszName,
  58. &pwszName);
  59. if(dwErr == ERROR_SUCCESS)
  60. {
  61. PWSTR pwszSvcName, pwszMachine;
  62. //
  63. // Separate the names
  64. //
  65. dwErr = ParseName(pwszName,
  66. &pwszMachine,
  67. &pwszSvcName);
  68. //
  69. // Go ahead and open the service control manager
  70. //
  71. if(dwErr == ERROR_SUCCESS)
  72. {
  73. SC_HANDLE hSC = OpenSCManager(pwszMachine,
  74. NULL,
  75. GENERIC_READ);
  76. if(hSC == NULL)
  77. {
  78. dwErr = GetLastError();
  79. }
  80. else
  81. {
  82. //
  83. // Open the service
  84. //
  85. *pHandle = OpenService(hSC,
  86. pwszSvcName,
  87. AccessMask);
  88. if(*pHandle == NULL)
  89. {
  90. dwErr = GetLastError();
  91. }
  92. //
  93. // Close the handle to the scm
  94. //
  95. CloseServiceHandle(hSC);
  96. }
  97. }
  98. //
  99. // Free our buffer
  100. //
  101. AccFreeBufferOfSizeW(wszName, pwszName);
  102. }
  103. }
  104. else
  105. {
  106. dwErr = ERROR_INVALID_PARAMETER;
  107. }
  108. acDebugOut((DEB_TRACE, "Out OpenServiceObject: %lu\n", dwErr));
  109. return(dwErr);
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Function: ReadServicePropertyRights
  114. //
  115. // Synopsis: Gets the specified security info for the specified service
  116. // object
  117. //
  118. // Arguments: [IN pwszService] -- The service to get the rights
  119. // for
  120. // [IN pRightsList] -- SecurityInfo to read based
  121. // on properties
  122. // [IN cRights] -- Number of items in rights list
  123. // [IN AccessList] -- Access List to fill in
  124. //
  125. // Returns: ERROR_SUCCESS -- Success
  126. // ERROR_INVALID_PARAMETER -- A bad property was encountered
  127. // ERROR_NOT_ENOUGH_MEMORY -- A memory allocation failed
  128. //
  129. //----------------------------------------------------------------------------
  130. DWORD
  131. ReadServicePropertyRights(IN LPWSTR pwszService,
  132. IN PACTRL_RIGHTS_INFO pRightsList,
  133. IN ULONG cRights,
  134. IN CAccessList& AccessList)
  135. {
  136. acDebugOut((DEB_TRACE, "in ReadServicePropertyRights\n"));
  137. DWORD dwErr = ERROR_SUCCESS;
  138. SC_HANDLE hSvc;
  139. //
  140. // For the moment, there is only service property itself...
  141. //
  142. ASSERT(cRights == 1 && pRightsList[0].pwszProperty == NULL);
  143. if(cRights != 1 || pRightsList[0].pwszProperty != NULL)
  144. {
  145. return(ERROR_INVALID_PARAMETER);
  146. }
  147. //
  148. // Open the service
  149. //
  150. dwErr = OpenServiceObject(pwszService,
  151. GetDesiredAccess(READ_ACCESS_RIGHTS,
  152. pRightsList[0].SeInfo),
  153. &hSvc);
  154. if(dwErr == ERROR_SUCCESS)
  155. {
  156. dwErr = ReadServiceRights(hSvc,
  157. pRightsList,
  158. cRights,
  159. AccessList);
  160. //
  161. // Close the object handle
  162. //
  163. CloseServiceHandle(hSvc);
  164. }
  165. acDebugOut((DEB_TRACE, "Out ReadServicePropertyRights: %lu\n", dwErr));
  166. return(dwErr);
  167. }
  168. //+---------------------------------------------------------------------------
  169. //
  170. // Function: ReadServiceRights
  171. //
  172. // Synopsis: Gets the specified security info for the specified service
  173. // object
  174. //
  175. // Arguments: [IN hSvc] -- Handle to the open service
  176. // [IN pRightsList] -- SecurityInfo to read based
  177. // on properties
  178. // [IN cRights] -- Number of items in rights list
  179. // [IN AccessList] -- Access List to fill in
  180. //
  181. // Returns: ERROR_SUCCESS -- Success
  182. // ERROR_INVALID_PARAMETER -- A bad property was encountered
  183. // ERROR_NOT_ENOUGH_MEMORY -- A memory allocation failed
  184. //
  185. //----------------------------------------------------------------------------
  186. DWORD
  187. ReadServiceRights(IN SC_HANDLE hSvc,
  188. IN PACTRL_RIGHTS_INFO pRightsList,
  189. IN ULONG cRights,
  190. IN CAccessList& AccessList)
  191. {
  192. acDebugOut((DEB_TRACE, "in ReadServiceRights\n"));
  193. DWORD dwErr = ERROR_SUCCESS;
  194. //
  195. // For the moment, there is only service property itself...
  196. //
  197. ASSERT(cRights == 1 && pRightsList[0].pwszProperty == NULL);
  198. if(cRights != 1 || pRightsList[0].pwszProperty != NULL)
  199. {
  200. return(ERROR_INVALID_PARAMETER);
  201. }
  202. //
  203. // Get the service security...
  204. //
  205. UCHAR SDBuff[PSD_BASE_LENGTH];
  206. PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SDBuff;
  207. ULONG cSize = 0;
  208. //
  209. // Get the size of the security descriptor from the service
  210. //
  211. if(QueryServiceObjectSecurity(hSvc,
  212. pRightsList[0].SeInfo,
  213. pSD,
  214. PSD_BASE_LENGTH,
  215. &cSize) == FALSE)
  216. {
  217. dwErr = GetLastError();
  218. if(dwErr == ERROR_INSUFFICIENT_BUFFER)
  219. {
  220. dwErr = ERROR_SUCCESS;
  221. pSD = (PISECURITY_DESCRIPTOR)AccAlloc(cSize);
  222. if(pSD == NULL)
  223. {
  224. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  225. }
  226. else
  227. {
  228. if(QueryServiceObjectSecurity(hSvc,
  229. pRightsList[0].SeInfo,
  230. pSD,
  231. cSize,
  232. &cSize) == FALSE)
  233. {
  234. dwErr = GetLastError();
  235. }
  236. }
  237. }
  238. }
  239. //
  240. // If all that worked, we'll add our SD
  241. //
  242. if(dwErr == ERROR_SUCCESS)
  243. {
  244. dwErr = AccessList.AddSD(pSD,
  245. pRightsList->SeInfo,
  246. pRightsList->pwszProperty);
  247. }
  248. //
  249. // Free our memory if we allocated...
  250. //
  251. if(cSize > PSD_BASE_LENGTH)
  252. {
  253. AccFree(pSD);
  254. }
  255. acDebugOut((DEB_TRACE, "Out ReadServiceRights: %lu\n", dwErr));
  256. return(dwErr);
  257. }
  258. //+---------------------------------------------------------------------------
  259. //
  260. // Function: GetServiceParentRights
  261. //
  262. // Synopsis: Determines who the parent is, and gets the access rights
  263. // for it. It is used to aid in determining what the approriate
  264. // inheritance bits are.
  265. //
  266. // This operation does not make sense for kernel objects
  267. //
  268. // Arguments: [IN pwszService] -- The service to get the parent
  269. // for
  270. // [IN pRightsList] -- The properties to get the
  271. // rights for
  272. // [IN cRights] -- Number of items in rights list
  273. // [OUT ppDAcl] -- Where the DACL is returned
  274. // [OUT ppSAcl] -- Where the SACL is returned
  275. // [OUT ppSD] -- Where the Security Descriptor
  276. // is returned
  277. //
  278. // Returns: ERROR_INVALID_FUNCTION -- Call doesn't make sense here
  279. //
  280. //----------------------------------------------------------------------------
  281. DWORD
  282. GetServiceParentRights(IN LPWSTR pwszService,
  283. IN PACTRL_RIGHTS_INFO pRightsList,
  284. IN ULONG cRights,
  285. OUT PACL *ppDAcl,
  286. OUT PACL *ppSAcl,
  287. OUT PSECURITY_DESCRIPTOR *ppSD)
  288. {
  289. //
  290. // This doesn't currently make sense for kernel objects, so simply
  291. // return an error
  292. //
  293. return(ERROR_INVALID_FUNCTION);
  294. }
  295. //+---------------------------------------------------------------------------
  296. //
  297. // Function: SetServiceSecurityInfo
  298. //
  299. // Synopsis: Sets the specified security info on the specified service
  300. // object
  301. //
  302. // Arguments: [IN hService] -- The handle of the object
  303. // [IN SeInfo] -- Flag indicating what security
  304. // info to set
  305. // [IN pwszProperty] -- The property on the object to
  306. // set
  307. // For kernel objects, this MBZ
  308. // [IN pSD] -- The security descriptor to set
  309. //
  310. // Returns: ERROR_SUCCESS -- Success
  311. // ERROR_INVALID_PARAMETER -- A bad property was given
  312. //
  313. //----------------------------------------------------------------------------
  314. DWORD
  315. SetServiceSecurityInfo(IN SC_HANDLE hService,
  316. IN SECURITY_INFORMATION SeInfo,
  317. IN PWSTR pwszProperty,
  318. IN PSECURITY_DESCRIPTOR pSD)
  319. {
  320. acDebugOut((DEB_TRACE, "in SetServiceSecurityInfo\n"));
  321. DWORD dwErr = ERROR_SUCCESS;
  322. //
  323. // Service don't have properties
  324. //
  325. if(pwszProperty != NULL)
  326. {
  327. dwErr = ERROR_INVALID_PARAMETER;
  328. }
  329. else
  330. {
  331. if(FLAG_ON(SeInfo, DACL_SECURITY_INFORMATION)) {
  332. ((PISECURITY_DESCRIPTOR)pSD)->Control |= SE_DACL_AUTO_INHERIT_REQ;
  333. }
  334. if(FLAG_ON(SeInfo, SACL_SECURITY_INFORMATION)) {
  335. ((PISECURITY_DESCRIPTOR)pSD)->Control |= SE_SACL_AUTO_INHERIT_REQ;
  336. }
  337. //
  338. // set the security descriptor on the service
  339. //
  340. if(SetServiceObjectSecurity(hService,
  341. SeInfo,
  342. pSD) == FALSE)
  343. {
  344. dwErr = GetLastError();
  345. }
  346. }
  347. acDebugOut((DEB_TRACE, "Out SetServiceSecurityInfo: %lu\n", dwErr));
  348. return(dwErr);
  349. }
  350. #if 0
  351. //+---------------------------------------------------------------------------
  352. //
  353. // Function : GetServiceAccessMaskFromProviderIndependentRights
  354. //
  355. // Synopsis : translates the specified provider independent access rights into
  356. // an access mask for a service
  357. //
  358. // Arguments: IN [AccessRights] - the input access rights
  359. // OUT [AccessMask] - the returned NT access mask
  360. //
  361. //----------------------------------------------------------------------------
  362. void GetServiceAccessMaskFromProviderIndependentRights(ULONG AccessRights,
  363. ACCESS_MASK *AccessMask)
  364. {
  365. if (PROV_OBJECT_READ & AccessRights)
  366. {
  367. *AccessMask |= SERVICE_READ;
  368. }
  369. if (PROV_OBJECT_WRITE & AccessRights)
  370. {
  371. *AccessMask |= SERVICE_WRITE;
  372. }
  373. if (PROV_OBJECT_EXECUTE & AccessRights)
  374. {
  375. *AccessMask |= SERVICE_EXECUTE;
  376. }
  377. }
  378. //+---------------------------------------------------------------------------
  379. //
  380. // Function : GetServiceProviderIndependentRightsFromAccessMask
  381. //
  382. // Synopsis : translates a service access mask into provider independent
  383. // access rights
  384. //
  385. // Arguments: IN OUT [AccessMask] - the input NT access mask (modified)
  386. // OUT [AccessRights] - the returned access rights
  387. //
  388. //----------------------------------------------------------------------------
  389. ACCESS_RIGHTS GetServiceProviderIndependentRightsFromAccessMask( ACCESS_MASK AccessMask)
  390. {
  391. ACCESS_RIGHTS accessrights = 0;
  392. if (GENERIC_ALL & AccessMask)
  393. {
  394. accessrights = PROV_ALL_ACCESS;
  395. } else
  396. {
  397. if (KEY_ALL_ACCESS == (KEY_ALL_ACCESS & AccessMask))
  398. {
  399. accessrights = PROV_ALL_ACCESS;
  400. } else
  401. {
  402. if (WRITE_DAC & AccessMask)
  403. {
  404. accessrights |= PROV_EDIT_ACCESSRIGHTS;
  405. }
  406. if (SERVICE_READ == (SERVICE_READ & AccessMask))
  407. {
  408. accessrights |= PROV_OBJECT_READ;
  409. }
  410. if (SERVICE_WRITE == (SERVICE_WRITE & AccessMask))
  411. {
  412. accessrights |= PROV_OBJECT_WRITE;
  413. }
  414. if (SERVICE_EXECUTE == (SERVICE_EXECUTE & AccessMask) )
  415. {
  416. accessrights |= PROV_OBJECT_EXECUTE;
  417. }
  418. }
  419. }
  420. return(accessrights);
  421. }
  422. #endif