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.

324 lines
8.1 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: logon.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. /*++
  11. Copyright (c) 1995, 1996 Scott A. Field
  12. Module Name:
  13. logon.c
  14. Abstract:
  15. This module implements the network logon type by interfacing
  16. with the NT Lan Man Security Support Provider (NTLMSSP).
  17. If the logon succeds via the provided credentials, we duplicate
  18. the resultant Impersonation token to a Primary level token.
  19. This allows the result to be used in a call to CreateProcessAsUser
  20. Author:
  21. Scott Field (sfield) 09-Jun-96
  22. Revision History:
  23. --*/
  24. #include "pch.cpp"
  25. #pragma hdrstop
  26. #define SECURITY_WIN32
  27. #include <windows.h>
  28. #include <rpc.h>
  29. #include <security.h>
  30. BOOL
  31. myNetLogonUser(
  32. LPTSTR UserName,
  33. LPTSTR DomainName,
  34. LPTSTR Password,
  35. PHANDLE phToken
  36. )
  37. {
  38. SECURITY_STATUS SecStatus;
  39. CredHandle CredentialHandle1;
  40. CredHandle CredentialHandle2;
  41. CtxtHandle ClientContextHandle;
  42. CtxtHandle ServerContextHandle;
  43. SecPkgCredentials_Names sNames;
  44. ULONG ContextAttributes;
  45. ULONG PackageCount;
  46. ULONG PackageIndex;
  47. PSecPkgInfo PackageInfo;
  48. DWORD cbMaxToken;
  49. TimeStamp Lifetime;
  50. SEC_WINNT_AUTH_IDENTITY AuthIdentity;
  51. SecBufferDesc NegotiateDesc;
  52. SecBuffer NegotiateBuffer;
  53. SecBufferDesc ChallengeDesc;
  54. SecBuffer ChallengeBuffer;
  55. HANDLE hImpersonationToken;
  56. BOOL bSuccess = FALSE ; // assume this function will fail
  57. NegotiateBuffer.pvBuffer = NULL;
  58. ChallengeBuffer.pvBuffer = NULL;
  59. sNames.sUserName = NULL;
  60. ClientContextHandle.dwUpper = -1;
  61. ClientContextHandle.dwLower = -1;
  62. ServerContextHandle.dwUpper = -1;
  63. ServerContextHandle.dwLower = -1;
  64. CredentialHandle1.dwUpper = -1;
  65. CredentialHandle1.dwLower = -1;
  66. CredentialHandle2.dwUpper = -1;
  67. CredentialHandle2.dwLower = -1;
  68. //
  69. // << this section could be cached in a repeat caller scenario >>
  70. //
  71. //
  72. // Get info about the security packages.
  73. //
  74. if(EnumerateSecurityPackages(
  75. &PackageCount,
  76. &PackageInfo
  77. ) != NO_ERROR) return FALSE;
  78. //
  79. // loop through the packages looking for NTLM
  80. //
  81. for(PackageIndex = 0 ; PackageIndex < PackageCount ; PackageIndex++ ) {
  82. if(PackageInfo[PackageIndex].Name != NULL) {
  83. if(lstrcmpi(PackageInfo[PackageIndex].Name, MICROSOFT_KERBEROS_NAME) == 0) {
  84. cbMaxToken = PackageInfo[PackageIndex].cbMaxToken;
  85. bSuccess = TRUE;
  86. break;
  87. }
  88. }
  89. }
  90. FreeContextBuffer( PackageInfo );
  91. if(!bSuccess) return FALSE;
  92. bSuccess = FALSE; // reset to assume failure
  93. //
  94. // << end of cached section >>
  95. //
  96. //
  97. // Acquire a credential handle for the server side
  98. //
  99. SecStatus = AcquireCredentialsHandle(
  100. NULL, // New principal
  101. MICROSOFT_KERBEROS_NAME, // Package Name
  102. SECPKG_CRED_INBOUND,
  103. NULL,
  104. NULL,
  105. NULL,
  106. NULL,
  107. &CredentialHandle1,
  108. &Lifetime
  109. );
  110. if ( SecStatus != NO_ERROR ) {
  111. goto cleanup;
  112. }
  113. //
  114. // Acquire a credential handle for the client side
  115. //
  116. ZeroMemory( &AuthIdentity, sizeof(AuthIdentity) );
  117. if ( DomainName != NULL ) {
  118. AuthIdentity.Domain = DomainName;
  119. AuthIdentity.DomainLength = lstrlen(DomainName);
  120. }
  121. if ( UserName != NULL ) {
  122. AuthIdentity.User = UserName;
  123. AuthIdentity.UserLength = lstrlen(UserName);
  124. }
  125. if ( Password != NULL ) {
  126. AuthIdentity.Password = Password;
  127. AuthIdentity.PasswordLength = lstrlen(Password);
  128. }
  129. #ifdef UNICODE
  130. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  131. #else
  132. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  133. #endif
  134. SecStatus = AcquireCredentialsHandle(
  135. NULL, // New principal
  136. MICROSOFT_KERBEROS_NAME, // Package Name
  137. SECPKG_CRED_OUTBOUND,
  138. NULL,
  139. (DomainName == NULL && UserName == NULL && Password == NULL) ?
  140. NULL : &AuthIdentity,
  141. NULL,
  142. NULL,
  143. &CredentialHandle2,
  144. &Lifetime
  145. );
  146. if ( SecStatus != NO_ERROR ) {
  147. goto cleanup;
  148. }
  149. SecStatus = QueryCredentialsAttributes(&CredentialHandle1, SECPKG_CRED_ATTR_NAMES, &sNames);
  150. if ( SecStatus != NO_ERROR ) {
  151. goto cleanup;
  152. }
  153. //
  154. // Get the NegotiateMessage (ClientSide)
  155. //
  156. NegotiateDesc.ulVersion = 0;
  157. NegotiateDesc.cBuffers = 1;
  158. NegotiateDesc.pBuffers = &NegotiateBuffer;
  159. NegotiateBuffer.cbBuffer = cbMaxToken;
  160. NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
  161. NegotiateBuffer.pvBuffer = LocalAlloc( LMEM_FIXED, NegotiateBuffer.cbBuffer );
  162. if ( NegotiateBuffer.pvBuffer == NULL ) {
  163. goto cleanup;
  164. }
  165. SecStatus = InitializeSecurityContext(
  166. &CredentialHandle2,
  167. NULL, // No Client context yet
  168. sNames.sUserName, // target name
  169. ISC_REQ_SEQUENCE_DETECT,
  170. 0, // Reserved 1
  171. SECURITY_NATIVE_DREP,
  172. NULL, // No initial input token
  173. 0, // Reserved 2
  174. &ClientContextHandle,
  175. &NegotiateDesc,
  176. &ContextAttributes,
  177. &Lifetime
  178. );
  179. if(SecStatus != NO_ERROR)
  180. {
  181. goto cleanup;
  182. }
  183. //
  184. // Get the ChallengeMessage (ServerSide)
  185. //
  186. NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
  187. ChallengeDesc.ulVersion = 0;
  188. ChallengeDesc.cBuffers = 1;
  189. ChallengeDesc.pBuffers = &ChallengeBuffer;
  190. ChallengeBuffer.cbBuffer = cbMaxToken;
  191. ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
  192. ChallengeBuffer.pvBuffer = LocalAlloc( LMEM_FIXED, ChallengeBuffer.cbBuffer );
  193. if ( ChallengeBuffer.pvBuffer == NULL ) {
  194. goto cleanup;
  195. }
  196. SecStatus = AcceptSecurityContext(
  197. &CredentialHandle1,
  198. NULL, // No Server context yet
  199. &NegotiateDesc,
  200. ISC_REQ_SEQUENCE_DETECT,
  201. SECURITY_NATIVE_DREP,
  202. &ServerContextHandle,
  203. &ChallengeDesc,
  204. &ContextAttributes,
  205. &Lifetime
  206. );
  207. if(SecStatus != NO_ERROR)
  208. {
  209. goto cleanup;
  210. }
  211. if(QuerySecurityContextToken(&ServerContextHandle, phToken) != NO_ERROR)
  212. goto cleanup;
  213. bSuccess = TRUE;
  214. cleanup:
  215. //
  216. // Delete context
  217. //
  218. if((ClientContextHandle.dwUpper != -1) ||
  219. (ClientContextHandle.dwLower != -1))
  220. {
  221. DeleteSecurityContext( &ClientContextHandle );
  222. }
  223. if((ServerContextHandle.dwUpper != -1) ||
  224. (ServerContextHandle.dwLower != -1))
  225. {
  226. DeleteSecurityContext( &ServerContextHandle );
  227. }
  228. //
  229. // Free credential handles
  230. //
  231. if((CredentialHandle1.dwUpper != -1) ||
  232. (CredentialHandle1.dwLower != -1))
  233. {
  234. FreeCredentialsHandle( &CredentialHandle1 );
  235. }
  236. if((CredentialHandle2.dwUpper != -1) ||
  237. (CredentialHandle2.dwLower != -1))
  238. {
  239. FreeCredentialsHandle( &CredentialHandle2 );
  240. }
  241. if ( NegotiateBuffer.pvBuffer != NULL ) {
  242. ZeroMemory( NegotiateBuffer.pvBuffer, NegotiateBuffer.cbBuffer );
  243. LocalFree( NegotiateBuffer.pvBuffer );
  244. }
  245. if ( ChallengeBuffer.pvBuffer != NULL ) {
  246. ZeroMemory( ChallengeBuffer.pvBuffer, ChallengeBuffer.cbBuffer );
  247. LocalFree( ChallengeBuffer.pvBuffer );
  248. }
  249. if ( sNames.sUserName != NULL ) {
  250. FreeContextBuffer( sNames.sUserName );
  251. }
  252. return bSuccess;
  253. }