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.

337 lines
8.8 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. BOOL bSuccess = FALSE ; // assume this function will fail
  56. NegotiateBuffer.pvBuffer = NULL;
  57. NegotiateBuffer.cbBuffer = 0;
  58. ChallengeBuffer.pvBuffer = NULL;
  59. ChallengeBuffer.cbBuffer = 0;
  60. sNames.sUserName = NULL;
  61. ClientContextHandle.dwUpper = MAXDWORD;
  62. ClientContextHandle.dwLower = MAXDWORD;
  63. ServerContextHandle.dwUpper = MAXDWORD;
  64. ServerContextHandle.dwLower = MAXDWORD;
  65. CredentialHandle1.dwUpper = MAXDWORD;
  66. CredentialHandle1.dwLower = MAXDWORD;
  67. CredentialHandle2.dwUpper = MAXDWORD;
  68. CredentialHandle2.dwLower = MAXDWORD;
  69. //
  70. // << this section could be cached in a repeat caller scenario >>
  71. //
  72. //
  73. // Get info about the security packages.
  74. //
  75. if(EnumerateSecurityPackages(
  76. &PackageCount,
  77. &PackageInfo
  78. ) != SEC_E_OK) return FALSE;
  79. //
  80. // loop through the packages looking for NTLM
  81. //
  82. cbMaxToken = 0;
  83. for(PackageIndex = 0 ; PackageIndex < PackageCount ; PackageIndex++ ) {
  84. if(PackageInfo[PackageIndex].Name != NULL) {
  85. if(LSTRCMPIS(PackageInfo[PackageIndex].Name, MICROSOFT_KERBEROS_NAME) == 0) {
  86. cbMaxToken = PackageInfo[PackageIndex].cbMaxToken;
  87. bSuccess = TRUE;
  88. break;
  89. }
  90. }
  91. }
  92. FreeContextBuffer( PackageInfo );
  93. if(!bSuccess) return FALSE;
  94. bSuccess = FALSE; // reset to assume failure
  95. //
  96. // << end of cached section >>
  97. //
  98. //
  99. // Acquire a credential handle for the server side
  100. //
  101. SecStatus = AcquireCredentialsHandle(
  102. NULL, // New principal
  103. MICROSOFT_KERBEROS_NAME, // Package Name
  104. SECPKG_CRED_INBOUND,
  105. NULL,
  106. NULL,
  107. NULL,
  108. NULL,
  109. &CredentialHandle1,
  110. &Lifetime
  111. );
  112. if ( SecStatus != SEC_E_OK ) {
  113. goto cleanup;
  114. }
  115. //
  116. // Acquire a credential handle for the client side
  117. //
  118. ZeroMemory( &AuthIdentity, sizeof(AuthIdentity) );
  119. if ( DomainName != NULL ) {
  120. AuthIdentity.Domain = DomainName;
  121. AuthIdentity.DomainLength = lstrlen(DomainName);
  122. }
  123. if ( UserName != NULL ) {
  124. AuthIdentity.User = UserName;
  125. AuthIdentity.UserLength = lstrlen(UserName);
  126. }
  127. if ( Password != NULL ) {
  128. AuthIdentity.Password = Password;
  129. AuthIdentity.PasswordLength = lstrlen(Password);
  130. }
  131. #ifdef UNICODE
  132. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  133. #else
  134. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  135. #endif
  136. SecStatus = AcquireCredentialsHandle(
  137. NULL, // New principal
  138. MICROSOFT_KERBEROS_NAME, // Package Name
  139. SECPKG_CRED_OUTBOUND,
  140. NULL,
  141. (DomainName == NULL && UserName == NULL && Password == NULL) ?
  142. NULL : &AuthIdentity,
  143. NULL,
  144. NULL,
  145. &CredentialHandle2,
  146. &Lifetime
  147. );
  148. if ( SecStatus != SEC_E_OK ) {
  149. goto cleanup;
  150. }
  151. SecStatus = QueryCredentialsAttributes(&CredentialHandle1, SECPKG_CRED_ATTR_NAMES, &sNames);
  152. if ( SecStatus != SEC_E_OK ) {
  153. goto cleanup;
  154. }
  155. //
  156. // Get the NegotiateMessage (ClientSide)
  157. //
  158. NegotiateDesc.ulVersion = 0;
  159. NegotiateDesc.cBuffers = 1;
  160. NegotiateDesc.pBuffers = &NegotiateBuffer;
  161. NegotiateBuffer.cbBuffer = cbMaxToken;
  162. NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
  163. NegotiateBuffer.pvBuffer = LocalAlloc( LMEM_FIXED, NegotiateBuffer.cbBuffer );
  164. if ( NegotiateBuffer.pvBuffer == NULL ) {
  165. goto cleanup;
  166. }
  167. SecStatus = InitializeSecurityContext(
  168. &CredentialHandle2,
  169. NULL, // No Client context yet
  170. sNames.sUserName, // target name
  171. ISC_REQ_SEQUENCE_DETECT,
  172. 0, // Reserved 1
  173. SECURITY_NATIVE_DREP,
  174. NULL, // No initial input token
  175. 0, // Reserved 2
  176. &ClientContextHandle,
  177. &NegotiateDesc,
  178. &ContextAttributes,
  179. &Lifetime
  180. );
  181. if(SecStatus != SEC_E_OK)
  182. {
  183. goto cleanup;
  184. }
  185. //
  186. // Get the ChallengeMessage (ServerSide)
  187. //
  188. NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
  189. ChallengeDesc.ulVersion = 0;
  190. ChallengeDesc.cBuffers = 1;
  191. ChallengeDesc.pBuffers = &ChallengeBuffer;
  192. ChallengeBuffer.cbBuffer = cbMaxToken;
  193. ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
  194. ChallengeBuffer.pvBuffer = LocalAlloc( LMEM_FIXED, ChallengeBuffer.cbBuffer );
  195. if ( ChallengeBuffer.pvBuffer == NULL ) {
  196. goto cleanup;
  197. }
  198. SecStatus = AcceptSecurityContext(
  199. &CredentialHandle1,
  200. NULL, // No Server context yet
  201. &NegotiateDesc,
  202. ISC_REQ_SEQUENCE_DETECT,
  203. SECURITY_NATIVE_DREP,
  204. &ServerContextHandle,
  205. &ChallengeDesc,
  206. &ContextAttributes,
  207. &Lifetime
  208. );
  209. if(SecStatus != SEC_E_OK)
  210. {
  211. goto cleanup;
  212. }
  213. if(QuerySecurityContextToken(&ServerContextHandle, phToken) != SEC_E_OK)
  214. goto cleanup;
  215. bSuccess = TRUE;
  216. cleanup:
  217. //
  218. // Delete context
  219. //
  220. if((ClientContextHandle.dwUpper != MAXDWORD) ||
  221. (ClientContextHandle.dwLower != MAXDWORD))
  222. {
  223. DeleteSecurityContext( &ClientContextHandle );
  224. }
  225. if((ServerContextHandle.dwUpper != MAXDWORD) ||
  226. (ServerContextHandle.dwLower != MAXDWORD))
  227. {
  228. DeleteSecurityContext( &ServerContextHandle );
  229. }
  230. //
  231. // Free credential handles
  232. //
  233. if((CredentialHandle1.dwUpper != MAXDWORD) ||
  234. (CredentialHandle1.dwLower != MAXDWORD))
  235. {
  236. FreeCredentialsHandle( &CredentialHandle1 );
  237. }
  238. if((CredentialHandle2.dwUpper != MAXDWORD) ||
  239. (CredentialHandle2.dwLower != MAXDWORD))
  240. {
  241. FreeCredentialsHandle( &CredentialHandle2 );
  242. }
  243. if ( NegotiateBuffer.pvBuffer != NULL ) {
  244. //
  245. // NegotiateBuffer.cbBuffer may change on the error path --
  246. // use the original allocation size.
  247. //
  248. SecureZeroMemory( NegotiateBuffer.pvBuffer, cbMaxToken );
  249. LocalFree( NegotiateBuffer.pvBuffer );
  250. }
  251. if ( ChallengeBuffer.pvBuffer != NULL ) {
  252. //
  253. // ChallengeBuffer.cbBuffer may change on the error path --
  254. // use the original allocation size.
  255. //
  256. SecureZeroMemory( ChallengeBuffer.pvBuffer, cbMaxToken );
  257. LocalFree( ChallengeBuffer.pvBuffer );
  258. }
  259. if ( sNames.sUserName != NULL ) {
  260. FreeContextBuffer( sNames.sUserName );
  261. }
  262. return bSuccess;
  263. }