shell32: Add Fonts to user's shell folders list.
[wine] / dlls / secur32 / tests / main.c
1 /*
2  * Miscellaneous secur32 tests
3  *
4  * Copyright 2005, 2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 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 typedef struct _SspiData {
51     PCredHandle cred;
52     PCtxtHandle ctxt;
53     PSecBufferDesc in_buf;
54     PSecBufferDesc out_buf;
55     PSEC_WINNT_AUTH_IDENTITY id;
56     ULONG max_token;
57 } SspiData;
58
59 /* Forward declare some functions to avoid moving around the code */
60 SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info);
61 void cleanupBuffers(SspiData *sspi_data);
62
63 void InitFunctionPtrs(void)
64 {
65     secdll = LoadLibraryA("secur32.dll");
66     if(!secdll)
67         secdll = LoadLibraryA("security.dll");
68     if(secdll)
69     {
70         pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
71         pEnumerateSecurityPackagesA = (PVOID)GetProcAddress(secdll, "EnumerateSecurityPackagesA");
72         pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
73         pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
74         pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
75         pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
76         pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
77         pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
78         pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
79         pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
80     }
81 }
82
83 /*---------------------------------------------------------*/
84 /* General helper functions */
85
86 static const char* getSecError(SECURITY_STATUS status)
87 {
88     static char buf[20];
89
90 #define _SEC_ERR(x) case (x): return #x;
91     switch(status)
92     {
93         _SEC_ERR(SEC_E_OK);
94         _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
95         _SEC_ERR(SEC_E_INVALID_HANDLE);
96         _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
97         _SEC_ERR(SEC_E_TARGET_UNKNOWN);
98         _SEC_ERR(SEC_E_INTERNAL_ERROR);
99         _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
100         _SEC_ERR(SEC_E_NOT_OWNER);
101         _SEC_ERR(SEC_E_CANNOT_INSTALL);
102         _SEC_ERR(SEC_E_INVALID_TOKEN);
103         _SEC_ERR(SEC_E_CANNOT_PACK);
104         _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
105         _SEC_ERR(SEC_E_NO_IMPERSONATION);
106         _SEC_ERR(SEC_I_CONTINUE_NEEDED);
107         _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
108         _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
109         _SEC_ERR(SEC_E_LOGON_DENIED);
110         _SEC_ERR(SEC_E_NO_CREDENTIALS);
111         _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
112         default:
113             sprintf(buf, "%08lx\n", status);
114             return buf;
115     }
116 #undef _SEC_ERR
117 }
118
119 /*---------------------------------------------------------*/
120 /* Helper for testQuerySecurityPagageInfo */
121
122 static SECURITY_STATUS setupPackageA(SEC_CHAR *p_package_name, 
123         PSecPkgInfo *p_pkg_info)
124 {
125     SECURITY_STATUS ret;
126     
127     ret = pQuerySecurityPackageInfoA( p_package_name, p_pkg_info);
128     return ret;
129 }
130
131 /*---------------------------------------------------------*/
132 /* Helper for testAuth* */
133
134 SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider)
135 {
136     SECURITY_STATUS ret;
137     TimeStamp ttl;
138     SecPkgInfoA *sec_pkg_info;
139
140     trace("Running setupClient\n");
141     
142     sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
143     sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
144     
145     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
146
147     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
148
149     setupBuffers(sspi_data, sec_pkg_info);
150     
151     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
152             NULL, sspi_data->id, NULL, NULL, sspi_data->cred, &ttl))
153             != SEC_E_OK)
154     {
155         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
156     }
157
158     ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n", 
159             getSecError(ret));
160
161     return ret;
162 }
163
164 /**********************************************************************/
165
166 SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
167 {
168     SECURITY_STATUS ret;
169     TimeStamp ttl;
170     SecPkgInfoA *sec_pkg_info;
171
172     trace("Running setupServer\n");
173
174     sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
175     sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
176
177     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
178
179     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
180
181     setupBuffers(sspi_data, sec_pkg_info);
182
183     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND, 
184             NULL, NULL, NULL, NULL, sspi_data->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(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info)
198 {
199     
200     sspi_data->in_buf  = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
201     sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
202     sspi_data->max_token = sec_pkg_info->cbMaxToken;
203
204     if(sspi_data->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         sspi_data->in_buf->ulVersion = SECBUFFER_VERSION;
214         sspi_data->in_buf->cBuffers = 1;
215         sspi_data->in_buf->pBuffers = sec_buffer;
216
217         sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
218         sec_buffer->BufferType = SECBUFFER_TOKEN;
219         if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0, 
220                         sec_pkg_info->cbMaxToken)) == NULL)
221         {
222             trace("in_buf: sec_buffer->pvBuffer == NULL\n");
223             return SEC_E_INSUFFICIENT_MEMORY;
224         }
225     }
226     else
227     {
228         trace("HeapAlloc in_buf returned NULL\n");
229         return SEC_E_INSUFFICIENT_MEMORY;
230     }
231     
232     if(sspi_data->out_buf != NULL)
233     {
234         PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
235                 sizeof(SecBuffer));
236         
237         if(sec_buffer == NULL){
238             trace("out_buf: sec_buffer == NULL\n");
239             return SEC_E_INSUFFICIENT_MEMORY;
240         }
241
242         sspi_data->out_buf->ulVersion = SECBUFFER_VERSION;
243         sspi_data->out_buf->cBuffers = 1;
244         sspi_data->out_buf->pBuffers = sec_buffer;
245
246         sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
247         sec_buffer->BufferType = SECBUFFER_TOKEN;
248         if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0, 
249                         sec_pkg_info->cbMaxToken)) == NULL){
250             trace("out_buf: sec_buffer->pvBuffer == NULL\n");
251             return SEC_E_INSUFFICIENT_MEMORY;
252         }
253     }
254     else
255     {
256         trace("HeapAlloc out_buf returned NULL\n");
257         return SEC_E_INSUFFICIENT_MEMORY;
258     }
259
260     return SEC_E_OK;
261 }
262
263 /**********************************************************************/
264
265 void cleanupBuffers(SspiData *sspi_data)
266 {
267     ULONG i;
268
269     if(sspi_data->in_buf != NULL)
270     {
271         for(i = 0; i < sspi_data->in_buf->cBuffers; ++i)
272         {
273             HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer);
274         }
275         HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers);
276         HeapFree(GetProcessHeap(), 0, sspi_data->in_buf);
277     }
278     
279     if(sspi_data->out_buf != NULL)
280     {
281         for(i = 0; i < sspi_data->out_buf->cBuffers; ++i)
282         {
283             HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer);
284         }
285         HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers);
286         HeapFree(GetProcessHeap(), 0, sspi_data->out_buf);
287     }
288 }
289
290 /**********************************************************************/
291
292 SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first)
293 {
294     SECURITY_STATUS ret;
295     ULONG req_attr = ISC_REQ_CONNECTION | ISC_REQ_CONFIDENTIALITY;
296     ULONG ctxt_attr;
297     TimeStamp ttl;
298     PSecBufferDesc in_buf = sspi_data->in_buf;
299     PSecBufferDesc out_buf = sspi_data->out_buf;
300
301     assert(in_buf->cBuffers >= 1);
302     assert(in_buf->pBuffers[0].pvBuffer != NULL);
303     assert(in_buf->pBuffers[0].cbBuffer != 0);
304
305     assert(out_buf->cBuffers >= 1);
306     assert(out_buf->pBuffers[0].pvBuffer != NULL);
307     assert(out_buf->pBuffers[0].cbBuffer != 0);
308
309     trace("Running the client the %s time.\n", first?"first":"second");
310
311     /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
312      * always allocate output buffers for us, or initialize cbBuffer
313      * before each call because the API changes it to represent actual
314      * amount of data in the buffer.
315      */
316
317     /* test a failing call only the first time, otherwise we get
318      * SEC_E_OUT_OF_SEQUENCE
319      */
320     if (first)
321     {
322         void *old_buf;
323
324         /* pass NULL as an output buffer */
325         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
326             0, SECURITY_NATIVE_DREP, NULL, 0, sspi_data->ctxt, NULL,
327             &ctxt_attr, &ttl);
328
329         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
330
331         /* pass NULL as an output buffer */
332         old_buf = out_buf->pBuffers[0].pvBuffer;
333         out_buf->pBuffers[0].pvBuffer = NULL;
334
335         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr, 
336             0, SECURITY_NATIVE_DREP, NULL, 0, sspi_data->ctxt, out_buf,
337             &ctxt_attr, &ttl);
338
339         ok(ret == SEC_E_INTERNAL_ERROR, "expected SEC_E_INTERNAL_ERROR, got %s\n", getSecError(ret));
340
341         out_buf->pBuffers[0].pvBuffer = old_buf;
342
343         /* pass an output buffer of 0 size */
344         out_buf->pBuffers[0].cbBuffer = 0;
345
346         ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr, 
347             0, SECURITY_NATIVE_DREP, NULL, 0, sspi_data->ctxt, out_buf,
348             &ctxt_attr, &ttl);
349
350         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
351
352         ok(out_buf->pBuffers[0].cbBuffer == 0,
353            "InitializeSecurityContext set buffer size to %lu\n", out_buf->pBuffers[0].cbBuffer);
354     }
355
356     out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
357
358     ret = pInitializeSecurityContextA(sspi_data->cred, first?NULL:sspi_data->ctxt, NULL, req_attr, 
359             0, SECURITY_NATIVE_DREP, first?NULL:in_buf, 0, sspi_data->ctxt, out_buf,
360             &ctxt_attr, &ttl);
361
362     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
363     {
364         pCompleteAuthToken(sspi_data->ctxt, out_buf);
365         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
366             ret = SEC_I_CONTINUE_NEEDED;
367         else if(ret == SEC_I_COMPLETE_NEEDED)
368             ret = SEC_E_OK;
369     }       
370
371     ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
372        "InitializeSecurityContext set buffer size to %lu\n", out_buf->pBuffers[0].cbBuffer);
373
374     return ret;
375 }
376
377 /**********************************************************************/
378
379 SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first)
380 {
381     SECURITY_STATUS ret;
382     ULONG ctxt_attr;
383     TimeStamp ttl;
384
385     trace("Running the server the %s time\n", first?"first":"second");
386
387     ret = pAcceptSecurityContext(sspi_data->cred, first?NULL:sspi_data->ctxt, 
388             sspi_data->in_buf, 0, SECURITY_NATIVE_DREP, sspi_data->ctxt, 
389             sspi_data->out_buf, &ctxt_attr, &ttl);
390
391     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
392     {
393         pCompleteAuthToken(sspi_data->ctxt, sspi_data->out_buf);
394         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
395             ret = SEC_I_CONTINUE_NEEDED;
396         else if(ret == SEC_I_COMPLETE_NEEDED)
397             ret = SEC_E_OK;
398     }
399
400     return ret;
401 }
402
403 /**********************************************************************/
404
405 void communicate(SspiData *from, SspiData *to)
406 {
407     if(from->out_buf != NULL && to->in_buf != NULL)
408     {
409         trace("Running communicate.\n");
410         if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
411         {
412             if((from->out_buf->pBuffers[0].pvBuffer != NULL) && 
413                     (to->in_buf->pBuffers[0].pvBuffer != NULL))
414             {
415                 memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
416                 
417                 memcpy(to->in_buf->pBuffers[0].pvBuffer, 
418                     from->out_buf->pBuffers[0].pvBuffer,
419                     from->out_buf->pBuffers[0].cbBuffer);
420                 
421                 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
422                 
423                 memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
424             }
425         }
426     }
427 }
428    
429 /**********************************************************************/
430
431 /*--------------------------------------------------------- */
432 /* The test functions */
433
434 static void testInitSecurityInterface(void)
435 {
436     PSecurityFunctionTable sec_fun_table = NULL;
437
438     sec_fun_table = pInitSecurityInterfaceA();
439     ok(sec_fun_table != NULL, "InitSecurityInterface() returned NULL.\n");
440
441 }
442
443 static void testEnumerateSecurityPackages(void)
444 {
445
446     SECURITY_STATUS sec_status;
447     ULONG           num_packages, i;
448     PSecPkgInfo     pkg_info = NULL;
449
450     trace("Running testEnumerateSecurityPackages\n");
451     
452     sec_status = pEnumerateSecurityPackagesA(&num_packages, &pkg_info);
453
454     ok(sec_status == SEC_E_OK, 
455             "EnumerateSecurityPackages() should return %ld, not %08lx\n",
456             (LONG)SEC_E_OK, (LONG)sec_status);
457
458     ok(num_packages > 0, "Number of sec packages should be > 0 ,but is %ld\n",
459             num_packages);
460
461     ok(pkg_info != NULL, 
462             "pkg_info should not be NULL after EnumerateSecurityPackages\n");
463     
464     trace("Number of packages: %ld\n", num_packages);
465     for(i = 0; i < num_packages; ++i){
466         trace("%ld: Package \"%s\"\n", i, pkg_info[i].Name);
467         trace("Supported flags:\n");
468         if(pkg_info[i].fCapabilities & SECPKG_FLAG_INTEGRITY)
469             trace("\tSECPKG_FLAG_INTEGRITY\n");
470         if(pkg_info[i].fCapabilities & SECPKG_FLAG_PRIVACY)
471             trace("\tSECPKG_FLAG_PRIVACY\n");
472         if(pkg_info[i].fCapabilities & SECPKG_FLAG_TOKEN_ONLY)
473             trace("\tSECPKG_FLAG_TOKEN_ONLY\n");
474         if(pkg_info[i].fCapabilities & SECPKG_FLAG_DATAGRAM)
475             trace("\tSECPKG_FLAG_DATAGRAM\n");
476         if(pkg_info[i].fCapabilities & SECPKG_FLAG_CONNECTION)
477             trace("\tSECPKG_FLAG_CONNECTION\n");
478         if(pkg_info[i].fCapabilities & SECPKG_FLAG_MULTI_REQUIRED)
479             trace("\tSECPKG_FLAG_MULTI_REQUIRED\n");
480         if(pkg_info[i].fCapabilities & SECPKG_FLAG_CLIENT_ONLY)
481             trace("\tSECPKG_FLAG_CLIENT_ONLY\n");
482         if(pkg_info[i].fCapabilities & SECPKG_FLAG_EXTENDED_ERROR)
483             trace("\tSECPKG_FLAG_EXTENDED_ERROR\n");
484         if(pkg_info[i].fCapabilities & SECPKG_FLAG_IMPERSONATION)
485             trace("\tSECPKG_FLAG_IMPERSONATION\n");
486         if(pkg_info[i].fCapabilities & SECPKG_FLAG_ACCEPT_WIN32_NAME)
487             trace("\tSECPKG_FLAG_ACCEPT_WIN32_NAME\n");
488         if(pkg_info[i].fCapabilities & SECPKG_FLAG_STREAM)
489             trace("\tSECPKG_FLAG_STREAM\n");
490         if(pkg_info[i].fCapabilities & SECPKG_FLAG_READONLY_WITH_CHECKSUM)
491             trace("\tSECPKG_FLAG_READONLY_WITH_CHECKSUM\n");
492         trace("Comment: %s\n", pkg_info[i].Comment);
493         trace("\n");
494     }
495
496     pFreeContextBuffer(pkg_info);
497 }
498
499
500 static void testQuerySecurityPackageInfo(void)
501 {
502     SECURITY_STATUS     sec_status;
503     PSecPkgInfo         pkg_info;
504     
505     trace("Running testQuerySecurityPackageInfo\n");
506     
507     /* Test with an existing package. Test should pass */
508
509     pkg_info = (void *)0xdeadbeef;
510     sec_status = setupPackageA("NTLM", &pkg_info);
511
512     ok((sec_status == SEC_E_OK) || (sec_status == SEC_E_SECPKG_NOT_FOUND), 
513        "Return value of QuerySecurityPackageInfo() shouldn't be %s\n",
514        getSecError(sec_status) );
515         
516     if (sec_status == SEC_E_OK)
517     {
518         ok(pkg_info != (void *)0xdeadbeef, "wrong pkg_info address %p\n", pkg_info);
519         ok(pkg_info->wVersion == 1, "wVersion always should be 1, but is %d\n", pkg_info->wVersion);
520         /* there is no point in testing pkg_info->cbMaxToken since it varies
521          * between implementations.
522          */
523     }
524
525     sec_status = pFreeContextBuffer(pkg_info);
526
527     ok( sec_status == SEC_E_OK,
528         "Return value of FreeContextBuffer() shouldn't be %s\n",
529         getSecError(sec_status) );
530
531     /* Test with a nonexistent package, test should fail */
532
533     pkg_info = (void *)0xdeadbeef;
534     sec_status = pQuerySecurityPackageInfoA("Winetest", &pkg_info);
535
536     ok( sec_status != SEC_E_OK,
537         "Return value of QuerySecurityPackageInfo() should not be %s for a nonexistent package\n", getSecError(SEC_E_OK));
538
539     ok(pkg_info == (void *)0xdeadbeef, "wrong pkg_info address %p\n", pkg_info);
540
541     sec_status = pFreeContextBuffer(pkg_info);
542     
543     ok( sec_status == SEC_E_OK,
544         "Return value of FreeContextBuffer() shouldn't be %s\n",
545         getSecError(sec_status) );
546 }
547
548 void testAuth(SEC_CHAR* sec_pkg_name)
549 {
550     SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
551     SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
552     SECURITY_STATUS         sec_status;
553     PSecPkgInfo             pkg_info = NULL;
554     BOOL                    first = TRUE;
555     SspiData                client, server;
556     SEC_WINNT_AUTH_IDENTITY id;
557
558     if(setupPackageA(sec_pkg_name, &pkg_info) == SEC_E_OK)
559     {
560         pFreeContextBuffer(pkg_info);
561         id.User = (unsigned char*) "Administrator";
562         id.UserLength = strlen((char *) id.User);
563         id.Domain = (unsigned char *) "WORKGROUP";
564         id.DomainLength = strlen((char *) id.Domain);
565         id.Password = (unsigned char*) "testpass";
566         id.PasswordLength = strlen((char *) id.Password);
567         id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
568
569         client.id = &id;
570         
571         sec_status = setupClient(&client, sec_pkg_name);
572
573         if(sec_status != SEC_E_OK)
574         {
575             trace("Error: Setting up the client returned %s, exiting test!\n",
576                     getSecError(sec_status));
577             pFreeCredentialsHandle(client.cred);
578             return;
579         }
580
581         sec_status = setupServer(&server, sec_pkg_name);
582
583         if(sec_status != SEC_E_OK)
584         {
585             trace("Error: Setting up the server returned %s, exiting test!\n",
586                     getSecError(sec_status));
587             pFreeCredentialsHandle(server.cred);
588             pFreeCredentialsHandle(client.cred);
589             return;
590         }
591
592
593         while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
594         {
595             client_stat = runClient(&client, first);
596
597             ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
598                     "Running the client returned %s, more tests will fail.\n",
599                     getSecError(client_stat));
600             
601             communicate(&client, &server);
602             
603             server_stat = runServer(&server, first);
604
605             ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
606                     server_stat == SEC_E_LOGON_DENIED,
607                     "Running the server returned %s, more tests will fail from now.\n",
608                     getSecError(server_stat));
609
610             communicate(&server, &client);
611             trace("Looping\n");
612             first = FALSE;
613         }
614         
615         cleanupBuffers(&client);
616         cleanupBuffers(&server);
617         
618         sec_status = pDeleteSecurityContext(server.ctxt);
619         ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
620                 getSecError(sec_status));
621
622         sec_status = pDeleteSecurityContext(client.ctxt);
623         ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
624                 getSecError(sec_status));
625            
626         sec_status = pFreeCredentialsHandle(server.cred);
627         ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
628                 getSecError(sec_status));
629         
630         sec_status = pFreeCredentialsHandle(client.cred);
631         ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
632                 getSecError(sec_status));
633     }
634     else
635     {
636         trace("Package not installed, skipping test.\n");
637     }
638 }
639
640 START_TEST(main)
641 {
642     InitFunctionPtrs();
643     if(pInitSecurityInterfaceA)
644         testInitSecurityInterface();
645     if(pFreeContextBuffer)
646     {
647         if(pEnumerateSecurityPackagesA)
648             testEnumerateSecurityPackages();
649         if(pQuerySecurityPackageInfoA)
650         {
651             testQuerySecurityPackageInfo();
652             if(pInitSecurityInterfaceA)
653                 testAuth("NTLM");
654         }
655     }
656     if(secdll)
657         FreeLibrary(secdll);
658 }