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.

1366 lines
38 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. sspiutils.cxx
  6. Abstract:
  7. sspiutils
  8. Author:
  9. Larry Zhu (LZhu) December 1, 2001 Created
  10. Environment:
  11. User Mode -Win32
  12. Revision History:
  13. --*/
  14. #include "precomp.hxx"
  15. #pragma hdrstop
  16. #include "sspiutils.hxx"
  17. #include <ntlmsp.h>
  18. #include <tchar.h>
  19. HRESULT
  20. AcquireCredHandle(
  21. IN OPTIONAL PSTR pszPrincipal,
  22. IN OPTIONAL LUID* pLogonID,
  23. IN PSTR pszPackageName,
  24. IN OPTIONAL VOID* pAuthData,
  25. IN ULONG fCredentialUse,
  26. OUT CredHandle* phCred
  27. )
  28. {
  29. THResult hRetval = S_OK;
  30. CredHandle hCred;
  31. TimeStamp Lifetime = {0};
  32. TimeStamp CurrentTime = {0};
  33. SecPkgCredentials_NamesA CredNames = {0};
  34. TPrivilege* pPriv = NULL;
  35. DebugPrintf(SSPI_LOG, "AcquireCredHandle pszPrincipal %s, pszPackageName %s, "
  36. "fCredentialUse %#x, pLogonID %p, pAuthData %p\n",
  37. pszPrincipal, pszPackageName, fCredentialUse,
  38. pLogonID, pAuthData);
  39. SecInvalidateHandle(&hCred);
  40. SecInvalidateHandle(phCred);
  41. if (pLogonID)
  42. {
  43. DebugPrintf(SSPI_LOG, "LogonId %#x:%#x\n", pLogonID->HighPart, pLogonID->LowPart);
  44. pPriv = new TPrivilege(SE_TCB_PRIVILEGE, TRUE);
  45. hRetval DBGCHK = pPriv ? pPriv->Validate() : E_OUTOFMEMORY;
  46. }
  47. if (SUCCEEDED(hRetval))
  48. {
  49. hRetval DBGCHK = AcquireCredentialsHandleA(
  50. pszPrincipal, // NULL
  51. pszPackageName,
  52. fCredentialUse, // SECPKG_CRED_INBOUND,
  53. pLogonID, // NULL
  54. pAuthData, // ServerAuthIdentity,
  55. NULL, // GetKey
  56. NULL, // value to pass to GetKey
  57. &hCred,
  58. &Lifetime
  59. );
  60. }
  61. if (pPriv)
  62. {
  63. delete pPriv;
  64. }
  65. if (SUCCEEDED(hRetval))
  66. {
  67. DebugPrintf(SSPI_LOG, "CredHandle: %#x:%#x\n", hCred.dwUpper, hCred.dwLower);
  68. DebugPrintSysTimeAsLocalTime(SSPI_LOG, "Lifetime", &Lifetime);
  69. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  70. DebugPrintSysTimeAsLocalTime(SSPI_LOG, "Current Time", &CurrentTime);
  71. DBGCFG1(hRetval, SEC_E_UNSUPPORTED_FUNCTION);
  72. hRetval DBGCHK = QueryCredentialsAttributesA(
  73. &hCred,
  74. SECPKG_CRED_ATTR_NAMES,
  75. &CredNames
  76. );
  77. if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  78. {
  79. hRetval DBGCHK = S_OK;
  80. DebugPrintf(SSPI_WARN, "QueryCredentialsAttributesA does not support SECPKG_CRED_ATTR_NAMES\n");
  81. }
  82. }
  83. if (SUCCEEDED(hRetval))
  84. {
  85. *phCred = hCred;
  86. SecInvalidateHandle(&hCred);
  87. DebugPrintf(SSPI_LOG, "Credential names: %s\n", CredNames.sUserName);
  88. }
  89. THResult hr;
  90. if (CredNames.sUserName)
  91. {
  92. hr DBGCHK = FreeContextBuffer(CredNames.sUserName);
  93. }
  94. if (SecIsValidHandle(&hCred))
  95. {
  96. hr DBGCHK = FreeCredentialsHandle(&hCred);
  97. }
  98. return hRetval;
  99. }
  100. VOID
  101. GetAuthdata(
  102. IN OPTIONAL PCTSTR pszUserName,
  103. IN OPTIONAL PCTSTR pszDomainName,
  104. IN OPTIONAL PCTSTR pszPassword,
  105. OUT SEC_WINNT_AUTH_IDENTITY* pAuthData
  106. )
  107. {
  108. #if defined(UNICODE) || defined(_UNICODE)
  109. pAuthData->Domain = (WCHAR*) pszDomainName;
  110. pAuthData->DomainLength = pszDomainName ? lstrlen(pszDomainName) : 0;
  111. pAuthData->Password = (WCHAR*) pszPassword;
  112. pAuthData->PasswordLength = pszPassword ? lstrlen(pszPassword) : 0;
  113. pAuthData->User = (WCHAR*) pszUserName;
  114. pAuthData->UserLength = pszUserName ? lstrlen(pszUserName) : 0;
  115. #else
  116. pAuthData->Domain = (UCHAR*) pszDomainName;
  117. pAuthData->DomainLength = pszDomainName ? lstrlen(pszDomainName) : 0;
  118. pAuthData->Password = (UCHAR*) pszPassword;
  119. pAuthData->PasswordLength = pszPassword ? lstrlen(pszPassword) : 0;
  120. pAuthData->User = (UCHAR*) pszUserName;
  121. pAuthData->UserLength = pszUserName ? lstrlen(pszUserName) : 0;
  122. #endif
  123. pAuthData->Flags = (sizeof(TCHAR) == sizeof(WCHAR)) ? SEC_WINNT_AUTH_IDENTITY_UNICODE : SEC_WINNT_AUTH_IDENTITY_ANSI;
  124. }
  125. VOID
  126. GetAuthdataExA(
  127. IN OPTIONAL PCSTR pszUserName,
  128. IN OPTIONAL PCSTR pszDomainName,
  129. IN OPTIONAL PCSTR pszPassword,
  130. IN OPTIONAL PCSTR pszPackageList,
  131. OUT SEC_WINNT_AUTH_IDENTITY_EXA* pAuthDataEx
  132. )
  133. {
  134. DebugPrintf(SSPI_LOG,
  135. "GetAuthdataExW pszUserName %s, pszDomainName %s, pszPassword %s, pszPackageList %s\n",
  136. pszUserName, pszDomainName, pszPassword, pszPackageList);
  137. pAuthDataEx->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
  138. pAuthDataEx->Length = sizeof(SEC_WINNT_AUTH_IDENTITY_EXA);
  139. pAuthDataEx->Domain = (UCHAR*) pszDomainName;
  140. pAuthDataEx->DomainLength = pszDomainName ? strlen(pszDomainName) : 0;
  141. pAuthDataEx->Password = (UCHAR*) pszPassword;
  142. pAuthDataEx->PasswordLength = pszPassword ? strlen(pszPassword) : 0;
  143. pAuthDataEx->User = (UCHAR*) pszUserName;
  144. pAuthDataEx->UserLength = pszUserName ? strlen(pszUserName) : 0;
  145. pAuthDataEx->PackageList = (UCHAR*) pszPackageList;
  146. pAuthDataEx->PackageListLength = pszPackageList ? strlen(pszPackageList) : 0;
  147. pAuthDataEx->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  148. }
  149. VOID
  150. GetAuthdataExW(
  151. IN OPTIONAL PCWSTR pszUserName,
  152. IN OPTIONAL PCWSTR pszDomainName,
  153. IN OPTIONAL PCWSTR pszPassword,
  154. IN OPTIONAL PCWSTR pszPackageList,
  155. OUT SEC_WINNT_AUTH_IDENTITY_EXW* pAuthDataEx
  156. )
  157. {
  158. DebugPrintf(SSPI_LOG,
  159. "GetAuthdataExW pszUserName %ws, pszDomainName %ws, pszPassword %ws, pszPackageList %ws\n",
  160. pszUserName, pszDomainName, pszPassword, pszPackageList);
  161. pAuthDataEx->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
  162. pAuthDataEx->Length = sizeof(SEC_WINNT_AUTH_IDENTITY_EXW);
  163. pAuthDataEx->Domain = (WCHAR*) pszDomainName;
  164. pAuthDataEx->DomainLength = pszDomainName ? wcslen(pszDomainName) : 0;
  165. pAuthDataEx->Password = (WCHAR*) pszPassword;
  166. pAuthDataEx->PasswordLength = pszPassword ? wcslen(pszPassword) : 0;
  167. pAuthDataEx->User = (WCHAR*) pszUserName;
  168. pAuthDataEx->UserLength = pszUserName ? wcslen(pszUserName) : 0;
  169. pAuthDataEx->PackageList = (WCHAR*) pszPackageList;
  170. pAuthDataEx->PackageListLength = pszPackageList ? wcslen(pszPackageList) : 0;
  171. pAuthDataEx->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  172. }
  173. HRESULT
  174. GetAuthdataWMarshalled(
  175. IN OPTIONAL PCWSTR pszUserName,
  176. IN OPTIONAL PCWSTR pszDomainName,
  177. IN OPTIONAL PCWSTR pszPassword,
  178. OUT SEC_WINNT_AUTH_IDENTITY_W** ppAuthData
  179. )
  180. {
  181. THResult hRetval;
  182. PUCHAR pWhere = NULL;
  183. ULONG cbCredSize = ( ((pszUserName != NULL) ? wcslen(pszUserName) + 1 : 0)
  184. + ((pszDomainName != NULL) ? wcslen(pszDomainName) + 1 : 0)
  185. + ((pszPassword != NULL) ? wcslen(pszPassword) + 1 : 0) ) * sizeof(WCHAR)
  186. + ROUND_UP_COUNT(sizeof(SEC_WINNT_AUTH_IDENTITY_W), sizeof(ULONG_PTR));
  187. *ppAuthData = (PSEC_WINNT_AUTH_IDENTITY_W) new CHAR[cbCredSize];
  188. hRetval DBGCHK = (*ppAuthData) ? S_OK : E_OUTOFMEMORY;
  189. if (SUCCEEDED(hRetval))
  190. {
  191. RtlZeroMemory((*ppAuthData), cbCredSize);
  192. pWhere = (PUCHAR) ((*ppAuthData) + 1);
  193. if (pszUserName != NULL)
  194. {
  195. (*ppAuthData)->UserLength = wcslen(pszUserName);
  196. (*ppAuthData)->User = (PWSTR) pWhere;
  197. RtlCopyMemory(
  198. pWhere,
  199. pszUserName,
  200. (*ppAuthData)->UserLength * sizeof(WCHAR)
  201. );
  202. pWhere += ((*ppAuthData)->UserLength + 1) * sizeof(WCHAR);
  203. }
  204. if (pszDomainName != NULL)
  205. {
  206. (*ppAuthData)->DomainLength = wcslen(pszDomainName);
  207. (*ppAuthData)->Domain = (PWSTR) pWhere;
  208. RtlCopyMemory(
  209. pWhere,
  210. pszDomainName,
  211. (*ppAuthData)->DomainLength * sizeof(WCHAR)
  212. );
  213. pWhere += ((*ppAuthData)->DomainLength + 1) * sizeof(WCHAR);
  214. }
  215. if (pszPassword != NULL)
  216. {
  217. (*ppAuthData)->PasswordLength = wcslen(pszPassword);
  218. (*ppAuthData)->Password = (PWSTR) pWhere;
  219. RtlCopyMemory(
  220. pWhere,
  221. pszPassword,
  222. (*ppAuthData)->PasswordLength * sizeof(WCHAR)
  223. );
  224. pWhere += ((*ppAuthData)->PasswordLength + 1) * sizeof(WCHAR);
  225. }
  226. (*ppAuthData)->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE | SEC_WINNT_AUTH_IDENTITY_MARSHALLED;
  227. }
  228. return hRetval;
  229. }
  230. HRESULT
  231. GetAuthdataExWMarshalled(
  232. IN OPTIONAL PCWSTR pszUserName,
  233. IN OPTIONAL PCWSTR pszDomainName,
  234. IN OPTIONAL PCWSTR pszPassword,
  235. IN OPTIONAL PCWSTR pszPackageList,
  236. OUT SEC_WINNT_AUTH_IDENTITY_EXW** ppAuthData
  237. )
  238. {
  239. THResult hRetval;
  240. PUCHAR pWhere = NULL;
  241. ULONG cbCredSize = ( ((pszUserName != NULL) ? wcslen(pszUserName) + 1 : 0)
  242. + ((pszDomainName != NULL) ? wcslen(pszDomainName) + 1 : 0)
  243. + ((pszPassword != NULL) ? wcslen(pszPassword) + 1 : 0)
  244. + ((pszPackageList != NULL) ? wcslen(pszPackageList) + 1 : 0) ) * sizeof(WCHAR)
  245. + ROUND_UP_COUNT(sizeof(SEC_WINNT_AUTH_IDENTITY_EXW), sizeof(ULONG_PTR));
  246. *ppAuthData = (PSEC_WINNT_AUTH_IDENTITY_EXW) new CHAR[cbCredSize];
  247. hRetval DBGCHK = (*ppAuthData) ? S_OK : E_OUTOFMEMORY;
  248. if (SUCCEEDED(hRetval))
  249. {
  250. RtlZeroMemory((*ppAuthData), cbCredSize);
  251. (*ppAuthData)->Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
  252. (*ppAuthData)->Length = sizeof(SEC_WINNT_AUTH_IDENTITY_EXW);
  253. pWhere = (PUCHAR) ((*ppAuthData) + 1);
  254. if (pszUserName != NULL)
  255. {
  256. (*ppAuthData)->UserLength = wcslen(pszUserName);
  257. (*ppAuthData)->User = (PWSTR) pWhere;
  258. RtlCopyMemory(
  259. pWhere,
  260. pszUserName,
  261. (*ppAuthData)->UserLength * sizeof(WCHAR)
  262. );
  263. pWhere += ((*ppAuthData)->UserLength + 1) * sizeof(WCHAR);
  264. }
  265. if (pszDomainName != NULL)
  266. {
  267. (*ppAuthData)->DomainLength = wcslen(pszDomainName);
  268. (*ppAuthData)->Domain = (PWSTR) pWhere;
  269. RtlCopyMemory(
  270. pWhere,
  271. pszDomainName,
  272. (*ppAuthData)->DomainLength * sizeof(WCHAR)
  273. );
  274. pWhere += ((*ppAuthData)->DomainLength + 1) * sizeof(WCHAR);
  275. }
  276. if (pszPassword != NULL)
  277. {
  278. (*ppAuthData)->PasswordLength = wcslen(pszPassword);
  279. (*ppAuthData)->Password = (PWSTR) pWhere;
  280. RtlCopyMemory(
  281. pWhere,
  282. pszPassword,
  283. (*ppAuthData)->PasswordLength * sizeof(WCHAR)
  284. );
  285. pWhere += ((*ppAuthData)->PasswordLength + 1) * sizeof(WCHAR);
  286. }
  287. if (pszPackageList != NULL)
  288. {
  289. (*ppAuthData)->PackageListLength = wcslen(pszPackageList);
  290. (*ppAuthData)->PackageList = (PWSTR) pWhere;
  291. RtlCopyMemory(
  292. pWhere,
  293. pszPackageList,
  294. (*ppAuthData)->PackageListLength * sizeof(WCHAR)
  295. );
  296. pWhere += ((*ppAuthData)->PackageListLength + 1) * sizeof(WCHAR);
  297. }
  298. (*ppAuthData)->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE | SEC_WINNT_AUTH_IDENTITY_MARSHALLED;
  299. }
  300. return hRetval;
  301. }
  302. NTSTATUS
  303. GetCredHandle(
  304. IN OPTIONAL PTSTR pszPrincipal,
  305. IN OPTIONAL LUID* pLogonID,
  306. IN PTSTR pszPackageName,
  307. IN OPTIONAL VOID* pAuthData,
  308. IN ULONG fCredentialUse,
  309. OUT CredHandle* phCred
  310. )
  311. {
  312. TNtStatus Status = STATUS_SUCCESS;
  313. CredHandle hCred;
  314. TimeStamp Lifetime = {0};
  315. TimeStamp CurrentTime = {0};
  316. SecPkgCredentials_Names CredNames = {0};
  317. TPrivilege* pPriv = NULL;
  318. SspiPrint(SSPI_LOG, TEXT("GetCredHandle pszPrincipal %s, pszPackageName %s, ")
  319. TEXT("fCredentialUse %#x, pLogonID %p, pAuthData %p\n"),
  320. pszPrincipal, pszPackageName, fCredentialUse,
  321. pLogonID, pAuthData);
  322. SecInvalidateHandle(&hCred);
  323. SecInvalidateHandle(phCred);
  324. if (pLogonID)
  325. {
  326. SspiPrint(SSPI_LOG, TEXT("LogonId %#x:%#x\n"), pLogonID->HighPart, pLogonID->LowPart);
  327. pPriv = new TPrivilege(SE_TCB_PRIVILEGE, TRUE);
  328. Status DBGCHK = pPriv ? pPriv->Validate() : E_OUTOFMEMORY;
  329. }
  330. if (NT_SUCCESS(Status))
  331. {
  332. Status DBGCHK = AcquireCredentialsHandle(
  333. pszPrincipal, // NULL
  334. pszPackageName,
  335. fCredentialUse, // SECPKG_CRED_INBOUND,
  336. pLogonID, // NULL
  337. pAuthData, // ServerAuthIdentity,
  338. NULL, // GetKey
  339. NULL, // value to pass to GetKey
  340. &hCred,
  341. &Lifetime
  342. );
  343. }
  344. if (pPriv)
  345. {
  346. delete pPriv;
  347. }
  348. if (NT_SUCCESS(Status))
  349. {
  350. SspiPrint(SSPI_LOG, TEXT("CredHandle: %#x:%#x\n"), hCred.dwUpper, hCred.dwLower);
  351. SspiPrintSysTimeAsLocalTime(SSPI_LOG, TEXT("Lifetime"), &Lifetime);
  352. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  353. SspiPrintSysTimeAsLocalTime(SSPI_LOG, TEXT("Current Time"), &CurrentTime);
  354. DBGCFG1(Status, SEC_E_UNSUPPORTED_FUNCTION);
  355. Status DBGCHK = QueryCredentialsAttributes(
  356. &hCred,
  357. SECPKG_CRED_ATTR_NAMES,
  358. &CredNames
  359. );
  360. if (SEC_E_UNSUPPORTED_FUNCTION == (NTSTATUS) Status)
  361. {
  362. Status DBGCHK = STATUS_SUCCESS;
  363. DebugPrintf(SSPI_WARN, "QueryCredentialsAttributesA does not support SECPKG_CRED_ATTR_NAMES\n");
  364. }
  365. }
  366. if (NT_SUCCESS(Status))
  367. {
  368. SspiPrint(SSPI_LOG, TEXT("Credential names: %s\n"), CredNames.sUserName);
  369. *phCred = hCred;
  370. SecInvalidateHandle(&hCred);
  371. }
  372. THResult hr;
  373. if (CredNames.sUserName)
  374. {
  375. hr DBGCHK = FreeContextBuffer(CredNames.sUserName);
  376. }
  377. if (SecIsValidHandle(&hCred))
  378. {
  379. hr DBGCHK = FreeCredentialsHandle(&hCred);
  380. }
  381. return Status;
  382. }
  383. HRESULT
  384. CheckSecurityContextHandle(
  385. IN PCtxtHandle phCtxt
  386. )
  387. {
  388. THResult hRetval = S_OK;
  389. LARGE_INTEGER CurrentTime = {0};
  390. SecPkgContext_NativeNamesA NativeNamesA = {0};
  391. SecPkgContext_DceInfo ContextDceInfo = {0};
  392. SecPkgContext_Lifespan ContextLifespan = {0};
  393. SecPkgContext_PackageInfoA ContextPackageInfo = {0};
  394. SecPkgContext_NegotiationInfoA NegotiationInfo = {0};
  395. SecPkgContext_Sizes ContextSizes = {0};
  396. SecPkgContext_Flags ContextFlags = {0};
  397. SecPkgContext_KeyInfoA KeyInfo = {0};
  398. SecPkgContext_NamesA ContextNames = {0};
  399. SecPkgContext_TargetInformation TargetInfo = {0};
  400. SecPkgContext_SessionKey SessionKey = {0};
  401. SecPkgContext_UserFlags UserFlags = {0};
  402. DBGCFG1(hRetval, SEC_E_UNSUPPORTED_FUNCTION);
  403. //
  404. // Query as many attributes as possible
  405. //
  406. hRetval DBGCHK = QueryContextAttributesA(
  407. phCtxt,
  408. SECPKG_ATTR_SIZES,
  409. &ContextSizes
  410. );
  411. if (SUCCEEDED(hRetval))
  412. {
  413. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_SIZES cbBlockSize %#x, cbMaxSignature %#x, "
  414. "cbMaxToken %#x, cbSecurityTrailer %#x\n",
  415. ContextSizes.cbBlockSize,
  416. ContextSizes.cbMaxSignature,
  417. ContextSizes.cbMaxToken,
  418. ContextSizes.cbSecurityTrailer);
  419. hRetval DBGCHK = QueryContextAttributesA(
  420. phCtxt,
  421. SECPKG_ATTR_FLAGS,
  422. &ContextFlags
  423. );
  424. }
  425. if (SUCCEEDED(hRetval))
  426. {
  427. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_FLAGS %#x\n", ContextFlags.Flags);
  428. }
  429. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  430. {
  431. hRetval DBGCHK = S_OK;
  432. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_FLAGS\n");
  433. }
  434. if (SUCCEEDED(hRetval))
  435. {
  436. hRetval DBGCHK = QueryContextAttributesA(
  437. phCtxt,
  438. SECPKG_ATTR_KEY_INFO,
  439. &KeyInfo
  440. );
  441. }
  442. if (SUCCEEDED(hRetval))
  443. {
  444. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_KEY_INFO EncryptAlgorithm %#x, KeySize %#x, "
  445. "sEncryptAlgorithmName %s, SignatureAlgorithm %#x, sSignatureAlgorithmName %s\n",
  446. KeyInfo.EncryptAlgorithm,
  447. KeyInfo.KeySize,
  448. KeyInfo.sEncryptAlgorithmName,
  449. KeyInfo.SignatureAlgorithm,
  450. KeyInfo.sSignatureAlgorithmName);
  451. }
  452. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  453. {
  454. hRetval DBGCHK = S_OK;
  455. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_KEY_INFO\n");
  456. }
  457. if (SUCCEEDED(hRetval))
  458. {
  459. hRetval DBGCHK = QueryContextAttributesA(
  460. phCtxt,
  461. SECPKG_ATTR_NAMES,
  462. &ContextNames
  463. );
  464. }
  465. if (SUCCEEDED(hRetval))
  466. {
  467. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_NAMES sUserName %s\n", ContextNames.sUserName);
  468. }
  469. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  470. {
  471. hRetval DBGCHK = S_OK;
  472. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_NAMES\n");
  473. }
  474. if (SUCCEEDED(hRetval))
  475. {
  476. hRetval DBGCHK = QueryContextAttributesA(
  477. phCtxt,
  478. SECPKG_ATTR_NATIVE_NAMES,
  479. &NativeNamesA
  480. );
  481. }
  482. if (SUCCEEDED(hRetval))
  483. {
  484. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_NATIVE_NAMES sClientName %s, sServerName %s\n",
  485. NativeNamesA.sClientName,
  486. NativeNamesA.sServerName);
  487. }
  488. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  489. {
  490. hRetval DBGCHK = S_OK;
  491. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_NATIVE_NAMES\n");
  492. }
  493. if (SUCCEEDED(hRetval))
  494. {
  495. hRetval DBGCHK = QueryContextAttributesA(
  496. phCtxt,
  497. SECPKG_ATTR_DCE_INFO,
  498. &ContextDceInfo
  499. );
  500. }
  501. if (SUCCEEDED(hRetval))
  502. {
  503. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_DCE_INFO: AuthzSvc %#x, pPAC %ws\n", ContextDceInfo.AuthzSvc, ContextDceInfo.pPac);
  504. }
  505. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  506. {
  507. hRetval DBGCHK = S_OK;
  508. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_DCE_INFO\n");
  509. }
  510. if (SUCCEEDED(hRetval))
  511. {
  512. hRetval DBGCHK = QueryContextAttributesA(
  513. phCtxt,
  514. SECPKG_ATTR_LIFESPAN,
  515. &ContextLifespan
  516. );
  517. }
  518. if (SUCCEEDED(hRetval))
  519. {
  520. DebugPrintLocalTime(SSPI_LOG, "SECPKG_ATTR_LIFESPAN Start", &ContextLifespan.tsStart);
  521. DebugPrintLocalTime(SSPI_LOG, "SECPKG_ATTR_LIFESPAN Expiry", &ContextLifespan.tsExpiry);
  522. GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
  523. DebugPrintSysTimeAsLocalTime(SSPI_LOG, "Current Time", &CurrentTime);
  524. }
  525. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  526. {
  527. hRetval DBGCHK = S_OK;
  528. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_LIFESPAN\n");
  529. }
  530. if (SUCCEEDED(hRetval))
  531. {
  532. hRetval DBGCHK = QueryContextAttributesA(
  533. phCtxt,
  534. SECPKG_ATTR_PACKAGE_INFO,
  535. &ContextPackageInfo
  536. );
  537. }
  538. if (SUCCEEDED(hRetval))
  539. {
  540. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_PACKAGE_INFO cbMaxToken %#x, Comment %s, fCapabilities %#x, "
  541. "Name %s, wRPCID %#x, wVersion %#x\n",
  542. ContextPackageInfo.PackageInfo->cbMaxToken,
  543. ContextPackageInfo.PackageInfo->Comment,
  544. ContextPackageInfo.PackageInfo->fCapabilities,
  545. ContextPackageInfo.PackageInfo->Name,
  546. ContextPackageInfo.PackageInfo->wRPCID,
  547. ContextPackageInfo.PackageInfo->wVersion);
  548. }
  549. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  550. {
  551. hRetval DBGCHK = S_OK;
  552. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_PACKAGE_INFO\n");
  553. }
  554. if (SUCCEEDED(hRetval))
  555. {
  556. hRetval DBGCHK = QueryContextAttributesA(
  557. phCtxt,
  558. SECPKG_ATTR_NEGOTIATION_INFO,
  559. &NegotiationInfo
  560. );
  561. }
  562. if (SUCCEEDED(hRetval))
  563. {
  564. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_NEGOTIATION_INFO cbMaxToken %#x, Comment %s, fCapabilities %#x, "
  565. "Name %s, wRPCID %#x, wVersion %#x, NegotiationState %#x\n",
  566. NegotiationInfo.PackageInfo->cbMaxToken,
  567. NegotiationInfo.PackageInfo->Comment,
  568. NegotiationInfo.PackageInfo->fCapabilities,
  569. NegotiationInfo.PackageInfo->Name,
  570. NegotiationInfo.PackageInfo->wRPCID,
  571. NegotiationInfo.PackageInfo->wVersion,
  572. NegotiationInfo.NegotiationState);
  573. }
  574. else if (STATUS_NOT_SUPPORTED == (HRESULT) hRetval)
  575. {
  576. hRetval DBGCHK = S_OK;
  577. SspiPrint(SSPI_WARN, TEXT("QueryContextAttributes does not support SECPKG_ATTR_NEGOTIATION_INFO\n"));
  578. }
  579. if (SUCCEEDED(hRetval))
  580. {
  581. hRetval DBGCHK = QueryContextAttributesA(
  582. phCtxt,
  583. SECPKG_ATTR_TARGET_INFORMATION,
  584. &TargetInfo
  585. );
  586. }
  587. if (SUCCEEDED(hRetval))
  588. {
  589. DebugPrintHex(SSPI_LOG, "SECPKG_ATTR_TARGET_INFORMATION", TargetInfo.MarshalledTargetInfoLength, TargetInfo.MarshalledTargetInfo);
  590. }
  591. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  592. {
  593. hRetval DBGCHK = S_OK;
  594. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_TARGET_INFORMATION\n");
  595. }
  596. #if 0
  597. SECPKG_ATTR_SESSION_KEY is Kernel mode only
  598. if (SUCCEEDED(hRetval))
  599. {
  600. hRetval DBGCHK = QueryContextAttributesA(
  601. phCtxt,
  602. SECPKG_ATTR_SESSION_KEY,
  603. &SessionKey
  604. );
  605. }
  606. if (SUCCEEDED(hRetval))
  607. {
  608. DebugPrintHex(SSPI_LOG, "SECPKG_ATTR_SESSION_KEY", SessionKey.SessionKeyLength, SessionKey.SessionKey);
  609. }
  610. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  611. {
  612. hRetval DBGCHK = S_OK;
  613. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_SESSION_KEY\n");
  614. }
  615. #endif
  616. if (SUCCEEDED(hRetval))
  617. {
  618. hRetval DBGCHK = QueryContextAttributesA(
  619. phCtxt,
  620. SECPKG_ATTR_USER_FLAGS,
  621. &UserFlags
  622. );
  623. }
  624. if (SUCCEEDED(hRetval))
  625. {
  626. DebugPrintf(SSPI_LOG, "SECPKG_ATTR_USER_FLAGS UserFlags %#x\n", UserFlags.UserFlags);
  627. }
  628. else if (SEC_E_UNSUPPORTED_FUNCTION == (HRESULT) hRetval)
  629. {
  630. hRetval DBGCHK = S_OK;
  631. DebugPrintf(SSPI_WARN, "QueryContextAttributesA does not support SECPKG_ATTR_SESSION_KEY\n");
  632. }
  633. THResult hr;
  634. if (TargetInfo.MarshalledTargetInfo)
  635. {
  636. hr DBGCHK = FreeContextBuffer(TargetInfo.MarshalledTargetInfo);
  637. }
  638. if (SessionKey.SessionKeyLength)
  639. {
  640. hr DBGCHK = FreeContextBuffer(SessionKey.SessionKey);
  641. }
  642. if (NativeNamesA.sClientName != NULL)
  643. {
  644. hr DBGCHK = FreeContextBuffer(NativeNamesA.sClientName);
  645. }
  646. if (NativeNamesA.sServerName != NULL)
  647. {
  648. hr DBGCHK = FreeContextBuffer(NativeNamesA.sServerName);
  649. }
  650. if (ContextNames.sUserName)
  651. {
  652. hr DBGCHK = FreeContextBuffer(ContextNames.sUserName);
  653. }
  654. if (ContextPackageInfo.PackageInfo)
  655. {
  656. hr DBGCHK = FreeContextBuffer(ContextPackageInfo.PackageInfo);
  657. }
  658. if (NegotiationInfo.PackageInfo)
  659. {
  660. hr DBGCHK = FreeContextBuffer(NegotiationInfo.PackageInfo);
  661. }
  662. if (ContextDceInfo.pPac)
  663. {
  664. hr DBGCHK = FreeContextBuffer(ContextDceInfo.pPac);
  665. }
  666. return hRetval;
  667. }
  668. MSV1_0_AV_PAIR*
  669. SspAvlInit(
  670. IN VOID* pAvList
  671. )
  672. {
  673. MSV1_0_AV_PAIR* pAvPair;
  674. pAvPair = (MSV1_0_AV_PAIR*) pAvList;
  675. if (!pAvPair)
  676. {
  677. return NULL;
  678. }
  679. pAvPair->AvId = MsvAvEOL;
  680. pAvPair->AvLen = 0;
  681. return pAvPair;
  682. }
  683. MSV1_0_AV_PAIR*
  684. SspAvlAdd(
  685. IN MSV1_0_AV_PAIR* pAvList,
  686. IN MSV1_0_AVID AvId,
  687. IN OPTIONAL UNICODE_STRING* pString,
  688. IN ULONG cAvList
  689. )
  690. {
  691. MSV1_0_AV_PAIR* pCurPair;
  692. if ((NULL == pString) || (0 == pString->Length) || (NULL == pString->Buffer))
  693. {
  694. return NULL;
  695. }
  696. //
  697. // find the EOL
  698. //
  699. pCurPair = SspAvlGet(pAvList, MsvAvEOL, cAvList);
  700. if (pCurPair == NULL)
  701. {
  702. return NULL;
  703. }
  704. //
  705. // check for enough space in the av list buffer, then append the new AvPair
  706. // (assume the buffer is long enough!)
  707. //
  708. if ( (((UCHAR*) pCurPair) - ((UCHAR*)pAvList)) + sizeof(MSV1_0_AV_PAIR) * 2 + pString->Length > cAvList)
  709. {
  710. return NULL;
  711. }
  712. pCurPair->AvId = (USHORT) AvId;
  713. pCurPair->AvLen = (USHORT) pString->Length;
  714. RtlCopyMemory(pCurPair + 1, pString->Buffer, pCurPair->AvLen);
  715. //
  716. // top it off with a new EOL
  717. //
  718. pCurPair = (MSV1_0_AV_PAIR*) ((UCHAR*) pCurPair + sizeof(MSV1_0_AV_PAIR) + pCurPair->AvLen);
  719. pCurPair->AvId = MsvAvEOL;
  720. pCurPair->AvLen = 0;
  721. return pCurPair;
  722. }
  723. MSV1_0_AV_PAIR*
  724. SspAvlGet(
  725. IN MSV1_0_AV_PAIR* pAvList,
  726. IN MSV1_0_AVID AvId,
  727. IN ULONG cAvList
  728. )
  729. {
  730. MSV1_0_AV_PAIR* pAvPair;
  731. pAvPair = pAvList;
  732. while (TRUE)
  733. {
  734. if (pAvPair->AvId == AvId)
  735. {
  736. return pAvPair;
  737. }
  738. if (pAvPair->AvId == MsvAvEOL)
  739. {
  740. return NULL;
  741. }
  742. cAvList -= (pAvPair->AvLen + sizeof(MSV1_0_AV_PAIR));
  743. if (cAvList <= 0)
  744. {
  745. return NULL;
  746. }
  747. pAvPair = (MSV1_0_AV_PAIR*) ((UCHAR*) pAvPair + pAvPair->AvLen + sizeof(MSV1_0_AV_PAIR));
  748. }
  749. }
  750. ULONG
  751. SspAvlLen(
  752. IN MSV1_0_AV_PAIR* pAvList,
  753. IN ULONG cAvList
  754. )
  755. {
  756. MSV1_0_AV_PAIR* pCurPair;
  757. //
  758. // find the EOL
  759. //
  760. pCurPair = SspAvlGet(pAvList, MsvAvEOL, cAvList);
  761. if (pCurPair == NULL)
  762. {
  763. return 0;
  764. }
  765. //
  766. // compute length (not forgetting the EOL pair)
  767. //
  768. return (ULONG)(((UCHAR*) pCurPair - (UCHAR*) pAvList) + sizeof(MSV1_0_AV_PAIR));
  769. }
  770. NTSTATUS
  771. CreateTargetInfo(
  772. IN UNICODE_STRING* pTargetName,
  773. OUT STRING* pTargetInfo
  774. )
  775. {
  776. UNICODE_STRING DomainName = {0};
  777. UNICODE_STRING ServerName = {0};
  778. ULONG i = 0;
  779. MSV1_0_AV_PAIR* pAV;
  780. //
  781. // check length of name to make sure it fits in my buffer
  782. //
  783. if (pTargetName->Length > (DNS_MAX_NAME_LENGTH + CNLEN + 2) * sizeof(WCHAR))
  784. {
  785. return STATUS_INVALID_PARAMETER;
  786. }
  787. //
  788. // init AV list in temp buffer
  789. //
  790. pAV = SspAvlInit(pTargetInfo->Buffer);
  791. if (!pAV)
  792. {
  793. return STATUS_INVALID_PARAMETER;
  794. }
  795. //
  796. // see if there's a NULL in the middle of the server name that indicates
  797. // that it's really a domain name followed by a server name
  798. //
  799. DomainName = *pTargetName;
  800. for (i = 0; i < (DomainName.Length / sizeof(WCHAR)); i++)
  801. {
  802. if (DomainName.Buffer[i] == L'\0')
  803. {
  804. //
  805. // take length of domain name without the NULL
  806. //
  807. DomainName.Length = (USHORT) i * sizeof(WCHAR);
  808. //
  809. // adjust server name and length to point after the domain name
  810. //
  811. ServerName.Length = (USHORT) (pTargetName->Length - (i + 1) * sizeof(WCHAR));
  812. ServerName.Buffer = pTargetName->Buffer + (i + 1);
  813. break;
  814. }
  815. }
  816. //
  817. // strip off possible trailing null after the server name
  818. //
  819. for (i = 0; i < (ServerName.Length / sizeof(WCHAR)); i++)
  820. {
  821. if (ServerName.Buffer[i] == L'\0')
  822. {
  823. ServerName.Length = (USHORT) i * sizeof(WCHAR);
  824. break;
  825. }
  826. }
  827. //
  828. // put both names in the AV list (if both exist)
  829. //
  830. if (!SspAvlAdd(pAV, MsvAvNbDomainName, &DomainName, pTargetInfo->MaximumLength))
  831. {
  832. return STATUS_INVALID_PARAMETER;
  833. }
  834. if ((ServerName.Length > 0) && !SspAvlAdd(pAV, MsvAvNbComputerName, &ServerName, pTargetInfo->MaximumLength))
  835. {
  836. return STATUS_INVALID_PARAMETER;
  837. }
  838. //
  839. // make the request point at AV list instead of names.
  840. //
  841. pTargetInfo->Length = (USHORT) SspAvlLen(pAV, pTargetInfo->MaximumLength);
  842. pTargetInfo->Buffer = (CHAR*) pAV;
  843. return STATUS_SUCCESS;
  844. }
  845. NTSTATUS
  846. GetTargetInfo(
  847. IN ULONG TargetFlags,
  848. IN BOOLEAN bForceGuest,
  849. IN OPTIONAL UNICODE_STRING* pDnsDomainName,
  850. IN OPTIONAL UNICODE_STRING* pDnsComputerName,
  851. IN OPTIONAL UNICODE_STRING* pDnsTreeName,
  852. IN OPTIONAL UNICODE_STRING* pTargetName,
  853. IN OPTIONAL UNICODE_STRING* pComputerName,
  854. OUT UNICODE_STRING* pTargetInfo
  855. )
  856. {
  857. TNtStatus Status;
  858. PMSV1_0_AV_PAIR pAV = NULL;
  859. ULONG cbAV = 0;
  860. ULONG AvFlags = 0;
  861. UNICODE_STRING* pDnsTargetName = NULL;
  862. if (TargetFlags == NTLMSSP_TARGET_TYPE_DOMAIN )
  863. {
  864. pDnsTargetName = pDnsDomainName;
  865. }
  866. else
  867. {
  868. pDnsTargetName = pDnsComputerName;
  869. }
  870. cbAV = ( pTargetInfo ? pTargetName->Length : 0 )
  871. + ( pComputerName ? pComputerName->Length : 0 )
  872. + ( pDnsComputerName ? pDnsComputerName->Length : 0 )
  873. + ( pDnsTargetName ? pDnsTargetName->Length : 0 )
  874. + ( pDnsTreeName ? pDnsTreeName->Length : 0)
  875. + sizeof( AvFlags ) + (sizeof( MSV1_0_AV_PAIR ) * 6)
  876. + sizeof( MSV1_0_AV_PAIR);
  877. pTargetInfo->Buffer = new WCHAR[cbAV];
  878. Status DBGCHK = pTargetInfo->Buffer ? STATUS_SUCCESS : STATUS_NO_MEMORY;
  879. if (NT_SUCCESS(Status))
  880. {
  881. RtlZeroMemory(pTargetInfo->Buffer, cbAV);
  882. pAV = SspAvlInit(pTargetInfo->Buffer);
  883. SspAvlAdd(
  884. pAV,
  885. MsvAvNbDomainName,
  886. pTargetName,
  887. cbAV
  888. );
  889. SspAvlAdd(
  890. pAV,
  891. MsvAvNbComputerName,
  892. pComputerName,
  893. cbAV
  894. );
  895. SspAvlAdd(
  896. pAV,
  897. MsvAvDnsDomainName,
  898. pDnsTargetName,
  899. cbAV
  900. );
  901. SspAvlAdd(
  902. pAV,
  903. MsvAvDnsComputerName,
  904. pDnsComputerName,
  905. cbAV
  906. );
  907. SspAvlAdd(
  908. pAV,
  909. MsvAvDnsTreeName,
  910. pDnsTreeName,
  911. cbAV
  912. );
  913. //
  914. // add in AvFlags into TargetInfo, if applicable.
  915. //
  916. if (bForceGuest)
  917. {
  918. AvFlags |= MSV1_0_AV_FLAG_FORCE_GUEST;
  919. }
  920. if (AvFlags)
  921. {
  922. UNICODE_STRING AvString;
  923. AvString.Buffer = (PWSTR)&AvFlags;
  924. AvString.Length = sizeof( AvFlags );
  925. AvString.MaximumLength = AvString.Length;
  926. SspAvlAdd(
  927. pAV,
  928. MsvAvFlags,
  929. &AvString,
  930. cbAV
  931. );
  932. }
  933. pTargetInfo->MaximumLength = pTargetInfo->Length = (USHORT) SspAvlLen(pAV, cbAV);
  934. }
  935. return Status;
  936. }
  937. NTSTATUS
  938. SspConvertRelativeToAbsolute(
  939. IN VOID* pMessageBase,
  940. IN ULONG cbMessageSize,
  941. IN STRING32* pStringToRelocate,
  942. IN BOOLEAN AlignToWchar,
  943. IN BOOLEAN AllowNullString,
  944. OUT STRING* pOutputString
  945. )
  946. {
  947. ULONG Offset;
  948. //
  949. // If the buffer is allowed to be null,
  950. // check that special case.
  951. //
  952. if (AllowNullString && (pStringToRelocate->Length == 0))
  953. {
  954. pOutputString->MaximumLength = pOutputString->Length = pStringToRelocate->Length;
  955. pOutputString->Buffer = NULL;
  956. return STATUS_SUCCESS;
  957. }
  958. //
  959. // Ensure the string in entirely within the message.
  960. //
  961. Offset = (ULONG)pStringToRelocate->Buffer;
  962. if (Offset >= cbMessageSize || Offset + pStringToRelocate->Length > cbMessageSize)
  963. {
  964. return STATUS_INVALID_PARAMETER;
  965. }
  966. //
  967. // Ensure the buffer is properly aligned.
  968. //
  969. if ( AlignToWchar
  970. && (!COUNT_IS_ALIGNED(Offset, ALIGN_WCHAR)
  971. || !COUNT_IS_ALIGNED(pStringToRelocate->Length, ALIGN_WCHAR)) )
  972. {
  973. return STATUS_INVALID_PARAMETER;
  974. }
  975. //
  976. // Finally make the pointer absolute.
  977. //
  978. pOutputString->Buffer = (CHAR*)(pMessageBase) + Offset;
  979. pOutputString->MaximumLength = pOutputString->Length = pStringToRelocate->Length ;
  980. return STATUS_SUCCESS;
  981. }
  982. VOID
  983. SspCopyStringAsString32(
  984. IN VOID* pMessageBuffer,
  985. IN OPTIONAL STRING* pInString,
  986. IN OUT UCHAR** ppWhere,
  987. OUT STRING32* pOutString32
  988. )
  989. {
  990. //
  991. // Copy the data to the Buffer
  992. //
  993. if (pInString && pInString->Buffer != NULL)
  994. {
  995. RtlCopyMemory(*ppWhere, pInString->Buffer, pInString->Length);
  996. }
  997. //
  998. // Build a descriptor to the newly copied data
  999. //
  1000. pOutString32->Length = pOutString32->MaximumLength = pInString ? pInString->Length : 0;
  1001. pOutString32->Buffer = (ULONG)(*ppWhere - (UCHAR*)(pMessageBuffer));
  1002. //
  1003. // Update Where to point past the copied data
  1004. //
  1005. *ppWhere += pInString ? pInString->Length : 0;
  1006. }
  1007. HRESULT
  1008. IsContinueNeeded(
  1009. IN HRESULT hr
  1010. )
  1011. {
  1012. if (SEC_E_OK == hr)
  1013. {
  1014. return S_FALSE;
  1015. }
  1016. else if ((SEC_I_CONTINUE_NEEDED == hr) || (SEC_I_COMPLETE_AND_CONTINUE == hr))
  1017. {
  1018. return S_OK;
  1019. }
  1020. else
  1021. {
  1022. return hr;
  1023. }
  1024. }
  1025. HRESULT
  1026. IsCompleteNeeded(
  1027. IN HRESULT hr
  1028. )
  1029. {
  1030. if (SEC_E_OK == hr)
  1031. {
  1032. return S_FALSE;
  1033. }
  1034. else if ((SEC_I_COMPLETE_NEEDED == hr) || (SEC_I_COMPLETE_AND_CONTINUE == hr))
  1035. {
  1036. return S_OK;
  1037. }
  1038. else
  1039. {
  1040. return hr;
  1041. }
  1042. }
  1043. HRESULT
  1044. CheckSecurityPackage(
  1045. IN OPTIONAL PCSTR pszPackageName
  1046. )
  1047. {
  1048. THResult hRetval = S_OK;
  1049. ULONG cPackages = 0;
  1050. PSecPkgInfoA pPackageInfo = NULL;
  1051. hRetval DBGCHK = EnumerateSecurityPackagesA(&cPackages, &pPackageInfo);
  1052. if (SUCCEEDED(hRetval))
  1053. {
  1054. DebugPrintf(SSPI_LOG, "PackageCount: %d\n", cPackages);
  1055. for (ULONG Index = 0; Index < cPackages ; Index++ )
  1056. {
  1057. DebugPrintf(SSPI_LOG, "*********Package %d:*************\n", Index);
  1058. DebugPrintf(SSPI_LOG, "Name: %s Comment: %s\n", pPackageInfo[Index].Name, pPackageInfo[Index].Comment );
  1059. DebugPrintf(SSPI_LOG, "Cap: %#x Version: %#x RPCid: %#x MaxToken: %#x\n\n",
  1060. pPackageInfo[Index].fCapabilities,
  1061. pPackageInfo[Index].wVersion,
  1062. pPackageInfo[Index].wRPCID,
  1063. pPackageInfo[Index].cbMaxToken);
  1064. }
  1065. }
  1066. THResult hr;
  1067. if (pPackageInfo)
  1068. {
  1069. hr DBGCHK = FreeContextBuffer(pPackageInfo);
  1070. pPackageInfo = NULL;
  1071. }
  1072. if (SUCCEEDED(hRetval) && pszPackageName)
  1073. {
  1074. hRetval DBGCHK = QuerySecurityPackageInfoA((SEC_CHAR *)pszPackageName, &pPackageInfo);
  1075. if (SUCCEEDED(hRetval))
  1076. {
  1077. DebugPrintf(SSPI_LOG, "Name: %s Comment: %s\n", pPackageInfo->Name, pPackageInfo->Comment );
  1078. DebugPrintf(SSPI_LOG, "Cap: %#x Version: %#x RPCid: %#x MaxToken: %#x\n\n",
  1079. pPackageInfo->fCapabilities,
  1080. pPackageInfo->wVersion,
  1081. pPackageInfo->wRPCID,
  1082. pPackageInfo->cbMaxToken);
  1083. }
  1084. }
  1085. if (pPackageInfo)
  1086. {
  1087. hr DBGCHK = FreeContextBuffer(pPackageInfo);
  1088. }
  1089. return hRetval;
  1090. }
  1091. HRESULT
  1092. SetProcessOptions(
  1093. IN HANDLE hLsa,
  1094. IN ULONG MsvPackageId,
  1095. IN ULONG ProcessOptions
  1096. )
  1097. {
  1098. THResult hRetval = E_FAIL;
  1099. MSV1_0_SETPROCESSOPTION_REQUEST OptionsRequest;
  1100. PVOID pResponse = NULL;
  1101. ULONG cbResponse = 0;
  1102. NTSTATUS ProtocolStatus = STATUS_UNSUCCESSFUL;
  1103. RtlZeroMemory(&OptionsRequest, sizeof(OptionsRequest));
  1104. OptionsRequest.MessageType = (MSV1_0_PROTOCOL_MESSAGE_TYPE) MsV1_0SetProcessOption;
  1105. OptionsRequest.ProcessOptions = ProcessOptions; // MSV1_0_OPTION_ALLOW_BLANK_PASSWORD | MSV1_0_OPTION_DISABLE_ADMIN_LOCKOUT
  1106. OptionsRequest.DisableOptions = FALSE;
  1107. SspiPrint(SSPI_LOG, TEXT("SetProcessOptions %#x, PackageId %#x\n"), ProcessOptions, MsvPackageId);
  1108. hRetval DBGCHK = LsaCallAuthenticationPackage(
  1109. hLsa,
  1110. MsvPackageId,
  1111. &OptionsRequest,
  1112. sizeof(OptionsRequest),
  1113. &pResponse,
  1114. &cbResponse,
  1115. &ProtocolStatus
  1116. );
  1117. if (NT_SUCCESS(hRetval))
  1118. {
  1119. hRetval DBGCHK = ProtocolStatus;
  1120. }
  1121. return hRetval;
  1122. }