xref: /reactos/dll/win32/secur32/wine/negotiate.c (revision 84ccccab)
1 /*
2  * Copyright 2005 Kai Blin
3  * Copyright 2012 Hans Leidekker for CodeWeavers
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  *
19  * This file implements a Negotiate provider that simply forwards to
20  * the NTLM provider.
21  */
22 
23 #include "precomp.h"
24 
25 #include <wine/debug.h>
26 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
27 
28 /***********************************************************************
29  *              QueryCredentialsAttributesA
30  */
31 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA(
32     PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
33 {
34     FIXME("%p, %u, %p\n", phCredential, ulAttribute, pBuffer);
35     return SEC_E_UNSUPPORTED_FUNCTION;
36 }
37 
38 /***********************************************************************
39  *              QueryCredentialsAttributesW
40  */
41 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW(
42     PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
43 {
44     FIXME("%p, %u, %p\n", phCredential, ulAttribute, pBuffer);
45     return SEC_E_UNSUPPORTED_FUNCTION;
46 }
47 
48 /***********************************************************************
49  *              AcquireCredentialsHandleW
50  */
51 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
52     SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
53     PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
54     PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry )
55 {
56     static SEC_WCHAR ntlmW[] = {'N','T','L','M',0};
57     SECURITY_STATUS ret;
58 
59     TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n",
60           debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
61           pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
62 
63     FIXME("forwarding to NTLM\n");
64     ret = ntlm_AcquireCredentialsHandleW( pszPrincipal, ntlmW, fCredentialUse,
65                                           pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument,
66                                           phCredential, ptsExpiry );
67     if (ret == SEC_E_OK)
68     {
69         NtlmCredentials *cred = (NtlmCredentials *)phCredential->dwLower;
70         cred->no_cached_credentials = (pAuthData == NULL);
71     }
72     return ret;
73 }
74 
75 /***********************************************************************
76  *              AcquireCredentialsHandleA
77  */
78 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA(
79     SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
80     PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
81     PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry )
82 {
83     SECURITY_STATUS ret = SEC_E_INSUFFICIENT_MEMORY;
84     SEC_WCHAR *user = NULL, *domain = NULL, *passwd = NULL, *package = NULL;
85     SEC_WINNT_AUTH_IDENTITY_W *identityW = NULL;
86 
87     TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n",
88           debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
89           pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
90 
91     if (pszPackage)
92     {
93         int package_len = MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, NULL, 0 );
94         package = HeapAlloc( GetProcessHeap(), 0, package_len * sizeof(SEC_WCHAR) );
95         if (!package) return SEC_E_INSUFFICIENT_MEMORY;
96         MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, package, package_len );
97     }
98     if (pAuthData)
99     {
100         SEC_WINNT_AUTH_IDENTITY_A *identity = pAuthData;
101         int user_len, domain_len, passwd_len;
102 
103         if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
104         {
105             identityW = HeapAlloc( GetProcessHeap(), 0, sizeof(*identityW) );
106             if (!identityW) goto done;
107 
108             if (!identity->UserLength) user_len = 0;
109             else
110             {
111                 user_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User,
112                                                 identity->UserLength, NULL, 0 );
113                 user = HeapAlloc( GetProcessHeap(), 0, user_len * sizeof(SEC_WCHAR) );
114                 if (!user) goto done;
115                 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User, identity->UserLength,
116                                      user, user_len );
117             }
118             if (!identity->DomainLength) domain_len = 0;
119             else
120             {
121                 domain_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain,
122                                                   identity->DomainLength, NULL, 0 );
123                 domain = HeapAlloc( GetProcessHeap(), 0, domain_len * sizeof(SEC_WCHAR) );
124                 if (!domain) goto done;
125                 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain, identity->DomainLength,
126                                      domain, domain_len );
127             }
128             if (!identity->PasswordLength) passwd_len = 0;
129             else
130             {
131                 passwd_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password,
132                                                   identity->PasswordLength, NULL, 0 );
133                 passwd = HeapAlloc( GetProcessHeap(), 0, passwd_len * sizeof(SEC_WCHAR) );
134                 if (!passwd) goto done;
135                 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password, identity->PasswordLength,
136                                      passwd, passwd_len );
137             }
138             identityW->Flags          = SEC_WINNT_AUTH_IDENTITY_UNICODE;
139             identityW->User           = user;
140             identityW->UserLength     = user_len;
141             identityW->Domain         = domain;
142             identityW->DomainLength   = domain_len;
143             identityW->Password       = passwd;
144             identityW->PasswordLength = passwd_len;
145         }
146         else identityW = (SEC_WINNT_AUTH_IDENTITY_W *)identity;
147     }
148     ret = nego_AcquireCredentialsHandleW( NULL, package, fCredentialUse, pLogonID, identityW,
149                                           pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry );
150 done:
151     HeapFree( GetProcessHeap(), 0, package );
152     HeapFree( GetProcessHeap(), 0, user );
153     HeapFree( GetProcessHeap(), 0, domain );
154     HeapFree( GetProcessHeap(), 0, passwd );
155     HeapFree( GetProcessHeap(), 0, identityW );
156     return ret;
157 }
158 
159 /***********************************************************************
160  *              InitializeSecurityContextW
161  */
162 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
163     PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
164     ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
165     PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
166     PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry )
167 {
168     TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n",
169           phCredential, phContext, debugstr_w(pszTargetName), fContextReq,
170           Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput,
171           pfContextAttr, ptsExpiry);
172 
173     return ntlm_InitializeSecurityContextW( phCredential, phContext, pszTargetName,
174                                             fContextReq, Reserved1, TargetDataRep,
175                                             pInput, Reserved2, phNewContext,
176                                             pOutput, pfContextAttr, ptsExpiry );
177 }
178 
179 /***********************************************************************
180  *              InitializeSecurityContextA
181  */
182 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA(
183     PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName,
184     ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
185     PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
186     PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry )
187 {
188     SECURITY_STATUS ret;
189     SEC_WCHAR *target = NULL;
190 
191     TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n",
192           phCredential, phContext, debugstr_a(pszTargetName), fContextReq,
193           Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput,
194           pfContextAttr, ptsExpiry);
195 
196     if (pszTargetName)
197     {
198         int target_len = MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, NULL, 0 );
199         target = HeapAlloc(GetProcessHeap(), 0, target_len * sizeof(SEC_WCHAR) );
200         if (!target) return SEC_E_INSUFFICIENT_MEMORY;
201         MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, target, target_len );
202     }
203     ret = nego_InitializeSecurityContextW( phCredential, phContext, target, fContextReq,
204                                            Reserved1, TargetDataRep, pInput, Reserved2,
205                                            phNewContext, pOutput, pfContextAttr, ptsExpiry );
206     HeapFree( GetProcessHeap(), 0, target );
207     return ret;
208 }
209 
210 /***********************************************************************
211  *              AcceptSecurityContext
212  */
213 static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
214     PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
215     ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
216     PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
217 {
218     TRACE("%p, %p, %p, 0x%08x, %u, %p, %p, %p, %p\n", phCredential, phContext,
219           pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
220           ptsExpiry);
221 
222     return ntlm_AcceptSecurityContext( phCredential, phContext, pInput,
223                                        fContextReq, TargetDataRep, phNewContext,
224                                        pOutput, pfContextAttr, ptsExpiry );
225 }
226 
227 /***********************************************************************
228  *              CompleteAuthToken
229  */
230 static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext,
231  PSecBufferDesc pToken)
232 {
233     SECURITY_STATUS ret;
234 
235     TRACE("%p %p\n", phContext, pToken);
236     if (phContext)
237     {
238         ret = SEC_E_UNSUPPORTED_FUNCTION;
239     }
240     else
241     {
242         ret = SEC_E_INVALID_HANDLE;
243     }
244     return ret;
245 }
246 
247 /***********************************************************************
248  *              DeleteSecurityContext
249  */
250 static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext)
251 {
252     TRACE("%p\n", phContext);
253 
254     return ntlm_DeleteSecurityContext( phContext );
255 }
256 
257 /***********************************************************************
258  *              ApplyControlToken
259  */
260 static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext,
261  PSecBufferDesc pInput)
262 {
263     SECURITY_STATUS ret;
264 
265     TRACE("%p %p\n", phContext, pInput);
266     if (phContext)
267     {
268         ret = SEC_E_UNSUPPORTED_FUNCTION;
269     }
270     else
271     {
272         ret = SEC_E_INVALID_HANDLE;
273     }
274     return ret;
275 }
276 
277 /***********************************************************************
278  *              QueryContextAttributesW
279  */
280 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(
281     PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
282 {
283     TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer);
284 
285     switch (ulAttribute)
286     {
287     case SECPKG_ATTR_SIZES:
288     {
289         SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)pBuffer;
290         sizes->cbMaxToken        = 2888;
291         sizes->cbMaxSignature    = 16;
292         sizes->cbSecurityTrailer = 16;
293         sizes->cbBlockSize       = 0;
294         return SEC_E_OK;
295     }
296     case SECPKG_ATTR_NEGOTIATION_INFO:
297     {
298         SecPkgContext_NegotiationInfoW *info = (SecPkgContext_NegotiationInfoW *)pBuffer;
299         info->PackageInfo      = ntlm_package_infoW;
300         info->NegotiationState = SECPKG_NEGOTIATION_COMPLETE;
301         return SEC_E_OK;
302     }
303     default:
304         return ntlm_QueryContextAttributesW( phContext, ulAttribute, pBuffer );
305     }
306 }
307 
308 /***********************************************************************
309  *              QueryContextAttributesA
310  */
311 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext,
312  ULONG ulAttribute, void *pBuffer)
313 {
314     TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer);
315 
316     switch (ulAttribute)
317     {
318     case SECPKG_ATTR_SIZES:
319     {
320         SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)pBuffer;
321         sizes->cbMaxToken        = 2888;
322         sizes->cbMaxSignature    = 16;
323         sizes->cbSecurityTrailer = 16;
324         sizes->cbBlockSize       = 0;
325         return SEC_E_OK;
326     }
327     case SECPKG_ATTR_NEGOTIATION_INFO:
328     {
329         SecPkgContext_NegotiationInfoA *info = (SecPkgContext_NegotiationInfoA *)pBuffer;
330         info->PackageInfo      = ntlm_package_infoA;
331         info->NegotiationState = SECPKG_NEGOTIATION_COMPLETE;
332         return SEC_E_OK;
333     }
334     default:
335         return ntlm_QueryContextAttributesA( phContext, ulAttribute, pBuffer );
336     }
337 }
338 
339 /***********************************************************************
340  *              ImpersonateSecurityContext
341  */
342 static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext)
343 {
344     SECURITY_STATUS ret;
345 
346     TRACE("%p\n", phContext);
347     if (phContext)
348     {
349         ret = SEC_E_UNSUPPORTED_FUNCTION;
350     }
351     else
352     {
353         ret = SEC_E_INVALID_HANDLE;
354     }
355     return ret;
356 }
357 
358 /***********************************************************************
359  *              RevertSecurityContext
360  */
361 static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext)
362 {
363     SECURITY_STATUS ret;
364 
365     TRACE("%p\n", phContext);
366     if (phContext)
367     {
368         ret = SEC_E_UNSUPPORTED_FUNCTION;
369     }
370     else
371     {
372         ret = SEC_E_INVALID_HANDLE;
373     }
374     return ret;
375 }
376 
377 /***********************************************************************
378  *              MakeSignature
379  */
380 static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext,
381     ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
382 {
383     TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo);
384 
385     return ntlm_MakeSignature( phContext, fQOP, pMessage, MessageSeqNo );
386 }
387 
388 /***********************************************************************
389  *              VerifySignature
390  */
391 static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext,
392     PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
393 {
394     TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
395 
396     return ntlm_VerifySignature( phContext, pMessage, MessageSeqNo, pfQOP );
397 }
398 
399 /***********************************************************************
400  *             FreeCredentialsHandle
401  */
402 static SECURITY_STATUS SEC_ENTRY nego_FreeCredentialsHandle(PCredHandle phCredential)
403 {
404     TRACE("%p\n", phCredential);
405 
406     return ntlm_FreeCredentialsHandle( phCredential );
407 }
408 
409 /***********************************************************************
410  *             EncryptMessage
411  */
412 static SECURITY_STATUS SEC_ENTRY nego_EncryptMessage(PCtxtHandle phContext,
413     ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
414 {
415     TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo);
416 
417     return ntlm_EncryptMessage( phContext, fQOP, pMessage, MessageSeqNo );
418 }
419 
420 /***********************************************************************
421  *             DecryptMessage
422  */
423 static SECURITY_STATUS SEC_ENTRY nego_DecryptMessage(PCtxtHandle phContext,
424     PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
425 {
426     TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
427 
428     return ntlm_DecryptMessage( phContext, pMessage, MessageSeqNo, pfQOP );
429 }
430 
431 static const SecurityFunctionTableA negoTableA = {
432     1,
433     NULL,                               /* EnumerateSecurityPackagesA */
434     nego_QueryCredentialsAttributesA,   /* QueryCredentialsAttributesA */
435     nego_AcquireCredentialsHandleA,     /* AcquireCredentialsHandleA */
436     nego_FreeCredentialsHandle,         /* FreeCredentialsHandle */
437     NULL,                               /* Reserved2 */
438     nego_InitializeSecurityContextA,    /* InitializeSecurityContextA */
439     nego_AcceptSecurityContext,         /* AcceptSecurityContext */
440     nego_CompleteAuthToken,             /* CompleteAuthToken */
441     nego_DeleteSecurityContext,         /* DeleteSecurityContext */
442     nego_ApplyControlToken,             /* ApplyControlToken */
443     nego_QueryContextAttributesA,       /* QueryContextAttributesA */
444     nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
445     nego_RevertSecurityContext,         /* RevertSecurityContext */
446     nego_MakeSignature,                 /* MakeSignature */
447     nego_VerifySignature,               /* VerifySignature */
448     FreeContextBuffer,                  /* FreeContextBuffer */
449     NULL,   /* QuerySecurityPackageInfoA */
450     NULL,   /* Reserved3 */
451     NULL,   /* Reserved4 */
452     NULL,   /* ExportSecurityContext */
453     NULL,   /* ImportSecurityContextA */
454     NULL,   /* AddCredentialsA */
455     NULL,   /* Reserved8 */
456     NULL,   /* QuerySecurityContextToken */
457     nego_EncryptMessage,                /* EncryptMessage */
458     nego_DecryptMessage,                /* DecryptMessage */
459     NULL,   /* SetContextAttributesA */
460 };
461 
462 static const SecurityFunctionTableW negoTableW = {
463     1,
464     NULL,                               /* EnumerateSecurityPackagesW */
465     nego_QueryCredentialsAttributesW,   /* QueryCredentialsAttributesW */
466     nego_AcquireCredentialsHandleW,     /* AcquireCredentialsHandleW */
467     nego_FreeCredentialsHandle,         /* FreeCredentialsHandle */
468     NULL,                               /* Reserved2 */
469     nego_InitializeSecurityContextW,    /* InitializeSecurityContextW */
470     nego_AcceptSecurityContext,         /* AcceptSecurityContext */
471     nego_CompleteAuthToken,             /* CompleteAuthToken */
472     nego_DeleteSecurityContext,         /* DeleteSecurityContext */
473     nego_ApplyControlToken,             /* ApplyControlToken */
474     nego_QueryContextAttributesW,       /* QueryContextAttributesW */
475     nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
476     nego_RevertSecurityContext,         /* RevertSecurityContext */
477     nego_MakeSignature,                 /* MakeSignature */
478     nego_VerifySignature,               /* VerifySignature */
479     FreeContextBuffer,                  /* FreeContextBuffer */
480     NULL,   /* QuerySecurityPackageInfoW */
481     NULL,   /* Reserved3 */
482     NULL,   /* Reserved4 */
483     NULL,   /* ExportSecurityContext */
484     NULL,   /* ImportSecurityContextW */
485     NULL,   /* AddCredentialsW */
486     NULL,   /* Reserved8 */
487     NULL,   /* QuerySecurityContextToken */
488     nego_EncryptMessage,                /* EncryptMessage */
489     nego_DecryptMessage,                /* DecryptMessage */
490     NULL,   /* SetContextAttributesW */
491 };
492 
493 #define NEGO_MAX_TOKEN 12000
494 
495 static WCHAR nego_name_W[] = {'N','e','g','o','t','i','a','t','e',0};
496 static char nego_name_A[] = "Negotiate";
497 
498 static WCHAR negotiate_comment_W[] =
499     {'M','i','c','r','o','s','o','f','t',' ','P','a','c','k','a','g','e',' ',
500      'N','e','g','o','t','i','a','t','o','r',0};
501 static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator";
502 
503 #define CAPS ( \
504     SECPKG_FLAG_INTEGRITY  | \
505     SECPKG_FLAG_PRIVACY    | \
506     SECPKG_FLAG_CONNECTION | \
507     SECPKG_FLAG_MULTI_REQUIRED | \
508     SECPKG_FLAG_EXTENDED_ERROR | \
509     SECPKG_FLAG_IMPERSONATION  | \
510     SECPKG_FLAG_ACCEPT_WIN32_NAME | \
511     SECPKG_FLAG_NEGOTIABLE        | \
512     SECPKG_FLAG_GSS_COMPATIBLE    | \
513     SECPKG_FLAG_LOGON             | \
514     SECPKG_FLAG_RESTRICTED_TOKENS )
515 
516 void SECUR32_initNegotiateSP(void)
517 {
518     SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW, NULL);
519 
520     const SecPkgInfoW infoW = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN,
521                                nego_name_W, negotiate_comment_W};
522     const SecPkgInfoA infoA = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN,
523                                nego_name_A, negotiate_comment_A};
524     SECUR32_addPackages(provider, 1L, &infoA, &infoW);
525 }
526