2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
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.
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.
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.
23 extern fstring remote_proto;
24 extern enum protocol_types Protocol;
27 BOOL global_encrypted_passwords_negotiated = False;
28 BOOL global_spnego_negotiated = False;
29 struct auth_context *negprot_global_auth_context = NULL;
31 static void get_challenge(char buff[8])
34 const uint8 *cryptkey;
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);
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");
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);
52 /****************************************************************************
53 Reply for the core protocol.
54 ****************************************************************************/
56 static int reply_corep(char *inbuf, char *outbuf)
58 int outsize = set_message(outbuf,1,0,True);
60 Protocol = PROTOCOL_CORE;
65 /****************************************************************************
66 Reply for the coreplus protocol.
67 ****************************************************************************/
69 static int reply_coreplus(char *inbuf, char *outbuf)
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 */
79 Protocol = PROTOCOL_COREPLUS;
84 /****************************************************************************
85 Reply for the lanman 1.0 protocol.
86 ****************************************************************************/
88 static int reply_lanman1(char *inbuf, char *outbuf)
90 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
92 time_t t = time(NULL);
94 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
96 if (lp_security()>=SEC_USER)
97 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
98 if (global_encrypted_passwords_negotiated)
99 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
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);
109 Protocol = PROTOCOL_LANMAN1;
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);
121 srv_put_dos_date(outbuf,smb_vwv8,t);
123 return (smb_len(outbuf)+4);
126 /****************************************************************************
127 Reply for the lanman 2.0 protocol.
128 ****************************************************************************/
130 static int reply_lanman2(char *inbuf, char *outbuf)
132 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
134 time_t t = time(NULL);
136 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
138 if (lp_security()>=SEC_USER)
139 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
140 if (global_encrypted_passwords_negotiated)
141 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
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());
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);
153 Protocol = PROTOCOL_LANMAN2;
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);
164 return (smb_len(outbuf)+4);
167 /****************************************************************************
168 Generate the spnego negprot reply blob. Return the number of bytes used.
169 ****************************************************************************/
171 static int negprot_spnego(char *p, uint8 *pkeylen)
177 const char *OIDs_krb5[] = {OID_KERBEROS5,
183 global_spnego_negotiated = True;
187 safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
188 strlower_m(unix_name);
189 push_ascii_nstring(dos_name, unix_name);
190 safe_strcpy(guid, dos_name, sizeof(guid)-1);
193 /* valgrind fixer... */
195 size_t sl = strlen(guid);
197 memset(&guid[sl], '\0', sizeof(guid)-sl);
201 /* strangely enough, NT does not sent the single OID NTLMSSP when
202 not a ADS member, it sends no OIDs at all
204 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
205 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
207 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
208 back to doing what W2K3 does here. This is needed to make PocketPC 2003
209 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
214 if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
220 char *host_princ_s = NULL;
221 name_to_fqdn(myname, global_myname());
223 asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
224 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
225 SAFE_FREE(host_princ_s);
227 memcpy(p, blob.data, blob.length);
230 DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len));
234 data_blob_free(&blob);
238 /****************************************************************************
239 Reply for the nt protocol.
240 ****************************************************************************/
242 static int reply_nt1(char *inbuf, char *outbuf)
244 /* dual names + lock_and_read + nt SMBs + remote API calls */
245 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
246 CAP_LEVEL_II_OPLOCKS;
250 BOOL negotiate_spnego = False;
251 time_t t = time(NULL);
253 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
255 /* do spnego in user level security if the client
256 supports it and we can do encrypted passwords */
258 if (global_encrypted_passwords_negotiated &&
259 (lp_security() != SEC_SHARE) &&
261 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
262 negotiate_spnego = True;
263 capabilities |= CAP_EXTENDED_SECURITY;
264 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
265 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
266 partially constructed. */
267 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
270 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
272 if (lp_unix_extensions()) {
273 capabilities |= CAP_UNIX;
276 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
277 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
279 if (SMB_OFF_T_BITS == 64)
280 capabilities |= CAP_LARGE_FILES;
282 if (lp_readraw() && lp_writeraw())
283 capabilities |= CAP_RAW_MODE;
285 if (lp_nt_status_support())
286 capabilities |= CAP_STATUS32;
289 capabilities |= CAP_DFS;
291 if (lp_security() >= SEC_USER)
292 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
293 if (global_encrypted_passwords_negotiated)
294 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
296 if (lp_server_signing()) {
297 if (lp_security() >= SEC_USER) {
298 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
299 /* No raw mode with smb signing. */
300 capabilities &= ~CAP_RAW_MODE;
301 if (lp_server_signing() == Required)
302 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
303 srv_set_signing_negotiated();
305 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
306 if (lp_server_signing() == Required) {
307 exit_server("reply_nt1: smb signing required and share level security selected.");
312 set_message(outbuf,17,0,True);
314 SCVAL(outbuf,smb_vwv1,secword);
316 Protocol = PROTOCOL_NT1;
318 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
319 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
320 SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
321 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
322 SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
323 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
324 put_long_date(outbuf+smb_vwv11+1,t);
325 SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
327 p = q = smb_buf(outbuf);
328 if (!negotiate_spnego) {
329 /* Create a token value and add it to the outgoing packet. */
330 if (global_encrypted_passwords_negotiated) {
331 /* note that we do not send a challenge at all if
332 we are using plaintext */
334 SCVAL(outbuf,smb_vwv16+1,8);
337 p += srvstr_push(outbuf, p, lp_workgroup(), -1,
338 STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
339 DEBUG(3,("not using SPNEGO\n"));
342 int len = negprot_spnego(p, &keylen);
344 SCVAL(outbuf,smb_vwv16+1,keylen);
346 DEBUG(3,("using SPNEGO\n"));
349 SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
350 set_message_end(outbuf, p);
352 return (smb_len(outbuf)+4);
355 /* these are the protocol lists used for auto architecture detection:
358 protocol [PC NETWORK PROGRAM 1.0]
359 protocol [XENIX CORE]
360 protocol [MICROSOFT NETWORKS 1.03]
362 protocol [Windows for Workgroups 3.1a]
365 protocol [NT LM 0.12]
368 protocol [PC NETWORK PROGRAM 1.0]
369 protocol [XENIX CORE]
370 protocol [MICROSOFT NETWORKS 1.03]
372 protocol [Windows for Workgroups 3.1a]
375 protocol [NT LM 0.12]
378 protocol [PC NETWORK PROGRAM 1.0]
380 protocol [Windows for Workgroups 3.1a]
383 protocol [NT LM 0.12]
386 protocol [PC NETWORK PROGRAM 1.0]
387 protocol [XENIX CORE]
394 * Modified to recognize the architecture of the remote machine better.
396 * This appears to be the matrix of which protocol is used by which
398 Protocol WfWg Win95 WinNT Win2K OS/2
399 PC NETWORK PROGRAM 1.0 1 1 1 1 1
401 MICROSOFT NETWORKS 3.0 2 2
403 MICROSOFT NETWORKS 1.03 3
406 Windows for Workgroups 3.1a 5 5 5 3
411 * tim@fsg.com 09/29/95
412 * Win2K added by matty 17/7/99
415 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
416 #define ARCH_WIN95 0x2
417 #define ARCH_WINNT 0x4
418 #define ARCH_WIN2K 0xC /* Win2K is like NT */
419 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
420 #define ARCH_SAMBA 0x20
421 #define ARCH_CIFSFS 0x40
423 #define ARCH_ALL 0x7F
425 /* List of supported protocols, most desired first */
426 static const struct {
427 const char *proto_name;
428 const char *short_name;
429 int (*proto_reply_fn)(char *, char *);
431 } supported_protocols[] = {
432 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
433 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
434 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
435 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
436 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
437 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
438 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
439 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
440 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
441 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
442 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
446 /****************************************************************************
448 ****************************************************************************/
450 int reply_negprot(connection_struct *conn,
451 char *inbuf,char *outbuf, int dum_size,
454 int outsize = set_message(outbuf,1,0,True);
459 int bcc = SVAL(smb_buf(inbuf),-2);
462 static BOOL done_negprot = False;
464 START_PROFILE(SMBnegprot);
467 END_PROFILE(SMBnegprot);
468 exit_server("multiple negprot's are not permitted");
472 p = smb_buf(inbuf)+1;
473 while (p < (smb_buf(inbuf) + bcc)) {
475 DEBUG(3,("Requested protocol [%s]\n",p));
476 if (strcsequal(p,"Windows for Workgroups 3.1a"))
477 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
478 else if (strcsequal(p,"DOS LM1.2X002"))
479 arch &= ( ARCH_WFWG | ARCH_WIN95 );
480 else if (strcsequal(p,"DOS LANMAN2.1"))
481 arch &= ( ARCH_WFWG | ARCH_WIN95 );
482 else if (strcsequal(p,"NT LM 0.12"))
483 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
484 else if (strcsequal(p,"LANMAN2.1"))
485 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
486 else if (strcsequal(p,"LM1.2X002"))
487 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
488 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
490 else if (strcsequal(p,"XENIX CORE"))
491 arch &= ( ARCH_WINNT | ARCH_OS2 );
492 else if (strcsequal(p,"Samba")) {
495 } else if (strcsequal(p,"POSIX 2")) {
503 /* CIFSFS can send one arch only, NT LM 0.12. */
504 if (Index == 1 && (arch & ARCH_CIFSFS)) {
510 set_remote_arch(RA_CIFSFS);
513 set_remote_arch(RA_SAMBA);
516 set_remote_arch(RA_WFWG);
519 set_remote_arch(RA_WIN95);
522 if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
523 set_remote_arch(RA_WIN2K);
525 set_remote_arch(RA_WINNT);
528 set_remote_arch(RA_WIN2K);
531 set_remote_arch(RA_OS2);
534 set_remote_arch(RA_UNKNOWN);
538 /* possibly reload - change of architecture */
539 reload_services(True);
541 /* moved from the netbios session setup code since we don't have that
542 when the client connects to port 445. Of course there is a small
543 window where we are listening to messages -- jerry */
545 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
547 /* Check for protocols, most desirable first */
548 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
549 p = smb_buf(inbuf)+1;
551 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
552 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
553 while (p < (smb_buf(inbuf) + bcc)) {
554 if (strequal(p,supported_protocols[protocol].proto_name))
563 SSVAL(outbuf,smb_vwv0,choice);
565 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
566 reload_services(True);
567 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
568 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
570 DEBUG(0,("No protocol supported !\n"));
572 SSVAL(outbuf,smb_vwv0,choice);
574 DEBUG( 5, ( "negprot index=%d\n", choice ) );
576 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
577 exit_server("SMB signing is required and client negotiated a downlevel protocol");
580 END_PROFILE(SMBnegprot);