r18772: Now that we don't have a one-byte keylength in the extended security case
[mat/samba.git] / source3 / smbd / negprot.c
1 /* 
2    Unix SMB/CIFS implementation.
3    negprot reply code
4    Copyright (C) Andrew Tridgell 1992-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program 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
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 extern fstring remote_proto;
24 extern enum protocol_types Protocol;
25 extern int max_recv;
26
27 BOOL global_encrypted_passwords_negotiated = False;
28 BOOL global_spnego_negotiated = False;
29 struct auth_context *negprot_global_auth_context = NULL;
30
31 static void get_challenge(char buff[8]) 
32 {
33         NTSTATUS nt_status;
34         const uint8 *cryptkey;
35
36         /* We might be called more than once, multiple negprots are
37          * permitted */
38         if (negprot_global_auth_context) {
39                 DEBUG(3, ("get challenge: is this a secondary negprot?  negprot_global_auth_context is non-NULL!\n"));
40                 (negprot_global_auth_context->free)(&negprot_global_auth_context);
41         }
42
43         DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
44         if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
45                 DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
46                 smb_panic("cannot make_negprot_global_auth_context!\n");
47         }
48         DEBUG(10, ("get challenge: getting challenge\n"));
49         cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context);
50         memcpy(buff, cryptkey, 8);
51 }
52
53 /****************************************************************************
54  Reply for the core protocol.
55 ****************************************************************************/
56
57 static int reply_corep(char *inbuf, char *outbuf)
58 {
59         int outsize = set_message(outbuf,1,0,True);
60
61         Protocol = PROTOCOL_CORE;
62         
63         return outsize;
64 }
65
66 /****************************************************************************
67  Reply for the coreplus protocol.
68 ****************************************************************************/
69
70 static int reply_coreplus(char *inbuf, char *outbuf)
71 {
72         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
73         int outsize = set_message(outbuf,13,0,True);
74         SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
75                         readbraw and writebraw (possibly) */
76         /* Reply, SMBlockread, SMBwritelock supported. */
77         SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
78         SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */    
79
80         Protocol = PROTOCOL_COREPLUS;
81
82         return outsize;
83 }
84
85 /****************************************************************************
86  Reply for the lanman 1.0 protocol.
87 ****************************************************************************/
88
89 static int reply_lanman1(char *inbuf, char *outbuf)
90 {
91         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
92         int secword=0;
93         time_t t = time(NULL);
94
95         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
96
97         if (lp_security()>=SEC_USER)
98                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
99         if (global_encrypted_passwords_negotiated)
100                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
101
102         set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
103         SSVAL(outbuf,smb_vwv1,secword); 
104         /* Create a token value and add it to the outgoing packet. */
105         if (global_encrypted_passwords_negotiated) {
106                 get_challenge(smb_buf(outbuf));
107                 SSVAL(outbuf,smb_vwv11, 8);
108         }
109
110         Protocol = PROTOCOL_LANMAN1;
111
112         /* Reply, SMBlockread, SMBwritelock supported. */
113         SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
114         SSVAL(outbuf,smb_vwv2,max_recv);
115         SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
116         SSVAL(outbuf,smb_vwv4,1);
117         SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
118                 readbraw writebraw (possibly) */
119         SIVAL(outbuf,smb_vwv6,sys_getpid());
120         SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60);
121
122         srv_put_dos_date(outbuf,smb_vwv8,t);
123
124         return (smb_len(outbuf)+4);
125 }
126
127 /****************************************************************************
128  Reply for the lanman 2.0 protocol.
129 ****************************************************************************/
130
131 static int reply_lanman2(char *inbuf, char *outbuf)
132 {
133         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
134         int secword=0;
135         time_t t = time(NULL);
136
137         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
138   
139         if (lp_security()>=SEC_USER)
140                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
141         if (global_encrypted_passwords_negotiated)
142                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
143
144         set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
145         SSVAL(outbuf,smb_vwv1,secword); 
146         SIVAL(outbuf,smb_vwv6,sys_getpid());
147
148         /* Create a token value and add it to the outgoing packet. */
149         if (global_encrypted_passwords_negotiated) {
150                 get_challenge(smb_buf(outbuf));
151                 SSVAL(outbuf,smb_vwv11, 8);
152         }
153
154         Protocol = PROTOCOL_LANMAN2;
155
156         /* Reply, SMBlockread, SMBwritelock supported. */
157         SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
158         SSVAL(outbuf,smb_vwv2,max_recv);
159         SSVAL(outbuf,smb_vwv3,lp_maxmux()); 
160         SSVAL(outbuf,smb_vwv4,1);
161         SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
162         SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60);
163         srv_put_dos_date(outbuf,smb_vwv8,t);
164
165         return (smb_len(outbuf)+4);
166 }
167
168 /****************************************************************************
169  Generate the spnego negprot reply blob. Return the number of bytes used.
170 ****************************************************************************/
171
172 static int negprot_spnego(char *p)
173 {
174         DATA_BLOB blob;
175         nstring dos_name;
176         fstring unix_name;
177         char guid[17];
178         const char *OIDs_krb5[] = {OID_KERBEROS5,
179                                    OID_KERBEROS5_OLD,
180                                    OID_NTLMSSP,
181                                    NULL};
182         const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
183         int len;
184
185         global_spnego_negotiated = True;
186
187         ZERO_STRUCT(guid);
188
189         safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
190         strlower_m(unix_name);
191         push_ascii_nstring(dos_name, unix_name);
192         safe_strcpy(guid, dos_name, sizeof(guid)-1);
193
194         /* strangely enough, NT does not sent the single OID NTLMSSP when
195            not a ADS member, it sends no OIDs at all
196
197            OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
198                    about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
199
200            Our sessionsetup code now handles raw NTLMSSP connects, so we can go
201            back to doing what W2K3 does here. This is needed to make PocketPC 2003
202            CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
203            for details. JRA.
204
205         */
206
207         if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
208 #if 0
209                 /* Code for PocketPC client */
210                 blob = data_blob(guid, 16);
211 #else
212                 /* Code for standalone WXP client */
213                 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
214 #endif
215         } else {
216                 fstring myname;
217                 char *host_princ_s = NULL;
218                 name_to_fqdn(myname, global_myname());
219                 strlower_m(myname);
220                 asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
221                 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
222                 SAFE_FREE(host_princ_s);
223         }
224
225         memcpy(p, blob.data, blob.length);
226         len = blob.length;
227         data_blob_free(&blob);
228
229         return len;
230 }
231
232 /****************************************************************************
233  Reply for the nt protocol.
234 ****************************************************************************/
235
236 static int reply_nt1(char *inbuf, char *outbuf)
237 {
238         /* dual names + lock_and_read + nt SMBs + remote API calls */
239         int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
240                 CAP_LEVEL_II_OPLOCKS;
241
242         int secword=0;
243         char *p, *q;
244         BOOL negotiate_spnego = False;
245         time_t t = time(NULL);
246
247         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
248
249         /* do spnego in user level security if the client
250            supports it and we can do encrypted passwords */
251         
252         if (global_encrypted_passwords_negotiated && 
253             (lp_security() != SEC_SHARE) &&
254             lp_use_spnego() &&
255             (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
256                 negotiate_spnego = True;
257                 capabilities |= CAP_EXTENDED_SECURITY;
258                 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
259                 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
260                         partially constructed. */
261                 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
262         }
263         
264         capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
265
266         if (lp_unix_extensions()) {
267                 capabilities |= CAP_UNIX;
268         }
269         
270         if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
271                 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
272         
273         if (SMB_OFF_T_BITS == 64)
274                 capabilities |= CAP_LARGE_FILES;
275
276         if (lp_readraw() && lp_writeraw())
277                 capabilities |= CAP_RAW_MODE;
278         
279         if (lp_nt_status_support())
280                 capabilities |= CAP_STATUS32;
281         
282         if (lp_host_msdfs())
283                 capabilities |= CAP_DFS;
284         
285         if (lp_security() >= SEC_USER)
286                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
287         if (global_encrypted_passwords_negotiated)
288                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
289         
290         if (lp_server_signing()) {
291                 if (lp_security() >= SEC_USER) {
292                         secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
293                         /* No raw mode with smb signing. */
294                         capabilities &= ~CAP_RAW_MODE;
295                         if (lp_server_signing() == Required)
296                                 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
297                         srv_set_signing_negotiated();
298                 } else {
299                         DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
300                         if (lp_server_signing() == Required) {
301                                 exit_server("reply_nt1: smb signing required and share level security selected.");
302                         }
303                 }
304         }
305
306         set_message(outbuf,17,0,True);
307         
308         SCVAL(outbuf,smb_vwv1,secword);
309         
310         Protocol = PROTOCOL_NT1;
311         
312         SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
313         SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
314         SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
315         SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
316         SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
317         SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
318         put_long_date(outbuf+smb_vwv11+1,t);
319         SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
320         
321         p = q = smb_buf(outbuf);
322         if (!negotiate_spnego) {
323                 /* Create a token value and add it to the outgoing packet. */
324                 if (global_encrypted_passwords_negotiated) {
325                         /* note that we do not send a challenge at all if
326                            we are using plaintext */
327                         get_challenge(p);
328                         SCVAL(outbuf,smb_vwv16+1,8);
329                         p += 8;
330                 }
331                 p += srvstr_push(outbuf, p, lp_workgroup(), -1, 
332                                  STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
333                 DEBUG(3,("not using SPNEGO\n"));
334         } else {
335                 int len = negprot_spnego(p);
336                 
337                 SCVAL(outbuf,smb_vwv16+1, 0);
338                 p += len;
339                 DEBUG(3,("using SPNEGO\n"));
340         }
341         
342         SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
343         set_message_end(outbuf, p);
344         
345         return (smb_len(outbuf)+4);
346 }
347
348 /* these are the protocol lists used for auto architecture detection:
349
350 WinNT 3.51:
351 protocol [PC NETWORK PROGRAM 1.0]
352 protocol [XENIX CORE]
353 protocol [MICROSOFT NETWORKS 1.03]
354 protocol [LANMAN1.0]
355 protocol [Windows for Workgroups 3.1a]
356 protocol [LM1.2X002]
357 protocol [LANMAN2.1]
358 protocol [NT LM 0.12]
359
360 Win95:
361 protocol [PC NETWORK PROGRAM 1.0]
362 protocol [XENIX CORE]
363 protocol [MICROSOFT NETWORKS 1.03]
364 protocol [LANMAN1.0]
365 protocol [Windows for Workgroups 3.1a]
366 protocol [LM1.2X002]
367 protocol [LANMAN2.1]
368 protocol [NT LM 0.12]
369
370 Win2K:
371 protocol [PC NETWORK PROGRAM 1.0]
372 protocol [LANMAN1.0]
373 protocol [Windows for Workgroups 3.1a]
374 protocol [LM1.2X002]
375 protocol [LANMAN2.1]
376 protocol [NT LM 0.12]
377
378 OS/2:
379 protocol [PC NETWORK PROGRAM 1.0]
380 protocol [XENIX CORE]
381 protocol [LANMAN1.0]
382 protocol [LM1.2X002]
383 protocol [LANMAN2.1]
384 */
385
386 /*
387   * Modified to recognize the architecture of the remote machine better.
388   *
389   * This appears to be the matrix of which protocol is used by which
390   * MS product.
391        Protocol                       WfWg    Win95   WinNT  Win2K  OS/2
392        PC NETWORK PROGRAM 1.0          1       1       1      1      1
393        XENIX CORE                                      2             2
394        MICROSOFT NETWORKS 3.0          2       2       
395        DOS LM1.2X002                   3       3       
396        MICROSOFT NETWORKS 1.03                         3
397        DOS LANMAN2.1                   4       4       
398        LANMAN1.0                                       4      2      3
399        Windows for Workgroups 3.1a     5       5       5      3
400        LM1.2X002                                       6      4      4
401        LANMAN2.1                                       7      5      5
402        NT LM 0.12                              6       8      6
403   *
404   *  tim@fsg.com 09/29/95
405   *  Win2K added by matty 17/7/99
406   */
407   
408 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
409 #define ARCH_WIN95    0x2
410 #define ARCH_WINNT    0x4
411 #define ARCH_WIN2K    0xC      /* Win2K is like NT */
412 #define ARCH_OS2      0x14     /* Again OS/2 is like NT */
413 #define ARCH_SAMBA    0x20
414 #define ARCH_CIFSFS   0x40
415  
416 #define ARCH_ALL      0x7F
417  
418 /* List of supported protocols, most desired first */
419 static const struct {
420         const char *proto_name;
421         const char *short_name;
422         int (*proto_reply_fn)(char *, char *);
423         int protocol_level;
424 } supported_protocols[] = {
425         {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
426         {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
427         {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
428         {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
429         {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
430         {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
431         {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
432         {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
433         {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
434         {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
435         {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
436         {NULL,NULL,NULL,0},
437 };
438
439 /****************************************************************************
440  Reply to a negprot.
441  conn POINTER CAN BE NULL HERE !
442 ****************************************************************************/
443
444 int reply_negprot(connection_struct *conn, 
445                   char *inbuf,char *outbuf, int dum_size, 
446                   int dum_buffsize)
447 {
448         int outsize = set_message(outbuf,1,0,True);
449         int Index=0;
450         int choice= -1;
451         int protocol;
452         char *p;
453         int bcc = SVAL(smb_buf(inbuf),-2);
454         int arch = ARCH_ALL;
455
456         static BOOL done_negprot = False;
457
458         START_PROFILE(SMBnegprot);
459
460         if (done_negprot) {
461                 END_PROFILE(SMBnegprot);
462                 exit_server("multiple negprot's are not permitted");
463         }
464         done_negprot = True;
465
466         p = smb_buf(inbuf)+1;
467         while (p < (smb_buf(inbuf) + bcc)) { 
468                 Index++;
469                 DEBUG(3,("Requested protocol [%s]\n",p));
470                 if (strcsequal(p,"Windows for Workgroups 3.1a"))
471                         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
472                 else if (strcsequal(p,"DOS LM1.2X002"))
473                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
474                 else if (strcsequal(p,"DOS LANMAN2.1"))
475                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
476                 else if (strcsequal(p,"NT LM 0.12"))
477                         arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
478                 else if (strcsequal(p,"LANMAN2.1"))
479                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
480                 else if (strcsequal(p,"LM1.2X002"))
481                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
482                 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
483                         arch &= ARCH_WINNT;
484                 else if (strcsequal(p,"XENIX CORE"))
485                         arch &= ( ARCH_WINNT | ARCH_OS2 );
486                 else if (strcsequal(p,"Samba")) {
487                         arch = ARCH_SAMBA;
488                         break;
489                 } else if (strcsequal(p,"POSIX 2")) {
490                         arch = ARCH_CIFSFS;
491                         break;
492                 }
493  
494                 p += strlen(p) + 2;
495         }
496
497         /* CIFSFS can send one arch only, NT LM 0.12. */
498         if (Index == 1 && (arch & ARCH_CIFSFS)) {
499                 arch = ARCH_CIFSFS;
500         }
501
502         switch ( arch ) {
503                 case ARCH_CIFSFS:
504                         set_remote_arch(RA_CIFSFS);
505                         break;
506                 case ARCH_SAMBA:
507                         set_remote_arch(RA_SAMBA);
508                         break;
509                 case ARCH_WFWG:
510                         set_remote_arch(RA_WFWG);
511                         break;
512                 case ARCH_WIN95:
513                         set_remote_arch(RA_WIN95);
514                         break;
515                 case ARCH_WINNT:
516                         if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
517                                 set_remote_arch(RA_WIN2K);
518                         else
519                                 set_remote_arch(RA_WINNT);
520                         break;
521                 case ARCH_WIN2K:
522                         set_remote_arch(RA_WIN2K);
523                         break;
524                 case ARCH_OS2:
525                         set_remote_arch(RA_OS2);
526                         break;
527                 default:
528                         set_remote_arch(RA_UNKNOWN);
529                 break;
530         }
531  
532         /* possibly reload - change of architecture */
533         reload_services(True);      
534         
535         /* moved from the netbios session setup code since we don't have that 
536            when the client connects to port 445.  Of course there is a small
537            window where we are listening to messages   -- jerry */
538
539         claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
540     
541         /* Check for protocols, most desirable first */
542         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
543                 p = smb_buf(inbuf)+1;
544                 Index = 0;
545                 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
546                                 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
547                         while (p < (smb_buf(inbuf) + bcc)) { 
548                                 if (strequal(p,supported_protocols[protocol].proto_name))
549                                         choice = Index;
550                                 Index++;
551                                 p += strlen(p) + 2;
552                         }
553                 if(choice != -1)
554                         break;
555         }
556   
557         SSVAL(outbuf,smb_vwv0,choice);
558         if(choice != -1) {
559                 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
560                 reload_services(True);          
561                 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
562                 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
563         } else {
564                 DEBUG(0,("No protocol supported !\n"));
565         }
566         SSVAL(outbuf,smb_vwv0,choice);
567   
568         DEBUG( 5, ( "negprot index=%d\n", choice ) );
569
570         if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
571                 exit_server("SMB signing is required and client negotiated a downlevel protocol");
572         }
573
574         END_PROFILE(SMBnegprot);
575         return(outsize);
576 }