mciseq: Fix typo.
[wine] / dlls / secur32 / wrapper.c
1 /* Copyright (C) 2004 Juan Lang
2  *
3  * Implements secur32 functions that forward to (wrap) an SSP's implementation.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 #include <stdarg.h>
20 #include "windef.h"
21 #include "winbase.h"
22 #include "winnls.h"
23 #include "sspi.h"
24 #include "secur32_priv.h"
25
26 #include "wine/debug.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
29
30 /* Tries to allocate a new SecHandle, into which it stores package (in
31  * phSec->dwUpper) and a copy of realHandle (allocated with SECUR32_ALLOC,
32  * and stored in phSec->dwLower).  SecHandle is equivalent to both a
33  * CredHandle and a CtxtHandle.
34  */
35 static SECURITY_STATUS SECUR32_makeSecHandle(PSecHandle phSec,
36  SecurePackage *package, PSecHandle realHandle)
37 {
38     SECURITY_STATUS ret;
39
40     TRACE("%p %p %p\n", phSec, package, realHandle);
41
42     if (phSec && package && realHandle)
43     {
44         PSecHandle newSec = HeapAlloc(GetProcessHeap(), 0, sizeof(SecHandle));
45
46         if (newSec)
47         {
48             *newSec = *realHandle;
49             phSec->dwUpper = (ULONG_PTR)package;
50             phSec->dwLower = (ULONG_PTR)newSec;
51             ret = SEC_E_OK;
52         }
53         else
54             ret = SEC_E_INSUFFICIENT_MEMORY;
55     }
56     else
57         ret = SEC_E_INVALID_HANDLE;
58     return ret;
59 }
60
61 /***********************************************************************
62  *              AcquireCredentialsHandleA (SECUR32.@)
63  */
64 SECURITY_STATUS WINAPI AcquireCredentialsHandleA(
65  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse,
66  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
67  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
68 {
69     SECURITY_STATUS ret;
70
71     TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal),
72      debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
73      pvGetKeyArgument, phCredential, ptsExpiry);
74     if (pszPackage)
75     {
76         SecurePackage *package = SECUR32_findPackageA(pszPackage);
77
78         if (package && package->provider)
79         {
80             if (package->provider->fnTableA.AcquireCredentialsHandleA)
81             {
82                 CredHandle myCred;
83
84                 ret = package->provider->fnTableA.AcquireCredentialsHandleA(
85                  pszPrincipal, pszPackage, fCredentialsUse, pvLogonID,
86                  pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred,
87                  ptsExpiry);
88                 if (ret == SEC_E_OK)
89                 {
90                     ret = SECUR32_makeSecHandle(phCredential, package, &myCred);
91                     if (ret != SEC_E_OK)
92                         package->provider->fnTableW.FreeCredentialsHandle(
93                          &myCred);
94                 }
95             }
96             else
97                 ret = SEC_E_UNSUPPORTED_FUNCTION;
98         }
99         else
100             ret = SEC_E_SECPKG_NOT_FOUND;
101     }
102     else
103         ret = SEC_E_SECPKG_NOT_FOUND;
104     return ret;
105 }
106
107 /***********************************************************************
108  *              AcquireCredentialsHandleW (SECUR32.@)
109  */
110 SECURITY_STATUS WINAPI AcquireCredentialsHandleW(
111  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse,
112  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
113  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
114 {
115     SECURITY_STATUS ret;
116
117     TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal),
118      debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
119      pvGetKeyArgument, phCredential, ptsExpiry);
120     if (pszPackage)
121     {
122         SecurePackage *package = SECUR32_findPackageW(pszPackage);
123
124         if (package && package->provider)
125         {
126             if (package->provider->fnTableW.AcquireCredentialsHandleW)
127             {
128                 CredHandle myCred;
129
130                 ret = package->provider->fnTableW.AcquireCredentialsHandleW(
131                  pszPrincipal, pszPackage, fCredentialsUse, pvLogonID,
132                  pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred,
133                  ptsExpiry);
134                 if (ret == SEC_E_OK)
135                 {
136                     ret = SECUR32_makeSecHandle(phCredential, package, &myCred);
137                     if (ret != SEC_E_OK)
138                         package->provider->fnTableW.FreeCredentialsHandle(
139                          &myCred);
140                 }
141             }
142             else
143                 ret = SEC_E_UNSUPPORTED_FUNCTION;
144         }
145         else
146             ret = SEC_E_SECPKG_NOT_FOUND;
147     }
148     else
149         ret = SEC_E_SECPKG_NOT_FOUND;
150     return ret;
151 }
152
153 /***********************************************************************
154  *              FreeCredentialsHandle (SECUR32.@)
155  */
156 SECURITY_STATUS WINAPI FreeCredentialsHandle(
157  PCredHandle phCredential)
158 {
159     SECURITY_STATUS ret;
160
161     TRACE("%p\n", phCredential);
162     if (phCredential)
163     {
164         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
165         PCredHandle cred = (PCredHandle)phCredential->dwLower;
166
167         if (package && package->provider &&
168          package->provider->fnTableW.FreeCredentialsHandle)
169             ret = package->provider->fnTableW.FreeCredentialsHandle(cred);
170         else
171             ret = SEC_E_INVALID_HANDLE;
172         HeapFree(GetProcessHeap(), 0, cred);
173     }
174     else
175         ret = SEC_E_INVALID_HANDLE;
176     return ret;
177 }
178
179 /***********************************************************************
180  *              QueryCredentialsAttributesA (SECUR32.@)
181  */
182 SECURITY_STATUS WINAPI QueryCredentialsAttributesA(
183  PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
184 {
185     SECURITY_STATUS ret;
186
187     TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
188     if (phCredential)
189     {
190         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
191         PCredHandle cred = (PCredHandle)phCredential->dwLower;
192
193         if (package && package->provider)
194         {
195             if (package->provider->fnTableA.QueryCredentialsAttributesA)
196                 ret = package->provider->fnTableA.QueryCredentialsAttributesA(
197                  cred, ulAttribute, pBuffer);
198             else
199                 ret = SEC_E_UNSUPPORTED_FUNCTION;
200         }
201         else
202             ret = SEC_E_INVALID_HANDLE;
203     }
204     else
205         ret = SEC_E_INVALID_HANDLE;
206     return ret;
207 }
208
209 /***********************************************************************
210  *              QueryCredentialsAttributesW (SECUR32.@)
211  */
212 SECURITY_STATUS WINAPI QueryCredentialsAttributesW(
213  PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
214 {
215     SECURITY_STATUS ret;
216
217     TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
218     if (phCredential)
219     {
220         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
221         PCredHandle cred = (PCredHandle)phCredential->dwLower;
222
223         if (package && package->provider)
224         {
225             if (package->provider->fnTableW.QueryCredentialsAttributesW)
226                 ret = package->provider->fnTableW.QueryCredentialsAttributesW(
227                  cred, ulAttribute, pBuffer);
228             else
229                 ret = SEC_E_UNSUPPORTED_FUNCTION;
230         }
231         else
232             ret = SEC_E_INVALID_HANDLE;
233     }
234     else
235         ret = SEC_E_INVALID_HANDLE;
236     return ret;
237 }
238
239 /***********************************************************************
240  *              InitializeSecurityContextA (SECUR32.@)
241  */
242 SECURITY_STATUS WINAPI InitializeSecurityContextA(
243  PCredHandle phCredential, PCtxtHandle phContext,
244  SEC_CHAR *pszTargetName, ULONG fContextReq,
245  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
246  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
247  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
248 {
249     SECURITY_STATUS ret;
250     SecurePackage *package = NULL;
251     PCredHandle cred = NULL;
252     PCredHandle ctxt = NULL;
253
254     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
255      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
256      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
257
258     if (phContext)
259     {
260         package = (SecurePackage *)phContext->dwUpper;
261         ctxt = (PCtxtHandle)phContext->dwLower;
262     }
263     if (phCredential)
264     {
265         package = (SecurePackage *)phCredential->dwUpper;
266         cred = (PCredHandle)phCredential->dwLower;
267     }
268
269     if (package && package->provider)
270     {
271         if (package->provider->fnTableA.InitializeSecurityContextA)
272         {
273             CtxtHandle myCtxt;
274
275             if (phContext)
276             {
277                 PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
278                 myCtxt.dwUpper = realCtxt->dwUpper;
279                 myCtxt.dwLower = realCtxt->dwLower;
280             }
281
282             ret = package->provider->fnTableA.InitializeSecurityContextA(
283                  cred, ctxt, pszTargetName, fContextReq,
284                  Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL,
285                  pOutput, pfContextAttr, ptsExpiry);
286             if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
287             {
288                 SECURITY_STATUS ret2;
289                 ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
290                 if (ret2 != SEC_E_OK)
291                     package->provider->fnTableA.DeleteSecurityContext(&myCtxt);
292             }
293         }
294         else
295             ret = SEC_E_UNSUPPORTED_FUNCTION;
296     }
297     else
298         ret = SEC_E_INVALID_HANDLE;
299     return ret;
300 }
301
302 /***********************************************************************
303  *              InitializeSecurityContextW (SECUR32.@)
304  */
305 SECURITY_STATUS WINAPI InitializeSecurityContextW(
306  PCredHandle phCredential, PCtxtHandle phContext,
307  SEC_WCHAR *pszTargetName, ULONG fContextReq,
308  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
309  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
310  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
311 {
312     SECURITY_STATUS ret;
313     SecurePackage *package = NULL;
314     PCredHandle cred = NULL;
315     PCredHandle ctxt = NULL;
316
317     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
318      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
319      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
320
321     if (phContext)
322     {
323         package = (SecurePackage *)phContext->dwUpper;
324         ctxt = (PCtxtHandle)phContext->dwLower;
325     }
326     if (phCredential)
327     {
328         package = (SecurePackage *)phCredential->dwUpper;
329         cred = (PCredHandle)phCredential->dwLower;
330     }
331
332     if (package && package->provider)
333     {
334         if (package->provider->fnTableW.InitializeSecurityContextW)
335         {
336             CtxtHandle myCtxt;
337
338             if (phContext)
339             {
340                 PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
341                 myCtxt.dwUpper = realCtxt->dwUpper;
342                 myCtxt.dwLower = realCtxt->dwLower;
343             }
344
345             ret = package->provider->fnTableW.InitializeSecurityContextW(
346                  cred, ctxt, pszTargetName, fContextReq,
347                  Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL,
348                  pOutput, pfContextAttr, ptsExpiry);
349             if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
350             {
351                 SECURITY_STATUS ret2;
352                 ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
353                 if (ret2 != SEC_E_OK)
354                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
355             }
356         }
357         else
358             ret = SEC_E_UNSUPPORTED_FUNCTION;
359     }
360     else
361         ret = SEC_E_INVALID_HANDLE;
362     return ret;
363 }
364
365 /***********************************************************************
366  *              AcceptSecurityContext (SECUR32.@)
367  */
368 SECURITY_STATUS WINAPI AcceptSecurityContext(
369  PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
370  ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
371  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
372 {
373     SECURITY_STATUS ret;
374
375     TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput,
376      fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
377      ptsExpiry);
378     if (phCredential)
379     {
380         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
381         PCredHandle cred = (PCredHandle)phCredential->dwLower;
382
383         if (package && package->provider)
384         {
385             if (package->provider->fnTableW.AcceptSecurityContext)
386             {
387                 CtxtHandle myCtxt;
388
389                 if(phContext)
390                 {
391                     PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
392                     TRACE("realCtx: %p\n", realCtxt);
393                     myCtxt.dwUpper = realCtxt->dwUpper;
394                     myCtxt.dwLower = realCtxt->dwLower;
395                 }
396                 
397                 ret = package->provider->fnTableW.AcceptSecurityContext(
398                  cred, phContext ? &myCtxt : NULL, pInput, fContextReq,
399                  TargetDataRep, &myCtxt, pOutput, pfContextAttr, ptsExpiry);
400                 if (ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED)
401                 {
402                     SECURITY_STATUS ret2;
403                     ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
404                     if (ret2 != SEC_E_OK)
405                         package->provider->fnTableW.DeleteSecurityContext(
406                          &myCtxt);
407                 }
408             }
409             else
410                 ret = SEC_E_UNSUPPORTED_FUNCTION;
411         }
412         else
413             ret = SEC_E_INVALID_HANDLE;
414     }
415     else
416         ret = SEC_E_INVALID_HANDLE;
417     return ret;
418 }
419
420 /***********************************************************************
421  *              CompleteAuthToken (SECUR32.@)
422  */
423 SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext,
424  PSecBufferDesc pToken)
425 {
426     SECURITY_STATUS ret;
427
428     TRACE("%p %p\n", phContext, pToken);
429     if (phContext)
430     {
431         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
432         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
433
434         if (package && package->provider)
435         {
436             if (package->provider->fnTableW.CompleteAuthToken)
437                 ret = package->provider->fnTableW.CompleteAuthToken(ctxt,
438                  pToken);
439             else
440                 ret = SEC_E_UNSUPPORTED_FUNCTION;
441         }
442         else
443             ret = SEC_E_INVALID_HANDLE;
444     }
445     else
446         ret = SEC_E_INVALID_HANDLE;
447     return ret;
448 }
449
450 /***********************************************************************
451  *              DeleteSecurityContext (SECUR32.@)
452  */
453 SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
454 {
455     SECURITY_STATUS ret;
456
457     TRACE("%p\n", phContext);
458     if (phContext)
459     {
460         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
461         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
462
463         if (package && package->provider &&
464          package->provider->fnTableW.DeleteSecurityContext)
465             ret = package->provider->fnTableW.DeleteSecurityContext(ctxt);
466         else
467             ret = SEC_E_INVALID_HANDLE;
468         HeapFree(GetProcessHeap(), 0, ctxt);
469     }
470     else
471         ret = SEC_E_INVALID_HANDLE;
472     return ret;
473 }
474
475 /***********************************************************************
476  *              ApplyControlToken (SECUR32.@)
477  */
478 SECURITY_STATUS WINAPI ApplyControlToken(PCtxtHandle phContext,
479  PSecBufferDesc pInput)
480 {
481     SECURITY_STATUS ret;
482
483     TRACE("%p %p\n", phContext, pInput);
484     if (phContext)
485     {
486         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
487         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
488
489         if (package && package->provider)
490         {
491             if (package->provider->fnTableW.ApplyControlToken)
492                 ret = package->provider->fnTableW.ApplyControlToken(
493                  ctxt, pInput);
494             else
495                 ret = SEC_E_UNSUPPORTED_FUNCTION;
496         }
497         else
498             ret = SEC_E_INVALID_HANDLE;
499     }
500     else
501         ret = SEC_E_INVALID_HANDLE;
502     return ret;
503 }
504
505 /***********************************************************************
506  *              QueryContextAttributesA (SECUR32.@)
507  */
508 SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext,
509  ULONG ulAttribute, void *pBuffer)
510 {
511     SECURITY_STATUS ret;
512
513     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
514     if (phContext)
515     {
516         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
517         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
518
519         if (package && package->provider)
520         {
521             if (package->provider->fnTableA.QueryContextAttributesA)
522                 ret = package->provider->fnTableA.QueryContextAttributesA(
523                  ctxt, ulAttribute, pBuffer);
524             else
525                 ret = SEC_E_UNSUPPORTED_FUNCTION;
526         }
527         else
528             ret = SEC_E_INVALID_HANDLE;
529     }
530     else
531         ret = SEC_E_INVALID_HANDLE;
532     return ret;
533 }
534
535 /***********************************************************************
536  *              QueryContextAttributesW (SECUR32.@)
537  */
538 SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext,
539  ULONG ulAttribute, void *pBuffer)
540 {
541     SECURITY_STATUS ret;
542
543     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
544     if (phContext)
545     {
546         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
547         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
548
549         if (package && package->provider)
550         {
551             if (package->provider->fnTableW.QueryContextAttributesW)
552                 ret = package->provider->fnTableW.QueryContextAttributesW(
553                  ctxt, ulAttribute, pBuffer);
554             else
555                 ret = SEC_E_UNSUPPORTED_FUNCTION;
556         }
557         else
558             ret = SEC_E_INVALID_HANDLE;
559     }
560     else
561         ret = SEC_E_INVALID_HANDLE;
562     return ret;
563 }
564
565 /***********************************************************************
566  *              ImpersonateSecurityContext (SECUR32.@)
567  */
568 SECURITY_STATUS WINAPI ImpersonateSecurityContext(PCtxtHandle phContext)
569 {
570     SECURITY_STATUS ret;
571
572     TRACE("%p\n", phContext);
573     if (phContext)
574     {
575         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
576         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
577
578         if (package && package->provider)
579         {
580             if (package->provider->fnTableW.ImpersonateSecurityContext)
581                 ret = package->provider->fnTableW.ImpersonateSecurityContext(
582                  ctxt);
583             else
584                 ret = SEC_E_UNSUPPORTED_FUNCTION;
585         }
586         else
587             ret = SEC_E_INVALID_HANDLE;
588     }
589     else
590         ret = SEC_E_INVALID_HANDLE;
591     return ret;
592 }
593
594 /***********************************************************************
595  *              RevertSecurityContext (SECUR32.@)
596  */
597 SECURITY_STATUS WINAPI RevertSecurityContext(PCtxtHandle phContext)
598 {
599     SECURITY_STATUS ret;
600
601     TRACE("%p\n", phContext);
602     if (phContext)
603     {
604         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
605         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
606
607         if (package && package->provider)
608         {
609             if (package->provider->fnTableW.RevertSecurityContext)
610                 ret = package->provider->fnTableW.RevertSecurityContext(
611                  ctxt);
612             else
613                 ret = SEC_E_UNSUPPORTED_FUNCTION;
614         }
615         else
616             ret = SEC_E_INVALID_HANDLE;
617     }
618     else
619         ret = SEC_E_INVALID_HANDLE;
620     return ret;
621 }
622
623 /***********************************************************************
624  *              MakeSignature (SECUR32.@)
625  */
626 SECURITY_STATUS WINAPI MakeSignature(PCtxtHandle phContext, ULONG fQOP,
627  PSecBufferDesc pMessage, ULONG MessageSeqNo)
628 {
629     SECURITY_STATUS ret;
630
631     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
632     if (phContext)
633     {
634         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
635         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
636
637         if (package && package->provider)
638         {
639             if (package->provider->fnTableW.MakeSignature)
640                 ret = package->provider->fnTableW.MakeSignature(
641                  ctxt, fQOP, pMessage, MessageSeqNo);
642             else
643                 ret = SEC_E_UNSUPPORTED_FUNCTION;
644         }
645         else
646             ret = SEC_E_INVALID_HANDLE;
647     }
648     else
649         ret = SEC_E_INVALID_HANDLE;
650     return ret;
651 }
652
653 /***********************************************************************
654  *              VerifySignature (SECUR32.@)
655  */
656 SECURITY_STATUS WINAPI VerifySignature(PCtxtHandle phContext,
657  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
658 {
659     SECURITY_STATUS ret;
660
661     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
662     if (phContext)
663     {
664         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
665         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
666
667         if (package && package->provider)
668         {
669             if (package->provider->fnTableW.VerifySignature)
670                 ret = package->provider->fnTableW.VerifySignature(
671                  ctxt, pMessage, MessageSeqNo, pfQOP);
672             else
673                 ret = SEC_E_UNSUPPORTED_FUNCTION;
674         }
675         else
676             ret = SEC_E_INVALID_HANDLE;
677     }
678     else
679         ret = SEC_E_INVALID_HANDLE;
680     return ret;
681 }
682
683 /***********************************************************************
684  *              QuerySecurityPackageInfoA (SECUR32.@)
685  */
686 SECURITY_STATUS WINAPI QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName,
687  PSecPkgInfoA *ppPackageInfo)
688 {
689     SECURITY_STATUS ret;
690    
691     TRACE("%s %p\n", debugstr_a(pszPackageName), ppPackageInfo);
692     if (pszPackageName)
693     {
694         SecurePackage *package = SECUR32_findPackageA(pszPackageName);
695
696         if (package)
697         {
698             size_t bytesNeeded = sizeof(SecPkgInfoA);
699             int nameLen = 0, commentLen = 0;
700
701             if (package->infoW.Name)
702             {
703                 nameLen = WideCharToMultiByte(CP_ACP, 0,
704                  package->infoW.Name, -1, NULL, 0, NULL, NULL);
705                 bytesNeeded += nameLen;
706             }
707             if (package->infoW.Comment)
708             {
709                 commentLen = WideCharToMultiByte(CP_ACP, 0,
710                  package->infoW.Comment, -1, NULL, 0, NULL, NULL);
711                 bytesNeeded += commentLen;
712             }
713             *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
714             if (*ppPackageInfo)
715             {
716                 PSTR nextString = (PSTR)((PBYTE)*ppPackageInfo +
717                  sizeof(SecPkgInfoA));
718
719                 memcpy(*ppPackageInfo, &package->infoW, sizeof(package->infoW));
720                 if (package->infoW.Name)
721                 {
722                     (*ppPackageInfo)->Name = nextString;
723                     nextString += WideCharToMultiByte(CP_ACP, 0,
724                      package->infoW.Name, -1, nextString, nameLen, NULL, NULL);
725                 }
726                 else
727                     (*ppPackageInfo)->Name = NULL;
728                 if (package->infoW.Comment)
729                 {
730                     (*ppPackageInfo)->Comment = nextString;
731                     nextString += WideCharToMultiByte(CP_ACP, 0,
732                      package->infoW.Comment, -1, nextString, commentLen, NULL,
733                      NULL);
734                 }
735                 else
736                     (*ppPackageInfo)->Comment = NULL;
737                 ret = SEC_E_OK;
738             }
739             else
740                 ret = SEC_E_INSUFFICIENT_MEMORY;
741         }
742         else
743             ret = SEC_E_SECPKG_NOT_FOUND;
744     }
745     else
746         ret = SEC_E_SECPKG_NOT_FOUND;
747     return ret;
748 }
749
750 /***********************************************************************
751  *              QuerySecurityPackageInfoW (SECUR32.@)
752  */
753 SECURITY_STATUS WINAPI QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName,
754  PSecPkgInfoW *ppPackageInfo)
755 {
756     SECURITY_STATUS ret;
757     SecurePackage *package = SECUR32_findPackageW(pszPackageName);
758
759     TRACE("%s %p\n", debugstr_w(pszPackageName), ppPackageInfo);
760     if (package)
761     {
762         size_t bytesNeeded = sizeof(SecPkgInfoW);
763         int nameLen = 0, commentLen = 0;
764
765         if (package->infoW.Name)
766         {
767             nameLen = lstrlenW(package->infoW.Name) + 1;
768             bytesNeeded += nameLen * sizeof(WCHAR);
769         }
770         if (package->infoW.Comment)
771         {
772             commentLen = lstrlenW(package->infoW.Comment) + 1;
773             bytesNeeded += commentLen * sizeof(WCHAR);
774         }
775         *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
776         if (*ppPackageInfo)
777         {
778             PWSTR nextString = (PWSTR)((PBYTE)*ppPackageInfo +
779              sizeof(SecPkgInfoW));
780
781             **ppPackageInfo = package->infoW;
782             if (package->infoW.Name)
783             {
784                 (*ppPackageInfo)->Name = nextString;
785                 lstrcpynW(nextString, package->infoW.Name, nameLen);
786                 nextString += nameLen;
787             }
788             else
789                 (*ppPackageInfo)->Name = NULL;
790             if (package->infoW.Comment)
791             {
792                 (*ppPackageInfo)->Comment = nextString;
793                 lstrcpynW(nextString, package->infoW.Comment, commentLen);
794                 nextString += commentLen;
795             }
796             else
797                 (*ppPackageInfo)->Comment = NULL;
798             ret = SEC_E_OK;
799         }
800         else
801             ret = SEC_E_INSUFFICIENT_MEMORY;
802     }
803     else
804         ret = SEC_E_SECPKG_NOT_FOUND;
805     return ret;
806 }
807
808 /***********************************************************************
809  *              ExportSecurityContext (SECUR32.@)
810  */
811 SECURITY_STATUS WINAPI ExportSecurityContext(PCtxtHandle phContext,
812  ULONG fFlags, PSecBuffer pPackedContext, void **pToken)
813 {
814     SECURITY_STATUS ret;
815
816     TRACE("%p %d %p %p\n", phContext, fFlags, pPackedContext, pToken);
817     if (phContext)
818     {
819         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
820         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
821
822         if (package && package->provider)
823         {
824             if (package->provider->fnTableW.ExportSecurityContext)
825                 ret = package->provider->fnTableW.ExportSecurityContext(
826                  ctxt, fFlags, pPackedContext, pToken);
827             else
828                 ret = SEC_E_UNSUPPORTED_FUNCTION;
829         }
830         else
831             ret = SEC_E_INVALID_HANDLE;
832     }
833     else
834         ret = SEC_E_INVALID_HANDLE;
835     return ret;
836 }
837
838 /***********************************************************************
839  *              ImportSecurityContextA (SECUR32.@)
840  */
841 SECURITY_STATUS WINAPI ImportSecurityContextA(SEC_CHAR *pszPackage,
842  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
843 {
844     SECURITY_STATUS ret;
845     SecurePackage *package = SECUR32_findPackageA(pszPackage);
846  
847     TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token,
848      phContext);
849     if (package && package->provider)
850     {
851         if (package->provider->fnTableA.ImportSecurityContextA)
852         {
853             CtxtHandle myCtxt;
854
855             ret = package->provider->fnTableA.ImportSecurityContextA(
856              pszPackage, pPackedContext, Token, &myCtxt);
857             if (ret == SEC_E_OK)
858             {
859                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
860                 if (ret != SEC_E_OK)
861                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
862             }
863         }
864         else
865             ret = SEC_E_UNSUPPORTED_FUNCTION;
866     }
867     else
868         ret = SEC_E_SECPKG_NOT_FOUND;
869     return ret;
870
871 }
872
873 /***********************************************************************
874  *              ImportSecurityContextW (SECUR32.@)
875  */
876 SECURITY_STATUS WINAPI ImportSecurityContextW(SEC_WCHAR *pszPackage,
877  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
878 {
879     SECURITY_STATUS ret;
880     SecurePackage *package = SECUR32_findPackageW(pszPackage);
881
882     TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token,
883      phContext);
884     if (package && package->provider)
885     {
886         if (package->provider->fnTableW.ImportSecurityContextW)
887         {
888             CtxtHandle myCtxt;
889
890             ret = package->provider->fnTableW.ImportSecurityContextW(
891              pszPackage, pPackedContext, Token, &myCtxt);
892             if (ret == SEC_E_OK)
893             {
894                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
895                 if (ret != SEC_E_OK)
896                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
897             }
898         }
899         else
900             ret = SEC_E_UNSUPPORTED_FUNCTION;
901     }
902     else
903         ret = SEC_E_SECPKG_NOT_FOUND;
904     return ret;
905 }
906
907 /***********************************************************************
908  *              AddCredentialsA (SECUR32.@)
909  */
910 SECURITY_STATUS WINAPI AddCredentialsA(PCredHandle hCredentials,
911  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
912  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
913  PTimeStamp ptsExpiry)
914 {
915     SECURITY_STATUS ret;
916
917     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal),
918      debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
919      pvGetKeyArgument, ptsExpiry);
920     if (hCredentials)
921     {
922         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
923         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
924
925         if (package && package->provider)
926         {
927             if (package->provider->fnTableA.AddCredentialsA)
928                 ret = package->provider->fnTableA.AddCredentialsA(
929                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
930                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
931             else
932                 ret = SEC_E_UNSUPPORTED_FUNCTION;
933         }
934         else
935             ret = SEC_E_INVALID_HANDLE;
936     }
937     else
938         ret = SEC_E_INVALID_HANDLE;
939     return ret;
940 }
941
942 /***********************************************************************
943  *              AddCredentialsW (SECUR32.@)
944  */
945 SECURITY_STATUS WINAPI AddCredentialsW(PCredHandle hCredentials,
946  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
947  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
948  PTimeStamp ptsExpiry)
949 {
950     SECURITY_STATUS ret;
951
952     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal),
953      debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
954      pvGetKeyArgument, ptsExpiry);
955     if (hCredentials)
956     {
957         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
958         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
959
960         if (package && package->provider)
961         {
962             if (package->provider->fnTableW.AddCredentialsW)
963                 ret = package->provider->fnTableW.AddCredentialsW(
964                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
965                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
966             else
967                 ret = SEC_E_UNSUPPORTED_FUNCTION;
968         }
969         else
970             ret = SEC_E_INVALID_HANDLE;
971     }
972     else
973         ret = SEC_E_INVALID_HANDLE;
974     return ret;
975 }
976
977 /***********************************************************************
978  *              QuerySecurityContextToken (SECUR32.@)
979  */
980 SECURITY_STATUS WINAPI QuerySecurityContextToken(PCtxtHandle phContext,
981  HANDLE *phToken)
982 {
983     SECURITY_STATUS ret;
984
985     TRACE("%p %p\n", phContext, phToken);
986     if (phContext)
987     {
988         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
989         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
990
991         if (package && package->provider)
992         {
993             if (package->provider->fnTableW.QuerySecurityContextToken)
994                 ret = package->provider->fnTableW.QuerySecurityContextToken(
995                  ctxt, phToken);
996             else
997                 ret = SEC_E_UNSUPPORTED_FUNCTION;
998         }
999         else
1000             ret = SEC_E_INVALID_HANDLE;
1001     }
1002     else
1003         ret = SEC_E_INVALID_HANDLE;
1004     return ret;
1005 }
1006
1007 /***********************************************************************
1008  *              EncryptMessage (SECUR32.@)
1009  */
1010 SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
1011  PSecBufferDesc pMessage, ULONG MessageSeqNo)
1012 {
1013     SECURITY_STATUS ret;
1014
1015     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
1016     if (phContext)
1017     {
1018         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1019         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1020
1021         if (package && package->provider)
1022         {
1023             if (package->provider->fnTableW.EncryptMessage)
1024                 ret = package->provider->fnTableW.EncryptMessage(
1025                  ctxt, fQOP, pMessage, MessageSeqNo);
1026             else
1027                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1028         }
1029         else
1030             ret = SEC_E_INVALID_HANDLE;
1031     }
1032     else
1033         ret = SEC_E_INVALID_HANDLE;
1034     return ret;
1035 }
1036
1037 /***********************************************************************
1038  *              DecryptMessage (SECUR32.@)
1039  */
1040 SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext,
1041  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
1042 {
1043     SECURITY_STATUS ret;
1044
1045     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
1046     if (phContext)
1047     {
1048         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1049         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1050
1051         if (package && package->provider)
1052         {
1053             if (package->provider->fnTableW.DecryptMessage)
1054                 ret = package->provider->fnTableW.DecryptMessage(
1055                  ctxt, pMessage, MessageSeqNo, pfQOP);
1056             else
1057                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1058         }
1059         else
1060             ret = SEC_E_INVALID_HANDLE;
1061     }
1062     else
1063         ret = SEC_E_INVALID_HANDLE;
1064     return ret;
1065 }
1066
1067 /***********************************************************************
1068  *              SetContextAttributesA (SECUR32.@)
1069  */
1070 SECURITY_STATUS WINAPI SetContextAttributesA(PCtxtHandle phContext,
1071  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
1072 {
1073     SECURITY_STATUS ret;
1074
1075     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
1076     if (phContext)
1077     {
1078         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1079         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1080
1081         if (package && package->provider)
1082         {
1083             if (package->provider->fnTableA.SetContextAttributesA)
1084                 ret = package->provider->fnTableA.SetContextAttributesA(
1085                  ctxt, ulAttribute, pBuffer, cbBuffer);
1086             else
1087                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1088         }
1089         else
1090             ret = SEC_E_INVALID_HANDLE;
1091     }
1092     else
1093         ret = SEC_E_INVALID_HANDLE;
1094     return ret;
1095 }
1096
1097 /***********************************************************************
1098  *              SetContextAttributesW (SECUR32.@)
1099  */
1100 SECURITY_STATUS WINAPI SetContextAttributesW(PCtxtHandle phContext,
1101  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
1102 {
1103     SECURITY_STATUS ret;
1104
1105     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
1106     if (phContext)
1107     {
1108         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1109         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1110
1111         if (package && package->provider)
1112         {
1113             if (package->provider->fnTableW.SetContextAttributesW)
1114                 ret = package->provider->fnTableW.SetContextAttributesW(
1115                  ctxt, ulAttribute, pBuffer, cbBuffer);
1116             else
1117                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1118         }
1119         else
1120             ret = SEC_E_INVALID_HANDLE;
1121     }
1122     else
1123         ret = SEC_E_INVALID_HANDLE;
1124     return ret;
1125 }