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