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.

309 lines
7.5 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999.
  5. //
  6. // File: users.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 8-10-99 JBrezak Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. #define SECURITY_WIN32
  22. #include <rpc.h>
  23. #include <ntsecapi.h>
  24. #include <sspi.h>
  25. extern "C" {
  26. #include <secint.h>
  27. }
  28. #include <stdio.h>
  29. #include <winsta.h>
  30. #include <ntdsapi.h>
  31. #include <shlwapi.h>
  32. #include <assert.h>
  33. #ifndef UNICODE
  34. #define UNICODE
  35. #endif
  36. #define _UNICODE
  37. LPTSTR FormatUserUpn(
  38. BOOL UseUpn,
  39. PSECURITY_STRING Domain,
  40. PSECURITY_STRING User
  41. )
  42. {
  43. static TCHAR UName[DOMAIN_LENGTH + USERNAME_LENGTH + 2];
  44. HANDLE hDs;
  45. ULONG NetStatus;
  46. PDS_NAME_RESULT Result;
  47. TCHAR DName[DOMAIN_LENGTH + 1];
  48. LPTSTR Name = UName;
  49. swprintf(DName, L"%wZ", Domain);
  50. swprintf(UName, L"%wZ\\%wZ", Domain, User);
  51. if (!UseUpn)
  52. return UName;
  53. NetStatus = DsBind(NULL, DName, &hDs);
  54. if (NetStatus != 0) {
  55. #ifdef DBGX
  56. wprintf(L"DsBind failed -0x%x\n", NetStatus);
  57. #endif
  58. return UName;
  59. }
  60. NetStatus = DsCrackNames(hDs, DS_NAME_NO_FLAGS, DS_NT4_ACCOUNT_NAME,
  61. DS_USER_PRINCIPAL_NAME, 1, &Name, &Result);
  62. if (NetStatus != 0) {
  63. #ifdef DBGX
  64. wprintf(L"DsCrackNames failed -0x%x\n", NetStatus);
  65. #endif
  66. return UName;
  67. }
  68. if (Result->rItems[0].pName)
  69. return Result->rItems[0].pName;
  70. else
  71. return UName;
  72. }
  73. static LPCTSTR dt_output_dhms = L"%d %s %02d:%02d:%02d";
  74. static LPCTSTR dt_day_plural = L"days";
  75. static LPCTSTR dt_day_singular = L"day";
  76. static LPCTSTR dt_output_donly = L"%d %s";
  77. static LPCTSTR dt_output_ms = L"%d:%02d";
  78. static LPCTSTR dt_output_hms = L"%d:%02d:%02d";
  79. static LPCTSTR ftime_default_fmt = L"%02d/%02d/%02d %02d:%02d";
  80. LPTSTR FormatIdleTime(
  81. long dt
  82. )
  83. {
  84. static TCHAR buf2[80];
  85. int days, hours, minutes, seconds, tt;
  86. days = (int) (dt / (24*3600l));
  87. tt = dt % (24*3600l);
  88. hours = (int) (tt / 3600);
  89. tt %= 3600;
  90. minutes = (int) (tt / 60);
  91. seconds = (int) (tt % 60);
  92. if (days) {
  93. if (hours || minutes || seconds) {
  94. wnsprintf(buf2, sizeof(buf2)/sizeof(buf2[0]),
  95. dt_output_dhms, days,
  96. (days > 1) ? dt_day_plural : dt_day_singular,
  97. hours, minutes, seconds);
  98. }
  99. else {
  100. wnsprintf(buf2, sizeof(buf2)/sizeof(buf2[0]),
  101. dt_output_donly, days,
  102. (days > 1) ? dt_day_plural : dt_day_singular);
  103. }
  104. }
  105. else {
  106. wnsprintf(buf2, sizeof(buf2)/sizeof(buf2[0]),
  107. dt_output_hms, hours, minutes, seconds);
  108. }
  109. return buf2;
  110. }
  111. LPTSTR FormatLogonType(
  112. ULONG LogonType
  113. )
  114. {
  115. static TCHAR buf[20];
  116. switch((SECURITY_LOGON_TYPE)LogonType) {
  117. case Interactive:
  118. lstrcpy(buf, L"Interactive");
  119. break;
  120. case Network:
  121. lstrcpy(buf, L"Network");
  122. break;
  123. case Batch:
  124. lstrcpy(buf, L"Batch");
  125. break;
  126. case Service:
  127. lstrcpy(buf, L"Service");
  128. break;
  129. case Proxy:
  130. lstrcpy(buf, L"Proxy");
  131. break;
  132. case Unlock:
  133. lstrcpy(buf, L"Unlock");
  134. break;
  135. case NetworkCleartext:
  136. lstrcpy(buf, L"NetworkCleartext");
  137. break;
  138. case NewCredentials:
  139. lstrcpy(buf, L"NewCredentials");
  140. break;
  141. default:
  142. wnsprintf(buf, sizeof(buf)/sizeof(buf[0]), TEXT("(%d)"), LogonType);
  143. break;
  144. }
  145. return buf;
  146. }
  147. void Usage(
  148. void
  149. )
  150. {
  151. wprintf(L"\
  152. Usage: users [-u] [-a]\n\
  153. -u = Print userPrincipalName\n\
  154. -a = Print all logon sessions\n");
  155. ExitProcess(0);
  156. }
  157. void __cdecl main (
  158. int argc,
  159. char *argv[]
  160. )
  161. {
  162. ULONG LogonSessionCount;
  163. PLUID LogonSessions;
  164. int i;
  165. DWORD err;
  166. PSECURITY_LOGON_SESSION_DATA SessionData;
  167. DWORD all = FALSE;
  168. DWORD UPN = FALSE;
  169. WINSTATIONINFORMATION WinStationInfo;
  170. DWORD WinStationInfoLen;
  171. char *ptr;
  172. FILETIME LocalTime;
  173. SYSTEMTIME LogonTime;
  174. TCHAR DateStr[40], TimeStr[40];
  175. WINSTATIONNAME WinStationName = L"inactive";
  176. long IdleTime = 0L;
  177. for (i = 1; i < argc; i++) {
  178. if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
  179. for (ptr = (argv[i] + 1); *ptr; ptr++) {
  180. switch(toupper(*ptr)) {
  181. case 'A':
  182. all = TRUE;
  183. break;
  184. case 'U':
  185. UPN = TRUE;
  186. break;
  187. case '?':
  188. default:
  189. Usage();
  190. break;
  191. }
  192. }
  193. }
  194. }
  195. err = LsaEnumerateLogonSessions(&LogonSessionCount, &LogonSessions);
  196. if (err != ERROR_SUCCESS) {
  197. wprintf(L"LsaEnumeratelogonSession failed - 0x%x\n", err);
  198. ExitProcess(1);
  199. }
  200. for (i = 0; i < (int)LogonSessionCount; i++) {
  201. err = LsaGetLogonSessionData(&LogonSessions[i], &SessionData);
  202. if (err != ERROR_SUCCESS) {
  203. wprintf(L"LsaGetLogonSessionData failed - 0x%x\n", err);
  204. continue;
  205. }
  206. if (SessionData->LogonType != 0 &&
  207. (all || ((SECURITY_LOGON_TYPE)SessionData->LogonType == Interactive))) {
  208. ZeroMemory(DateStr, sizeof(DateStr));
  209. ZeroMemory(TimeStr, sizeof(TimeStr));
  210. if (!FileTimeToLocalFileTime((LPFILETIME)&SessionData->LogonTime,
  211. &LocalTime) ||
  212. !FileTimeToSystemTime(&LocalTime, &LogonTime)) {
  213. wprintf(L"Time conversion failed - 0x%x\n", GetLastError());
  214. }
  215. else {
  216. if (!GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE,
  217. &LogonTime, NULL,
  218. DateStr, sizeof(DateStr)/sizeof(DateStr[0]))) {
  219. wprintf(L"Date format failed - 0x%x\n", GetLastError());
  220. }
  221. if (!GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS,
  222. &LogonTime, NULL,
  223. TimeStr, sizeof(TimeStr)/sizeof(TimeStr[0]))) {
  224. wprintf(L"Time format failed - 0x%x\n", GetLastError());
  225. }
  226. }
  227. if (WinStationQueryInformation(SERVERNAME_CURRENT,
  228. SessionData->Session,
  229. WinStationInformation,
  230. &WinStationInfo,
  231. sizeof(WinStationInfo),
  232. &WinStationInfoLen)) {
  233. if (WinStationInfo.ConnectState != State_Idle) {
  234. wcsncpy(WinStationName, WinStationInfo.WinStationName, sizeof(WinStationName)/sizeof(WinStationName[0]));
  235. WinStationName[sizeof(WinStationName)/sizeof(WinStationName[0])-1] = 0;
  236. }
  237. const long TPS = (10*1000*1000);
  238. FILETIME CurrentFileTime;
  239. LARGE_INTEGER Quad;
  240. GetSystemTimeAsFileTime(&CurrentFileTime);
  241. Quad.LowPart = CurrentFileTime.dwLowDateTime;
  242. Quad.HighPart = CurrentFileTime.dwHighDateTime;
  243. IdleTime = (long)
  244. ((Quad.QuadPart - WinStationInfo.LastInputTime.QuadPart) / TPS);
  245. }
  246. else if (GetLastError() == ERROR_APP_WRONG_OS) {
  247. assert(sizeof(WinStationName)/sizeof(WinStationName[0]) >= wcslen(L"Console"));
  248. wcscpy(WinStationName, L"Console");
  249. }
  250. else {
  251. #ifdef DBGX
  252. wprintf(L"Query failed for %wZ\\%wZ @ %d - 0x%x\n",
  253. &SessionData->LogonDomain, &SessionData->UserName,
  254. SessionData->Session,
  255. GetLastError());
  256. #endif
  257. continue;
  258. }
  259. wprintf(L"%-30.30s",
  260. FormatUserUpn(UPN, &SessionData->LogonDomain,
  261. &SessionData->UserName));
  262. if (all)
  263. wprintf(L" %-12.12s",
  264. FormatLogonType(SessionData->LogonType));
  265. wprintf(L" %8.8s %s %s", WinStationName, DateStr, TimeStr);
  266. if (all)
  267. wprintf(L" %wZ",
  268. &SessionData->AuthenticationPackage);
  269. if (all && (IdleTime > 10))
  270. wprintf(L" %-12.12s", FormatIdleTime(IdleTime));
  271. wprintf(L"\n");
  272. }
  273. }
  274. ExitProcess(0);
  275. }