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.

480 lines
11 KiB

  1. #ifndef _WIN32_WINNT
  2. #define _WIN32_WINNT 0x0500
  3. #endif
  4. #include <windows.h>
  5. #include <tchar.h>
  6. #include <stdio.h>
  7. #include "webcaum.h"
  8. #include "..\..\shared\common.h"
  9. #include "..\..\shared\apppool.h"
  10. bool AddAccessRights( TCHAR *lpszFileName, TCHAR *szUserName, DWORD dwAccessMask )
  11. {
  12. //
  13. // SID variables.
  14. //
  15. SID_NAME_USE snuType;
  16. TCHAR * szDomain = NULL;
  17. DWORD cbDomain = 0;
  18. //
  19. // User name variables.
  20. //
  21. LPVOID pUserSID = NULL;
  22. DWORD cbUserSID = 0;
  23. DWORD cbUserName = 0;
  24. //
  25. // File SD variables.
  26. //
  27. PSECURITY_DESCRIPTOR pFileSD = NULL;
  28. DWORD cbFileSD = 0;
  29. //
  30. // New SD variables.
  31. //
  32. PSECURITY_DESCRIPTOR pNewSD = NULL;
  33. //
  34. // ACL variables.
  35. //
  36. PACL pACL = NULL;
  37. BOOL fDaclPresent;
  38. BOOL fDaclDefaulted;
  39. ACL_SIZE_INFORMATION AclInfo;
  40. //
  41. // New ACL variables.
  42. //
  43. PACL pNewACL = NULL;
  44. DWORD cbNewACL = 0;
  45. //
  46. // Temporary ACE.
  47. //
  48. LPVOID pTempAce = NULL;
  49. UINT CurrentAceIndex;
  50. bool fResult = false;
  51. BOOL fAPISuccess;
  52. // error code
  53. DWORD lastErr = 0;
  54. try
  55. {
  56. //
  57. // Call this API once to get the buffer sizes ( it will return ERROR_INSUFFICIENT_BUFFER )
  58. //
  59. fAPISuccess = LookupAccountName( NULL, szUserName, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType );
  60. if( fAPISuccess )
  61. {
  62. throw E_FAIL; // we throw some fake error to skip through to the exit door
  63. }
  64. else if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
  65. {
  66. lastErr = GetLastError();
  67. LogError( TEXT( "LookupAccountName() failed" ), lastErr );
  68. throw lastErr;
  69. }
  70. //
  71. // allocate the buffers
  72. //
  73. pUserSID = calloc( cbUserSID, 1 );
  74. if( !pUserSID )
  75. {
  76. lastErr = GetLastError();
  77. LogError( TEXT( "Alloc() for UserSID failed" ), lastErr );
  78. throw lastErr;
  79. }
  80. szDomain = ( TCHAR * ) calloc( cbDomain + sizeof TCHAR, sizeof TCHAR );
  81. if( !szDomain )
  82. {
  83. lastErr = GetLastError();
  84. LogError( TEXT( "Alloc() for szDomain failed" ), lastErr );
  85. throw lastErr;
  86. }
  87. //
  88. // The LookupAccountName function accepts the name of a system and an account as input.
  89. // It retrieves a security identifier ( SID ) for the account and
  90. // the name of the domain on which the account was found
  91. //
  92. fAPISuccess = LookupAccountName( NULL /* = local computer */, szUserName, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType );
  93. if( !fAPISuccess )
  94. {
  95. lastErr = GetLastError();
  96. LogError( TEXT( "LookupAccountName() failed" ), lastErr );
  97. throw lastErr;
  98. }
  99. //
  100. // call this API once to get the buffer sizes
  101. // API should have failed with insufficient buffer.
  102. //
  103. fAPISuccess = GetFileSecurity( lpszFileName, DACL_SECURITY_INFORMATION, pFileSD, 0, &cbFileSD );
  104. if( fAPISuccess )
  105. {
  106. throw E_FAIL;
  107. }
  108. else if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
  109. {
  110. lastErr = GetLastError();
  111. LogError( TEXT( "GetFileSecurity() failed" ), lastErr );
  112. throw lastErr;
  113. }
  114. //
  115. // allocate the buffers
  116. //
  117. pFileSD = calloc( cbFileSD, 1 );
  118. if( !pFileSD )
  119. {
  120. lastErr = GetLastError();
  121. LogError( TEXT( "Alloc() for pFileSD failed" ), lastErr );
  122. throw lastErr;
  123. }
  124. //
  125. // call the api to get the actual data
  126. //
  127. fAPISuccess = GetFileSecurity( lpszFileName, DACL_SECURITY_INFORMATION, pFileSD, cbFileSD, &cbFileSD );
  128. if( !fAPISuccess )
  129. {
  130. lastErr = GetLastError();
  131. LogError( TEXT( "GetFileSecurity() failed" ), lastErr );
  132. throw lastErr;
  133. }
  134. //
  135. // Initialize new SD.
  136. //
  137. pNewSD = calloc( cbFileSD, 1 ); // Should be same size as FileSD.
  138. if( !pNewSD )
  139. {
  140. lastErr = GetLastError();
  141. LogError( TEXT( "Alloc() for pNewDS failed" ), GetLastError() );
  142. throw lastErr;
  143. }
  144. if( !InitializeSecurityDescriptor( pNewSD, SECURITY_DESCRIPTOR_REVISION ) )
  145. {
  146. lastErr = GetLastError();
  147. LogError( TEXT( "InitializeSecurityDescriptor() failed" ), lastErr );
  148. throw lastErr;
  149. }
  150. //
  151. // Get DACL from SD.
  152. //
  153. if( !GetSecurityDescriptorDacl( pFileSD, &fDaclPresent, &pACL, &fDaclDefaulted ) )
  154. {
  155. lastErr = GetLastError();
  156. LogError( TEXT( "GetSecurityDescriptorDacl() failed" ), lastErr );
  157. throw lastErr;
  158. }
  159. //
  160. // Get size information for DACL.
  161. //
  162. AclInfo.AceCount = 0; // Assume NULL DACL.
  163. AclInfo.AclBytesFree = 0;
  164. AclInfo.AclBytesInUse = sizeof( ACL ); // If not NULL DACL, gather size information from DACL.
  165. if( fDaclPresent && pACL )
  166. {
  167. if( !GetAclInformation( pACL, &AclInfo, sizeof( ACL_SIZE_INFORMATION ), AclSizeInformation ) )
  168. {
  169. lastErr = GetLastError();
  170. LogError( TEXT( "GetAclInformation() failed" ), lastErr );
  171. throw lastErr;
  172. }
  173. }
  174. //
  175. // Compute size needed for the new ACL.
  176. //
  177. cbNewACL = AclInfo.AclBytesInUse + sizeof( ACCESS_ALLOWED_ACE ) + GetLengthSid( pUserSID );
  178. //
  179. // Allocate memory for new ACL.
  180. //
  181. pNewACL = ( PACL ) calloc( cbNewACL, 1 );
  182. if( !pNewACL )
  183. {
  184. lastErr = GetLastError();
  185. LogError( TEXT( "HeapAlloc() failed" ), lastErr );
  186. throw lastErr;
  187. }
  188. //
  189. // Initialize the new ACL.
  190. //
  191. if( !InitializeAcl( pNewACL, cbNewACL, ACL_REVISION2 ) )
  192. {
  193. lastErr = GetLastError();
  194. LogError( TEXT( "InitializeAcl() failed" ), lastErr );
  195. throw lastErr;
  196. }
  197. //
  198. // Add the access-allowed ACE to the new DACL.
  199. //
  200. ACE_HEADER aceheader = {0};
  201. aceheader.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
  202. aceheader.AceSize = sizeof( ACE_HEADER );
  203. aceheader.AceType = ACCESS_ALLOWED_OBJECT_ACE_TYPE;
  204. if( !AddAccessAllowedAceEx( pNewACL, ACL_REVISION2, aceheader.AceFlags, dwAccessMask, pUserSID ) )
  205. {
  206. lastErr = GetLastError();
  207. LogError( TEXT( "AddAccessAllowedAce() failed" ), lastErr );
  208. throw lastErr;
  209. }
  210. //
  211. // If DACL is present, copy it to a new DACL.
  212. //
  213. if( fDaclPresent )
  214. {
  215. //
  216. // Copy the file's ACEs to the new ACL
  217. //
  218. if( AclInfo.AceCount )
  219. {
  220. for( CurrentAceIndex = 0; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++ )
  221. {
  222. //
  223. // Get an ACE.
  224. //
  225. if( !GetAce( pACL, CurrentAceIndex, &pTempAce ) )
  226. {
  227. lastErr = GetLastError();
  228. LogError( TEXT( "GetAce() failed" ), lastErr );
  229. throw lastErr;
  230. }
  231. //
  232. // Add the ACE to the new ACL.
  233. //
  234. if( !AddAce( pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ( ( PACE_HEADER ) pTempAce )->AceSize ) )
  235. {
  236. lastErr = GetLastError();
  237. LogError( TEXT( "AddAce() failed" ), lastErr );
  238. throw lastErr;
  239. }
  240. }
  241. }
  242. }
  243. //
  244. // Set the new DACL to the file SD.
  245. //
  246. if( !SetSecurityDescriptorDacl( pNewSD, TRUE, pNewACL, FALSE ) )
  247. {
  248. lastErr = GetLastError();
  249. LogError( TEXT( "SetSecurityDescriptorDacl() failed" ), lastErr );
  250. lastErr;
  251. }
  252. //
  253. // Set the SD to the File.
  254. //
  255. if( !SetFileSecurity( lpszFileName, DACL_SECURITY_INFORMATION, pNewSD ) )
  256. {
  257. lastErr = GetLastError();
  258. LogError( TEXT( "SetFileSecurity() failed" ), lastErr );
  259. throw lastErr;
  260. }
  261. fResult = TRUE;
  262. }
  263. catch (...)
  264. {
  265. fResult = FALSE;
  266. }
  267. //
  268. // Free allocated memory
  269. //
  270. if( pUserSID )
  271. free( pUserSID );
  272. if( szDomain )
  273. free( szDomain );
  274. if( pFileSD )
  275. free( pFileSD );
  276. if( pNewSD )
  277. free( pNewSD );
  278. if( pNewACL )
  279. free( pNewACL );
  280. return fResult;
  281. }
  282. //----------------------------------------------------------------------------
  283. // give the domain account read access to the webroot folder and subfolders
  284. //
  285. bool SetUDDIFolderDacls( TCHAR *szUserName )
  286. {
  287. ENTER();
  288. TCHAR szUDDIInstallPath[ MAX_PATH + 1 ];
  289. TCHAR szSubfolderPath[ MAX_PATH + 1 ];
  290. //
  291. // get UDDI install location ( it already has a backslash )
  292. //
  293. if( !GetUDDIInstallPath( szUDDIInstallPath, MAX_PATH ) )
  294. return false;
  295. //
  296. // give read access to the webroot folder
  297. //
  298. _sntprintf( szSubfolderPath, MAX_PATH, TEXT( "%s%s" ), szUDDIInstallPath, TEXT( "webroot\\" ) );
  299. SetFolderAclRecurse( szSubfolderPath, szUserName );
  300. return true;
  301. }
  302. //-------------------------------------------------------------------*
  303. bool SetFolderAclRecurse( PTCHAR szDirName, PTCHAR szUserName, DWORD dwAccessMask )
  304. {
  305. //
  306. // add the ACE for this folder
  307. //
  308. Log( TEXT( "Giving %s access to folder %s" ), szUserName, szDirName );
  309. if( !AddAccessRights( szDirName, szUserName, dwAccessMask ) )
  310. {
  311. LogError( TEXT( "Error:" ), GetLastError() );
  312. return false;
  313. }
  314. //
  315. // search any subdirectories:
  316. //
  317. TCHAR tmpFileName[MAX_PATH];
  318. _tcscpy( tmpFileName, szDirName );
  319. _tcscat( tmpFileName, TEXT( "*" ) );
  320. WIN32_FIND_DATA FindData;
  321. HANDLE hFindFile = FindFirstFileEx( tmpFileName, FindExInfoStandard, &FindData,
  322. FindExSearchLimitToDirectories, NULL, 0 );
  323. if( hFindFile == INVALID_HANDLE_VALUE )
  324. {
  325. return true;
  326. }
  327. do
  328. {
  329. // make sure it's really a directory
  330. if( FILE_ATTRIBUTE_DIRECTORY & FindData.dwFileAttributes &&
  331. 0 != _tcscmp( FindData.cFileName, TEXT( "." ) ) &&
  332. 0 != _tcscmp( FindData.cFileName, TEXT( ".." ) ) )
  333. {
  334. _tcscpy( tmpFileName, szDirName );
  335. _tcscat( tmpFileName, FindData.cFileName );
  336. _tcscat( tmpFileName, TEXT( "\\" ) );
  337. // recursively call this routine
  338. if( !SetFolderAclRecurse( tmpFileName, szUserName ) )
  339. {
  340. FindClose( hFindFile );
  341. return false;
  342. }
  343. }
  344. }
  345. while( FindNextFile( hFindFile, &FindData ) );
  346. // clean up
  347. FindClose( hFindFile );
  348. return true;
  349. }
  350. //-------------------------------------------------------------------*
  351. bool SetWindowsTempDacls( TCHAR *szUserName )
  352. {
  353. //
  354. // Get the windows temp directory.
  355. //
  356. TCHAR *systemTemp = GetSystemTemp();
  357. if( NULL == systemTemp )
  358. {
  359. return false;
  360. }
  361. //
  362. // Add the rights
  363. //
  364. bool rightsAdded = AddAccessRights( systemTemp, szUserName, GENERIC_READ );
  365. //
  366. // Clean up
  367. //
  368. delete[] systemTemp;
  369. systemTemp = NULL;
  370. return rightsAdded;
  371. }
  372. TCHAR * GetSystemTemp()
  373. {
  374. TCHAR *TEMP = _T( "\\TEMP\\" );
  375. //
  376. // Get the WINDIR environment variable
  377. //
  378. DWORD valueSize = GetEnvironmentVariable( L"WINDIR", NULL, NULL );
  379. if( 0 == valueSize )
  380. {
  381. return NULL;
  382. }
  383. //
  384. // Keep in mind that we need to append \\TEMP to our string as well.
  385. //
  386. valueSize += ( DWORD) _tcslen( TEMP );
  387. TCHAR *valueBuffer = NULL;
  388. valueBuffer = new TCHAR[ valueSize ];
  389. ZeroMemory( valueBuffer, valueSize );
  390. if( NULL == valueBuffer )
  391. {
  392. return NULL;
  393. }
  394. DWORD realSize = GetEnvironmentVariable( L"WINDIR", valueBuffer, valueSize );
  395. if( 0 == realSize || realSize > valueSize )
  396. {
  397. delete[] valueBuffer;
  398. valueBuffer = NULL;
  399. return NULL;
  400. }
  401. //
  402. // Append a \\TEMP to it
  403. //
  404. _tcsncat( valueBuffer, TEMP, _tcslen( TEMP ) );
  405. //
  406. // Make sure we have null terminated.
  407. //
  408. valueBuffer[ valueSize - 1] = 0;
  409. //
  410. // Return the value
  411. //
  412. return valueBuffer;
  413. }