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 3 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, see <http://www.gnu.org/licenses/>.
22 extern fstring remote_proto;
23 extern enum protocol_types Protocol;
26 BOOL global_encrypted_passwords_negotiated = False;
27 BOOL global_spnego_negotiated = False;
28 struct auth_context *negprot_global_auth_context = NULL;
30 static void get_challenge(char buff[8])
33 const uint8 *cryptkey;
35 /* We might be called more than once, multiple negprots are
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!");
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(inbuf,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(inbuf,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(inbuf,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(inbuf,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 DATA_BLOB negprot_spnego(void)
180 const char *OIDs_krb5[] = {OID_KERBEROS5,
184 const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
186 global_spnego_negotiated = True;
188 memset(guid, '\0', sizeof(guid));
190 safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
191 strlower_m(unix_name);
192 push_ascii_nstring(dos_name, unix_name);
193 safe_strcpy(guid, dos_name, sizeof(guid)-1);
196 /* Fix valgrind 'uninitialized bytes' issue. */
197 slen = strlen(dos_name);
198 if (slen < sizeof(guid)) {
199 memset(guid+slen, '\0', sizeof(guid) - slen);
203 /* strangely enough, NT does not sent the single OID NTLMSSP when
204 not a ADS member, it sends no OIDs at all
206 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
207 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
209 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
210 back to doing what W2K3 does here. This is needed to make PocketPC 2003
211 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
216 if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
218 /* Code for PocketPC client */
219 blob = data_blob(guid, 16);
221 /* Code for standalone WXP client */
222 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
226 char *host_princ_s = NULL;
227 name_to_fqdn(myname, global_myname());
229 asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
230 if (host_princ_s == NULL) {
231 blob = data_blob_null;
234 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
235 SAFE_FREE(host_princ_s);
241 /****************************************************************************
242 Reply for the nt protocol.
243 ****************************************************************************/
245 static int reply_nt1(char *inbuf, char *outbuf)
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;
253 BOOL negotiate_spnego = False;
254 time_t t = time(NULL);
256 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
258 /* Check the flags field to see if this is Vista.
259 WinXP sets it and Vista does not. But we have to
260 distinguish from NT which doesn't set it either. */
262 if ( (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY) &&
263 ((SVAL(inbuf, smb_flg2) & FLAGS2_UNKNOWN_BIT4) == 0) )
265 if (get_remote_arch() != RA_SAMBA) {
266 set_remote_arch( RA_VISTA );
270 /* do spnego in user level security if the client
271 supports it and we can do encrypted passwords */
273 if (global_encrypted_passwords_negotiated &&
274 (lp_security() != SEC_SHARE) &&
276 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
277 negotiate_spnego = True;
278 capabilities |= CAP_EXTENDED_SECURITY;
279 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
280 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
281 partially constructed. */
282 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
285 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
287 if (lp_unix_extensions()) {
288 capabilities |= CAP_UNIX;
291 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
292 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
294 if (SMB_OFF_T_BITS == 64)
295 capabilities |= CAP_LARGE_FILES;
297 if (lp_readraw() && lp_writeraw())
298 capabilities |= CAP_RAW_MODE;
300 if (lp_nt_status_support())
301 capabilities |= CAP_STATUS32;
304 capabilities |= CAP_DFS;
306 if (lp_security() >= SEC_USER)
307 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
308 if (global_encrypted_passwords_negotiated)
309 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
311 if (lp_server_signing()) {
312 if (lp_security() >= SEC_USER) {
313 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
314 /* No raw mode with smb signing. */
315 capabilities &= ~CAP_RAW_MODE;
316 if (lp_server_signing() == Required)
317 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
318 srv_set_signing_negotiated();
320 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
321 if (lp_server_signing() == Required) {
322 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
327 set_message(inbuf,outbuf,17,0,True);
329 SCVAL(outbuf,smb_vwv1,secword);
331 Protocol = PROTOCOL_NT1;
333 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
334 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
335 SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
336 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
337 SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
338 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
339 put_long_date(outbuf+smb_vwv11+1,t);
340 SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
342 p = q = smb_buf(outbuf);
343 if (!negotiate_spnego) {
344 /* Create a token value and add it to the outgoing packet. */
345 if (global_encrypted_passwords_negotiated) {
346 /* note that we do not send a challenge at all if
347 we are using plaintext */
349 SCVAL(outbuf,smb_vwv16+1,8);
352 p += srvstr_push(outbuf, p, lp_workgroup(), -1,
353 STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
354 DEBUG(3,("not using SPNEGO\n"));
356 DATA_BLOB spnego_blob = negprot_spnego();
358 if (spnego_blob.data == NULL) {
359 return ERROR_NT(NT_STATUS_NO_MEMORY);
362 memcpy(p, spnego_blob.data, spnego_blob.length);
363 p += spnego_blob.length;
364 data_blob_free(&spnego_blob);
366 SCVAL(outbuf,smb_vwv16+1, 0);
367 DEBUG(3,("using SPNEGO\n"));
370 SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
371 set_message_end(inbuf,outbuf, p);
373 return (smb_len(outbuf)+4);
376 /* these are the protocol lists used for auto architecture detection:
379 protocol [PC NETWORK PROGRAM 1.0]
380 protocol [XENIX CORE]
381 protocol [MICROSOFT NETWORKS 1.03]
383 protocol [Windows for Workgroups 3.1a]
386 protocol [NT LM 0.12]
389 protocol [PC NETWORK PROGRAM 1.0]
390 protocol [XENIX CORE]
391 protocol [MICROSOFT NETWORKS 1.03]
393 protocol [Windows for Workgroups 3.1a]
396 protocol [NT LM 0.12]
399 protocol [PC NETWORK PROGRAM 1.0]
401 protocol [Windows for Workgroups 3.1a]
404 protocol [NT LM 0.12]
407 protocol [PC NETWORK PROGRAM 1.0]
409 protocol [Windows for Workgroups 3.1a]
412 protocol [NT LM 0.12]
416 protocol [PC NETWORK PROGRAM 1.0]
417 protocol [XENIX CORE]
424 * Modified to recognize the architecture of the remote machine better.
426 * This appears to be the matrix of which protocol is used by which
428 Protocol WfWg Win95 WinNT Win2K OS/2 Vista
429 PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
431 MICROSOFT NETWORKS 3.0 2 2
433 MICROSOFT NETWORKS 1.03 3
436 Windows for Workgroups 3.1a 5 5 5 3 3
442 * tim@fsg.com 09/29/95
443 * Win2K added by matty 17/7/99
446 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
447 #define ARCH_WIN95 0x2
448 #define ARCH_WINNT 0x4
449 #define ARCH_WIN2K 0xC /* Win2K is like NT */
450 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
451 #define ARCH_SAMBA 0x20
452 #define ARCH_CIFSFS 0x40
453 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */
455 #define ARCH_ALL 0x7F
457 /* List of supported protocols, most desired first */
458 static const struct {
459 const char *proto_name;
460 const char *short_name;
461 int (*proto_reply_fn)(char *, char *);
463 } supported_protocols[] = {
464 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
465 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
466 {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
467 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
468 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
469 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
470 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
471 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
472 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
473 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
474 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
478 /****************************************************************************
480 conn POINTER CAN BE NULL HERE !
481 ****************************************************************************/
483 int reply_negprot(connection_struct *conn,
484 char *inbuf,char *outbuf, int size,
487 int outsize = set_message(inbuf,outbuf,1,0,True);
496 static BOOL done_negprot = False;
498 START_PROFILE(SMBnegprot);
501 END_PROFILE(SMBnegprot);
502 exit_server_cleanly("multiple negprot's are not permitted");
506 if (inbuf[size-1] != '\0') {
507 DEBUG(0, ("negprot protocols not 0-terminated\n"));
508 END_PROFILE(SMBnegprot);
509 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
512 p = smb_buf(inbuf)+1;
517 while (smb_bufrem(inbuf, p) > 0) {
520 tmp = TALLOC_REALLOC_ARRAY(tmp_talloc_ctx(), cliprotos, char *,
523 DEBUG(0, ("talloc failed\n"));
524 TALLOC_FREE(cliprotos);
525 END_PROFILE(SMBnegprot);
526 return ERROR_NT(NT_STATUS_NO_MEMORY);
531 if (pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p)
533 DEBUG(0, ("pull_ascii_talloc failed\n"));
534 TALLOC_FREE(cliprotos);
535 END_PROFILE(SMBnegprot);
536 return ERROR_NT(NT_STATUS_NO_MEMORY);
539 DEBUG(3, ("Requested protocol [%s]\n",
540 cliprotos[num_cliprotos]));
546 for (i=0; i<num_cliprotos; i++) {
547 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a"))
548 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT
550 else if (strcsequal(cliprotos[i], "DOS LM1.2X002"))
551 arch &= ( ARCH_WFWG | ARCH_WIN95 );
552 else if (strcsequal(cliprotos[i], "DOS LANMAN2.1"))
553 arch &= ( ARCH_WFWG | ARCH_WIN95 );
554 else if (strcsequal(cliprotos[i], "NT LM 0.12"))
555 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
557 else if (strcsequal(cliprotos[i], "SMB 2.001"))
559 else if (strcsequal(cliprotos[i], "LANMAN2.1"))
560 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
561 else if (strcsequal(cliprotos[i], "LM1.2X002"))
562 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
563 else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03"))
565 else if (strcsequal(cliprotos[i], "XENIX CORE"))
566 arch &= ( ARCH_WINNT | ARCH_OS2 );
567 else if (strcsequal(cliprotos[i], "Samba")) {
570 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
576 /* CIFSFS can send one arch only, NT LM 0.12. */
577 if (i == 1 && (arch & ARCH_CIFSFS)) {
583 set_remote_arch(RA_CIFSFS);
586 set_remote_arch(RA_SAMBA);
589 set_remote_arch(RA_WFWG);
592 set_remote_arch(RA_WIN95);
595 if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
596 set_remote_arch(RA_WIN2K);
598 set_remote_arch(RA_WINNT);
601 /* Vista may have been set in the negprot so don't
603 if ( get_remote_arch() != RA_VISTA )
604 set_remote_arch(RA_WIN2K);
607 set_remote_arch(RA_VISTA);
610 set_remote_arch(RA_OS2);
613 set_remote_arch(RA_UNKNOWN);
617 /* possibly reload - change of architecture */
618 reload_services(True);
620 /* moved from the netbios session setup code since we don't have that
621 when the client connects to port 445. Of course there is a small
622 window where we are listening to messages -- jerry */
625 NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
627 /* Check for protocols, most desirable first */
628 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
630 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
631 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
632 while (i < num_cliprotos) {
633 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name))
641 SSVAL(outbuf,smb_vwv0,choice);
643 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
644 reload_services(True);
645 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
646 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
648 DEBUG(0,("No protocol supported !\n"));
650 SSVAL(outbuf,smb_vwv0,choice);
652 DEBUG( 5, ( "negprot index=%d\n", choice ) );
654 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
655 exit_server_cleanly("SMB signing is required and "
656 "client negotiated a downlevel protocol");
659 TALLOC_FREE(cliprotos);
660 END_PROFILE(SMBnegprot);