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.

483 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: util.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 5-21-97 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <ntlsa.h>
  21. #include <windows.h>
  22. #include <userenv.h>
  23. #include <userenvp.h>
  24. #include <lm.h>
  25. #include "moveme.h"
  26. #define USER_SHELL_FOLDER TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders")
  27. #define PROFILE_LIST_PATH TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList")
  28. #define PROFILE_FLAGS TEXT("Flags")
  29. #define PROFILE_STATE TEXT("State")
  30. #define PROFILE_IMAGE_VALUE_NAME TEXT("ProfileImagePath")
  31. #define PROFILE_CENTRAL_PROFILE TEXT("CentralProfile")
  32. #define CONFIG_FILE_PATH TEXT("%SystemRoot%\\Profiles\\")
  33. #define USER_PREFERENCE TEXT("UserPreference")
  34. #define PROFILE_BUILD_NUMBER TEXT("BuildNumber")
  35. #define TEMP_PROFILE_NAME_BASE TEXT("TEMP")
  36. #define DELETE_ROAMING_CACHE TEXT("DeleteRoamingCache")
  37. #define USER_PROFILE_MUTEX TEXT("userenv: User Profile Mutex")
  38. LPTSTR
  39. SidToString(
  40. PSID Sid
  41. )
  42. {
  43. UNICODE_STRING String ;
  44. NTSTATUS Status ;
  45. Status = RtlConvertSidToUnicodeString( &String, Sid, TRUE );
  46. if ( NT_SUCCESS( Status ) )
  47. {
  48. return String.Buffer ;
  49. }
  50. return NULL ;
  51. }
  52. VOID
  53. FreeSidString(
  54. LPTSTR SidString
  55. )
  56. {
  57. UNICODE_STRING String ;
  58. RtlInitUnicodeString( &String, SidString );
  59. RtlFreeUnicodeString( &String );
  60. }
  61. //*************************************************************
  62. //
  63. // GetUserProfileDirectory()
  64. //
  65. // Purpose: Returns the root of the user's profile directory.
  66. //
  67. // Parameters: hToken - User's token
  68. // lpProfileDir - Output buffer
  69. // lpcchSize - Size of output buffer
  70. //
  71. // Return: TRUE if successful
  72. // FALSE if an error occurs
  73. //
  74. // Comments: If false is returned, lpcchSize holds the number of
  75. // characters needed.
  76. //
  77. // History: Date Author Comment
  78. // 9/18/95 ericflo Created
  79. //
  80. //*************************************************************
  81. BOOL
  82. WINAPI
  83. GetUserProfileDirectoryFromSid(
  84. PSID Sid,
  85. LPTSTR lpProfileDir,
  86. LPDWORD lpcchSize
  87. )
  88. {
  89. DWORD dwLength = MAX_PATH * sizeof(TCHAR);
  90. DWORD dwType;
  91. BOOL bRetVal = FALSE;
  92. LPTSTR lpSidString;
  93. TCHAR szBuffer[MAX_PATH];
  94. TCHAR szDirectory[MAX_PATH];
  95. HKEY hKey;
  96. LONG lResult;
  97. //
  98. // Retrieve the user's sid string
  99. //
  100. lpSidString = SidToString( Sid );
  101. if (!lpSidString) {
  102. return FALSE;
  103. }
  104. //
  105. // Check the registry
  106. //
  107. lstrcpy(szBuffer, PROFILE_LIST_PATH);
  108. lstrcat(szBuffer, TEXT("\\"));
  109. lstrcat(szBuffer, lpSidString);
  110. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ,
  111. &hKey);
  112. if (lResult != ERROR_SUCCESS) {
  113. FreeSidString(lpSidString);
  114. return FALSE;
  115. }
  116. lResult = RegQueryValueEx(hKey,
  117. PROFILE_IMAGE_VALUE_NAME,
  118. NULL,
  119. &dwType,
  120. (LPBYTE) szBuffer,
  121. &dwLength);
  122. if (lResult != ERROR_SUCCESS) {
  123. RegCloseKey (hKey);
  124. FreeSidString(lpSidString);
  125. return FALSE;
  126. }
  127. //
  128. // Clean up
  129. //
  130. RegCloseKey(hKey);
  131. FreeSidString(lpSidString);
  132. //
  133. // Expand and get the length of string
  134. //
  135. ExpandEnvironmentStrings(szBuffer, szDirectory, MAX_PATH);
  136. dwLength = lstrlen(szDirectory) + 1;
  137. //
  138. // Save the string if appropriate
  139. //
  140. if (lpProfileDir) {
  141. if (*lpcchSize >= dwLength) {
  142. lstrcpy (lpProfileDir, szDirectory);
  143. bRetVal = TRUE;
  144. } else {
  145. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  146. }
  147. }
  148. *lpcchSize = dwLength;
  149. return bRetVal;
  150. }
  151. BOOL
  152. SetUserProfileDirectory(
  153. PSID Base,
  154. PSID Copy
  155. )
  156. {
  157. LPTSTR lpSidString;
  158. TCHAR szBuffer[MAX_PATH];
  159. HKEY hKey;
  160. HKEY hNewKey ;
  161. LONG lResult;
  162. DWORD Disp ;
  163. WCHAR CopyBuffer[ MAX_PATH ] ;
  164. DWORD CopySize ;
  165. DWORD ValueCount ;
  166. DWORD ValueNameLen ;
  167. DWORD ValueDataLen ;
  168. PUCHAR Value ;
  169. DWORD Type ;
  170. DWORD Index ;
  171. DWORD NameSize ;
  172. //
  173. // Retrieve the user's sid string
  174. //
  175. lpSidString = SidToString( Base );
  176. if (!lpSidString) {
  177. return FALSE;
  178. }
  179. //
  180. // Check the registry
  181. //
  182. lstrcpy(szBuffer, PROFILE_LIST_PATH);
  183. lstrcat(szBuffer, TEXT("\\"));
  184. lstrcat(szBuffer, lpSidString);
  185. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ,
  186. &hKey);
  187. FreeSidString( lpSidString );
  188. if ( lResult != 0 )
  189. {
  190. return FALSE ;
  191. }
  192. //
  193. // Retrieve the user's sid string
  194. //
  195. lpSidString = SidToString( Copy );
  196. if (!lpSidString) {
  197. return FALSE;
  198. }
  199. //
  200. // Check the registry
  201. //
  202. lstrcpy(szBuffer, PROFILE_LIST_PATH);
  203. lstrcat(szBuffer, TEXT("\\"));
  204. lstrcat(szBuffer, lpSidString);
  205. lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  206. szBuffer,
  207. 0,
  208. TEXT(""),
  209. REG_OPTION_NON_VOLATILE,
  210. KEY_READ | KEY_WRITE,
  211. NULL,
  212. &hNewKey,
  213. &Disp );
  214. FreeSidString( lpSidString );
  215. if ( lResult != 0 )
  216. {
  217. return FALSE ;
  218. }
  219. //
  220. // Copy Key:
  221. //
  222. lResult = RegQueryInfoKey( hKey,
  223. NULL,
  224. NULL,
  225. NULL,
  226. NULL,
  227. NULL,
  228. NULL,
  229. &ValueCount,
  230. &ValueNameLen,
  231. &ValueDataLen,
  232. NULL,
  233. NULL );
  234. if ( lResult != 0 )
  235. {
  236. return FALSE ;
  237. }
  238. Value = LocalAlloc( LMEM_FIXED, ValueDataLen );
  239. if ( Value )
  240. {
  241. Index = 0 ;
  242. do
  243. {
  244. CopySize = ValueDataLen ;
  245. NameSize = MAX_PATH ;
  246. lResult = RegEnumValue( hKey,
  247. Index,
  248. CopyBuffer,
  249. &NameSize,
  250. NULL,
  251. &Type,
  252. Value,
  253. &CopySize );
  254. if ( lResult == 0 )
  255. {
  256. lResult = RegSetValueEx( hNewKey,
  257. CopyBuffer,
  258. 0,
  259. Type,
  260. Value,
  261. CopySize );
  262. }
  263. ValueCount-- ;
  264. Index ++ ;
  265. } while ( ValueCount );
  266. LocalFree( Value );
  267. }
  268. lResult = RegSetValueEx( hNewKey,
  269. TEXT("Sid"),
  270. 0,
  271. REG_BINARY,
  272. Copy,
  273. RtlLengthSid( Copy )
  274. );
  275. if (lResult == 0) {
  276. return TRUE;
  277. } else {
  278. return FALSE;
  279. }
  280. }
  281. LONG
  282. MyRegSaveKey(
  283. HKEY Key,
  284. LPTSTR File,
  285. LPSECURITY_ATTRIBUTES lpsa
  286. )
  287. {
  288. BOOL bResult = TRUE;
  289. LONG error;
  290. NTSTATUS Status;
  291. BOOLEAN WasEnabled;
  292. //
  293. // Enable the restore privilege
  294. //
  295. Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  296. if (NT_SUCCESS(Status))
  297. {
  298. error = RegSaveKey( Key, File, lpsa );
  299. Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, WasEnabled, FALSE, &WasEnabled);
  300. }
  301. else
  302. {
  303. error = RtlNtStatusToDosError( Status );
  304. }
  305. return error ;
  306. }
  307. BOOL
  308. GetPrimaryDomain(
  309. PWSTR Domain
  310. )
  311. {
  312. NTSTATUS Status, IgnoreStatus;
  313. OBJECT_ATTRIBUTES ObjectAttributes;
  314. LSA_HANDLE LsaHandle;
  315. SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
  316. PPOLICY_PRIMARY_DOMAIN_INFO PrimaryDomainInfo;
  317. BOOL PrimaryDomainPresent = FALSE;
  318. //
  319. // Set up the Security Quality Of Service
  320. //
  321. SecurityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  322. SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation;
  323. SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  324. SecurityQualityOfService.EffectiveOnly = FALSE;
  325. //
  326. // Set up the object attributes to open the Lsa policy object
  327. //
  328. InitializeObjectAttributes(&ObjectAttributes,
  329. NULL,
  330. 0L,
  331. (HANDLE)NULL,
  332. NULL);
  333. ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService;
  334. //
  335. // Open the local LSA policy object
  336. //
  337. Status = LsaOpenPolicy( NULL,
  338. &ObjectAttributes,
  339. POLICY_VIEW_LOCAL_INFORMATION,
  340. &LsaHandle
  341. );
  342. if (!NT_SUCCESS(Status)) {
  343. DebugLog((DEB_ERROR, "Failed to open local LsaPolicyObject, Status = 0x%lx\n", Status));
  344. return(FALSE);
  345. }
  346. //
  347. // Get the primary domain info
  348. //
  349. Status = LsaQueryInformationPolicy(LsaHandle,
  350. PolicyPrimaryDomainInformation,
  351. (PVOID *)&PrimaryDomainInfo);
  352. if (!NT_SUCCESS(Status)) {
  353. DebugLog((DEB_ERROR, "Failed to query primary domain from Lsa, Status = 0x%lx\n", Status));
  354. IgnoreStatus = LsaClose(LsaHandle);
  355. ASSERT(NT_SUCCESS(IgnoreStatus));
  356. return(FALSE);
  357. }
  358. //
  359. // Copy the primary domain name into the return string
  360. //
  361. if (PrimaryDomainInfo->Sid != NULL) {
  362. PrimaryDomainPresent = TRUE;
  363. if ( Domain )
  364. {
  365. CopyMemory( Domain, PrimaryDomainInfo->Name.Buffer,
  366. PrimaryDomainInfo->Name.Length + 2 );
  367. }
  368. }
  369. //
  370. // We're finished with the Lsa
  371. //
  372. IgnoreStatus = LsaFreeMemory(PrimaryDomainInfo);
  373. ASSERT(NT_SUCCESS(IgnoreStatus));
  374. IgnoreStatus = LsaClose(LsaHandle);
  375. ASSERT(NT_SUCCESS(IgnoreStatus));
  376. return(PrimaryDomainPresent);
  377. }