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, uint8 *pkeylen)
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);
228 DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len));
231 data_blob_free(&blob);
233 if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
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 /* do spnego in user level security if the client
259 supports it and we can do encrypted passwords */
261 if (global_encrypted_passwords_negotiated &&
262 (lp_security() != SEC_SHARE) &&
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);
273 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
275 if (lp_unix_extensions()) {
276 capabilities |= CAP_UNIX;
279 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
280 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
282 if (SMB_OFF_T_BITS == 64)
283 capabilities |= CAP_LARGE_FILES;
285 if (lp_readraw() && lp_writeraw())
286 capabilities |= CAP_RAW_MODE;
288 if (lp_nt_status_support())
289 capabilities |= CAP_STATUS32;
292 capabilities |= CAP_DFS;
294 if (lp_security() >= SEC_USER)
295 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
296 if (global_encrypted_passwords_negotiated)
297 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
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();
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.");
315 set_message(outbuf,17,0,True);
317 SCVAL(outbuf,smb_vwv1,secword);
319 Protocol = PROTOCOL_NT1;
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);
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 */
337 SCVAL(outbuf,smb_vwv16+1,8);
340 p += srvstr_push(outbuf, p, lp_workgroup(), -1,
341 STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
342 DEBUG(3,("not using SPNEGO\n"));
345 int len = negprot_spnego(p, &keylen);
347 SCVAL(outbuf,smb_vwv16+1,keylen);
349 DEBUG(3,("using SPNEGO\n"));
352 SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
353 set_message_end(outbuf, p);
355 return (smb_len(outbuf)+4);
358 /* these are the protocol lists used for auto architecture detection:
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]
372 protocol [XENIX CORE]
373 protocol [MICROSOFT NETWORKS 1.03]
375 protocol [Windows for Workgroups 3.1a]
378 protocol [NT LM 0.12]
381 protocol [PC NETWORK PROGRAM 1.0]
383 protocol [Windows for Workgroups 3.1a]
386 protocol [NT LM 0.12]
389 protocol [PC NETWORK PROGRAM 1.0]
390 protocol [XENIX CORE]
397 * Modified to recognize the architecture of the remote machine better.
399 * This appears to be the matrix of which protocol is used by which
401 Protocol WfWg Win95 WinNT Win2K OS/2
402 PC NETWORK PROGRAM 1.0 1 1 1 1 1
404 MICROSOFT NETWORKS 3.0 2 2
406 MICROSOFT NETWORKS 1.03 3
409 Windows for Workgroups 3.1a 5 5 5 3
414 * tim@fsg.com 09/29/95
415 * Win2K added by matty 17/7/99
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
426 #define ARCH_ALL 0x7F
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 *);
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},
449 /****************************************************************************
451 conn POINTER CAN BE NULL HERE !
452 ****************************************************************************/
454 int reply_negprot(connection_struct *conn,
455 char *inbuf,char *outbuf, int dum_size,
458 int outsize = set_message(outbuf,1,0,True);
463 int bcc = SVAL(smb_buf(inbuf),-2);
466 static BOOL done_negprot = False;
468 START_PROFILE(SMBnegprot);
471 END_PROFILE(SMBnegprot);
472 exit_server("multiple negprot's are not permitted");
476 p = smb_buf(inbuf)+1;
477 while (p < (smb_buf(inbuf) + bcc)) {
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"))
494 else if (strcsequal(p,"XENIX CORE"))
495 arch &= ( ARCH_WINNT | ARCH_OS2 );
496 else if (strcsequal(p,"Samba")) {
499 } else if (strcsequal(p,"POSIX 2")) {
507 /* CIFSFS can send one arch only, NT LM 0.12. */
508 if (Index == 1 && (arch & ARCH_CIFSFS)) {
514 set_remote_arch(RA_CIFSFS);
517 set_remote_arch(RA_SAMBA);
520 set_remote_arch(RA_WFWG);
523 set_remote_arch(RA_WIN95);
526 if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
527 set_remote_arch(RA_WIN2K);
529 set_remote_arch(RA_WINNT);
532 set_remote_arch(RA_WIN2K);
535 set_remote_arch(RA_OS2);
538 set_remote_arch(RA_UNKNOWN);
542 /* possibly reload - change of architecture */
543 reload_services(True);
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 */
549 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
551 /* Check for protocols, most desirable first */
552 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
553 p = smb_buf(inbuf)+1;
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))
567 SSVAL(outbuf,smb_vwv0,choice);
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));
574 DEBUG(0,("No protocol supported !\n"));
576 SSVAL(outbuf,smb_vwv0,choice);
578 DEBUG( 5, ( "negprot index=%d\n", choice ) );
580 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
581 exit_server("SMB signing is required and client negotiated a downlevel protocol");
584 END_PROFILE(SMBnegprot);