shell32: Add support of KF_REDIRECT_DEL_SOURCE_CONTENTS flag to redirection.
[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 0x%08x %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) &&
287                 phNewContext && phNewContext != phContext)
288             {
289                 SECURITY_STATUS ret2;
290                 ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
291                 if (ret2 != SEC_E_OK)
292                     package->provider->fnTableA.DeleteSecurityContext(&myCtxt);
293             }
294         }
295         else
296             ret = SEC_E_UNSUPPORTED_FUNCTION;
297     }
298     else
299         ret = SEC_E_INVALID_HANDLE;
300     return ret;
301 }
302
303 /***********************************************************************
304  *              InitializeSecurityContextW (SECUR32.@)
305  */
306 SECURITY_STATUS WINAPI InitializeSecurityContextW(
307  PCredHandle phCredential, PCtxtHandle phContext,
308  SEC_WCHAR *pszTargetName, ULONG fContextReq,
309  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
310  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
311  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
312 {
313     SECURITY_STATUS ret;
314     SecurePackage *package = NULL;
315     PCredHandle cred = NULL;
316     PCredHandle ctxt = NULL;
317
318     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
319      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
320      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
321
322     if (phContext)
323     {
324         package = (SecurePackage *)phContext->dwUpper;
325         ctxt = (PCtxtHandle)phContext->dwLower;
326     }
327     if (phCredential)
328     {
329         package = (SecurePackage *)phCredential->dwUpper;
330         cred = (PCredHandle)phCredential->dwLower;
331     }
332
333     if (package && package->provider)
334     {
335         if (package->provider->fnTableW.InitializeSecurityContextW)
336         {
337             CtxtHandle myCtxt;
338
339             if (phContext)
340             {
341                 PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
342                 myCtxt.dwUpper = realCtxt->dwUpper;
343                 myCtxt.dwLower = realCtxt->dwLower;
344             }
345
346             ret = package->provider->fnTableW.InitializeSecurityContextW(
347                  cred, ctxt, pszTargetName, fContextReq,
348                  Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL,
349                  pOutput, pfContextAttr, ptsExpiry);
350             if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) &&
351                 phNewContext && phNewContext != phContext)
352             {
353                 SECURITY_STATUS ret2;
354                 ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
355                 if (ret2 != SEC_E_OK)
356                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
357             }
358         }
359         else
360             ret = SEC_E_UNSUPPORTED_FUNCTION;
361     }
362     else
363         ret = SEC_E_INVALID_HANDLE;
364     return ret;
365 }
366
367 /***********************************************************************
368  *              AcceptSecurityContext (SECUR32.@)
369  */
370 SECURITY_STATUS WINAPI AcceptSecurityContext(
371  PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
372  ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
373  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
374 {
375     SECURITY_STATUS ret;
376
377     TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput,
378      fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
379      ptsExpiry);
380     if (phCredential)
381     {
382         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
383         PCredHandle cred = (PCredHandle)phCredential->dwLower;
384
385         if (package && package->provider)
386         {
387             if (package->provider->fnTableW.AcceptSecurityContext)
388             {
389                 CtxtHandle myCtxt;
390
391                 if(phContext)
392                 {
393                     PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
394                     TRACE("realCtx: %p\n", realCtxt);
395                     myCtxt.dwUpper = realCtxt->dwUpper;
396                     myCtxt.dwLower = realCtxt->dwLower;
397                 }
398                 
399                 ret = package->provider->fnTableW.AcceptSecurityContext(
400                  cred, phContext ? &myCtxt : NULL, pInput, fContextReq,
401                  TargetDataRep, &myCtxt, pOutput, pfContextAttr, ptsExpiry);
402                 if (ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED)
403                 {
404                     SECURITY_STATUS ret2;
405                     ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
406                     if (ret2 != SEC_E_OK)
407                         package->provider->fnTableW.DeleteSecurityContext(
408                          &myCtxt);
409                 }
410             }
411             else
412                 ret = SEC_E_UNSUPPORTED_FUNCTION;
413         }
414         else
415             ret = SEC_E_INVALID_HANDLE;
416     }
417     else
418         ret = SEC_E_INVALID_HANDLE;
419     return ret;
420 }
421
422 /***********************************************************************
423  *              CompleteAuthToken (SECUR32.@)
424  */
425 SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext,
426  PSecBufferDesc pToken)
427 {
428     SECURITY_STATUS ret;
429
430     TRACE("%p %p\n", phContext, pToken);
431     if (phContext)
432     {
433         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
434         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
435
436         if (package && package->provider)
437         {
438             if (package->provider->fnTableW.CompleteAuthToken)
439                 ret = package->provider->fnTableW.CompleteAuthToken(ctxt,
440                  pToken);
441             else
442                 ret = SEC_E_UNSUPPORTED_FUNCTION;
443         }
444         else
445             ret = SEC_E_INVALID_HANDLE;
446     }
447     else
448         ret = SEC_E_INVALID_HANDLE;
449     return ret;
450 }
451
452 /***********************************************************************
453  *              DeleteSecurityContext (SECUR32.@)
454  */
455 SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
456 {
457     SECURITY_STATUS ret;
458
459     TRACE("%p\n", phContext);
460     if (phContext)
461     {
462         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
463         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
464
465         if (package && package->provider &&
466          package->provider->fnTableW.DeleteSecurityContext)
467             ret = package->provider->fnTableW.DeleteSecurityContext(ctxt);
468         else
469             ret = SEC_E_INVALID_HANDLE;
470         HeapFree(GetProcessHeap(), 0, ctxt);
471     }
472     else
473         ret = SEC_E_INVALID_HANDLE;
474     return ret;
475 }
476
477 /***********************************************************************
478  *              ApplyControlToken (SECUR32.@)
479  */
480 SECURITY_STATUS WINAPI ApplyControlToken(PCtxtHandle phContext,
481  PSecBufferDesc pInput)
482 {
483     SECURITY_STATUS ret;
484
485     TRACE("%p %p\n", phContext, pInput);
486     if (phContext)
487     {
488         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
489         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
490
491         if (package && package->provider)
492         {
493             if (package->provider->fnTableW.ApplyControlToken)
494                 ret = package->provider->fnTableW.ApplyControlToken(
495                  ctxt, pInput);
496             else
497                 ret = SEC_E_UNSUPPORTED_FUNCTION;
498         }
499         else
500             ret = SEC_E_INVALID_HANDLE;
501     }
502     else
503         ret = SEC_E_INVALID_HANDLE;
504     return ret;
505 }
506
507 /***********************************************************************
508  *              QueryContextAttributesA (SECUR32.@)
509  */
510 SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext,
511  ULONG ulAttribute, void *pBuffer)
512 {
513     SECURITY_STATUS ret;
514
515     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
516     if (phContext)
517     {
518         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
519         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
520
521         if (package && package->provider)
522         {
523             if (package->provider->fnTableA.QueryContextAttributesA)
524                 ret = package->provider->fnTableA.QueryContextAttributesA(
525                  ctxt, ulAttribute, pBuffer);
526             else
527                 ret = SEC_E_UNSUPPORTED_FUNCTION;
528         }
529         else
530             ret = SEC_E_INVALID_HANDLE;
531     }
532     else
533         ret = SEC_E_INVALID_HANDLE;
534     return ret;
535 }
536
537 /***********************************************************************
538  *              QueryContextAttributesW (SECUR32.@)
539  */
540 SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext,
541  ULONG ulAttribute, void *pBuffer)
542 {
543     SECURITY_STATUS ret;
544
545     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
546     if (phContext)
547     {
548         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
549         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
550
551         if (package && package->provider)
552         {
553             if (package->provider->fnTableW.QueryContextAttributesW)
554                 ret = package->provider->fnTableW.QueryContextAttributesW(
555                  ctxt, ulAttribute, pBuffer);
556             else
557                 ret = SEC_E_UNSUPPORTED_FUNCTION;
558         }
559         else
560             ret = SEC_E_INVALID_HANDLE;
561     }
562     else
563         ret = SEC_E_INVALID_HANDLE;
564     return ret;
565 }
566
567 /***********************************************************************
568  *              ImpersonateSecurityContext (SECUR32.@)
569  */
570 SECURITY_STATUS WINAPI ImpersonateSecurityContext(PCtxtHandle phContext)
571 {
572     SECURITY_STATUS ret;
573
574     TRACE("%p\n", phContext);
575     if (phContext)
576     {
577         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
578         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
579
580         if (package && package->provider)
581         {
582             if (package->provider->fnTableW.ImpersonateSecurityContext)
583                 ret = package->provider->fnTableW.ImpersonateSecurityContext(
584                  ctxt);
585             else
586                 ret = SEC_E_UNSUPPORTED_FUNCTION;
587         }
588         else
589             ret = SEC_E_INVALID_HANDLE;
590     }
591     else
592         ret = SEC_E_INVALID_HANDLE;
593     return ret;
594 }
595
596 /***********************************************************************
597  *              RevertSecurityContext (SECUR32.@)
598  */
599 SECURITY_STATUS WINAPI RevertSecurityContext(PCtxtHandle phContext)
600 {
601     SECURITY_STATUS ret;
602
603     TRACE("%p\n", phContext);
604     if (phContext)
605     {
606         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
607         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
608
609         if (package && package->provider)
610         {
611             if (package->provider->fnTableW.RevertSecurityContext)
612                 ret = package->provider->fnTableW.RevertSecurityContext(
613                  ctxt);
614             else
615                 ret = SEC_E_UNSUPPORTED_FUNCTION;
616         }
617         else
618             ret = SEC_E_INVALID_HANDLE;
619     }
620     else
621         ret = SEC_E_INVALID_HANDLE;
622     return ret;
623 }
624
625 /***********************************************************************
626  *              MakeSignature (SECUR32.@)
627  */
628 SECURITY_STATUS WINAPI MakeSignature(PCtxtHandle phContext, ULONG fQOP,
629  PSecBufferDesc pMessage, ULONG MessageSeqNo)
630 {
631     SECURITY_STATUS ret;
632
633     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
634     if (phContext)
635     {
636         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
637         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
638
639         if (package && package->provider)
640         {
641             if (package->provider->fnTableW.MakeSignature)
642                 ret = package->provider->fnTableW.MakeSignature(
643                  ctxt, fQOP, pMessage, MessageSeqNo);
644             else
645                 ret = SEC_E_UNSUPPORTED_FUNCTION;
646         }
647         else
648             ret = SEC_E_INVALID_HANDLE;
649     }
650     else
651         ret = SEC_E_INVALID_HANDLE;
652     return ret;
653 }
654
655 /***********************************************************************
656  *              VerifySignature (SECUR32.@)
657  */
658 SECURITY_STATUS WINAPI VerifySignature(PCtxtHandle phContext,
659  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
660 {
661     SECURITY_STATUS ret;
662
663     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
664     if (phContext)
665     {
666         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
667         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
668
669         if (package && package->provider)
670         {
671             if (package->provider->fnTableW.VerifySignature)
672                 ret = package->provider->fnTableW.VerifySignature(
673                  ctxt, pMessage, MessageSeqNo, pfQOP);
674             else
675                 ret = SEC_E_UNSUPPORTED_FUNCTION;
676         }
677         else
678             ret = SEC_E_INVALID_HANDLE;
679     }
680     else
681         ret = SEC_E_INVALID_HANDLE;
682     return ret;
683 }
684
685 /***********************************************************************
686  *              QuerySecurityPackageInfoA (SECUR32.@)
687  */
688 SECURITY_STATUS WINAPI QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName,
689  PSecPkgInfoA *ppPackageInfo)
690 {
691     SECURITY_STATUS ret;
692    
693     TRACE("%s %p\n", debugstr_a(pszPackageName), ppPackageInfo);
694     if (pszPackageName)
695     {
696         SecurePackage *package = SECUR32_findPackageA(pszPackageName);
697
698         if (package)
699         {
700             size_t bytesNeeded = sizeof(SecPkgInfoA);
701             int nameLen = 0, commentLen = 0;
702
703             if (package->infoW.Name)
704             {
705                 nameLen = WideCharToMultiByte(CP_ACP, 0,
706                  package->infoW.Name, -1, NULL, 0, NULL, NULL);
707                 bytesNeeded += nameLen;
708             }
709             if (package->infoW.Comment)
710             {
711                 commentLen = WideCharToMultiByte(CP_ACP, 0,
712                  package->infoW.Comment, -1, NULL, 0, NULL, NULL);
713                 bytesNeeded += commentLen;
714             }
715             *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
716             if (*ppPackageInfo)
717             {
718                 PSTR nextString = (PSTR)((PBYTE)*ppPackageInfo +
719                  sizeof(SecPkgInfoA));
720
721                 memcpy(*ppPackageInfo, &package->infoW, sizeof(package->infoW));
722                 if (package->infoW.Name)
723                 {
724                     (*ppPackageInfo)->Name = nextString;
725                     nextString += WideCharToMultiByte(CP_ACP, 0,
726                      package->infoW.Name, -1, nextString, nameLen, NULL, NULL);
727                 }
728                 else
729                     (*ppPackageInfo)->Name = NULL;
730                 if (package->infoW.Comment)
731                 {
732                     (*ppPackageInfo)->Comment = nextString;
733                     nextString += WideCharToMultiByte(CP_ACP, 0,
734                      package->infoW.Comment, -1, nextString, commentLen, NULL,
735                      NULL);
736                 }
737                 else
738                     (*ppPackageInfo)->Comment = NULL;
739                 ret = SEC_E_OK;
740             }
741             else
742                 ret = SEC_E_INSUFFICIENT_MEMORY;
743         }
744         else
745             ret = SEC_E_SECPKG_NOT_FOUND;
746     }
747     else
748         ret = SEC_E_SECPKG_NOT_FOUND;
749     return ret;
750 }
751
752 /***********************************************************************
753  *              QuerySecurityPackageInfoW (SECUR32.@)
754  */
755 SECURITY_STATUS WINAPI QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName,
756  PSecPkgInfoW *ppPackageInfo)
757 {
758     SECURITY_STATUS ret;
759     SecurePackage *package = SECUR32_findPackageW(pszPackageName);
760
761     TRACE("%s %p\n", debugstr_w(pszPackageName), ppPackageInfo);
762     if (package)
763     {
764         size_t bytesNeeded = sizeof(SecPkgInfoW);
765         int nameLen = 0, commentLen = 0;
766
767         if (package->infoW.Name)
768         {
769             nameLen = lstrlenW(package->infoW.Name) + 1;
770             bytesNeeded += nameLen * sizeof(WCHAR);
771         }
772         if (package->infoW.Comment)
773         {
774             commentLen = lstrlenW(package->infoW.Comment) + 1;
775             bytesNeeded += commentLen * sizeof(WCHAR);
776         }
777         *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
778         if (*ppPackageInfo)
779         {
780             PWSTR nextString = (PWSTR)((PBYTE)*ppPackageInfo +
781              sizeof(SecPkgInfoW));
782
783             **ppPackageInfo = package->infoW;
784             if (package->infoW.Name)
785             {
786                 (*ppPackageInfo)->Name = nextString;
787                 lstrcpynW(nextString, package->infoW.Name, nameLen);
788                 nextString += nameLen;
789             }
790             else
791                 (*ppPackageInfo)->Name = NULL;
792             if (package->infoW.Comment)
793             {
794                 (*ppPackageInfo)->Comment = nextString;
795                 lstrcpynW(nextString, package->infoW.Comment, commentLen);
796                 nextString += commentLen;
797             }
798             else
799                 (*ppPackageInfo)->Comment = NULL;
800             ret = SEC_E_OK;
801         }
802         else
803             ret = SEC_E_INSUFFICIENT_MEMORY;
804     }
805     else
806         ret = SEC_E_SECPKG_NOT_FOUND;
807     return ret;
808 }
809
810 /***********************************************************************
811  *              ExportSecurityContext (SECUR32.@)
812  */
813 SECURITY_STATUS WINAPI ExportSecurityContext(PCtxtHandle phContext,
814  ULONG fFlags, PSecBuffer pPackedContext, void **pToken)
815 {
816     SECURITY_STATUS ret;
817
818     TRACE("%p %d %p %p\n", phContext, fFlags, pPackedContext, pToken);
819     if (phContext)
820     {
821         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
822         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
823
824         if (package && package->provider)
825         {
826             if (package->provider->fnTableW.ExportSecurityContext)
827                 ret = package->provider->fnTableW.ExportSecurityContext(
828                  ctxt, fFlags, pPackedContext, pToken);
829             else
830                 ret = SEC_E_UNSUPPORTED_FUNCTION;
831         }
832         else
833             ret = SEC_E_INVALID_HANDLE;
834     }
835     else
836         ret = SEC_E_INVALID_HANDLE;
837     return ret;
838 }
839
840 /***********************************************************************
841  *              ImportSecurityContextA (SECUR32.@)
842  */
843 SECURITY_STATUS WINAPI ImportSecurityContextA(SEC_CHAR *pszPackage,
844  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
845 {
846     SECURITY_STATUS ret;
847     SecurePackage *package = SECUR32_findPackageA(pszPackage);
848  
849     TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token,
850      phContext);
851     if (package && package->provider)
852     {
853         if (package->provider->fnTableA.ImportSecurityContextA)
854         {
855             CtxtHandle myCtxt;
856
857             ret = package->provider->fnTableA.ImportSecurityContextA(
858              pszPackage, pPackedContext, Token, &myCtxt);
859             if (ret == SEC_E_OK)
860             {
861                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
862                 if (ret != SEC_E_OK)
863                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
864             }
865         }
866         else
867             ret = SEC_E_UNSUPPORTED_FUNCTION;
868     }
869     else
870         ret = SEC_E_SECPKG_NOT_FOUND;
871     return ret;
872
873 }
874
875 /***********************************************************************
876  *              ImportSecurityContextW (SECUR32.@)
877  */
878 SECURITY_STATUS WINAPI ImportSecurityContextW(SEC_WCHAR *pszPackage,
879  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
880 {
881     SECURITY_STATUS ret;
882     SecurePackage *package = SECUR32_findPackageW(pszPackage);
883
884     TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token,
885      phContext);
886     if (package && package->provider)
887     {
888         if (package->provider->fnTableW.ImportSecurityContextW)
889         {
890             CtxtHandle myCtxt;
891
892             ret = package->provider->fnTableW.ImportSecurityContextW(
893              pszPackage, pPackedContext, Token, &myCtxt);
894             if (ret == SEC_E_OK)
895             {
896                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
897                 if (ret != SEC_E_OK)
898                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
899             }
900         }
901         else
902             ret = SEC_E_UNSUPPORTED_FUNCTION;
903     }
904     else
905         ret = SEC_E_SECPKG_NOT_FOUND;
906     return ret;
907 }
908
909 /***********************************************************************
910  *              AddCredentialsA (SECUR32.@)
911  */
912 SECURITY_STATUS WINAPI AddCredentialsA(PCredHandle hCredentials,
913  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
914  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
915  PTimeStamp ptsExpiry)
916 {
917     SECURITY_STATUS ret;
918
919     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal),
920      debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
921      pvGetKeyArgument, ptsExpiry);
922     if (hCredentials)
923     {
924         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
925         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
926
927         if (package && package->provider)
928         {
929             if (package->provider->fnTableA.AddCredentialsA)
930                 ret = package->provider->fnTableA.AddCredentialsA(
931                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
932                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
933             else
934                 ret = SEC_E_UNSUPPORTED_FUNCTION;
935         }
936         else
937             ret = SEC_E_INVALID_HANDLE;
938     }
939     else
940         ret = SEC_E_INVALID_HANDLE;
941     return ret;
942 }
943
944 /***********************************************************************
945  *              AddCredentialsW (SECUR32.@)
946  */
947 SECURITY_STATUS WINAPI AddCredentialsW(PCredHandle hCredentials,
948  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
949  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
950  PTimeStamp ptsExpiry)
951 {
952     SECURITY_STATUS ret;
953
954     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal),
955      debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
956      pvGetKeyArgument, ptsExpiry);
957     if (hCredentials)
958     {
959         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
960         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
961
962         if (package && package->provider)
963         {
964             if (package->provider->fnTableW.AddCredentialsW)
965                 ret = package->provider->fnTableW.AddCredentialsW(
966                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
967                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
968             else
969                 ret = SEC_E_UNSUPPORTED_FUNCTION;
970         }
971         else
972             ret = SEC_E_INVALID_HANDLE;
973     }
974     else
975         ret = SEC_E_INVALID_HANDLE;
976     return ret;
977 }
978
979 /***********************************************************************
980  *              QuerySecurityContextToken (SECUR32.@)
981  */
982 SECURITY_STATUS WINAPI QuerySecurityContextToken(PCtxtHandle phContext,
983  HANDLE *phToken)
984 {
985     SECURITY_STATUS ret;
986
987     TRACE("%p %p\n", phContext, phToken);
988     if (phContext)
989     {
990         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
991         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
992
993         if (package && package->provider)
994         {
995             if (package->provider->fnTableW.QuerySecurityContextToken)
996                 ret = package->provider->fnTableW.QuerySecurityContextToken(
997                  ctxt, phToken);
998             else
999                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1000         }
1001         else
1002             ret = SEC_E_INVALID_HANDLE;
1003     }
1004     else
1005         ret = SEC_E_INVALID_HANDLE;
1006     return ret;
1007 }
1008
1009 /***********************************************************************
1010  *              EncryptMessage (SECUR32.@)
1011  */
1012 SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
1013  PSecBufferDesc pMessage, ULONG MessageSeqNo)
1014 {
1015     SECURITY_STATUS ret;
1016
1017     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
1018     if (phContext)
1019     {
1020         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1021         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1022
1023         if (package && package->provider)
1024         {
1025             if (package->provider->fnTableW.EncryptMessage)
1026                 ret = package->provider->fnTableW.EncryptMessage(
1027                  ctxt, fQOP, pMessage, MessageSeqNo);
1028             else
1029                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1030         }
1031         else
1032             ret = SEC_E_INVALID_HANDLE;
1033     }
1034     else
1035         ret = SEC_E_INVALID_HANDLE;
1036     return ret;
1037 }
1038
1039 /***********************************************************************
1040  *              DecryptMessage (SECUR32.@)
1041  */
1042 SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext,
1043  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
1044 {
1045     SECURITY_STATUS ret;
1046
1047     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
1048     if (phContext)
1049     {
1050         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1051         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1052
1053         if (package && package->provider)
1054         {
1055             if (package->provider->fnTableW.DecryptMessage)
1056                 ret = package->provider->fnTableW.DecryptMessage(
1057                  ctxt, pMessage, MessageSeqNo, pfQOP);
1058             else
1059                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1060         }
1061         else
1062             ret = SEC_E_INVALID_HANDLE;
1063     }
1064     else
1065         ret = SEC_E_INVALID_HANDLE;
1066     return ret;
1067 }
1068
1069 /***********************************************************************
1070  *              SetContextAttributesA (SECUR32.@)
1071  */
1072 SECURITY_STATUS WINAPI SetContextAttributesA(PCtxtHandle phContext,
1073  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
1074 {
1075     SECURITY_STATUS ret;
1076
1077     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
1078     if (phContext)
1079     {
1080         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1081         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1082
1083         if (package && package->provider)
1084         {
1085             if (package->provider->fnTableA.SetContextAttributesA)
1086                 ret = package->provider->fnTableA.SetContextAttributesA(
1087                  ctxt, ulAttribute, pBuffer, cbBuffer);
1088             else
1089                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1090         }
1091         else
1092             ret = SEC_E_INVALID_HANDLE;
1093     }
1094     else
1095         ret = SEC_E_INVALID_HANDLE;
1096     return ret;
1097 }
1098
1099 /***********************************************************************
1100  *              SetContextAttributesW (SECUR32.@)
1101  */
1102 SECURITY_STATUS WINAPI SetContextAttributesW(PCtxtHandle phContext,
1103  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
1104 {
1105     SECURITY_STATUS ret;
1106
1107     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
1108     if (phContext)
1109     {
1110         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1111         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1112
1113         if (package && package->provider)
1114         {
1115             if (package->provider->fnTableW.SetContextAttributesW)
1116                 ret = package->provider->fnTableW.SetContextAttributesW(
1117                  ctxt, ulAttribute, pBuffer, cbBuffer);
1118             else
1119                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1120         }
1121         else
1122             ret = SEC_E_INVALID_HANDLE;
1123     }
1124     else
1125         ret = SEC_E_INVALID_HANDLE;
1126     return ret;
1127 }