comctl32: A couple fixes for tab icon offsets.
[wine] / dlls / secur32 / tests / main.c
1 /*
2  * Miscellaneous secur32 tests
3  *
4  * Copyright 2005 Kai Blin
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #define SECURITY_WIN32
22
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <windows.h>
26 #include "wine/test.h"
27 #include <winbase.h>
28 #include <sspi.h>
29
30 #define BUFF_SIZE 2048
31 #define MAX_MESSAGE 12000
32
33 static HMODULE secdll;
34 static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void);
35 static SECURITY_STATUS (SEC_ENTRY * pEnumerateSecurityPackagesA)(PULONG, PSecPkgInfoA*);
36 static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv);
37 static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*);
38 static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*,
39                             ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
40 static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle,
41                             SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG, 
42                             PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
43 static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc);
44 static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle,
45                             PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc,
46                             PULONG, PTimeStamp);
47 static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
48 static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
49
50 void InitFunctionPtrs(void)
51 {
52     secdll = LoadLibraryA("secur32.dll");
53     if(!secdll)
54         secdll = LoadLibraryA("security.dll");
55     if(secdll)
56     {
57         pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
58         pEnumerateSecurityPackagesA = (PVOID)GetProcAddress(secdll, "EnumerateSecurityPackagesA");
59         pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
60         pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
61         pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
62         pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
63         pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
64         pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
65         pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
66         pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
67     }
68 }
69
70 /*---------------------------------------------------------*/
71 /* General helper functions */
72
73 static const char* getSecError(SECURITY_STATUS status)
74 {
75 #define _SEC_ERR(x) case (x): return #x;
76     switch(status)
77     {
78         _SEC_ERR(SEC_E_OK);
79         _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
80         _SEC_ERR(SEC_E_INVALID_HANDLE);
81         _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
82         _SEC_ERR(SEC_E_TARGET_UNKNOWN);
83         _SEC_ERR(SEC_E_INTERNAL_ERROR);
84         _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
85         _SEC_ERR(SEC_E_NOT_OWNER);
86         _SEC_ERR(SEC_E_CANNOT_INSTALL);
87         _SEC_ERR(SEC_E_INVALID_TOKEN);
88         _SEC_ERR(SEC_E_CANNOT_PACK);
89         _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
90         _SEC_ERR(SEC_E_NO_IMPERSONATION);
91         _SEC_ERR(SEC_I_CONTINUE_NEEDED);
92         _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
93         _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
94         _SEC_ERR(SEC_E_LOGON_DENIED);
95         _SEC_ERR(SEC_E_NO_CREDENTIALS);
96         default:
97             trace("Error = %ld\n", status);
98             return "Unknown error";
99     }
100 #undef _SEC_ERR
101 }
102
103 /*---------------------------------------------------------*/
104 /* Helper for testQuerySecurityPagageInfo */
105
106 static SECURITY_STATUS setupPackageA(SEC_CHAR *p_package_name, 
107         PSecPkgInfo *p_pkg_info)
108 {
109     SECURITY_STATUS ret = SEC_E_SECPKG_NOT_FOUND;
110     
111     ret = pQuerySecurityPackageInfoA( p_package_name, p_pkg_info);
112     return ret;
113 }
114
115 /*---------------------------------------------------------*/
116 /* Helper for testAuth* */
117
118 SECURITY_STATUS setupClient(PCredHandle cred, const char *user, 
119         const char *pass, const char *domain, char *provider)
120 {
121     SECURITY_STATUS ret;
122     PSEC_WINNT_AUTH_IDENTITY identity = NULL;
123     TimeStamp ttl;
124
125     trace("Running setupClient\n");
126     
127     if(user != NULL)
128     {
129         identity = HeapAlloc(GetProcessHeap(), 0, 
130                 sizeof(SEC_WINNT_AUTH_IDENTITY_A));
131
132         memset( identity, 0, sizeof(identity));
133         identity->Domain = HeapAlloc(GetProcessHeap(), 0, 
134             lstrlenA( domain ? domain :"") + 1);
135         lstrcpyA((char*)identity->Domain, domain ? domain :"");
136         identity->DomainLength = domain ? lstrlenA(domain): 0;
137         identity->User = HeapAlloc(GetProcessHeap(), 0, 
138             lstrlenA( user ? user :"") + 1);
139         lstrcpyA((char*)identity->User, user ? user :"");
140         identity->UserLength = user ? lstrlenA(user) : 0;
141         identity->Password = HeapAlloc(GetProcessHeap(), 0, 
142             lstrlenA( pass ? pass :"") + 1);
143         lstrcpyA((char*)identity->Password, pass ? pass : "");
144         identity->PasswordLength = pass ? lstrlenA(pass): 0;
145         identity->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
146     }
147
148     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
149             NULL, identity, NULL, NULL, cred, &ttl)) != SEC_E_OK)
150     {
151         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
152     }
153     
154     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n", 
155             getSecError(ret));
156
157     if( identity != NULL)
158     {
159         if(identity->Domain != 0)
160             HeapFree(GetProcessHeap(), 0, identity->Domain);
161         if(identity->User != 0)
162             HeapFree(GetProcessHeap(), 0, identity->User);
163         if(identity->Password != 0)
164             HeapFree(GetProcessHeap(), 0, identity->Password);
165         HeapFree(GetProcessHeap(), 0, identity);
166     }       
167
168     return ret;
169 }
170
171 /**********************************************************************/
172
173 SECURITY_STATUS setupServer(PCredHandle cred, char *provider)
174 {
175     SECURITY_STATUS ret;
176     TimeStamp ttl;
177
178     trace("Running setupServer\n");
179     
180     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND, 
181                     NULL, NULL, NULL, NULL, cred, &ttl)) != SEC_E_OK)
182     {
183         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
184     }
185
186     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
187             getSecError(ret));
188
189     return ret;
190 }
191  
192 /**********************************************************************/
193
194 SECURITY_STATUS setupBuffers(PSecBufferDesc *new_in_buf, 
195         PSecBufferDesc *new_out_buf)
196 {
197     int size = MAX_MESSAGE;
198     PBYTE buffer = NULL;
199     PSecBufferDesc in_buf = HeapAlloc(GetProcessHeap(), 0, 
200             sizeof(SecBufferDesc));
201     PSecBufferDesc out_buf = HeapAlloc(GetProcessHeap(), 0,
202             sizeof(PSecBufferDesc));
203
204     if(in_buf != NULL)
205     {
206         PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
207                 sizeof(SecBuffer));
208         if(sec_buffer == NULL){
209             trace("in_buf: sec_buffer == NULL\n");
210             return SEC_E_INSUFFICIENT_MEMORY;
211         }
212         
213         buffer = HeapAlloc(GetProcessHeap(), 0, size);
214
215         if(buffer == NULL){
216             trace("in_buf: buffer == NULL\n");
217             return SEC_E_INSUFFICIENT_MEMORY;
218         }
219
220         in_buf->ulVersion = SECBUFFER_VERSION;
221         in_buf->cBuffers = 1;
222         in_buf->pBuffers = sec_buffer;
223
224         sec_buffer->cbBuffer = size;
225         sec_buffer->BufferType = SECBUFFER_TOKEN;
226         sec_buffer->pvBuffer = buffer;
227         *new_in_buf = in_buf;
228     }
229     else
230     {
231         trace("HeapAlloc in_buf returned NULL\n");
232         return SEC_E_INSUFFICIENT_MEMORY;
233     }
234     
235     if(out_buf != NULL)
236     {
237         PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
238                 sizeof(SecBuffer));
239         PBYTE buffer = NULL;
240         
241         if(sec_buffer == NULL){
242             trace("out_buf: sec_buffer == NULL\n");
243             return SEC_E_INSUFFICIENT_MEMORY;
244         }
245
246         buffer = HeapAlloc(GetProcessHeap(), 0, size);
247
248         if(buffer == NULL){
249             trace("out_buf: buffer == NULL\n");
250             return SEC_E_INSUFFICIENT_MEMORY;
251         }
252
253         out_buf->ulVersion = SECBUFFER_VERSION;
254         out_buf->cBuffers = 1;
255         out_buf->pBuffers = sec_buffer;
256
257         sec_buffer->cbBuffer = 0;
258         sec_buffer->BufferType = SECBUFFER_TOKEN;
259         sec_buffer->pvBuffer = buffer;
260         *new_out_buf = out_buf;
261     }
262     else
263     {
264         trace("HeapAlloc out_buf returned NULL\n");
265         return SEC_E_INSUFFICIENT_MEMORY;
266     }
267
268     return SEC_E_OK;
269 }
270
271 /**********************************************************************/
272
273 void cleanupBuffers(PSecBufferDesc in_buf, PSecBufferDesc out_buf)
274 {
275     int i;
276
277     if(in_buf != NULL)
278     {
279         for(i = 0; i < in_buf->cBuffers; ++i)
280         {
281             HeapFree(GetProcessHeap(), 0, in_buf->pBuffers[i].pvBuffer);
282         }
283         HeapFree(GetProcessHeap(), 0, in_buf->pBuffers);
284         HeapFree(GetProcessHeap(), 0, in_buf);
285     }
286     
287     if(out_buf != NULL)
288     {
289         for(i = 0; i < out_buf->cBuffers; ++i)
290         {
291             HeapFree(GetProcessHeap(), 0, out_buf->pBuffers[i].pvBuffer);
292         }
293         HeapFree(GetProcessHeap(), 0, out_buf->pBuffers);
294         HeapFree(GetProcessHeap(), 0, out_buf);
295     }
296 }
297
298 /**********************************************************************/
299
300 SECURITY_STATUS runClient(PCredHandle cred, PCtxtHandle ctxt, 
301         PSecBufferDesc in_buf, PSecBufferDesc out_buf, BOOL first)
302 {
303     SECURITY_STATUS ret;
304     ULONG req_attr = ISC_REQ_CONNECTION;
305     ULONG ctxt_attr;
306     TimeStamp ttl;
307
308     trace("Running the client the %s time.\n", first?"first":"second");
309
310     ret = pInitializeSecurityContextA(cred, first?NULL:ctxt, NULL, req_attr, 
311             0, SECURITY_NATIVE_DREP, first?NULL:in_buf, 0, ctxt, out_buf,
312             &ctxt_attr, &ttl);
313     
314     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
315     {
316         pCompleteAuthToken(ctxt, out_buf);
317         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
318             ret = SEC_I_CONTINUE_NEEDED;
319         else if(ret == SEC_I_COMPLETE_NEEDED)
320             ret = SEC_E_OK;
321     }       
322     
323     return ret;
324 }
325
326 /**********************************************************************/
327
328 SECURITY_STATUS runServer(PCredHandle cred, PCtxtHandle ctxt,
329         PSecBufferDesc in_buf, PSecBufferDesc out_buf, BOOL first)
330 {
331     SECURITY_STATUS ret;
332     ULONG ctxt_attr;
333     TimeStamp ttl;
334
335     trace("Running the server the %s time\n", first?"first":"second");
336
337     ret = pAcceptSecurityContext(cred, first?NULL:ctxt, in_buf, 0,
338             SECURITY_NATIVE_DREP, ctxt, out_buf, &ctxt_attr, &ttl);
339
340     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
341     {
342         pCompleteAuthToken(ctxt, out_buf);
343         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
344             ret = SEC_I_CONTINUE_NEEDED;
345         else if(ret == SEC_I_COMPLETE_NEEDED)
346             ret = SEC_E_OK;
347     }
348     
349
350     return ret;
351 }
352
353 /**********************************************************************/
354
355 void communicate(PSecBufferDesc in_buf, PSecBufferDesc out_buf)
356 {
357     if(in_buf != NULL && out_buf != NULL)
358     {
359         trace("Running communicate.\n");
360         if((in_buf->cBuffers >= 1) && (out_buf->cBuffers >= 1))
361         {
362             if((in_buf->pBuffers[0].pvBuffer != NULL) && 
363                     (out_buf->pBuffers[0].pvBuffer != NULL))
364             {
365                 memset(out_buf->pBuffers[0].pvBuffer, 0, MAX_MESSAGE);
366                 
367                 memcpy(out_buf->pBuffers[0].pvBuffer, 
368                         in_buf->pBuffers[0].pvBuffer,
369                         in_buf->pBuffers[0].cbBuffer);
370                 
371                 out_buf->pBuffers[0].cbBuffer = in_buf->pBuffers[0].cbBuffer;
372                 
373                 memset(in_buf->pBuffers[0].pvBuffer, 0, MAX_MESSAGE);
374             }
375         }
376     }
377 }
378    
379 /**********************************************************************/
380
381 /*--------------------------------------------------------- */
382 /* The test functions */
383
384 static void testInitSecurityInterface(void)
385 {
386     PSecurityFunctionTable sec_fun_table = NULL;
387
388     sec_fun_table = pInitSecurityInterfaceA();
389     ok(sec_fun_table != NULL, "InitSecurityInterface() returned NULL.\n");
390
391 }
392
393 static void testEnumerateSecurityPackages(void)
394 {
395
396     SECURITY_STATUS sec_status;
397     ULONG           num_packages, i;
398     PSecPkgInfo     pkg_info = NULL;
399
400     trace("Running testEnumerateSecurityPackages\n");
401     
402     sec_status = pEnumerateSecurityPackagesA(&num_packages, &pkg_info);
403
404     ok(sec_status == SEC_E_OK, 
405             "EnumerateSecurityPackages() should return %ld, not %08lx\n",
406             (LONG)SEC_E_OK, (LONG)sec_status);
407
408     ok(num_packages > 0, "Number of sec packages should be > 0 ,but is %ld\n",
409             num_packages);
410
411     ok(pkg_info != NULL, 
412             "pkg_info should not be NULL after EnumerateSecurityPackages\n");
413     
414     trace("Number of packages: %ld\n", num_packages);
415     for(i = 0; i < num_packages; ++i){
416         trace("%ld: Package \"%s\"\n", i, pkg_info[i].Name);
417         trace("Supported flags:\n");
418         if(pkg_info[i].fCapabilities & SECPKG_FLAG_INTEGRITY)
419             trace("\tSECPKG_FLAG_INTEGRITY\n");
420         if(pkg_info[i].fCapabilities & SECPKG_FLAG_PRIVACY)
421             trace("\tSECPKG_FLAG_PRIVACY\n");
422         if(pkg_info[i].fCapabilities & SECPKG_FLAG_TOKEN_ONLY)
423             trace("\tSECPKG_FLAG_TOKEN_ONLY\n");
424         if(pkg_info[i].fCapabilities & SECPKG_FLAG_DATAGRAM)
425             trace("\tSECPKG_FLAG_DATAGRAM\n");
426         if(pkg_info[i].fCapabilities & SECPKG_FLAG_CONNECTION)
427             trace("\tSECPKG_FLAG_CONNECTION\n");
428         if(pkg_info[i].fCapabilities & SECPKG_FLAG_MULTI_REQUIRED)
429             trace("\tSECPKG_FLAG_MULTI_REQUIRED\n");
430         if(pkg_info[i].fCapabilities & SECPKG_FLAG_CLIENT_ONLY)
431             trace("\tSECPKG_FLAG_CLIENT_ONLY\n");
432         if(pkg_info[i].fCapabilities & SECPKG_FLAG_EXTENDED_ERROR)
433             trace("\tSECPKG_FLAG_EXTENDED_ERROR\n");
434         if(pkg_info[i].fCapabilities & SECPKG_FLAG_IMPERSONATION)
435             trace("\tSECPKG_FLAG_IMPERSONATION\n");
436         if(pkg_info[i].fCapabilities & SECPKG_FLAG_ACCEPT_WIN32_NAME)
437             trace("\tSECPKG_FLAG_ACCEPT_WIN32_NAME\n");
438         if(pkg_info[i].fCapabilities & SECPKG_FLAG_STREAM)
439             trace("\tSECPKG_FLAG_STREAM\n");
440         if(pkg_info[i].fCapabilities & SECPKG_FLAG_READONLY_WITH_CHECKSUM)
441             trace("\tSECPKG_FLAG_READONLY_WITH_CHECKSUM\n");
442         trace("Comment: %s\n", pkg_info[i].Comment);
443         trace("\n");
444     }
445
446     pFreeContextBuffer(pkg_info);
447 }
448
449
450 static void testQuerySecurityPackageInfo(void)
451 {
452     SECURITY_STATUS     sec_status;
453     SEC_CHAR            sec_pkg_name[256];
454     PSecPkgInfo         pkg_info = NULL;
455     ULONG               max_token = 0;
456     USHORT              version = 0;
457     
458     trace("Running testQuerySecurityPackageInfo\n");
459     
460     /* Test with an existing package. Test should pass */
461     
462     lstrcpy(sec_pkg_name, "NTLM");
463     
464     sec_status = setupPackageA(sec_pkg_name, &pkg_info);
465
466     ok((sec_status == SEC_E_OK) || (sec_status == SEC_E_SECPKG_NOT_FOUND), 
467        "Return value of QuerySecurityPackageInfo() shouldn't be %s\n",
468        getSecError(sec_status) );
469         
470     if(pkg_info != NULL){
471         max_token = pkg_info->cbMaxToken;
472         version   = pkg_info->wVersion;
473         ok(version == 1, "wVersion always should be 1, but is %d\n", version);
474         todo_wine{
475             ok(max_token == 12000, "cbMaxToken for NTLM is %ld, not 12000.\n",
476                 max_token);
477         }
478     }
479     
480     
481     sec_status = pFreeContextBuffer(&pkg_info);
482     
483     ok( sec_status == SEC_E_OK,
484         "Return value of FreeContextBuffer() shouldn't be %s\n",
485         getSecError(sec_status) );
486
487     /* Test with a nonexistent package, test should fail */
488    
489     lstrcpy(sec_pkg_name, "Winetest");
490
491     sec_status = pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info);
492
493     ok( sec_status != SEC_E_OK,
494         "Return value of QuerySecurityPackageInfo() should not be %s for a nonexistent package\n", getSecError(SEC_E_OK));
495
496     sec_status = pFreeContextBuffer(&pkg_info);
497     
498     ok( sec_status == SEC_E_OK,
499         "Return value of FreeContextBuffer() shouldn't be %s\n",
500         getSecError(sec_status) );
501
502
503 }
504
505 void testAuth(const char* sec_pkg, const char* domain)
506 {
507     SECURITY_STATUS     sec_status;
508     PSecPkgInfo         pkg_info = NULL;
509     CredHandle          server_cred;
510     CredHandle          client_cred;
511     CtxtHandle          server_ctxt;
512     CtxtHandle          client_ctxt;
513     SEC_CHAR            sec_pkg_name[256];
514
515     PSecBufferDesc client_in = NULL, client_out = NULL;
516     PSecBufferDesc server_in = NULL, server_out = NULL;
517
518     BOOL continue_client = FALSE, continue_server = FALSE;
519
520     lstrcpy(sec_pkg_name, sec_pkg);
521     if(setupPackageA(sec_pkg_name, &pkg_info) == SEC_E_OK)
522     {
523         pFreeContextBuffer(&pkg_info);
524         sec_status = setupClient(&client_cred, "testuser", "testpass", domain,
525                 sec_pkg_name);
526
527         if(sec_status != SEC_E_OK)
528         {
529             trace("Error: Setting up the client returned %s, exiting test!\n",
530                     getSecError(sec_status));
531             pFreeCredentialsHandle(&client_cred);
532             return;
533         }
534
535         sec_status = setupServer(&server_cred, sec_pkg_name);
536
537         if(sec_status != SEC_E_OK)
538         {
539             trace("Error: Setting up the server returned %s, exiting test!\n",
540                     getSecError(sec_status));
541             pFreeCredentialsHandle(&server_cred);
542             pFreeCredentialsHandle(&client_cred);
543             return;
544         }
545
546         setupBuffers(&client_in, &client_out);
547         setupBuffers(&server_in, &server_out);
548         
549         sec_status = runClient(&client_cred, &client_ctxt, client_in, client_out, 
550                 TRUE);
551
552         ok(sec_status == SEC_E_OK || sec_status == SEC_I_CONTINUE_NEEDED,
553                 "Running the client returned %s, more tests will fail from now.\n",
554                 getSecError(sec_status));
555         
556         if(sec_status == SEC_I_CONTINUE_NEEDED)
557             continue_client = TRUE;
558
559         communicate(client_out, server_in);
560         
561         sec_status = runServer(&server_cred, &server_ctxt, server_in, server_out, 
562                 TRUE);
563
564         ok(sec_status == SEC_E_OK || sec_status == SEC_I_CONTINUE_NEEDED,
565                 "Running the server returned %s, more tests will fail from now.\n",
566                 getSecError(sec_status));
567         
568         if(sec_status == SEC_I_CONTINUE_NEEDED)
569         {
570             continue_server = TRUE;
571             communicate(server_out, client_in);
572         }
573         
574         if(continue_client)
575         {
576             sec_status = runClient(&client_cred, &client_ctxt, client_in, client_out,
577                 FALSE);
578
579             ok(sec_status == SEC_E_OK,
580                 "Running the client returned %s, more tests will fail from now.\n",
581                 getSecError(sec_status));
582             
583             communicate(client_out, server_in);
584         }
585
586         if(continue_server)
587         {
588             sec_status = runServer(&server_cred, &server_ctxt, server_in, server_out,
589                 FALSE);
590             ok(sec_status == SEC_E_OK || SEC_E_LOGON_DENIED,
591                     "Running the server returned %s.\n", getSecError(sec_status));
592         }
593
594         cleanupBuffers(client_in, client_out);
595         cleanupBuffers(server_in, server_out);
596         
597         sec_status = pDeleteSecurityContext(&server_ctxt);
598         ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
599                 getSecError(sec_status));
600
601         sec_status = pDeleteSecurityContext(&client_ctxt);
602         ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
603                 getSecError(sec_status));
604            
605         sec_status = pFreeCredentialsHandle(&server_cred);
606         ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
607                 getSecError(sec_status));
608         
609         sec_status = pFreeCredentialsHandle(&client_cred);
610         ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
611                 getSecError(sec_status));
612     }
613     else
614     {
615         trace("Package not installed, skipping test.\n");
616     }
617     pFreeContextBuffer(&pkg_info);
618 }
619
620
621 START_TEST(main)
622 {
623     InitFunctionPtrs();
624     if(pInitSecurityInterfaceA)
625         testInitSecurityInterface();
626     if(pFreeContextBuffer)
627     {
628         if(pEnumerateSecurityPackagesA)
629             testEnumerateSecurityPackages();
630         if(pQuerySecurityPackageInfoA)
631         {
632             testQuerySecurityPackageInfo();
633             if(pInitSecurityInterfaceA)
634                 testAuth("NTLM", "WORKGROUP");
635         }
636     }
637     if(secdll)
638         FreeLibrary(secdll);
639 }