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.

629 lines
16 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name :
  4. common.cxx
  5. Abstract:
  6. Class that are used to do a number of commonly needed things
  7. Author:
  8. Christopher Achille (cachille)
  9. Project:
  10. Internet Services Setup
  11. Revision History:
  12. August 2001: Created
  13. --*/
  14. #include "stdafx.h"
  15. #include "common.hxx"
  16. #include "dcomperm.h"
  17. // function: VerifyParameters
  18. //
  19. // Verify the parameters are correct
  20. //
  21. // Parameters of ciParams
  22. // 0 params - The caller want to know if this is an upgrade, period
  23. // 2 params - The caller wants to know if this is an upgrade in the range from param(0) to param(1) (inclusive)
  24. //
  25. BOOL
  26. CIsUpgrade::VerifyParameters(CItemList &ciParams)
  27. {
  28. if ( ( ciParams.GetNumberOfItems() == 0 ) ||
  29. ( ( ciParams.GetNumberOfItems() == 2 ) &&
  30. ( ciParams.IsNumber(0) ) &&
  31. ( ciParams.IsNumber(1) )
  32. )
  33. )
  34. {
  35. return TRUE;
  36. }
  37. return FALSE;
  38. }
  39. // function: GetMethodName
  40. //
  41. // Returns the name of the CIsMetabase call
  42. //
  43. LPTSTR
  44. CIsUpgrade::GetMethodName()
  45. {
  46. return _T("IsUpgrade");
  47. }
  48. // function: DoInternalWork
  49. //
  50. // Do the Verification of the upgrade
  51. //
  52. BOOL
  53. CIsUpgrade::DoInternalWork(CItemList &ciParams)
  54. {
  55. BOOL fRet = TRUE;
  56. DWORD dwUpgradeType = g_pTheApp->m_eUpgradeType;
  57. // Init return to installmode==upgrade
  58. fRet = g_pTheApp->m_eInstallMode == IM_UPGRADE;
  59. if (ciParams.GetNumberOfItems() == 0)
  60. {
  61. // We only wanted to know if it was an upgrade, so return
  62. return fRet;
  63. }
  64. // Check lower bound
  65. if (fRet)
  66. {
  67. DWORD dwMin = ciParams.GetNumber(0);
  68. switch ( dwUpgradeType )
  69. {
  70. case UT_10:
  71. case UT_10_W95:
  72. fRet = dwMin <= 1;
  73. break;
  74. case UT_20:
  75. fRet = dwMin <= 2;
  76. break;
  77. case UT_30:
  78. case UT_351:
  79. fRet = dwMin <= 3;
  80. break;
  81. case UT_40:
  82. fRet = dwMin <= 4;
  83. break;
  84. case UT_50:
  85. case UT_51:
  86. fRet = dwMin <= 5;
  87. break;
  88. case UT_60:
  89. fRet = dwMin <= 6;
  90. break;
  91. default:
  92. fRet = FALSE;
  93. }
  94. }
  95. // Check upper bound
  96. if (fRet)
  97. {
  98. DWORD dwMax = ciParams.GetNumber(1);
  99. switch ( dwUpgradeType )
  100. {
  101. case UT_10:
  102. case UT_10_W95:
  103. fRet = dwMax >= 1;
  104. break;
  105. case UT_20:
  106. fRet = dwMax >= 2;
  107. break;
  108. case UT_30:
  109. case UT_351:
  110. fRet = dwMax >= 3;
  111. break;
  112. case UT_40:
  113. fRet = dwMax >= 4;
  114. break;
  115. case UT_50:
  116. case UT_51:
  117. fRet = dwMax >= 5;
  118. break;
  119. case UT_60:
  120. fRet = dwMax >= 6;
  121. break;
  122. default:
  123. fRet = FALSE;
  124. } // switch
  125. }
  126. return fRet;
  127. }
  128. // function: AddAceToSD
  129. //
  130. // Add an ACE (Access Control List) to a Source Descriptor.
  131. //
  132. // Parameters:
  133. // hObject - Handle to the object
  134. // ObjectType - The type of object
  135. // pszTustee - The trustee for new ACE
  136. // TrusteeForm - The format of the trustee structure
  137. // dwAccessRights - Access Mask for the New ACE
  138. // AccessMode - Type of ACE
  139. // dwInderitance - Inheritance Flags for ACE
  140. // bAddToExisting - TRUE==add ace to existing ACL, FALSE==ignore existing ACL
  141. //
  142. // Return
  143. // TRUE - It was successful
  144. // FALSE - It failed
  145. BOOL
  146. CFileSys_Acl::AddAcetoSD( HANDLE hObject, // handle to object
  147. SE_OBJECT_TYPE ObjectType, // type of object
  148. LPTSTR pszTrustee, // trustee for new ACE
  149. TRUSTEE_FORM TrusteeForm, // format of TRUSTEE structure
  150. DWORD dwAccessRights, // access mask for new ACE
  151. ACCESS_MODE AccessMode, // type of ACE
  152. DWORD dwInheritance, // inheritance flags for new ACE
  153. BOOL bAddToExisting // add the new ace to the old SD, if not create a new SD
  154. )
  155. {
  156. DWORD dwErr = ERROR_SUCCESS;
  157. PACL pNewDacl = NULL;
  158. PACL pOldDacl = NULL;
  159. EXPLICIT_ACCESS ea;
  160. PSECURITY_DESCRIPTOR pSD = NULL;
  161. if ( bAddToExisting )
  162. {
  163. // If we are adding, then lets retrieve the old SD
  164. dwErr = GetSecurityInfo( hObject,
  165. ObjectType,
  166. DACL_SECURITY_INFORMATION,
  167. NULL,
  168. NULL,
  169. &pOldDacl,
  170. NULL,
  171. &pSD);
  172. if ( dwErr == ERROR_SUCCESS )
  173. {
  174. // It is possible that we did not retrieve any acl's for this file,
  175. // so don't try to remove a user from them
  176. if ( pOldDacl )
  177. {
  178. RemoveUserFromAcl( pOldDacl, pszTrustee);
  179. }
  180. }
  181. }
  182. // Create new SD with the new ACE
  183. if ( dwErr == ERROR_SUCCESS )
  184. {
  185. ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
  186. ea.grfAccessPermissions = dwAccessRights;
  187. ea.grfAccessMode = AccessMode;
  188. ea.grfInheritance = dwInheritance;
  189. ea.Trustee.TrusteeForm = TrusteeForm;
  190. ea.Trustee.ptstrName = pszTrustee;
  191. dwErr = SetEntriesInAcl(1, &ea, pOldDacl, &pNewDacl);
  192. }
  193. if ( ( dwErr == ERROR_SUCCESS ) &&
  194. ( pNewDacl )
  195. )
  196. {
  197. dwErr = SetSecurityInfo( hObject,
  198. ObjectType,
  199. DACL_SECURITY_INFORMATION |
  200. ( bAddToExisting ?
  201. UNPROTECTED_DACL_SECURITY_INFORMATION :
  202. PROTECTED_DACL_SECURITY_INFORMATION ),
  203. NULL,
  204. NULL,
  205. pNewDacl,
  206. NULL);
  207. }
  208. if ( pSD )
  209. {
  210. LocalFree( pSD );
  211. }
  212. if ( pNewDacl )
  213. {
  214. LocalFree( pNewDacl );
  215. }
  216. return dwErr == ERROR_SUCCESS;
  217. }
  218. // function: RemoveUserFromAcl
  219. //
  220. // Remove a User from the Acl
  221. //
  222. // Parameters
  223. // pAcl - A pointer to the Acl
  224. // szUserName - The user to remove
  225. BOOL
  226. CFileSys_Acl::RemoveUserFromAcl(PACL pAcl, LPTSTR szUserName)
  227. {
  228. BOOL bUserExisted;
  229. do {
  230. bUserExisted = FALSE;
  231. // Keep removing until all instances of that user are gone.
  232. } while ( ( RemovePrincipalFromACL(pAcl,szUserName,&bUserExisted) == ERROR_SUCCESS) && bUserExisted );
  233. return TRUE;
  234. }
  235. // function: VerifyParameters
  236. //
  237. // Verify the parameters are correct
  238. //
  239. BOOL
  240. CFileSys_AddAcl::VerifyParameters(CItemList &ciParams)
  241. {
  242. if ( ( ciParams.GetNumberOfItems() == 6 ) &&
  243. ciParams.IsNumber(3) &&
  244. ciParams.IsNumber(4) &&
  245. ciParams.IsNumber(5)
  246. )
  247. {
  248. return TRUE;
  249. }
  250. return FALSE;
  251. }
  252. // function: GetMethodName
  253. //
  254. // Return the Method Name for this Class
  255. //
  256. LPTSTR
  257. CFileSys_AddAcl::GetMethodName()
  258. {
  259. return _T("FilSys_AddAcl");
  260. }
  261. // function: CreateFullFileName
  262. //
  263. // Create the Full FileName from the Path with wildcards, and the filename
  264. //
  265. // Parameters:
  266. // buffFullFileName [out] - The FileName including the path
  267. // szFullPathwithWildCard [in] - The search path (ie. c:\winnt\system32\inetsrv\*.*)
  268. // szFileName [in] - The filename to append to the seach path (ie. asp.dll)
  269. //
  270. BOOL
  271. CFileSys_Acl::CreateFullFileName(BUFFER &buffFullFileName, LPTSTR szFullPathwithWildCard, LPTSTR szFileName)
  272. {
  273. LPTSTR szLastSlash;
  274. if ( !buffFullFileName.Resize( ( _tcslen(szFullPathwithWildCard) + _tcslen(szFileName) + 1 ) * sizeof(TCHAR) ) )
  275. {
  276. // Could not allocate memory needed
  277. return FALSE;
  278. }
  279. // Copy the full path to the buffer
  280. _tcscpy( (LPTSTR) buffFullFileName.QueryPtr(), szFullPathwithWildCard);
  281. // Look for last part of path
  282. szLastSlash = _tcsrchr( (LPTSTR) buffFullFileName.QueryPtr(), L'\\' );
  283. if (!szLastSlash)
  284. {
  285. return FALSE;
  286. }
  287. // Copy the filename on top of the end of the path
  288. _tcscpy( szLastSlash + 1, szFileName);
  289. return TRUE;
  290. }
  291. // function: SetFileAcl
  292. //
  293. // Add the file/directory acl
  294. //
  295. BOOL
  296. CFileSys_Acl::SetFileAcl(LPTSTR szFileName, LPTSTR szUserName, SE_OBJECT_TYPE ObjectType,
  297. DWORD dwAccessMask, BOOL bAllowAccess, DWORD dwInheritable, BOOL bAddAcetoOriginal)
  298. {
  299. HANDLE hFile;
  300. BOOL bRet;
  301. hFile = CreateFile( szFileName,
  302. WRITE_DAC|READ_CONTROL,
  303. 0,
  304. NULL,
  305. OPEN_EXISTING,
  306. FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
  307. NULL);
  308. if ( hFile == INVALID_HANDLE_VALUE )
  309. {
  310. return FALSE;
  311. }
  312. bRet = AddAcetoSD( hFile, ObjectType, szUserName, TRUSTEE_IS_NAME, dwAccessMask,
  313. bAllowAccess ? SET_ACCESS: DENY_ACCESS, dwInheritable,
  314. bAddAcetoOriginal );
  315. // bAllowAccess ? GRANT_ACCESS: DENY_ACCESS, dwInheritable);
  316. CloseHandle( hFile );
  317. return bRet;
  318. }
  319. // function: RemoveUserAcl
  320. //
  321. // Remove a User's ACL from a file
  322. //
  323. BOOL
  324. CFileSys_Acl::RemoveUserAcl(LPTSTR szFile, LPTSTR szUserName)
  325. {
  326. HANDLE hFile;
  327. DWORD dwErr;
  328. PACL pDacl;
  329. PSECURITY_DESCRIPTOR pSD = NULL;
  330. hFile = CreateFile( szFile,
  331. WRITE_DAC|READ_CONTROL,
  332. 0,
  333. NULL,
  334. OPEN_EXISTING,
  335. FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
  336. NULL);
  337. if ( hFile == INVALID_HANDLE_VALUE )
  338. {
  339. return FALSE;
  340. }
  341. dwErr = GetSecurityInfo( hFile,
  342. SE_FILE_OBJECT,
  343. DACL_SECURITY_INFORMATION,
  344. NULL,
  345. NULL,
  346. &pDacl,
  347. NULL,
  348. &pSD);
  349. if ( ( dwErr == ERROR_SUCCESS ) &&
  350. ( pDacl )
  351. )
  352. {
  353. RemoveUserFromAcl( pDacl, szUserName);
  354. dwErr = SetSecurityInfo(hFile,
  355. SE_FILE_OBJECT,
  356. DACL_SECURITY_INFORMATION,
  357. NULL,
  358. NULL,
  359. pDacl,
  360. NULL);
  361. }
  362. CloseHandle( hFile );
  363. if ( pSD )
  364. {
  365. LocalFree( pSD );
  366. }
  367. return dwErr == ERROR_SUCCESS;
  368. }
  369. // function: DoSetAcl
  370. //
  371. // Set or remove an ACL on a file.
  372. // If it is Set, then we will either add or just set based on bIgnorePreviousAcls
  373. //
  374. // Parameters
  375. // bAdd - Add the ace. FALSE==remove the ace from the acl
  376. // bAddAcltoOrignial - TRUE==add ace, FALSE==do not add to old ace, just replace
  377. //
  378. // ciList - The list of the parameters from the inf file
  379. // 0 - A list of files (full paths)
  380. // 1 - The exclusion list, list of files to not be inclused (file names only)
  381. // 2 - The user(s) to have access for
  382. // the following are needed it bAdd is true...
  383. // 3 - Access Mask
  384. // 4 - bAllowAccess (FALSE==Denuy Access)
  385. // 5 - Inheritance Flags
  386. //
  387. BOOL
  388. CFileSys_Acl::DoAcling(CItemList &ciList, BOOL bAdd, BOOL bAddAcltoOriginal)
  389. {
  390. HANDLE hFileList;
  391. WIN32_FIND_DATA sFD;
  392. BUFFER BuffFullFileName;
  393. CItemList ciExclusionList;
  394. CItemList ciUserList;
  395. // Load exclusion list, and userlist
  396. if ( (!ciExclusionList.LoadSubList(ciList.GetItem(1))) ||
  397. (!ciUserList.LoadSubList(ciList.GetItem(2)))
  398. )
  399. {
  400. return FALSE;
  401. }
  402. if ( !_tcsstr( ciList.GetItem(0), _T("*")) )
  403. {
  404. for (DWORD i = 0; i < ciUserList.GetNumberOfItems(); i++)
  405. {
  406. if ( bAdd )
  407. {
  408. // It is only a single file, so only call it once
  409. SetFileAcl( (LPTSTR) ciList.GetItem(0), // FileName
  410. ciUserList.GetItem(i), // UserName
  411. SE_FILE_OBJECT, // The type of object
  412. ciList.GetNumber(3), // dwAccess Mask
  413. ciList.GetNumber(4), // bAllow access
  414. ciList.GetNumber(5), // bInhertance Flags
  415. bAddAcltoOriginal );
  416. }
  417. else
  418. {
  419. RemoveUserAcl(ciList.GetItem(0),ciUserList.GetItem(i));
  420. }
  421. }
  422. return TRUE;
  423. }
  424. hFileList = FindFirstFile( ciList.GetItem(0), &sFD );
  425. if (hFileList == INVALID_HANDLE_VALUE)
  426. {
  427. return FALSE;
  428. }
  429. do {
  430. if ( ( !ciExclusionList.FindItem( sFD.cFileName, FALSE ) ) &&
  431. ( _tcscmp( sFD.cFileName, _T(".") ) ) &&
  432. ( _tcscmp( sFD.cFileName, _T("..") ) ) &&
  433. ( CreateFullFileName( BuffFullFileName, ciList.GetItem(0), sFD.cFileName ) )
  434. )
  435. {
  436. for (DWORD i = 0; i < ciUserList.GetNumberOfItems(); i++)
  437. {
  438. if ( bAdd )
  439. {
  440. SetFileAcl( (LPTSTR) BuffFullFileName.QueryPtr(), // FileName
  441. ciUserList.GetItem(i), // UserName
  442. SE_FILE_OBJECT, // The type of object
  443. ciList.GetNumber(3), // dwAccess Mask
  444. ciList.GetNumber(4), // bAllow access
  445. ciList.GetNumber(5), // bInhertance Flags
  446. bAddAcltoOriginal );
  447. }
  448. else
  449. {
  450. RemoveUserAcl((LPTSTR) BuffFullFileName.QueryPtr(),ciUserList.GetItem(i));
  451. }
  452. }
  453. }
  454. } while ( FindNextFile( hFileList, &sFD ) );
  455. FindClose( hFileList );
  456. return TRUE;
  457. }
  458. // function: DoInternalWork
  459. //
  460. // Add the Acl for the files specified
  461. //
  462. // Parameters
  463. // ciList - The list of the parameters from the inf file
  464. // 0 - A list of files (full paths)
  465. // 1 - The exclusion list, list of files to not be inclused (file names only)
  466. // 2 - The user(s) to have access for
  467. // 3 - Access Mask
  468. // 4 - bAllowAccess (FALSE==Denuy Access)
  469. // 5 - Inheritance Flags
  470. BOOL
  471. CFileSys_AddAcl::DoInternalWork(CItemList &ciList)
  472. {
  473. return DoAcling( ciList, TRUE, TRUE );
  474. }
  475. // function: VerifyParameters
  476. //
  477. // Verify the parameters are correct
  478. //
  479. BOOL
  480. CFileSys_RemoveAcl::VerifyParameters(CItemList &ciParams)
  481. {
  482. return ciParams.GetNumberOfItems() == 3;
  483. }
  484. // function: GetMethodName
  485. //
  486. // Return the Method Name for this Class
  487. //
  488. LPTSTR
  489. CFileSys_RemoveAcl::GetMethodName()
  490. {
  491. return _T("FilSys_RemoveAcl");
  492. }
  493. // function: DoInternalWork
  494. //
  495. // Remove an Acl for a specific user
  496. //
  497. // Parameters
  498. // ciList - The list of the parameters from the inf file
  499. // 0 - A list of files (full paths)
  500. // 1 - The exclusion list, list of files to not be inclused (file names only)
  501. // 2 - The user(s) to remove access for
  502. BOOL
  503. CFileSys_RemoveAcl::DoInternalWork(CItemList &ciList)
  504. {
  505. return DoAcling( ciList, FALSE );
  506. }
  507. // function: VerifyParameters
  508. //
  509. // Verify the parameters are correct
  510. //
  511. BOOL
  512. CFileSys_SetAcl::VerifyParameters(CItemList &ciParams)
  513. {
  514. if ( ( ciParams.GetNumberOfItems() == 6 ) &&
  515. ciParams.IsNumber(3) &&
  516. ciParams.IsNumber(4) &&
  517. ciParams.IsNumber(5)
  518. )
  519. {
  520. return TRUE;
  521. }
  522. return FALSE;
  523. }
  524. // function: GetMethodName
  525. //
  526. // Return the Method Name for this Class
  527. //
  528. LPTSTR
  529. CFileSys_SetAcl::GetMethodName()
  530. {
  531. return _T("FilSys_SetAcl");
  532. }
  533. // function: DoInternalWork
  534. //
  535. // Set the Acl for the files specified (ignoring previous acl's)
  536. //
  537. // Parameters
  538. // ciList - The list of the parameters from the inf file
  539. // 0 - A list of files (full paths)
  540. // 1 - The exclusion list, list of files to not be inclused (file names only)
  541. // 2 - The user(s) to have access for
  542. // 3 - Access Mask
  543. // 4 - bAllowAccess (FALSE==Denuy Access)
  544. // 5 - Inheritance Flags
  545. BOOL
  546. CFileSys_SetAcl::DoInternalWork(CItemList &ciList)
  547. {
  548. return DoAcling( ciList, TRUE, FALSE );
  549. }