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