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.

622 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. setupsrv.cpp
  5. Abstract:
  6. Routines for secedit integration with system setup and component setup
  7. Author:
  8. Jin Huang (jinhuang) 15-Aug-1997
  9. Revision History:
  10. jinhuang 26-Jan-1998 splitted to client-server
  11. --*/
  12. #include "headers.h"
  13. #include "serverp.h"
  14. #include "srvrpcp.h"
  15. #include "pfp.h"
  16. #include <io.h>
  17. SCESTATUS
  18. ScepUpdateObjectInSection(
  19. IN PSCECONTEXT hProfile,
  20. IN SCETYPE ProfileType,
  21. IN PWSTR ObjectName,
  22. IN SE_OBJECT_TYPE ObjectType,
  23. IN UINT nFlag,
  24. IN PWSTR SDText,
  25. OUT UINT *pStatus
  26. );
  27. //
  28. // implementations
  29. //
  30. DWORD
  31. ScepSetupUpdateObject(
  32. IN PSCECONTEXT Context,
  33. IN PWSTR ObjectFullName,
  34. IN SE_OBJECT_TYPE ObjectType,
  35. IN UINT nFlag,
  36. IN PWSTR SDText
  37. )
  38. /*
  39. Routine Description:
  40. This routine is the private API called from the RPC interface to
  41. update object information in the database.
  42. Arguments:
  43. Context - the database context handle
  44. ObjectFullName - the object's name
  45. Objecttype - the object type
  46. nFlag - the flag on how to update this object
  47. SDText - the security descriptor in SDDL text
  48. Return Value:
  49. */
  50. {
  51. if ( !ObjectFullName || NULL == SDText ) {
  52. return ERROR_INVALID_PARAMETER;
  53. }
  54. switch ( ObjectType ) {
  55. case SE_SERVICE:
  56. case SE_REGISTRY_KEY:
  57. case SE_FILE_OBJECT:
  58. break;
  59. default:
  60. return ERROR_INVALID_PARAMETER;
  61. }
  62. SCESTATUS rc;
  63. DWORD dwInSetup=0;
  64. ScepRegQueryIntValue(HKEY_LOCAL_MACHINE,
  65. TEXT("System\\Setup"),
  66. TEXT("SystemSetupInProgress"),
  67. &dwInSetup
  68. );
  69. //
  70. // convert SDText to security descriptor
  71. //
  72. PSECURITY_DESCRIPTOR pSD=NULL;
  73. DWORD SDSize;
  74. SECURITY_INFORMATION SeInfo=0;
  75. HANDLE Token=NULL;
  76. DWORD Win32rc=ERROR_SUCCESS;
  77. if ( !(nFlag & SCESETUP_UPDATE_DB_ONLY) ) {
  78. //
  79. // security will be set, so compute the security descriptor
  80. //
  81. Win32rc = ConvertTextSecurityDescriptor (
  82. SDText,
  83. &pSD,
  84. &SDSize,
  85. &SeInfo
  86. );
  87. if ( NO_ERROR == Win32rc ) {
  88. ScepChangeAclRevision(pSD, ACL_REVISION);
  89. //
  90. // get current thread/process's token
  91. //
  92. if (!OpenThreadToken( GetCurrentThread(),
  93. TOKEN_QUERY,
  94. TRUE,
  95. &Token)) {
  96. if(ERROR_NO_TOKEN == GetLastError()){
  97. if(!OpenProcessToken( GetCurrentProcess(),
  98. TOKEN_QUERY,
  99. &Token )){
  100. Win32rc = GetLastError();
  101. }
  102. } else {
  103. Win32rc = GetLastError();
  104. }
  105. }
  106. if ( Token && (SeInfo & SACL_SECURITY_INFORMATION) ) {
  107. SceAdjustPrivilege( SE_SECURITY_PRIVILEGE, TRUE, Token );
  108. }
  109. }
  110. }
  111. if ( NO_ERROR == Win32rc ) {
  112. //
  113. // only update DB if it's in setup
  114. //
  115. //
  116. // on 64-bit platform, only update database if setup does not indicate SCE_SETUP_32KEY flag
  117. //
  118. #ifdef _WIN64
  119. if ( dwInSetup && !(nFlag & SCE_SETUP_32KEY) ) {
  120. #else
  121. if ( dwInSetup ) {
  122. #endif
  123. // save this into SCP and SMP, do not overwrite the status/container flag
  124. // if there is one exist, else use SCE_STATUS_CHECK and check for container
  125. //
  126. //
  127. // start a transaction since there are multiple operations
  128. //
  129. rc = SceJetStartTransaction( Context );
  130. if ( rc == SCESTATUS_SUCCESS ) {
  131. UINT Status=SCE_STATUS_CHECK;
  132. rc = ScepUpdateObjectInSection(
  133. Context,
  134. SCE_ENGINE_SMP,
  135. ObjectFullName,
  136. ObjectType,
  137. nFlag,
  138. SDText,
  139. &Status
  140. );
  141. if ( rc == SCESTATUS_SUCCESS &&
  142. (Context->JetSapID != JET_tableidNil) ) {
  143. //
  144. // the SAP table ID points to the tattoo table
  145. // should update the tattoo table too if it exist
  146. //
  147. rc = ScepUpdateObjectInSection(
  148. Context,
  149. SCE_ENGINE_SAP,
  150. ObjectFullName,
  151. ObjectType,
  152. nFlag,
  153. SDText,
  154. NULL
  155. );
  156. }
  157. }
  158. } else {
  159. rc = SCESTATUS_SUCCESS;
  160. }
  161. if ( rc == SCESTATUS_SUCCESS &&
  162. !(nFlag & SCESETUP_UPDATE_DB_ONLY) ) {
  163. //
  164. // set security to the object
  165. //
  166. //
  167. // if 64-bit platform, no synchronization is done and setup will have
  168. // to call the exported API with SCE_SETUP_32KEY if 32-bit hive is desired
  169. //
  170. #ifdef _WIN64
  171. if ( ObjectType == SE_REGISTRY_KEY && (nFlag & SCE_SETUP_32KEY) ){
  172. ObjectType = SE_REGISTRY_WOW64_32KEY;
  173. }
  174. #endif
  175. Win32rc = ScepSetSecurityWin32(
  176. ObjectFullName,
  177. SeInfo,
  178. pSD,
  179. ObjectType
  180. );
  181. } else
  182. Win32rc = ScepSceStatusToDosError(rc);
  183. if ( Win32rc == ERROR_SUCCESS ||
  184. Win32rc == ERROR_FILE_NOT_FOUND ||
  185. Win32rc == ERROR_PATH_NOT_FOUND ||
  186. Win32rc == ERROR_INVALID_OWNER ||
  187. Win32rc == ERROR_INVALID_PRIMARY_GROUP ||
  188. Win32rc == ERROR_INVALID_HANDLE ) {
  189. if ( Win32rc )
  190. gWarningCode = Win32rc;
  191. if ( dwInSetup ) { // in setup, update DB
  192. Win32rc = ScepSceStatusToDosError(
  193. SceJetCommitTransaction( Context, 0));
  194. } else {
  195. Win32rc = ERROR_SUCCESS;
  196. }
  197. } else if ( dwInSetup ) { // in setup
  198. SceJetRollback( Context, 0 );
  199. }
  200. if ( Token && (SeInfo & SACL_SECURITY_INFORMATION) )
  201. SceAdjustPrivilege( SE_SECURITY_PRIVILEGE, FALSE, Token );
  202. }
  203. CloseHandle(Token);
  204. if ( pSD ) {
  205. LocalFree(pSD);
  206. pSD = NULL;
  207. }
  208. return(Win32rc);
  209. }
  210. SCESTATUS
  211. ScepUpdateObjectInSection(
  212. IN PSCECONTEXT Context,
  213. IN SCETYPE ProfileType,
  214. IN PWSTR ObjectName,
  215. IN SE_OBJECT_TYPE ObjectType,
  216. IN UINT nFlag,
  217. IN PWSTR SDText,
  218. OUT UINT *pStatus
  219. )
  220. /*
  221. Routine Description:
  222. Update SCP and SMP. if the table does not exist at all, ignore the update.
  223. Delete SAP entry for the object. If table or record not found, ignore the error.
  224. Arguments:
  225. Return Value:
  226. */
  227. {
  228. if ( Context == NULL || ObjectName == NULL ) {
  229. return(SCESTATUS_INVALID_PARAMETER);
  230. }
  231. SCESTATUS rc;
  232. PSCESECTION hSection=NULL;
  233. PCWSTR SectionName;
  234. switch ( ObjectType ) {
  235. case SE_FILE_OBJECT:
  236. SectionName = szFileSecurity;
  237. break;
  238. case SE_REGISTRY_KEY:
  239. SectionName = szRegistryKeys;
  240. break;
  241. case SE_SERVICE:
  242. SectionName = szServiceGeneral;
  243. break;
  244. default:
  245. return(SCESTATUS_INVALID_PARAMETER);
  246. }
  247. rc = ScepOpenSectionForName(
  248. Context,
  249. ProfileType,
  250. SectionName,
  251. &hSection
  252. );
  253. if ( rc == SCESTATUS_BAD_FORMAT ||
  254. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  255. return(SCESTATUS_SUCCESS);
  256. }
  257. if ( rc == SCESTATUS_SUCCESS ) {
  258. WCHAR StatusFlag=L'\0';
  259. DWORD ValueLen;
  260. BYTE Status=SCE_STATUS_CHECK;
  261. BOOL IsContainer=TRUE;
  262. BYTE StartType;
  263. rc = SceJetGetValue(
  264. hSection,
  265. SCEJET_EXACT_MATCH_NO_CASE,
  266. ObjectName,
  267. NULL,
  268. 0,
  269. NULL,
  270. (PWSTR)&StatusFlag,
  271. 2,
  272. &ValueLen
  273. );
  274. if ( rc == SCESTATUS_SUCCESS ||
  275. rc == SCESTATUS_BUFFER_TOO_SMALL ) {
  276. rc = SCESTATUS_SUCCESS;
  277. Status = *((BYTE *)&StatusFlag);
  278. if ( pStatus ) {
  279. *pStatus = Status;
  280. }
  281. if ( ObjectType == SE_SERVICE ) {
  282. StartType = *((BYTE *)&StatusFlag+1);
  283. } else {
  284. IsContainer = *((CHAR *)&StatusFlag+1) != '0' ? TRUE : FALSE;
  285. }
  286. }
  287. if ( ObjectType == SE_SERVICE ) {
  288. DWORD SDLen, Len;
  289. PWSTR ValueToSet;
  290. StartType = (BYTE)nFlag;
  291. if ( SDText != NULL ) {
  292. SDLen = wcslen(SDText);
  293. Len = ( SDLen+1)*sizeof(WCHAR);
  294. } else
  295. Len = sizeof(WCHAR);
  296. ValueToSet = (PWSTR)ScepAlloc( (UINT)0, Len+sizeof(WCHAR) );
  297. if ( ValueToSet != NULL ) {
  298. //
  299. // The first byte is the flag, the second byte is IsContainer (1,0)
  300. //
  301. *((BYTE *)ValueToSet) = Status;
  302. *((BYTE *)ValueToSet+1) = StartType;
  303. if ( SDText != NULL ) {
  304. wcscpy(ValueToSet+1, SDText );
  305. ValueToSet[SDLen+1] = L'\0'; //terminate this string
  306. } else {
  307. ValueToSet[1] = L'\0';
  308. }
  309. if ( SCESTATUS_SUCCESS == rc || ProfileType != SCE_ENGINE_SAP ) {
  310. //
  311. // only update tattoo table (pointed by SAP handle) if it finds a record there
  312. // for other table (SMP), ignore the error code, just set
  313. //
  314. rc = SceJetSetLine( hSection,
  315. ObjectName,
  316. FALSE,
  317. ValueToSet,
  318. Len,
  319. 0);
  320. }
  321. ScepFree( ValueToSet );
  322. } else {
  323. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  324. }
  325. } else if ( SCESTATUS_SUCCESS == rc || ProfileType != SCE_ENGINE_SAP ) {
  326. //
  327. // only update tattoo table (pointed by SAP handle) if it finds a record there
  328. // for other table (SMP), ignore the error code, just set
  329. //
  330. rc = ScepSaveObjectString(
  331. hSection,
  332. ObjectName,
  333. IsContainer,
  334. Status,
  335. SDText,
  336. (SDText == NULL ) ? 0 : wcslen(SDText)
  337. );
  338. }
  339. if ( rc == SCESTATUS_RECORD_NOT_FOUND )
  340. rc = SCESTATUS_SUCCESS;
  341. SceJetCloseSection(&hSection, TRUE);
  342. }
  343. return(rc);
  344. }
  345. DWORD
  346. ScepSetupMoveFile(
  347. IN PSCECONTEXT Context,
  348. PWSTR OldName,
  349. PWSTR NewName OPTIONAL,
  350. PWSTR SDText OPTIONAL
  351. )
  352. /*
  353. Routine Description:
  354. Set security to OldName but save with NewName in SCE database if SDText
  355. is not NULL. If NewName is NULL, delete OldName from SCE database.
  356. Arguments:
  357. Context - the databaes context handle
  358. SectionName - the section name
  359. OldName - the object's old name
  360. NewName - the new name to rename to, if NULL, delete the old object
  361. SDText - security string
  362. Return Value:
  363. Win32 error code
  364. */
  365. {
  366. if ( !Context || !OldName ) {
  367. return ERROR_INVALID_PARAMETER;
  368. }
  369. DWORD rc32=ERROR_SUCCESS;
  370. if ( NewName && SDText ) {
  371. //
  372. // set security on OldName with SDText
  373. //
  374. rc32 = ScepSetupUpdateObject(
  375. Context,
  376. OldName,
  377. SE_FILE_OBJECT,
  378. 0,
  379. SDText
  380. );
  381. }
  382. if ( rc32 == ERROR_SUCCESS ) {
  383. //
  384. // save this into SCP and SMP, do not overwrite the status/container flag
  385. // if there is one exist, else use SCE_STATUS_CHECK and check for container
  386. //
  387. SCESTATUS rc = SceJetStartTransaction( Context );
  388. if ( rc == SCESTATUS_SUCCESS ) {
  389. PSCESECTION hSection=NULL;
  390. //
  391. // process SMP section first
  392. //
  393. rc = ScepOpenSectionForName(
  394. Context,
  395. SCE_ENGINE_SMP,
  396. szFileSecurity,
  397. &hSection
  398. );
  399. if ( rc == SCESTATUS_SUCCESS ) {
  400. if ( NewName ) {
  401. //
  402. // rename this line
  403. //
  404. rc = SceJetRenameLine(
  405. hSection,
  406. OldName,
  407. NewName,
  408. FALSE);
  409. } else {
  410. //
  411. // delete this line first
  412. //
  413. rc = SceJetDelete(
  414. hSection,
  415. OldName,
  416. FALSE,
  417. SCEJET_DELETE_LINE_NO_CASE
  418. );
  419. }
  420. SceJetCloseSection( &hSection, TRUE);
  421. }
  422. if ( (SCESTATUS_SUCCESS == rc ||
  423. SCESTATUS_RECORD_NOT_FOUND == rc ||
  424. SCESTATUS_BAD_FORMAT == rc) &&
  425. (Context->JetSapID != JET_tableidNil) ) {
  426. //
  427. // process tattoo table
  428. //
  429. rc = ScepOpenSectionForName(
  430. Context,
  431. SCE_ENGINE_SAP,
  432. szFileSecurity,
  433. &hSection
  434. );
  435. if ( rc == SCESTATUS_SUCCESS ) {
  436. if ( NewName ) {
  437. //
  438. // rename this line
  439. //
  440. rc = SceJetRenameLine(
  441. hSection,
  442. OldName,
  443. NewName,
  444. FALSE);
  445. } else {
  446. //
  447. // delete this line first
  448. //
  449. rc = SceJetDelete(
  450. hSection,
  451. OldName,
  452. FALSE,
  453. SCEJET_DELETE_LINE_NO_CASE
  454. );
  455. }
  456. SceJetCloseSection( &hSection, TRUE);
  457. }
  458. }
  459. if ( SCESTATUS_RECORD_NOT_FOUND == rc ||
  460. SCESTATUS_BAD_FORMAT == rc ) {
  461. rc = SCESTATUS_SUCCESS;
  462. }
  463. if ( SCESTATUS_SUCCESS == rc ) {
  464. //
  465. // commit the transaction
  466. //
  467. rc = SceJetCommitTransaction( Context, 0 );
  468. } else {
  469. //
  470. // rollback the transaction
  471. //
  472. SceJetRollback( Context, 0 );
  473. }
  474. }
  475. rc32 = ScepSceStatusToDosError(rc);
  476. }
  477. return(rc32);
  478. }