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.

741 lines
17 KiB

  1. /*++
  2. Copyright (c) 1996, 1997 Microsoft Corporation
  3. Module Name:
  4. config.cpp
  5. Abstract:
  6. This module contains routines to perform configuration data item management
  7. in the protected store.
  8. Author:
  9. Scott Field (sfield) 28-Mar-97
  10. --*/
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. //
  14. // these are temporary until better home is found.
  15. //
  16. extern PST_PROVIDERID g_guidBaseProvider;
  17. extern CALL_STATE g_sDummyCallState;
  18. extern PLIST_ITEM g_psDummyListItem;
  19. BOOL
  20. AllocatePseudoUniqueHandle(
  21. PST_PROVIDER_HANDLE *phPSTProv
  22. );
  23. BOOL
  24. FAcquireProvider(
  25. PST_PROVIDERID* pProviderID
  26. );
  27. BOOL
  28. CreateDummyUserContext(
  29. IN PST_PROVIDER_HANDLE *hPSTProv,
  30. IN CALL_STATE *pNewContext
  31. );
  32. BOOL
  33. DeleteDummyUserContext(
  34. IN CALL_STATE *pNewContext
  35. );
  36. //
  37. // ... end of temporary section.
  38. //
  39. LPVOID
  40. RulesAlloc(
  41. IN DWORD cb
  42. )
  43. {
  44. return SSAlloc( cb );
  45. }
  46. VOID
  47. RulesFree(
  48. IN LPVOID pv
  49. )
  50. {
  51. SSFree( pv );
  52. }
  53. BOOL
  54. FGetConfigurationData(
  55. IN PST_PROVIDER_HANDLE *hPSTProv,
  56. IN PST_KEY KeyLocation,
  57. IN GUID *pguidSubtype,
  58. IN LPCWSTR szItemName,
  59. OUT BYTE **ppbData,
  60. OUT DWORD *pcbData
  61. )
  62. {
  63. PST_PROVIDER_HANDLE *phNewPSTProv = NULL;
  64. CALL_STATE NewContext;
  65. BOOL fDummyContext = FALSE;
  66. BOOL fSuccess = FALSE;
  67. HRESULT hr;
  68. if(KeyLocation != PST_KEY_CURRENT_USER && KeyLocation != PST_KEY_LOCAL_MACHINE) {
  69. SetLastError(ERROR_INVALID_PARAMETER);
  70. return FALSE;
  71. }
  72. //
  73. // Hard case is PST_KEY_CURRENT_USER. Prepare user context for that
  74. // scenario.
  75. //
  76. if(KeyLocation == PST_KEY_CURRENT_USER) {
  77. phNewPSTProv = (PST_PROVIDER_HANDLE *)&NewContext;
  78. //
  79. // hard case: PST_KEY_CURRENT_USER
  80. //
  81. fDummyContext = CreateDummyUserContext( hPSTProv, &NewContext );
  82. if(!fDummyContext)
  83. goto cleanup;
  84. } else {
  85. //
  86. // PST_KEY_LOCAL_MACHINE : global dummy call state
  87. //
  88. phNewPSTProv = (PST_PROVIDER_HANDLE *)&g_sDummyCallState;
  89. }
  90. __try {
  91. //
  92. // get the system provider (dispatch table)
  93. //
  94. PPROV_LIST_ITEM pli = SearchProvListByID(&g_guidBaseProvider);
  95. GUID guidType = PST_CONFIGDATA_TYPE_GUID;
  96. PST_PROMPTINFO sPrompt = {sizeof(PST_PROMPTINFO), 0, 0, L""};
  97. if( pli == NULL )
  98. goto cleanup;
  99. //
  100. // make call with the new context we setup
  101. //
  102. hr = pli->fnList.SPReadItem(
  103. phNewPSTProv,
  104. KeyLocation, // target PST_KEY_CURRENT_USER or PST_KEY_LOCAL_MACHINE
  105. &guidType,
  106. pguidSubtype,
  107. szItemName,
  108. pcbData,
  109. ppbData,
  110. &sPrompt,
  111. 0
  112. );
  113. if( hr == S_OK )
  114. fSuccess = TRUE;
  115. } __except(EXCEPTION_EXECUTE_HANDLER) {
  116. // swallow
  117. fSuccess = FALSE;
  118. }
  119. cleanup:
  120. if(fDummyContext) {
  121. DeleteDummyUserContext( &NewContext );
  122. }
  123. return fSuccess;
  124. }
  125. BOOL
  126. FSetConfigurationData(
  127. IN PST_PROVIDER_HANDLE *hPSTProv,
  128. IN PST_KEY KeyLocation,
  129. IN GUID *pguidSubtype,
  130. IN LPCWSTR szItemName,
  131. IN BYTE *pbData,
  132. IN DWORD cbData
  133. )
  134. {
  135. PST_PROVIDER_HANDLE *phNewPSTProv = NULL;
  136. CALL_STATE NewContext;
  137. BOOL fDummyContext = FALSE;
  138. BOOL fSuccess = FALSE;
  139. HRESULT hr;
  140. if(KeyLocation != PST_KEY_CURRENT_USER && KeyLocation != PST_KEY_LOCAL_MACHINE) {
  141. SetLastError(ERROR_INVALID_PARAMETER);
  142. return FALSE;
  143. }
  144. //
  145. // Hard case is PST_KEY_CURRENT_USER. Prepare user context for that
  146. // scenario.
  147. //
  148. if(KeyLocation == PST_KEY_CURRENT_USER) {
  149. phNewPSTProv = (PST_PROVIDER_HANDLE *)&NewContext;
  150. //
  151. // hard case: PST_KEY_CURRENT_USER
  152. //
  153. fDummyContext = CreateDummyUserContext( hPSTProv, &NewContext );
  154. if(!fDummyContext)
  155. goto cleanup;
  156. } else {
  157. //
  158. // PST_KEY_LOCAL_MACHINE : global dummy call state
  159. //
  160. phNewPSTProv = (PST_PROVIDER_HANDLE *)&g_sDummyCallState;
  161. }
  162. __try {
  163. //
  164. // get the system provider (dispatch table)
  165. //
  166. PPROV_LIST_ITEM pli = SearchProvListByID(&g_guidBaseProvider);
  167. GUID guidType = PST_CONFIGDATA_TYPE_GUID;
  168. PST_PROMPTINFO sPrompt = {sizeof(PST_PROMPTINFO), 0, 0, L""};
  169. if( pli == NULL )
  170. goto cleanup;
  171. //
  172. // make call with the new context we setup
  173. //
  174. hr = pli->fnList.SPWriteItem(
  175. phNewPSTProv,
  176. KeyLocation, // target PST_KEY_CURRENT_USER or PST_KEY_LOCAL_MACHINE
  177. &guidType,
  178. pguidSubtype,
  179. szItemName,
  180. cbData,
  181. pbData,
  182. &sPrompt,
  183. 0,
  184. 0
  185. );
  186. if( hr == S_OK )
  187. fSuccess = TRUE;
  188. } __except(EXCEPTION_EXECUTE_HANDLER) {
  189. // swallow
  190. fSuccess = FALSE;
  191. }
  192. cleanup:
  193. if(fDummyContext) {
  194. DeleteDummyUserContext( &NewContext );
  195. }
  196. return fSuccess;
  197. }
  198. BOOL
  199. FInternalCreateType(
  200. PST_PROVIDER_HANDLE *phPSTProv,
  201. PST_KEY KeyLocation,
  202. const GUID *pguidType,
  203. PPST_TYPEINFO pinfoType,
  204. DWORD dwFlags
  205. )
  206. {
  207. PST_PROVIDER_HANDLE *phNewPSTProv = NULL;
  208. CALL_STATE NewContext;
  209. BOOL fDummyContext = FALSE;
  210. BOOL fSuccess = FALSE;
  211. PST_ACCESSRULESET Rules;
  212. HRESULT hr;
  213. if(KeyLocation != PST_KEY_CURRENT_USER && KeyLocation != PST_KEY_LOCAL_MACHINE) {
  214. SetLastError(ERROR_INVALID_PARAMETER);
  215. return FALSE;
  216. }
  217. //
  218. // Hard case is PST_KEY_CURRENT_USER. Prepare user context for that
  219. // scenario.
  220. //
  221. if(KeyLocation == PST_KEY_CURRENT_USER) {
  222. phNewPSTProv = (PST_PROVIDER_HANDLE *)&NewContext;
  223. //
  224. // hard case: PST_KEY_CURRENT_USER
  225. //
  226. fDummyContext = CreateDummyUserContext( phPSTProv, &NewContext );
  227. if(!fDummyContext)
  228. goto cleanup;
  229. } else {
  230. //
  231. // PST_KEY_LOCAL_MACHINE : global dummy call state
  232. //
  233. phNewPSTProv = (PST_PROVIDER_HANDLE *)&g_sDummyCallState;
  234. }
  235. __try {
  236. //
  237. // get the system provider (dispatch table)
  238. //
  239. PPROV_LIST_ITEM pli = SearchProvListByID(&g_guidBaseProvider);
  240. if( pli == NULL )
  241. goto cleanup;
  242. //
  243. // make call with the new context we setup
  244. //
  245. Rules.cbSize = sizeof( Rules );
  246. Rules.cRules = 0;
  247. Rules.rgRules = NULL;
  248. hr = pli->fnList.SPCreateType(
  249. phNewPSTProv,
  250. KeyLocation,
  251. pguidType,
  252. pinfoType,
  253. dwFlags
  254. );
  255. if(hr == S_OK || hr == PST_E_TYPE_EXISTS)
  256. fSuccess = TRUE;
  257. } __except(EXCEPTION_EXECUTE_HANDLER) {
  258. // swallow
  259. fSuccess = FALSE;
  260. }
  261. cleanup:
  262. if(fDummyContext) {
  263. DeleteDummyUserContext( &NewContext );
  264. }
  265. return fSuccess;
  266. }
  267. BOOL
  268. FInternalCreateSubtype(
  269. PST_PROVIDER_HANDLE *phPSTProv,
  270. PST_KEY KeyLocation,
  271. const GUID *pguidType,
  272. const GUID *pguidSubtype,
  273. PPST_TYPEINFO pinfoSubtype,
  274. DWORD dwFlags
  275. )
  276. /*++
  277. This routine allows the protected storage server to create a subtype
  278. within the Microsoft Protected Storage Base Provider.
  279. The subtype is created with no access ruleset. The caller should use
  280. the FInternalWriteAccessRuleset() if an access ruleset needs to be applied
  281. after the subtype is created.
  282. --*/
  283. {
  284. PST_PROVIDER_HANDLE *phNewPSTProv = NULL;
  285. CALL_STATE NewContext;
  286. BOOL fDummyContext = FALSE;
  287. BOOL fSuccess = FALSE;
  288. PST_ACCESSRULESET Rules;
  289. HRESULT hr;
  290. if(KeyLocation != PST_KEY_CURRENT_USER && KeyLocation != PST_KEY_LOCAL_MACHINE) {
  291. SetLastError(ERROR_INVALID_PARAMETER);
  292. return FALSE;
  293. }
  294. //
  295. // Hard case is PST_KEY_CURRENT_USER. Prepare user context for that
  296. // scenario.
  297. //
  298. if(KeyLocation == PST_KEY_CURRENT_USER) {
  299. phNewPSTProv = (PST_PROVIDER_HANDLE *)&NewContext;
  300. //
  301. // hard case: PST_KEY_CURRENT_USER
  302. //
  303. fDummyContext = CreateDummyUserContext( phPSTProv, &NewContext );
  304. if(!fDummyContext)
  305. goto cleanup;
  306. } else {
  307. //
  308. // PST_KEY_LOCAL_MACHINE : global dummy call state
  309. //
  310. phNewPSTProv = (PST_PROVIDER_HANDLE *)&g_sDummyCallState;
  311. }
  312. __try {
  313. //
  314. // get the system provider (dispatch table)
  315. //
  316. PPROV_LIST_ITEM pli = SearchProvListByID(&g_guidBaseProvider);
  317. if( pli == NULL )
  318. goto cleanup;
  319. //
  320. // make call with the new context we setup
  321. //
  322. Rules.cbSize = sizeof( Rules );
  323. Rules.cRules = 0;
  324. Rules.rgRules = NULL;
  325. hr = pli->fnList.SPCreateSubtype(
  326. phNewPSTProv,
  327. KeyLocation,
  328. pguidType,
  329. pguidSubtype,
  330. pinfoSubtype,
  331. &Rules,
  332. dwFlags
  333. );
  334. if(hr == S_OK || hr == PST_E_TYPE_EXISTS)
  335. fSuccess = TRUE;
  336. } __except(EXCEPTION_EXECUTE_HANDLER) {
  337. // swallow
  338. fSuccess = FALSE;
  339. }
  340. cleanup:
  341. if(fDummyContext) {
  342. DeleteDummyUserContext( &NewContext );
  343. }
  344. return fSuccess;
  345. }
  346. BOOL
  347. FInternalWriteAccessRuleset(
  348. PST_PROVIDER_HANDLE *phPSTProv,
  349. PST_KEY KeyLocation,
  350. const GUID *pguidType,
  351. const GUID *pguidSubtype,
  352. PPST_ACCESSRULESET psRules,
  353. DWORD dwFlags
  354. )
  355. {
  356. PST_PROVIDER_HANDLE *phNewPSTProv = NULL;
  357. CALL_STATE NewContext;
  358. BOOL fDummyContext = FALSE;
  359. BOOL fSuccess = FALSE;
  360. PPST_ACCESSRULESET NewRules = NULL;
  361. HRESULT hr = S_OK;
  362. if(KeyLocation != PST_KEY_CURRENT_USER && KeyLocation != PST_KEY_LOCAL_MACHINE) {
  363. SetLastError(ERROR_INVALID_PARAMETER);
  364. return FALSE;
  365. }
  366. //
  367. // Hard case is PST_KEY_CURRENT_USER. Prepare user context for that
  368. // scenario.
  369. //
  370. if(KeyLocation == PST_KEY_CURRENT_USER) {
  371. phNewPSTProv = (PST_PROVIDER_HANDLE *)&NewContext;
  372. //
  373. // hard case: PST_KEY_CURRENT_USER
  374. //
  375. fDummyContext = CreateDummyUserContext( phPSTProv, &NewContext );
  376. if(!fDummyContext)
  377. goto cleanup;
  378. } else {
  379. //
  380. // PST_KEY_LOCAL_MACHINE : global dummy call state
  381. //
  382. phNewPSTProv = (PST_PROVIDER_HANDLE *)&g_sDummyCallState;
  383. }
  384. __try {
  385. //
  386. // get the system provider (dispatch table)
  387. //
  388. PPROV_LIST_ITEM pli = SearchProvListByID(&g_guidBaseProvider);
  389. if( pli == NULL )
  390. goto cleanup;
  391. //
  392. // Need to make rule data contiguous for push across RPC
  393. //
  394. DWORD cbRules;
  395. // get the length of the entire ruleset structure
  396. if (!GetLengthOfRuleset(psRules, &cbRules))
  397. {
  398. hr = PST_E_INVALID_RULESET;
  399. goto cleanup;
  400. }
  401. // allocate space for the rules
  402. if (NULL == (NewRules = (PST_ACCESSRULESET*)SSAlloc(cbRules)))
  403. {
  404. hr = E_OUTOFMEMORY;
  405. goto cleanup;
  406. }
  407. ZeroMemory(NewRules, cbRules);
  408. // set up the rules to be output
  409. if (!MyCopyOfRuleset(psRules, NewRules))
  410. {
  411. hr = PST_E_FAIL;
  412. goto cleanup;
  413. }
  414. // make clause data relative
  415. if(!RulesAbsoluteToRelative(NewRules))
  416. {
  417. hr = PST_E_INVALID_RULESET;
  418. goto cleanup;
  419. }
  420. //
  421. // make call with the new context we setup
  422. //
  423. hr = pli->fnList.SPWriteAccessRuleset(
  424. phNewPSTProv,
  425. KeyLocation,
  426. pguidType,
  427. pguidSubtype,
  428. NewRules,
  429. dwFlags
  430. );
  431. if(hr == S_OK || hr == PST_E_TYPE_EXISTS)
  432. fSuccess = TRUE;
  433. } __except(EXCEPTION_EXECUTE_HANDLER) {
  434. // swallow
  435. fSuccess = FALSE;
  436. }
  437. cleanup:
  438. if(fDummyContext) {
  439. DeleteDummyUserContext( &NewContext );
  440. }
  441. if(NewRules)
  442. {
  443. FreeClauseDataRelative( NewRules );
  444. SSFree( NewRules );
  445. }
  446. if(!fSuccess && hr != S_OK)
  447. SetLastError((DWORD) hr);
  448. return fSuccess;
  449. }
  450. BOOL
  451. CreateDummyUserContext(
  452. IN PST_PROVIDER_HANDLE *hPSTProv,
  453. IN CALL_STATE *pNewContext
  454. )
  455. {
  456. //
  457. // hard case: PST_KEY_CURRENT_USER
  458. //
  459. PLIST_ITEM pliCaller; // list item associated with user calling this function
  460. PLIST_ITEM pliNew; // newly allocated list item
  461. DWORD cbName;
  462. CALL_STATE *CallerContext = (CALL_STATE *)hPSTProv;
  463. BOOL bSuccess = FALSE;
  464. if (NULL == (pliCaller = SearchListByHandleT(hPSTProv)))
  465. return FALSE;
  466. //
  467. // allocate memory for new list item, and initially populate
  468. // it with information from the calling list item.
  469. //
  470. pliNew = (PLIST_ITEM)SSAlloc(sizeof(LIST_ITEM));
  471. if(pliNew == NULL)
  472. return FALSE;
  473. CopyMemory(pliNew, pliCaller, sizeof(LIST_ITEM));
  474. pliNew->szProcessName = NULL;
  475. pliNew->szCallerUsername = NULL;
  476. //
  477. // now, overwrite with some server related elements to
  478. // make it look like the server is accessing the data as the calling
  479. // user.
  480. //
  481. if(!AllocatePseudoUniqueHandle( &(pliNew->hPSTProv) ))
  482. goto cleanup;
  483. CopyMemory(&(pliNew->ProviderID), &g_guidBaseProvider, sizeof(PST_PROVIDERID));
  484. pliNew->hProcess = g_psDummyListItem->hProcess;
  485. pliNew->hThread = g_psDummyListItem->hThread;
  486. pliNew->dwProcessId = g_psDummyListItem->dwProcessId;
  487. //
  488. // allocate new copy of process name string because it get separately freed
  489. // by DelItemFromList
  490. //
  491. // TODO: consider not allocating copies of szProcessName and szCallerUsername
  492. // and just set these member to NULL prior to calling DelItemFromList()
  493. //
  494. cbName = (lstrlenW(g_psDummyListItem->szProcessName) + 1) * sizeof(WCHAR);
  495. pliNew->szProcessName = (LPWSTR)SSAlloc(cbName);
  496. if(pliNew->szProcessName == NULL)
  497. goto cleanup;
  498. CopyMemory(pliNew->szProcessName, g_psDummyListItem->szProcessName, cbName);
  499. //
  500. // user name associated with caller.
  501. //
  502. cbName = (lstrlenW(pliCaller->szCallerUsername) + 1) * sizeof(WCHAR);
  503. pliNew->szCallerUsername = (LPWSTR)SSAlloc(cbName);
  504. if(pliNew->szCallerUsername == NULL)
  505. goto cleanup;
  506. CopyMemory(pliNew->szCallerUsername, pliCaller->szCallerUsername, cbName);
  507. //
  508. // build new PST_PROVIDER_HANDLE, which is really a CALL_CONTEXT in disguise
  509. //
  510. ZeroMemory( pNewContext, sizeof(CALL_STATE) );
  511. CopyMemory(&(pNewContext->hPSTProv), &(pliNew->hPSTProv), sizeof(PST_PROVIDER_HANDLE));
  512. pNewContext->hBinding = CallerContext->hBinding;
  513. //
  514. // pickup stuff from server context
  515. //
  516. pNewContext->hThread = pliNew->hThread;
  517. pNewContext->hProcess = pliNew->hProcess;
  518. pNewContext->dwProcessId = pliNew->dwProcessId;
  519. //
  520. // add to list
  521. //
  522. AddItemToList(pliNew);
  523. //
  524. // make sure ref count is raised - caller in PST_KEY_CURRENT_USER
  525. // case is responsible for decrementing when finished.
  526. //
  527. bSuccess = FAcquireProvider(&g_guidBaseProvider);
  528. cleanup:
  529. if(!bSuccess && pliNew) {
  530. //
  531. // these should only be non-NULL if we allocated storage that
  532. // was not freed as a result of the call to DelItemFromList()
  533. //
  534. if(pliNew->szProcessName)
  535. SSFree(pliNew->szProcessName);
  536. if(pliNew->szCallerUsername)
  537. SSFree(pliNew->szCallerUsername);
  538. SSFree(pliNew);
  539. }
  540. return bSuccess;
  541. }
  542. BOOL
  543. DeleteDummyUserContext(
  544. IN CALL_STATE *pNewContext
  545. )
  546. {
  547. PST_PROVIDER_HANDLE *phProv = (PST_PROVIDER_HANDLE *)pNewContext;
  548. DelItemFromList( phProv );
  549. return TRUE;
  550. }