4362bb5467121b3fcb5ce21fff5d522a251cf088
[kai/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, uint8 *pkeylen)
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         if (len > 256) {
228                 DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len));
229                 len = 255;
230         }
231         data_blob_free(&blob);
232
233         if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
234                 *pkeylen = 0;
235         } else {
236                 *pkeylen = len;
237         }
238         return len;
239 }
240
241 /****************************************************************************
242  Reply for the nt protocol.
243 ****************************************************************************/
244
245 static int reply_nt1(char *inbuf, char *outbuf)
246 {
247         /* dual names + lock_and_read + nt SMBs + remote API calls */
248         int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
249                 CAP_LEVEL_II_OPLOCKS;
250
251         int secword=0;
252         char *p, *q;
253         BOOL negotiate_spnego = False;
254         time_t t = time(NULL);
255
256         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
257
258         /* do spnego in user level security if the client
259            supports it and we can do encrypted passwords */
260         
261         if (global_encrypted_passwords_negotiated && 
262             (lp_security() != SEC_SHARE) &&
263             lp_use_spnego() &&
264             (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
265                 negotiate_spnego = True;
266                 capabilities |= CAP_EXTENDED_SECURITY;
267                 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
268                 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
269                         partially constructed. */
270                 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
271         }
272         
273         capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
274
275         if (lp_unix_extensions()) {
276                 capabilities |= CAP_UNIX;
277         }
278         
279         if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
280                 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
281         
282         if (SMB_OFF_T_BITS == 64)
283                 capabilities |= CAP_LARGE_FILES;
284
285         if (lp_readraw() && lp_writeraw())
286                 capabilities |= CAP_RAW_MODE;
287         
288         if (lp_nt_status_support())
289                 capabilities |= CAP_STATUS32;
290         
291         if (lp_host_msdfs())
292                 capabilities |= CAP_DFS;
293         
294         if (lp_security() >= SEC_USER)
295                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
296         if (global_encrypted_passwords_negotiated)
297                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
298         
299         if (lp_server_signing()) {
300                 if (lp_security() >= SEC_USER) {
301                         secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
302                         /* No raw mode with smb signing. */
303                         capabilities &= ~CAP_RAW_MODE;
304                         if (lp_server_signing() == Required)
305                                 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
306                         srv_set_signing_negotiated();
307                 } else {
308                         DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
309                         if (lp_server_signing() == Required) {
310                                 exit_server("reply_nt1: smb signing required and share level security selected.");
311                         }
312                 }
313         }
314
315         set_message(outbuf,17,0,True);
316         
317         SCVAL(outbuf,smb_vwv1,secword);
318         
319         Protocol = PROTOCOL_NT1;
320         
321         SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
322         SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
323         SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
324         SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
325         SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
326         SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
327         put_long_date(outbuf+smb_vwv11+1,t);
328         SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
329         
330         p = q = smb_buf(outbuf);
331         if (!negotiate_spnego) {
332                 /* Create a token value and add it to the outgoing packet. */
333                 if (global_encrypted_passwords_negotiated) {
334                         /* note that we do not send a challenge at all if
335                            we are using plaintext */
336                         get_challenge(p);
337                         SCVAL(outbuf,smb_vwv16+1,8);
338                         p += 8;
339                 }
340                 p += srvstr_push(outbuf, p, lp_workgroup(), -1, 
341                                  STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
342                 DEBUG(3,("not using SPNEGO\n"));
343         } else {
344                 uint8 keylen;
345                 int len = negprot_spnego(p, &keylen);
346                 
347                 SCVAL(outbuf,smb_vwv16+1,keylen);
348                 p += len;
349                 DEBUG(3,("using SPNEGO\n"));
350         }
351         
352         SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
353         set_message_end(outbuf, p);
354         
355         return (smb_len(outbuf)+4);
356 }
357
358 /* these are the protocol lists used for auto architecture detection:
359
360 WinNT 3.51:
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 Win95:
371 protocol [PC NETWORK PROGRAM 1.0]
372 protocol [XENIX CORE]
373 protocol [MICROSOFT NETWORKS 1.03]
374 protocol [LANMAN1.0]
375 protocol [Windows for Workgroups 3.1a]
376 protocol [LM1.2X002]
377 protocol [LANMAN2.1]
378 protocol [NT LM 0.12]
379
380 Win2K:
381 protocol [PC NETWORK PROGRAM 1.0]
382 protocol [LANMAN1.0]
383 protocol [Windows for Workgroups 3.1a]
384 protocol [LM1.2X002]
385 protocol [LANMAN2.1]
386 protocol [NT LM 0.12]
387
388 OS/2:
389 protocol [PC NETWORK PROGRAM 1.0]
390 protocol [XENIX CORE]
391 protocol [LANMAN1.0]
392 protocol [LM1.2X002]
393 protocol [LANMAN2.1]
394 */
395
396 /*
397   * Modified to recognize the architecture of the remote machine better.
398   *
399   * This appears to be the matrix of which protocol is used by which
400   * MS product.
401        Protocol                       WfWg    Win95   WinNT  Win2K  OS/2
402        PC NETWORK PROGRAM 1.0          1       1       1      1      1
403        XENIX CORE                                      2             2
404        MICROSOFT NETWORKS 3.0          2       2       
405        DOS LM1.2X002                   3       3       
406        MICROSOFT NETWORKS 1.03                         3
407        DOS LANMAN2.1                   4       4       
408        LANMAN1.0                                       4      2      3
409        Windows for Workgroups 3.1a     5       5       5      3
410        LM1.2X002                                       6      4      4
411        LANMAN2.1                                       7      5      5
412        NT LM 0.12                              6       8      6
413   *
414   *  tim@fsg.com 09/29/95
415   *  Win2K added by matty 17/7/99
416   */
417   
418 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
419 #define ARCH_WIN95    0x2
420 #define ARCH_WINNT    0x4
421 #define ARCH_WIN2K    0xC      /* Win2K is like NT */
422 #define ARCH_OS2      0x14     /* Again OS/2 is like NT */
423 #define ARCH_SAMBA    0x20
424 #define ARCH_CIFSFS   0x40
425  
426 #define ARCH_ALL      0x7F
427  
428 /* List of supported protocols, most desired first */
429 static const struct {
430         const char *proto_name;
431         const char *short_name;
432         int (*proto_reply_fn)(char *, char *);
433         int protocol_level;
434 } supported_protocols[] = {
435         {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
436         {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
437         {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
438         {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
439         {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
440         {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
441         {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
442         {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
443         {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
444         {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
445         {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
446         {NULL,NULL,NULL,0},
447 };
448
449 /****************************************************************************
450  Reply to a negprot.
451  conn POINTER CAN BE NULL HERE !
452 ****************************************************************************/
453
454 int reply_negprot(connection_struct *conn, 
455                   char *inbuf,char *outbuf, int dum_size, 
456                   int dum_buffsize)
457 {
458         int outsize = set_message(outbuf,1,0,True);
459         int Index=0;
460         int choice= -1;
461         int protocol;
462         char *p;
463         int bcc = SVAL(smb_buf(inbuf),-2);
464         int arch = ARCH_ALL;
465
466         static BOOL done_negprot = False;
467
468         START_PROFILE(SMBnegprot);
469
470         if (done_negprot) {
471                 END_PROFILE(SMBnegprot);
472                 exit_server("multiple negprot's are not permitted");
473         }
474         done_negprot = True;
475
476         p = smb_buf(inbuf)+1;
477         while (p < (smb_buf(inbuf) + bcc)) { 
478                 Index++;
479                 DEBUG(3,("Requested protocol [%s]\n",p));
480                 if (strcsequal(p,"Windows for Workgroups 3.1a"))
481                         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
482                 else if (strcsequal(p,"DOS LM1.2X002"))
483                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
484                 else if (strcsequal(p,"DOS LANMAN2.1"))
485                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
486                 else if (strcsequal(p,"NT LM 0.12"))
487                         arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
488                 else if (strcsequal(p,"LANMAN2.1"))
489                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
490                 else if (strcsequal(p,"LM1.2X002"))
491                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
492                 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
493                         arch &= ARCH_WINNT;
494                 else if (strcsequal(p,"XENIX CORE"))
495                         arch &= ( ARCH_WINNT | ARCH_OS2 );
496                 else if (strcsequal(p,"Samba")) {
497                         arch = ARCH_SAMBA;
498                         break;
499                 } else if (strcsequal(p,"POSIX 2")) {
500                         arch = ARCH_CIFSFS;
501                         break;
502                 }
503  
504                 p += strlen(p) + 2;
505         }
506
507         /* CIFSFS can send one arch only, NT LM 0.12. */
508         if (Index == 1 && (arch & ARCH_CIFSFS)) {
509                 arch = ARCH_CIFSFS;
510         }
511
512         switch ( arch ) {
513                 case ARCH_CIFSFS:
514                         set_remote_arch(RA_CIFSFS);
515                         break;
516                 case ARCH_SAMBA:
517                         set_remote_arch(RA_SAMBA);
518                         break;
519                 case ARCH_WFWG:
520                         set_remote_arch(RA_WFWG);
521                         break;
522                 case ARCH_WIN95:
523                         set_remote_arch(RA_WIN95);
524                         break;
525                 case ARCH_WINNT:
526                         if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
527                                 set_remote_arch(RA_WIN2K);
528                         else
529                                 set_remote_arch(RA_WINNT);
530                         break;
531                 case ARCH_WIN2K:
532                         set_remote_arch(RA_WIN2K);
533                         break;
534                 case ARCH_OS2:
535                         set_remote_arch(RA_OS2);
536                         break;
537                 default:
538                         set_remote_arch(RA_UNKNOWN);
539                 break;
540         }
541  
542         /* possibly reload - change of architecture */
543         reload_services(True);      
544         
545         /* moved from the netbios session setup code since we don't have that 
546            when the client connects to port 445.  Of course there is a small
547            window where we are listening to messages   -- jerry */
548
549         claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
550     
551         /* Check for protocols, most desirable first */
552         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
553                 p = smb_buf(inbuf)+1;
554                 Index = 0;
555                 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
556                                 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
557                         while (p < (smb_buf(inbuf) + bcc)) { 
558                                 if (strequal(p,supported_protocols[protocol].proto_name))
559                                         choice = Index;
560                                 Index++;
561                                 p += strlen(p) + 2;
562                         }
563                 if(choice != -1)
564                         break;
565         }
566   
567         SSVAL(outbuf,smb_vwv0,choice);
568         if(choice != -1) {
569                 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
570                 reload_services(True);          
571                 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
572                 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
573         } else {
574                 DEBUG(0,("No protocol supported !\n"));
575         }
576         SSVAL(outbuf,smb_vwv0,choice);
577   
578         DEBUG( 5, ( "negprot index=%d\n", choice ) );
579
580         if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
581                 exit_server("SMB signing is required and client negotiated a downlevel protocol");
582         }
583
584         END_PROFILE(SMBnegprot);
585         return(outsize);
586 }