2 * Copyright 2005 Kai Blin
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * This file implements the NTLM security provider.
19 * FIXME: So far, this beast doesn't do anything.
26 #include "secur32_priv.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(secur32
);
31 static char ntlm_name_A
[] = "NTLM";
32 static WCHAR ntlm_name_W
[] = {'N', 'T', 'L', 'M', 0};
35 /***********************************************************************
36 * QueryCredentialsAttributesA
38 static SECURITY_STATUS SEC_ENTRY
ntlm_QueryCredentialsAttributesA(
39 PCredHandle phCredential
, ULONG ulAttribute
, PVOID pBuffer
)
43 TRACE("(%p, %ld, %p)\n", phCredential
, ulAttribute
, pBuffer
);
45 if(ulAttribute
== SECPKG_ATTR_NAMES
)
47 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
48 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
51 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
56 /***********************************************************************
57 * QueryCredentialsAttributesW
59 static SECURITY_STATUS SEC_ENTRY
ntlm_QueryCredentialsAttributesW(
60 PCredHandle phCredential
, ULONG ulAttribute
, PVOID pBuffer
)
64 TRACE("(%p, %ld, %p)\n", phCredential
, ulAttribute
, pBuffer
);
66 if(ulAttribute
== SECPKG_ATTR_NAMES
)
68 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
69 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
72 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
77 static SECURITY_STATUS
ntlm_AcquireCredentialsHandle(ULONG fCredentialsUse
,
78 PCredHandle phCredential
, PTimeStamp ptsExpiry
)
82 if(fCredentialsUse
== SECPKG_CRED_BOTH
)
84 ret
= SEC_E_NO_CREDENTIALS
;
88 /* Ok, just store the direction like schannel does for now.
89 * FIXME: This should probably do something useful later on
91 phCredential
->dwUpper
= fCredentialsUse
;
92 phCredential
->dwLower
= 0;
93 /* Same here, shamelessly stolen from schannel.c */
95 ptsExpiry
->QuadPart
= 0;
101 /***********************************************************************
102 * AcquireCredentialsHandleA
104 static SECURITY_STATUS SEC_ENTRY
ntlm_AcquireCredentialsHandleA(
105 SEC_CHAR
*pszPrincipal
, SEC_CHAR
*pszPackage
, ULONG fCredentialUse
,
106 PLUID pLogonID
, PVOID pAuthData
, SEC_GET_KEY_FN pGetKeyFn
,
107 PVOID pGetKeyArgument
, PCredHandle phCredential
, PTimeStamp ptsExpiry
)
109 TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
110 debugstr_a(pszPrincipal
), debugstr_a(pszPackage
), fCredentialUse
,
111 pLogonID
, pAuthData
, pGetKeyFn
, pGetKeyArgument
, phCredential
, ptsExpiry
);
112 return ntlm_AcquireCredentialsHandle(fCredentialUse
, phCredential
,
116 /***********************************************************************
117 * AcquireCredentialsHandleW
119 static SECURITY_STATUS SEC_ENTRY
ntlm_AcquireCredentialsHandleW(
120 SEC_WCHAR
*pszPrincipal
, SEC_WCHAR
*pszPackage
, ULONG fCredentialUse
,
121 PLUID pLogonID
, PVOID pAuthData
, SEC_GET_KEY_FN pGetKeyFn
,
122 PVOID pGetKeyArgument
, PCredHandle phCredential
, PTimeStamp ptsExpiry
)
124 TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
125 debugstr_w(pszPrincipal
), debugstr_w(pszPackage
), fCredentialUse
,
126 pLogonID
, pAuthData
, pGetKeyFn
, pGetKeyArgument
, phCredential
, ptsExpiry
);
127 return ntlm_AcquireCredentialsHandle(fCredentialUse
, phCredential
,
131 /***********************************************************************
132 * InitializeSecurityContextA
134 static SECURITY_STATUS SEC_ENTRY
ntlm_InitializeSecurityContextA(
135 PCredHandle phCredential
, PCtxtHandle phContext
, SEC_CHAR
*pszTargetName
,
136 ULONG fContextReq
, ULONG Reserved1
, ULONG TargetDataRep
,
137 PSecBufferDesc pInput
, ULONG Reserved2
, PCtxtHandle phNewContext
,
138 PSecBufferDesc pOutput
, ULONG
*pfContextAttr
, PTimeStamp ptsExpiry
)
142 TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential
, phContext
,
143 debugstr_a(pszTargetName
), fContextReq
, Reserved1
, TargetDataRep
, pInput
,
144 Reserved1
, phNewContext
, pOutput
, pfContextAttr
, ptsExpiry
);
146 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
150 ret
= SEC_E_INVALID_HANDLE
;
155 /***********************************************************************
156 * InitializeSecurityContextW
158 static SECURITY_STATUS SEC_ENTRY
ntlm_InitializeSecurityContextW(
159 PCredHandle phCredential
, PCtxtHandle phContext
, SEC_WCHAR
*pszTargetName
,
160 ULONG fContextReq
, ULONG Reserved1
, ULONG TargetDataRep
,
161 PSecBufferDesc pInput
,ULONG Reserved2
, PCtxtHandle phNewContext
,
162 PSecBufferDesc pOutput
, ULONG
*pfContextAttr
, PTimeStamp ptsExpiry
)
166 TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential
, phContext
,
167 debugstr_w(pszTargetName
), fContextReq
, Reserved1
, TargetDataRep
, pInput
,
168 Reserved1
, phNewContext
, pOutput
, pfContextAttr
, ptsExpiry
);
171 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
175 ret
= SEC_E_INVALID_HANDLE
;
180 /***********************************************************************
181 * AcceptSecurityContext
183 static SECURITY_STATUS SEC_ENTRY
ntlm_AcceptSecurityContext(
184 PCredHandle phCredential
, PCtxtHandle phContext
, PSecBufferDesc pInput
,
185 ULONG fContextReq
, ULONG TargetDataRep
, PCtxtHandle phNewContext
,
186 PSecBufferDesc pOutput
, ULONG
*pfContextAttr
, PTimeStamp ptsExpiry
)
190 TRACE("%p %p %p %ld %ld %p %p %p %p\n", phCredential
, phContext
, pInput
,
191 fContextReq
, TargetDataRep
, phNewContext
, pOutput
, pfContextAttr
,
195 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
199 ret
= SEC_E_INVALID_HANDLE
;
204 /***********************************************************************
207 static SECURITY_STATUS SEC_ENTRY
ntlm_CompleteAuthToken(PCtxtHandle phContext
,
208 PSecBufferDesc pToken
)
212 TRACE("%p %p\n", phContext
, pToken
);
215 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
219 ret
= SEC_E_INVALID_HANDLE
;
224 /***********************************************************************
225 * DeleteSecurityContext
227 static SECURITY_STATUS SEC_ENTRY
ntlm_DeleteSecurityContext(PCtxtHandle phContext
)
231 TRACE("%p\n", phContext
);
234 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
238 ret
= SEC_E_INVALID_HANDLE
;
243 /***********************************************************************
246 static SECURITY_STATUS SEC_ENTRY
ntlm_ApplyControlToken(PCtxtHandle phContext
,
247 PSecBufferDesc pInput
)
251 TRACE("%p %p\n", phContext
, pInput
);
254 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
258 ret
= SEC_E_INVALID_HANDLE
;
263 /***********************************************************************
264 * QueryContextAttributesW
266 static SECURITY_STATUS SEC_ENTRY
ntlm_QueryContextAttributesW(PCtxtHandle phContext
,
267 unsigned long ulAttribute
, void *pBuffer
)
271 /* FIXME: From reading wrapper.h, I think the dwUpper part of a context is
272 * the SecurePackage part and the dwLower part is the actual context
273 * handle. It should be easy to extract the context attributes from that.
275 TRACE("%p %ld %p\n", phContext
, ulAttribute
, pBuffer
);
278 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
282 ret
= SEC_E_INVALID_HANDLE
;
287 /***********************************************************************
288 * QueryContextAttributesA
290 static SECURITY_STATUS SEC_ENTRY
ntlm_QueryContextAttributesA(PCtxtHandle phContext
,
291 unsigned long ulAttribute
, void *pBuffer
)
293 return ntlm_QueryContextAttributesW(phContext
, ulAttribute
, pBuffer
);
296 /***********************************************************************
297 * ImpersonateSecurityContext
299 static SECURITY_STATUS SEC_ENTRY
ntlm_ImpersonateSecurityContext(PCtxtHandle phContext
)
303 TRACE("%p\n", phContext
);
306 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
310 ret
= SEC_E_INVALID_HANDLE
;
315 /***********************************************************************
316 * RevertSecurityContext
318 static SECURITY_STATUS SEC_ENTRY
ntlm_RevertSecurityContext(PCtxtHandle phContext
)
322 TRACE("%p\n", phContext
);
325 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
329 ret
= SEC_E_INVALID_HANDLE
;
334 /***********************************************************************
337 static SECURITY_STATUS SEC_ENTRY
ntlm_MakeSignature(PCtxtHandle phContext
, ULONG fQOP
,
338 PSecBufferDesc pMessage
, ULONG MessageSeqNo
)
342 TRACE("%p %ld %p %ld\n", phContext
, fQOP
, pMessage
, MessageSeqNo
);
345 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
349 ret
= SEC_E_INVALID_HANDLE
;
354 /***********************************************************************
357 static SECURITY_STATUS SEC_ENTRY
ntlm_VerifySignature(PCtxtHandle phContext
,
358 PSecBufferDesc pMessage
, ULONG MessageSeqNo
, PULONG pfQOP
)
362 TRACE("%p %p %ld %p\n", phContext
, pMessage
, MessageSeqNo
, pfQOP
);
365 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
369 ret
= SEC_E_INVALID_HANDLE
;
376 static SecurityFunctionTableA negoTableA
= {
378 NULL
, /* EnumerateSecurityPackagesA */
379 ntlm_QueryCredentialsAttributesA
, /* QueryCredentialsAttributesA */
380 ntlm_AcquireCredentialsHandleA
, /* AcquireCredentialsHandleA */
381 FreeCredentialsHandle
, /* FreeCredentialsHandle */
382 NULL
, /* Reserved2 */
383 ntlm_InitializeSecurityContextA
, /* InitializeSecurityContextA */
384 ntlm_AcceptSecurityContext
, /* AcceptSecurityContext */
385 ntlm_CompleteAuthToken
, /* CompleteAuthToken */
386 ntlm_DeleteSecurityContext
, /* DeleteSecurityContext */
387 ntlm_ApplyControlToken
, /* ApplyControlToken */
388 ntlm_QueryContextAttributesA
, /* QueryContextAttributesA */
389 ntlm_ImpersonateSecurityContext
, /* ImpersonateSecurityContext */
390 ntlm_RevertSecurityContext
, /* RevertSecurityContext */
391 ntlm_MakeSignature
, /* MakeSignature */
392 ntlm_VerifySignature
, /* VerifySignature */
393 FreeContextBuffer
, /* FreeContextBuffer */
394 NULL
, /* QuerySecurityPackageInfoA */
395 NULL
, /* Reserved3 */
396 NULL
, /* Reserved4 */
397 NULL
, /* ExportSecurityContext */
398 NULL
, /* ImportSecurityContextA */
399 NULL
, /* AddCredentialsA */
400 NULL
, /* Reserved8 */
401 NULL
, /* QuerySecurityContextToken */
402 NULL
, /* EncryptMessage */
403 NULL
, /* DecryptMessage */
404 NULL
, /* SetContextAttributesA */
407 static SecurityFunctionTableW negoTableW
= {
409 NULL
, /* EnumerateSecurityPackagesW */
410 ntlm_QueryCredentialsAttributesW
, /* QueryCredentialsAttributesW */
411 ntlm_AcquireCredentialsHandleW
, /* AcquireCredentialsHandleW */
412 FreeCredentialsHandle
, /* FreeCredentialsHandle */
413 NULL
, /* Reserved2 */
414 ntlm_InitializeSecurityContextW
, /* InitializeSecurityContextW */
415 ntlm_AcceptSecurityContext
, /* AcceptSecurityContext */
416 ntlm_CompleteAuthToken
, /* CompleteAuthToken */
417 ntlm_DeleteSecurityContext
, /* DeleteSecurityContext */
418 ntlm_ApplyControlToken
, /* ApplyControlToken */
419 ntlm_QueryContextAttributesW
, /* QueryContextAttributesW */
420 ntlm_ImpersonateSecurityContext
, /* ImpersonateSecurityContext */
421 ntlm_RevertSecurityContext
, /* RevertSecurityContext */
422 ntlm_MakeSignature
, /* MakeSignature */
423 ntlm_VerifySignature
, /* VerifySignature */
424 FreeContextBuffer
, /* FreeContextBuffer */
425 NULL
, /* QuerySecurityPackageInfoW */
426 NULL
, /* Reserved3 */
427 NULL
, /* Reserved4 */
428 NULL
, /* ExportSecurityContext */
429 NULL
, /* ImportSecurityContextW */
430 NULL
, /* AddCredentialsW */
431 NULL
, /* Reserved8 */
432 NULL
, /* QuerySecurityContextToken */
433 NULL
, /* EncryptMessage */
434 NULL
, /* DecryptMessage */
435 NULL
, /* SetContextAttributesW */
438 static WCHAR ntlm_comment_W
[] = { 'N', 'T', 'L', 'M', ' ', 'S', 'e',
439 'c', 'u', 'r', 'i', 't', 'y', ' ', 'P', 'a', 'c', 'k', 'a', 'g', 'e',0};
441 static CHAR ntlm_comment_A
[] = "NTLM Security Package";
443 void SECUR32_initNTLMSP(void)
445 SecureProvider
*provider
= SECUR32_addProvider(&negoTableA
, &negoTableW
,
447 /* According to Windows, NTLM has the following capabilities.
450 static const LONG caps
=
451 SECPKG_FLAG_INTEGRITY
|
452 SECPKG_FLAG_PRIVACY
|
453 SECPKG_FLAG_TOKEN_ONLY
|
454 SECPKG_FLAG_CONNECTION
|
455 SECPKG_FLAG_MULTI_REQUIRED
|
456 SECPKG_FLAG_IMPERSONATION
|
457 SECPKG_FLAG_ACCEPT_WIN32_NAME
|
458 SECPKG_FLAG_READONLY_WITH_CHECKSUM
;
460 static const USHORT version
= 1;
461 static const USHORT rpcid
= 10;
462 static const ULONG max_token
= 12000;
463 const SecPkgInfoW infoW
= { caps
, version
, rpcid
, max_token
, ntlm_name_W
,
465 const SecPkgInfoA infoA
= { caps
, version
, rpcid
, max_token
, ntlm_name_A
,
468 SECUR32_addPackages(provider
, 1L, &infoA
, &infoW
);