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, multiple negprots are
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);
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");
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);
53 /****************************************************************************
54 Reply for the core protocol.
55 ****************************************************************************/
57 static int reply_corep(char *inbuf, char *outbuf)
59 int outsize = set_message(outbuf,1,0,True);
61 Protocol = PROTOCOL_CORE;
66 /****************************************************************************
67 Reply for the coreplus protocol.
68 ****************************************************************************/
70 static int reply_coreplus(char *inbuf, char *outbuf)
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 */
80 Protocol = PROTOCOL_COREPLUS;
85 /****************************************************************************
86 Reply for the lanman 1.0 protocol.
87 ****************************************************************************/
89 static int reply_lanman1(char *inbuf, char *outbuf)
91 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
93 time_t t = time(NULL);
95 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
97 if (lp_security()>=SEC_USER)
98 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
99 if (global_encrypted_passwords_negotiated)
100 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
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);
110 Protocol = PROTOCOL_LANMAN1;
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);
122 srv_put_dos_date(outbuf,smb_vwv8,t);
124 return (smb_len(outbuf)+4);
127 /****************************************************************************
128 Reply for the lanman 2.0 protocol.
129 ****************************************************************************/
131 static int reply_lanman2(char *inbuf, char *outbuf)
133 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
135 time_t t = time(NULL);
137 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
139 if (lp_security()>=SEC_USER)
140 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
141 if (global_encrypted_passwords_negotiated)
142 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
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());
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);
154 Protocol = PROTOCOL_LANMAN2;
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);
165 return (smb_len(outbuf)+4);
168 /****************************************************************************
169 Generate the spnego negprot reply blob. Return the number of bytes used.
170 ****************************************************************************/
172 static int negprot_spnego(char *p)
178 const char *OIDs_krb5[] = {OID_KERBEROS5,
182 const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
185 global_spnego_negotiated = True;
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);
194 /* strangely enough, NT does not sent the single OID NTLMSSP when
195 not a ADS member, it sends no OIDs at all
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)"
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
207 if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
209 /* Code for PocketPC client */
210 blob = data_blob(guid, 16);
212 /* Code for standalone WXP client */
213 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
217 char *host_princ_s = NULL;
218 name_to_fqdn(myname, global_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);
225 memcpy(p, blob.data, blob.length);
227 data_blob_free(&blob);
232 /****************************************************************************
233 Reply for the nt protocol.
234 ****************************************************************************/
236 static int reply_nt1(char *inbuf, char *outbuf)
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;
244 BOOL negotiate_spnego = False;
245 time_t t = time(NULL);
247 global_encrypted_passwords_negotiated = lp_encrypted_passwords();
249 /* do spnego in user level security if the client
250 supports it and we can do encrypted passwords */
252 if (global_encrypted_passwords_negotiated &&
253 (lp_security() != SEC_SHARE) &&
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);
264 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
266 if (lp_unix_extensions()) {
267 capabilities |= CAP_UNIX;
270 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
271 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
273 if (SMB_OFF_T_BITS == 64)
274 capabilities |= CAP_LARGE_FILES;
276 if (lp_readraw() && lp_writeraw())
277 capabilities |= CAP_RAW_MODE;
279 if (lp_nt_status_support())
280 capabilities |= CAP_STATUS32;
283 capabilities |= CAP_DFS;
285 if (lp_security() >= SEC_USER)
286 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
287 if (global_encrypted_passwords_negotiated)
288 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
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();
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.");
306 set_message(outbuf,17,0,True);
308 SCVAL(outbuf,smb_vwv1,secword);
310 Protocol = PROTOCOL_NT1;
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);
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 */
328 SCVAL(outbuf,smb_vwv16+1,8);
331 p += srvstr_push(outbuf, p, lp_workgroup(), -1,
332 STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
333 DEBUG(3,("not using SPNEGO\n"));
335 int len = negprot_spnego(p);
337 SCVAL(outbuf,smb_vwv16+1, 0);
339 DEBUG(3,("using SPNEGO\n"));
342 SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
343 set_message_end(outbuf, p);
345 return (smb_len(outbuf)+4);
348 /* these are the protocol lists used for auto architecture detection:
351 protocol [PC NETWORK PROGRAM 1.0]
352 protocol [XENIX CORE]
353 protocol [MICROSOFT NETWORKS 1.03]
355 protocol [Windows for Workgroups 3.1a]
358 protocol [NT LM 0.12]
361 protocol [PC NETWORK PROGRAM 1.0]
362 protocol [XENIX CORE]
363 protocol [MICROSOFT NETWORKS 1.03]
365 protocol [Windows for Workgroups 3.1a]
368 protocol [NT LM 0.12]
371 protocol [PC NETWORK PROGRAM 1.0]
373 protocol [Windows for Workgroups 3.1a]
376 protocol [NT LM 0.12]
379 protocol [PC NETWORK PROGRAM 1.0]
380 protocol [XENIX CORE]
387 * Modified to recognize the architecture of the remote machine better.
389 * This appears to be the matrix of which protocol is used by which
391 Protocol WfWg Win95 WinNT Win2K OS/2
392 PC NETWORK PROGRAM 1.0 1 1 1 1 1
394 MICROSOFT NETWORKS 3.0 2 2
396 MICROSOFT NETWORKS 1.03 3
399 Windows for Workgroups 3.1a 5 5 5 3
404 * tim@fsg.com 09/29/95
405 * Win2K added by matty 17/7/99
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
416 #define ARCH_ALL 0x7F
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 *);
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},
439 /****************************************************************************
441 conn POINTER CAN BE NULL HERE !
442 ****************************************************************************/
444 int reply_negprot(connection_struct *conn,
445 char *inbuf,char *outbuf, int dum_size,
448 int outsize = set_message(outbuf,1,0,True);
453 int bcc = SVAL(smb_buf(inbuf),-2);
456 static BOOL done_negprot = False;
458 START_PROFILE(SMBnegprot);
461 END_PROFILE(SMBnegprot);
462 exit_server("multiple negprot's are not permitted");
466 p = smb_buf(inbuf)+1;
467 while (p < (smb_buf(inbuf) + bcc)) {
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"))
484 else if (strcsequal(p,"XENIX CORE"))
485 arch &= ( ARCH_WINNT | ARCH_OS2 );
486 else if (strcsequal(p,"Samba")) {
489 } else if (strcsequal(p,"POSIX 2")) {
497 /* CIFSFS can send one arch only, NT LM 0.12. */
498 if (Index == 1 && (arch & ARCH_CIFSFS)) {
504 set_remote_arch(RA_CIFSFS);
507 set_remote_arch(RA_SAMBA);
510 set_remote_arch(RA_WFWG);
513 set_remote_arch(RA_WIN95);
516 if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
517 set_remote_arch(RA_WIN2K);
519 set_remote_arch(RA_WINNT);
522 set_remote_arch(RA_WIN2K);
525 set_remote_arch(RA_OS2);
528 set_remote_arch(RA_UNKNOWN);
532 /* possibly reload - change of architecture */
533 reload_services(True);
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 */
539 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
541 /* Check for protocols, most desirable first */
542 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
543 p = smb_buf(inbuf)+1;
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))
557 SSVAL(outbuf,smb_vwv0,choice);
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));
564 DEBUG(0,("No protocol supported !\n"));
566 SSVAL(outbuf,smb_vwv0,choice);
568 DEBUG( 5, ( "negprot index=%d\n", choice ) );
570 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
571 exit_server("SMB signing is required and client negotiated a downlevel protocol");
574 END_PROFILE(SMBnegprot);