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.

500 lines
12 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name :
  4. tsnutl.c
  5. Abstract:
  6. Contains TS Notification DLL Utilities
  7. Author:
  8. TadB
  9. Revision History:
  10. --*/
  11. #include <precomp.h>
  12. #pragma hdrstop
  13. #include "tsnutl.h"
  14. #include "drdbg.h"
  15. //
  16. // For Tracing
  17. //
  18. extern DWORD GLOBAL_DEBUG_FLAGS;
  19. BOOL TSNUTL_IsProtocolRDP()
  20. /*++
  21. Routine Description:
  22. Returns TRUE if the protocol is RDP for this Winstation
  23. Arguments:
  24. Return Value:
  25. TRUE if the protocol is RDP.
  26. --*/
  27. {
  28. ULONG Length;
  29. BOOL bResult;
  30. WINSTATIONCLIENT ClientData;
  31. bResult = WinStationQueryInformation(SERVERNAME_CURRENT,
  32. LOGONID_CURRENT,
  33. WinStationClient,
  34. &ClientData,
  35. sizeof(ClientData),
  36. &Length);
  37. if (bResult) {
  38. return ClientData.ProtocolType == PROTOCOL_RDP;
  39. }
  40. else {
  41. DBGMSG(DBG_ERROR, ("UMRDPPRN:WinStationQueryInformation returned false: %ld\n",
  42. GetLastError()));
  43. return FALSE;
  44. }
  45. }
  46. BOOL TSNUTL_FetchRegistryValue(
  47. IN HKEY regKey,
  48. IN LPWSTR regValueName,
  49. IN OUT PBYTE *buf
  50. )
  51. /*++
  52. Routine Description:
  53. Fetch a registry value.
  54. Arguments:
  55. regKey - Open reg key for value to fetch.
  56. regValueName - Name of registry value to fetch.
  57. buf - Location of fetched value.
  58. Return Value:
  59. TRUE if the value was successfully fetched. Otherwise, FALSE
  60. is returned and GetLastError returns the error code.
  61. --*/
  62. {
  63. LONG sz;
  64. BOOL result = FALSE;
  65. LONG s;
  66. WCHAR tmp[1];
  67. //
  68. // Get the size.
  69. //
  70. sz = 0;
  71. s = RegQueryValueEx(regKey,
  72. regValueName, NULL,
  73. NULL, (PBYTE)&tmp, &sz);
  74. //
  75. // Get the value.
  76. //
  77. if (s == ERROR_MORE_DATA) {
  78. //
  79. // Allocate the buf.
  80. //
  81. if (*buf != NULL) {
  82. PBYTE pTmp = REALLOCMEM(*buf, sz);
  83. if (pTmp != NULL) {
  84. *buf = pTmp;
  85. } else {
  86. FREEMEM(*buf);
  87. *buf = NULL;
  88. }
  89. }
  90. else {
  91. *buf = ALLOCMEM(sz);
  92. }
  93. //
  94. // Fetch the value.
  95. //
  96. if (*buf) {
  97. s = RegQueryValueEx(
  98. regKey,
  99. regValueName, NULL,
  100. NULL,
  101. *buf, &sz
  102. );
  103. if (s != ERROR_SUCCESS) {
  104. DBGMSG(DBG_ERROR, ("TSNUTL: Can't fetch resource %s: %ld.\n",
  105. regValueName, GetLastError()));
  106. FREEMEM(*buf);
  107. *buf = NULL;
  108. }
  109. else {
  110. result = TRUE;
  111. }
  112. }
  113. else {
  114. DBGMSG(DBG_ERROR, ("TSNUTL: Can't allocate %ld bytes\n", sz));
  115. }
  116. }
  117. return result;
  118. }
  119. BOOL
  120. TSNUTL_GetTextualSid(
  121. IN PSID pSid,
  122. IN OUT LPTSTR textualSid,
  123. IN OUT LPDWORD pSidSize
  124. )
  125. /*++
  126. Routine Description:
  127. Get a textual representation of a user SID.
  128. Arguments:
  129. pSid - Binary SID
  130. textualSid - buffer for Textual representaion of Sid
  131. pSidSize - required/provided textualSid buffersize
  132. Return Value:
  133. TRUE if the conversion was successful. Otherwise, FALSE is returned.
  134. GetLastError() can be used for retrieving extended error information.
  135. --*/
  136. {
  137. PSID_IDENTIFIER_AUTHORITY psia;
  138. DWORD dwSubAuthorities;
  139. DWORD dwCounter;
  140. DWORD sidCopySize;
  141. PUCHAR pCount;
  142. BOOL result;
  143. //
  144. // Test if Sid passed in is valid
  145. //
  146. result = IsValidSid(pSid);
  147. //
  148. // Obtain SidIdentifierAuthority
  149. //
  150. if (result) {
  151. psia = GetSidIdentifierAuthority(pSid);
  152. result = GetLastError() == ERROR_SUCCESS;
  153. }
  154. //
  155. // Obtain sidsubauthority count
  156. //
  157. if (result) {
  158. pCount = GetSidSubAuthorityCount(pSid);
  159. result = GetLastError() == ERROR_SUCCESS;
  160. if (result) {
  161. dwSubAuthorities = *pCount;
  162. }
  163. }
  164. //
  165. // Compute approximate buffer length
  166. //
  167. if (result) {
  168. #if DBG
  169. WCHAR buf[MAX_PATH];
  170. wsprintf(buf, TEXT("%lu"), SID_REVISION);
  171. ASSERT(wcslen(buf) <= 15);
  172. #endif
  173. // 'S-' + SID_REVISION + identifierauthority- + subauthorities- + NULL
  174. sidCopySize = (2 + 15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
  175. }
  176. //
  177. // Check provided buffer length.
  178. // If not large enough, indicate proper size and setlasterror
  179. //
  180. if (result) {
  181. if(*pSidSize < sidCopySize) {
  182. *pSidSize = sidCopySize;
  183. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  184. result = FALSE;
  185. }
  186. }
  187. //
  188. // Prepare S-SID_REVISION-
  189. //
  190. if (result) {
  191. sidCopySize = wsprintf(textualSid, TEXT("S-%lu-"), SID_REVISION );
  192. }
  193. //
  194. // Prepare SidIdentifierAuthority
  195. //
  196. if (result) {
  197. if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) {
  198. sidCopySize += wsprintf(textualSid + sidCopySize,
  199. TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
  200. (USHORT)psia->Value[0],
  201. (USHORT)psia->Value[1],
  202. (USHORT)psia->Value[2],
  203. (USHORT)psia->Value[3],
  204. (USHORT)psia->Value[4],
  205. (USHORT)psia->Value[5]);
  206. } else {
  207. sidCopySize += wsprintf(textualSid + sidCopySize,
  208. TEXT("%lu"),
  209. (ULONG)(psia->Value[5] ) +
  210. (ULONG)(psia->Value[4] << 8) +
  211. (ULONG)(psia->Value[3] << 16) +
  212. (ULONG)(psia->Value[2] << 24) );
  213. }
  214. }
  215. //
  216. // Loop through SidSubAuthorities
  217. //
  218. if (result) {
  219. for(dwCounter = 0 ; result && (dwCounter < dwSubAuthorities) ; dwCounter++) {
  220. PDWORD ptr = GetSidSubAuthority(pSid, dwCounter);
  221. result = GetLastError() == ERROR_SUCCESS;
  222. if (result) {
  223. sidCopySize += wsprintf(textualSid + sidCopySize, TEXT("-%lu"), *ptr);
  224. }
  225. }
  226. }
  227. //
  228. // Tell the caller how many chars we provided, not including NULL
  229. //
  230. if (result) {
  231. *pSidSize = sidCopySize;
  232. }
  233. return result;
  234. }
  235. PSID
  236. TSNUTL_GetUserSid(
  237. IN HANDLE hTokenForLoggedOnUser
  238. )
  239. {
  240. /*++
  241. Routine Description:
  242. Allocates memory for psid and returns the psid for the current user
  243. The caller should call FREEMEM to free the memory.
  244. Arguments:
  245. Access Token for the User
  246. Return Value:
  247. if successful, returns the PSID
  248. else, returns NULL
  249. --*/
  250. TOKEN_USER * ptu = NULL;
  251. BOOL bResult;
  252. PSID psid = NULL;
  253. DWORD defaultSize = sizeof(TOKEN_USER);
  254. DWORD Size;
  255. DWORD dwResult;
  256. ptu = (TOKEN_USER *)ALLOCMEM(defaultSize);
  257. if (ptu == NULL) {
  258. goto Cleanup;
  259. }
  260. bResult = GetTokenInformation(
  261. hTokenForLoggedOnUser, // Handle to Token
  262. TokenUser, // Token Information Class
  263. ptu, // Buffer for Token Information
  264. defaultSize, // Size of Buffer
  265. &Size); // Return length
  266. if (bResult == FALSE) {
  267. dwResult = GetLastError();
  268. if (dwResult == ERROR_INSUFFICIENT_BUFFER) {
  269. //
  270. //Allocate required memory
  271. //
  272. FREEMEM(ptu);
  273. ptu = (TOKEN_USER *)ALLOCMEM(Size);
  274. if (ptu == NULL) {
  275. goto Cleanup;
  276. }
  277. else {
  278. defaultSize = Size;
  279. bResult = GetTokenInformation(
  280. hTokenForLoggedOnUser,
  281. TokenUser,
  282. ptu,
  283. defaultSize,
  284. &Size);
  285. if (bResult == FALSE) { //Still failed
  286. DBGMSG(DBG_ERROR,
  287. ("UMRDPDR:GetTokenInformation Failed, Error: %ld\n", GetLastError()));
  288. goto Cleanup;
  289. }
  290. }
  291. }
  292. else {
  293. DBGMSG(DBG_ERROR, ("UMRDPDR:GetTokenInformation Failed, Error: %ld\n", dwResult));
  294. goto Cleanup;
  295. }
  296. }
  297. Size = GetLengthSid(ptu->User.Sid);
  298. //
  299. // Allocate memory. This will be freed by the caller.
  300. //
  301. psid = (PSID) ALLOCMEM(Size);
  302. if (psid != NULL) { // Make sure the allocation succeeded
  303. if (!CopySid(Size, psid, ptu->User.Sid)) {
  304. DBGMSG(DBG_ERROR,
  305. ("UMRDPDR:CopySid Failed, Error: %ld\n", GetLastError()));
  306. FREEMEM(psid);
  307. psid = NULL;
  308. goto Cleanup;
  309. }
  310. }
  311. Cleanup:
  312. if (ptu != NULL)
  313. FREEMEM(ptu);
  314. return psid;
  315. }
  316. #ifdef ENABLETHISWHENITISUSED
  317. PSID
  318. TSNUTL_GetLogonSessionSid(
  319. IN HANDLE hTokenForLoggedOnUser
  320. )
  321. {
  322. /*++
  323. Routine Description:
  324. Get a SID for a logon session.
  325. Arguments:
  326. Access Token for the User
  327. Return Value:
  328. if successful, returns the PSID
  329. else, returns NULL and GetLastError() can be used to get the error code.
  330. --*/
  331. TOKEN_GROUPS * ptg = NULL;
  332. BOOL bResult;
  333. PSID psid = NULL;
  334. DWORD i;
  335. DWORD defaultSize = sizeof(TOKEN_GROUPS);
  336. DWORD size;
  337. DWORD dwResult = ERROR_SUCCESS;
  338. ptg = (TOKEN_GROUPS *)ALLOCMEM(defaultSize);
  339. if (ptg == NULL) {
  340. goto CLEANUPANDEXIT;
  341. }
  342. bResult = GetTokenInformation(
  343. hTokenForLoggedOnUser, // Handle to Token
  344. TokenGroups, // Token Information Class
  345. ptg, // Buffer for Token Information
  346. defaultSize, // Size of Buffer
  347. &size); // Return length
  348. if (bResult == FALSE) {
  349. dwResult = GetLastError();
  350. if (dwResult == ERROR_INSUFFICIENT_BUFFER) {
  351. //
  352. //Allocate required memory
  353. //
  354. FREEMEM(ptg);
  355. ptg = (TOKEN_GROUPS *)ALLOCMEM(size);
  356. if (ptg == NULL) {
  357. dwResult = ERROR_OUTOFMEMORY;
  358. goto CLEANUPANDEXIT;
  359. }
  360. else {
  361. defaultSize = size;
  362. bResult = GetTokenInformation(
  363. hTokenForLoggedOnUser,
  364. TokenGroups,
  365. ptg,
  366. defaultSize,
  367. &size);
  368. if (bResult == FALSE) { //Still failed
  369. dwResult = GetLastError();
  370. DBGMSG(DBG_ERROR,
  371. ("UMRDPDR:GetTokenInformation Failed, Error: %ld\n", GetLastError()));
  372. goto CLEANUPANDEXIT;
  373. }
  374. }
  375. }
  376. else {
  377. DBGMSG(DBG_ERROR, ("UMRDPDR:GetTokenInformation Failed, Error: %ld\n", dwResult));
  378. goto CLEANUPANDEXIT;
  379. }
  380. }
  381. //
  382. // Iterate through the groups until we find the session SID.
  383. //
  384. for (i=0; i<ptg->GroupCount; i++) {
  385. if (ptg->Groups[i].Attributes & SE_GROUP_LOGON_ID) {
  386. size = GetLengthSid(ptg->Groups[i].Sid);
  387. psid = (PSID)ALLOCMEM(size);
  388. if (psid != NULL) { // Make sure the allocation succeeded
  389. CopySid(size, psid, ptg->Groups[i].Sid);
  390. }
  391. break;
  392. }
  393. }
  394. CLEANUPANDEXIT:
  395. if (ptg != NULL) {
  396. FREEMEM(ptg);
  397. }
  398. SetLastError(dwResult);
  399. return psid;
  400. }
  401. #endif