Source code of Windows XP (NT5)
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.

377 lines
8.7 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1992 - 1992
  6. //
  7. // File: expired.cxx
  8. //
  9. // Contents: Program to test if a NT account is about to expire.
  10. //
  11. //
  12. // History: 10-Nov-94 Created MikeSw
  13. //
  14. //------------------------------------------------------------------------
  15. extern "C"
  16. {
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. #include <ntsam.h>
  22. #include <ntlsa.h>
  23. #include <lmaccess.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. }
  28. VOID
  29. DoMsvStuff(
  30. PWSTR Domain
  31. )
  32. {
  33. HKEY hKey ;
  34. DWORD dwType, dwSize ;
  35. int err ;
  36. WCHAR DomainBuffer[ 64 ];
  37. err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  38. TEXT("System\\CurrentControlSet\\Control\\Lsa\\MSV1_0" ),
  39. 0,
  40. KEY_READ | KEY_WRITE,
  41. &hKey );
  42. if ( err == 0 )
  43. {
  44. dwSize = sizeof( DomainBuffer );
  45. err = RegQueryValueEx( hKey,
  46. TEXT("PreferredDomain"),
  47. NULL,
  48. &dwType,
  49. (PBYTE) DomainBuffer,
  50. &dwSize );
  51. if ( err == 0 )
  52. {
  53. //
  54. // Already set, we're done.
  55. //
  56. RegCloseKey( hKey );
  57. return ;
  58. }
  59. dwSize = wcslen( Domain ) * sizeof( WCHAR ) + 2;
  60. err = RegSetValueEx( hKey,
  61. TEXT("PreferredDomain"),
  62. NULL,
  63. REG_SZ,
  64. (PBYTE) Domain,
  65. dwSize );
  66. err = RegSetValueEx( hKey,
  67. TEXT("MappedDomain"),
  68. NULL,
  69. REG_SZ,
  70. (PBYTE) TEXT("NTDEV"),
  71. sizeof( TEXT("NTDEV") ) );
  72. RegCloseKey( hKey );
  73. return ;
  74. }
  75. if ( err = ERROR_ACCESS_DENIED )
  76. {
  77. err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  78. TEXT("System\\CurrentControlSet\\Control\\Lsa\\MSV1_0" ),
  79. 0,
  80. KEY_READ,
  81. &hKey );
  82. if ( err == 0 )
  83. {
  84. err = RegQueryValueEx( hKey,
  85. TEXT("PreferredDomain"),
  86. NULL,
  87. &dwType,
  88. (PBYTE) DomainBuffer,
  89. &dwSize );
  90. if ( err == 0 )
  91. {
  92. //
  93. // Already set, we're done.
  94. //
  95. RegCloseKey( hKey );
  96. return ;
  97. }
  98. OutputDebugStringW( TEXT("[SECURITY] Unable to set IDW Domain Mapping") );
  99. RegCloseKey( hKey );
  100. return ;
  101. }
  102. }
  103. }
  104. void _cdecl
  105. main(int argc, char *argv[])
  106. {
  107. WCHAR DomainName[100];
  108. WCHAR UserBuffer[100];
  109. WCHAR TestDCName[100];
  110. LPWSTR UserName = NULL;
  111. LPWSTR DCName = NULL;
  112. NTSTATUS Status;
  113. ULONG BufSize = 100;
  114. OBJECT_ATTRIBUTES oa;
  115. UNICODE_STRING UnicodeName;
  116. SAM_HANDLE SamHandle = NULL;
  117. SAM_HANDLE DomainHandle = NULL;
  118. SAM_HANDLE UserHandle = NULL;
  119. LSA_HANDLE LsaHandle = NULL;
  120. PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo = NULL;
  121. PULONG RelativeIds = NULL;
  122. PSID_NAME_USE Use = NULL;
  123. PUSER_LOGON_INFORMATION LogonInfo = NULL;
  124. LARGE_INTEGER CurrentTime;
  125. ULONG CurrentSeconds;
  126. ULONG ExpireSeconds;
  127. ULONG DiffSeconds;
  128. ULONG ExpiryDays;
  129. WCHAR TextBuffer[100];
  130. if (argc != 2)
  131. {
  132. printf("Usage: %s domainname\n",argv[0]);
  133. return;
  134. }
  135. mbstowcs(DomainName,argv[1],100);
  136. DoMsvStuff( DomainName );
  137. if (!GetUserName(UserBuffer,&BufSize))
  138. {
  139. printf("Failed to get user name: %d\n",GetLastError());
  140. return;
  141. }
  142. UserName = wcsrchr(UserBuffer,L'\\');
  143. if (UserName != NULL)
  144. {
  145. UserName++;
  146. }
  147. else UserName = UserBuffer;
  148. // printf("Checking account %ws\\%ws\n",DomainName,UserName);
  149. Status = NetGetDCName(
  150. NULL,
  151. DomainName,
  152. (PBYTE *) &DCName
  153. );
  154. if (Status != 0)
  155. {
  156. printf("Failed to find a DC: %d\n",Status);
  157. return;
  158. }
  159. //
  160. // Connect to the LSA on the DC
  161. //
  162. RtlInitUnicodeString(&UnicodeName,DCName);
  163. // printf("Connecting to DC %wZ\n",&UnicodeName);
  164. InitializeObjectAttributes(&oa,NULL,0,NULL,NULL);
  165. Status = LsaOpenPolicy(
  166. &UnicodeName,
  167. &oa,
  168. POLICY_VIEW_LOCAL_INFORMATION,
  169. &LsaHandle
  170. );
  171. if (!NT_SUCCESS(Status))
  172. {
  173. printf("Failed to open lsa: 0x%x\n",Status);
  174. goto Cleanup;
  175. }
  176. Status = LsaQueryInformationPolicy(
  177. LsaHandle,
  178. PolicyAccountDomainInformation,
  179. (PVOID *) &DomainInfo
  180. );
  181. if (!NT_SUCCESS(Status))
  182. {
  183. printf("Failed to query information policy: 0x%x\n",Status);
  184. goto Cleanup;
  185. }
  186. // printf("Found account domain %wZ\n",&DomainInfo->DomainName);
  187. Status = SamConnect(
  188. &UnicodeName,
  189. &SamHandle,
  190. SAM_SERVER_LOOKUP_DOMAIN,
  191. &oa);
  192. if (!NT_SUCCESS(Status))
  193. {
  194. printf("Failed to connect to sam: 0x%x\n",Status);
  195. goto Cleanup;
  196. }
  197. Status = SamOpenDomain(
  198. SamHandle,
  199. DOMAIN_LOOKUP,
  200. DomainInfo->DomainSid,
  201. &DomainHandle
  202. );
  203. if (!NT_SUCCESS(Status))
  204. {
  205. printf("Failed to open domain: 0x%x\n",Status);
  206. goto Cleanup;
  207. }
  208. RtlInitUnicodeString(
  209. &UnicodeName,
  210. UserName
  211. );
  212. Status = SamLookupNamesInDomain(
  213. DomainHandle,
  214. 1,
  215. &UnicodeName,
  216. &RelativeIds,
  217. &Use
  218. );
  219. if (!NT_SUCCESS(Status))
  220. {
  221. printf("Failed to lookup names in domain: 0x%x\n",Status);
  222. goto Cleanup;
  223. }
  224. if (Use[0] != SidTypeUser)
  225. {
  226. printf("Sid type for user %wZ is not user, is %d\n",&UnicodeName,Use[0]);
  227. goto Cleanup;
  228. }
  229. Status = SamOpenUser(
  230. DomainHandle,
  231. USER_READ_GENERAL | USER_READ_LOGON | USER_READ_ACCOUNT | USER_READ_PREFERENCES,
  232. RelativeIds[0],
  233. &UserHandle
  234. );
  235. if (!NT_SUCCESS(Status))
  236. {
  237. printf("Failed to open user: 0x%x\n",Status);
  238. goto Cleanup;
  239. }
  240. Status = SamQueryInformationUser(
  241. UserHandle,
  242. UserLogonInformation,
  243. (PVOID *) &LogonInfo
  244. );
  245. if (!NT_SUCCESS(Status))
  246. {
  247. printf("Failed to query logon information: 0x%x\n",Status);
  248. goto Cleanup;
  249. }
  250. //
  251. // We got the PasswordMustChange field. Now do something with it.
  252. //
  253. Status = NtQuerySystemTime( &CurrentTime );
  254. if (!NT_SUCCESS(Status))
  255. {
  256. printf("Failed to query system time: 0x%x\n",Status);
  257. goto Cleanup;
  258. }
  259. if (!RtlTimeToSecondsSince1980(&CurrentTime,&CurrentSeconds))
  260. {
  261. printf("Cannot convert current time to seconds since 1980\n");
  262. goto Cleanup;
  263. }
  264. if (!RtlTimeToSecondsSince1980(&LogonInfo->PasswordMustChange,&ExpireSeconds))
  265. {
  266. printf("No password expiry date\n");
  267. goto Cleanup;
  268. }
  269. if (ExpireSeconds < CurrentSeconds)
  270. {
  271. DiffSeconds = 0;
  272. printf("Password has expired\n");
  273. }
  274. else
  275. {
  276. #define SECONDS_PER_DAY (60 * 60 * 24)
  277. DiffSeconds = ExpireSeconds - CurrentSeconds;
  278. ExpiryDays = DiffSeconds/SECONDS_PER_DAY;
  279. wsprintf(TextBuffer,L"Password will expire in %d days\n",ExpiryDays);
  280. if (ExpiryDays <= 14)
  281. {
  282. MessageBox(NULL,TextBuffer,L"Password Will Expire",MB_OK );
  283. }
  284. else
  285. {
  286. printf("%ws",TextBuffer);
  287. }
  288. };
  289. Cleanup:
  290. if (LsaHandle != NULL)
  291. {
  292. LsaClose(LsaHandle);
  293. }
  294. if (UserHandle != NULL)
  295. {
  296. SamCloseHandle(UserHandle);
  297. }
  298. if (DomainHandle != NULL)
  299. {
  300. SamCloseHandle(DomainHandle);
  301. }
  302. if (SamHandle != NULL)
  303. {
  304. SamCloseHandle(SamHandle);
  305. }
  306. if (DomainInfo != NULL)
  307. {
  308. LsaFreeMemory(DomainInfo);
  309. }
  310. if (RelativeIds != NULL)
  311. {
  312. SamFreeMemory(RelativeIds);
  313. }
  314. if (Use != NULL)
  315. {
  316. SamFreeMemory(Use);
  317. }
  318. if (LogonInfo != NULL)
  319. {
  320. SamFreeMemory(LogonInfo);
  321. }
  322. }