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