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
;
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, muliple negprots are premitted */
36 if (negprot_global_auth_context
) {
37 DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
38 (negprot_global_auth_context
->free
)(&negprot_global_auth_context
);
41 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
42 if (!NT_STATUS_IS_OK(nt_status
= make_auth_context_subsystem(&negprot_global_auth_context
))) {
43 DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status
)));
44 smb_panic("cannot make_negprot_global_auth_context!\n");
46 DEBUG(10, ("get challenge: getting challenge\n"));
47 cryptkey
= negprot_global_auth_context
->get_ntlm_challenge(negprot_global_auth_context
);
48 memcpy(buff
, cryptkey
, 8);
51 /****************************************************************************
52 Reply for the core protocol.
53 ****************************************************************************/
55 static int reply_corep(char *inbuf
, char *outbuf
)
57 int outsize
= set_message(outbuf
,1,0,True
);
59 Protocol
= PROTOCOL_CORE
;
64 /****************************************************************************
65 Reply for the coreplus protocol.
66 ****************************************************************************/
68 static int reply_coreplus(char *inbuf
, char *outbuf
)
70 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
71 int outsize
= set_message(outbuf
,13,0,True
);
72 SSVAL(outbuf
,smb_vwv5
,raw
); /* tell redirector we support
73 readbraw and writebraw (possibly) */
74 /* Reply, SMBlockread, SMBwritelock supported. */
75 SCVAL(outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
76 SSVAL(outbuf
,smb_vwv1
,0x1); /* user level security, don't encrypt */
78 Protocol
= PROTOCOL_COREPLUS
;
83 /****************************************************************************
84 Reply for the lanman 1.0 protocol.
85 ****************************************************************************/
87 static int reply_lanman1(char *inbuf
, char *outbuf
)
89 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
91 time_t t
= time(NULL
);
93 global_encrypted_passwords_negotiated
= lp_encrypted_passwords();
95 if (lp_security()>=SEC_USER
)
96 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
97 if (global_encrypted_passwords_negotiated
)
98 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
100 set_message(outbuf
,13,global_encrypted_passwords_negotiated
?8:0,True
);
101 SSVAL(outbuf
,smb_vwv1
,secword
);
102 /* Create a token value and add it to the outgoing packet. */
103 if (global_encrypted_passwords_negotiated
) {
104 get_challenge(smb_buf(outbuf
));
105 SSVAL(outbuf
,smb_vwv11
, 8);
108 Protocol
= PROTOCOL_LANMAN1
;
110 /* Reply, SMBlockread, SMBwritelock supported. */
111 SCVAL(outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
112 SSVAL(outbuf
,smb_vwv2
,max_recv
);
113 SSVAL(outbuf
,smb_vwv3
,lp_maxmux()); /* maxmux */
114 SSVAL(outbuf
,smb_vwv4
,1);
115 SSVAL(outbuf
,smb_vwv5
,raw
); /* tell redirector we support
116 readbraw writebraw (possibly) */
117 SIVAL(outbuf
,smb_vwv6
,sys_getpid());
118 SSVAL(outbuf
,smb_vwv10
, TimeDiff(t
)/60);
120 put_dos_date(outbuf
,smb_vwv8
,t
);
122 return (smb_len(outbuf
)+4);
125 /****************************************************************************
126 Reply for the lanman 2.0 protocol.
127 ****************************************************************************/
129 static int reply_lanman2(char *inbuf
, char *outbuf
)
131 int raw
= (lp_readraw()?1:0) | (lp_writeraw()?2:0);
133 time_t t
= time(NULL
);
135 global_encrypted_passwords_negotiated
= lp_encrypted_passwords();
137 if (lp_security()>=SEC_USER
)
138 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
139 if (global_encrypted_passwords_negotiated
)
140 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
142 set_message(outbuf
,13,global_encrypted_passwords_negotiated
?8:0,True
);
143 SSVAL(outbuf
,smb_vwv1
,secword
);
144 SIVAL(outbuf
,smb_vwv6
,sys_getpid());
146 /* Create a token value and add it to the outgoing packet. */
147 if (global_encrypted_passwords_negotiated
) {
148 get_challenge(smb_buf(outbuf
));
149 SSVAL(outbuf
,smb_vwv11
, 8);
152 Protocol
= PROTOCOL_LANMAN2
;
154 /* Reply, SMBlockread, SMBwritelock supported. */
155 SCVAL(outbuf
,smb_flg
,FLAG_REPLY
|FLAG_SUPPORT_LOCKREAD
);
156 SSVAL(outbuf
,smb_vwv2
,max_recv
);
157 SSVAL(outbuf
,smb_vwv3
,lp_maxmux());
158 SSVAL(outbuf
,smb_vwv4
,1);
159 SSVAL(outbuf
,smb_vwv5
,raw
); /* readbraw and/or writebraw */
160 SSVAL(outbuf
,smb_vwv10
, TimeDiff(t
)/60);
161 put_dos_date(outbuf
,smb_vwv8
,t
);
163 return (smb_len(outbuf
)+4);
166 /****************************************************************************
167 Generate the spnego negprot reply blob. Return the number of bytes used.
168 ****************************************************************************/
170 static int negprot_spnego(char *p
)
176 const char *OIDs_krb5
[] = {OID_KERBEROS5
,
182 global_spnego_negotiated
= True
;
186 safe_strcpy(unix_name
, global_myname(), sizeof(unix_name
)-1);
187 strlower_m(unix_name
);
188 push_ascii_nstring(dos_name
, unix_name
);
189 safe_strcpy((char *)guid
, dos_name
, sizeof(guid
)-1);
192 /* valgrind fixer... */
194 size_t sl
= strlen(guid
);
196 memset(&guid
[sl
], '\0', sizeof(guid
)-sl
);
200 /* strangely enough, NT does not sent the single OID NTLMSSP when
201 not a ADS member, it sends no OIDs at all
203 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
204 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
206 Our sessionsetup code now handles raw NTLMSSP connects, so we can go
207 back to doing what W2K3 does here. This is needed to make PocketPC 2003
208 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
213 if (lp_security() != SEC_ADS
&& !lp_use_kerberos_keytab()) {
218 char *host_princ_s
= NULL
;
219 name_to_fqdn(myname
, global_myname());
221 asprintf(&host_princ_s
, "cifs/%s@%s", myname
, lp_realm());
222 blob
= spnego_gen_negTokenInit(guid
, OIDs_krb5
, host_princ_s
);
223 SAFE_FREE(host_princ_s
);
225 memcpy(p
, blob
.data
, blob
.length
);
227 data_blob_free(&blob
);
231 /****************************************************************************
232 Reply for the nt protocol.
233 ****************************************************************************/
235 static int reply_nt1(char *inbuf
, char *outbuf
)
237 /* dual names + lock_and_read + nt SMBs + remote API calls */
238 int capabilities
= CAP_NT_FIND
|CAP_LOCK_AND_READ
|
239 CAP_LEVEL_II_OPLOCKS
;
242 time_t t
= time(NULL
);
244 BOOL negotiate_spnego
= False
;
246 global_encrypted_passwords_negotiated
= lp_encrypted_passwords();
248 /* do spnego in user level security if the client
249 supports it and we can do encrypted passwords */
251 if (global_encrypted_passwords_negotiated
&&
252 (lp_security() != SEC_SHARE
) &&
254 (SVAL(inbuf
, smb_flg2
) & FLAGS2_EXTENDED_SECURITY
)) {
255 negotiate_spnego
= True
;
256 capabilities
|= CAP_EXTENDED_SECURITY
;
257 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY
);
258 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
259 partially constructed. */
260 SSVAL(outbuf
,smb_flg2
, SVAL(outbuf
,smb_flg2
) | FLAGS2_EXTENDED_SECURITY
);
263 capabilities
|= CAP_NT_SMBS
|CAP_RPC_REMOTE_APIS
|CAP_UNICODE
;
265 if (lp_unix_extensions()) {
266 capabilities
|= CAP_UNIX
;
269 if (lp_large_readwrite() && (SMB_OFF_T_BITS
== 64))
270 capabilities
|= CAP_LARGE_READX
|CAP_LARGE_WRITEX
|CAP_W2K_SMBS
;
272 if (SMB_OFF_T_BITS
== 64)
273 capabilities
|= CAP_LARGE_FILES
;
275 if (lp_readraw() && lp_writeraw())
276 capabilities
|= CAP_RAW_MODE
;
278 if (lp_nt_status_support())
279 capabilities
|= CAP_STATUS32
;
282 capabilities
|= CAP_DFS
;
284 if (lp_security() >= SEC_USER
)
285 secword
|= NEGOTIATE_SECURITY_USER_LEVEL
;
286 if (global_encrypted_passwords_negotiated
)
287 secword
|= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
;
289 if (lp_server_signing()) {
290 if (lp_security() >= SEC_USER
) {
291 secword
|= NEGOTIATE_SECURITY_SIGNATURES_ENABLED
;
292 /* No raw mode with smb signing. */
293 capabilities
&= ~CAP_RAW_MODE
;
294 if (lp_server_signing() == Required
)
295 secword
|=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
;
296 srv_set_signing_negotiated();
298 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
299 if (lp_server_signing() == Required
) {
300 exit_server("reply_nt1: smb signing required and share level security selected.");
305 set_message(outbuf
,17,0,True
);
307 SCVAL(outbuf
,smb_vwv1
,secword
);
309 Protocol
= PROTOCOL_NT1
;
311 SSVAL(outbuf
,smb_vwv1
+1,lp_maxmux()); /* maxmpx */
312 SSVAL(outbuf
,smb_vwv2
+1,1); /* num vcs */
313 SIVAL(outbuf
,smb_vwv3
+1,max_recv
); /* max buffer. LOTS! */
314 SIVAL(outbuf
,smb_vwv5
+1,0x10000); /* raw size. full 64k */
315 SIVAL(outbuf
,smb_vwv7
+1,sys_getpid()); /* session key */
316 SIVAL(outbuf
,smb_vwv9
+1,capabilities
); /* capabilities */
317 put_long_date(outbuf
+smb_vwv11
+1,t
);
318 SSVALS(outbuf
,smb_vwv15
+1,TimeDiff(t
)/60);
320 p
= q
= smb_buf(outbuf
);
321 if (!negotiate_spnego
) {
322 /* Create a token value and add it to the outgoing packet. */
323 if (global_encrypted_passwords_negotiated
) {
324 /* note that we do not send a challenge at all if
325 we are using plaintext */
327 SSVALS(outbuf
,smb_vwv16
+1,8);
330 p
+= srvstr_push(outbuf
, p
, lp_workgroup(), -1,
331 STR_UNICODE
|STR_TERMINATE
|STR_NOALIGN
);
332 DEBUG(3,("not using SPNEGO\n"));
334 int len
= negprot_spnego(p
);
336 SSVALS(outbuf
,smb_vwv16
+1,len
);
338 DEBUG(3,("using SPNEGO\n"));
341 SSVAL(outbuf
,smb_vwv17
, p
- q
); /* length of challenge+domain strings */
342 set_message_end(outbuf
, p
);
344 return (smb_len(outbuf
)+4);
347 /* these are the protocol lists used for auto architecture detection:
350 protocol [PC NETWORK PROGRAM 1.0]
351 protocol [XENIX CORE]
352 protocol [MICROSOFT NETWORKS 1.03]
354 protocol [Windows for Workgroups 3.1a]
357 protocol [NT LM 0.12]
360 protocol [PC NETWORK PROGRAM 1.0]
361 protocol [XENIX CORE]
362 protocol [MICROSOFT NETWORKS 1.03]
364 protocol [Windows for Workgroups 3.1a]
367 protocol [NT LM 0.12]
370 protocol [PC NETWORK PROGRAM 1.0]
372 protocol [Windows for Workgroups 3.1a]
375 protocol [NT LM 0.12]
378 protocol [PC NETWORK PROGRAM 1.0]
379 protocol [XENIX CORE]
386 * Modified to recognize the architecture of the remote machine better.
388 * This appears to be the matrix of which protocol is used by which
390 Protocol WfWg Win95 WinNT Win2K OS/2
391 PC NETWORK PROGRAM 1.0 1 1 1 1 1
393 MICROSOFT NETWORKS 3.0 2 2
395 MICROSOFT NETWORKS 1.03 3
398 Windows for Workgroups 3.1a 5 5 5 3
403 * tim@fsg.com 09/29/95
404 * Win2K added by matty 17/7/99
407 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
408 #define ARCH_WIN95 0x2
409 #define ARCH_WINNT 0x4
410 #define ARCH_WIN2K 0xC /* Win2K is like NT */
411 #define ARCH_OS2 0x14 /* Again OS/2 is like NT */
412 #define ARCH_SAMBA 0x20
413 #define ARCH_CIFSFS 0x40
415 #define ARCH_ALL 0x7F
417 /* List of supported protocols, most desired first */
418 static const struct {
419 const char *proto_name
;
420 const char *short_name
;
421 int (*proto_reply_fn
)(char *, char *);
423 } supported_protocols
[] = {
424 {"NT LANMAN 1.0", "NT1", reply_nt1
, PROTOCOL_NT1
},
425 {"NT LM 0.12", "NT1", reply_nt1
, PROTOCOL_NT1
},
426 {"POSIX 2", "NT1", reply_nt1
, PROTOCOL_NT1
},
427 {"LANMAN2.1", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
428 {"LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
429 {"Samba", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
430 {"DOS LM1.2X002", "LANMAN2", reply_lanman2
, PROTOCOL_LANMAN2
},
431 {"LANMAN1.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
432 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1
, PROTOCOL_LANMAN1
},
433 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus
, PROTOCOL_COREPLUS
},
434 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep
, PROTOCOL_CORE
},
438 /****************************************************************************
440 ****************************************************************************/
442 int reply_negprot(connection_struct
*conn
,
443 char *inbuf
,char *outbuf
, int dum_size
,
446 int outsize
= set_message(outbuf
,1,0,True
);
451 int bcc
= SVAL(smb_buf(inbuf
),-2);
454 static BOOL done_negprot
= False
;
456 START_PROFILE(SMBnegprot
);
459 END_PROFILE(SMBnegprot
);
460 exit_server("multiple negprot's are not permitted");
464 p
= smb_buf(inbuf
)+1;
465 while (p
< (smb_buf(inbuf
) + bcc
)) {
467 DEBUG(3,("Requested protocol [%s]\n",p
));
468 if (strcsequal(p
,"Windows for Workgroups 3.1a"))
469 arch
&= ( ARCH_WFWG
| ARCH_WIN95
| ARCH_WINNT
| ARCH_WIN2K
);
470 else if (strcsequal(p
,"DOS LM1.2X002"))
471 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
472 else if (strcsequal(p
,"DOS LANMAN2.1"))
473 arch
&= ( ARCH_WFWG
| ARCH_WIN95
);
474 else if (strcsequal(p
,"NT LM 0.12"))
475 arch
&= ( ARCH_WIN95
| ARCH_WINNT
| ARCH_WIN2K
| ARCH_CIFSFS
);
476 else if (strcsequal(p
,"LANMAN2.1"))
477 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
478 else if (strcsequal(p
,"LM1.2X002"))
479 arch
&= ( ARCH_WINNT
| ARCH_WIN2K
| ARCH_OS2
);
480 else if (strcsequal(p
,"MICROSOFT NETWORKS 1.03"))
482 else if (strcsequal(p
,"XENIX CORE"))
483 arch
&= ( ARCH_WINNT
| ARCH_OS2
);
484 else if (strcsequal(p
,"Samba")) {
487 } else if (strcsequal(p
,"POSIX 2")) {
495 /* CIFSFS can send one arch only, NT LM 0.12. */
496 if (Index
== 1 && (arch
& ARCH_CIFSFS
)) {
502 set_remote_arch(RA_CIFSFS
);
505 set_remote_arch(RA_SAMBA
);
508 set_remote_arch(RA_WFWG
);
511 set_remote_arch(RA_WIN95
);
514 if(SVAL(inbuf
,smb_flg2
)==FLAGS2_WIN2K_SIGNATURE
)
515 set_remote_arch(RA_WIN2K
);
517 set_remote_arch(RA_WINNT
);
520 set_remote_arch(RA_WIN2K
);
523 set_remote_arch(RA_OS2
);
526 set_remote_arch(RA_UNKNOWN
);
530 /* possibly reload - change of architecture */
531 reload_services(True
);
533 /* moved from the netbios session setup code since we don't have that
534 when the client connects to port 445. Of course there is a small
535 window where we are listening to messages -- jerry */
537 claim_connection(NULL
,"",0,True
,FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
|FLAG_MSG_PRINT_GENERAL
);
539 /* Check for protocols, most desirable first */
540 for (protocol
= 0; supported_protocols
[protocol
].proto_name
; protocol
++) {
541 p
= smb_buf(inbuf
)+1;
543 if ((supported_protocols
[protocol
].protocol_level
<= lp_maxprotocol()) &&
544 (supported_protocols
[protocol
].protocol_level
>= lp_minprotocol()))
545 while (p
< (smb_buf(inbuf
) + bcc
)) {
546 if (strequal(p
,supported_protocols
[protocol
].proto_name
))
555 SSVAL(outbuf
,smb_vwv0
,choice
);
557 fstrcpy(remote_proto
,supported_protocols
[protocol
].short_name
);
558 reload_services(True
);
559 outsize
= supported_protocols
[protocol
].proto_reply_fn(inbuf
, outbuf
);
560 DEBUG(3,("Selected protocol %s\n",supported_protocols
[protocol
].proto_name
));
562 DEBUG(0,("No protocol supported !\n"));
564 SSVAL(outbuf
,smb_vwv0
,choice
);
566 DEBUG( 5, ( "negprot index=%d\n", choice
) );
568 if ((lp_server_signing() == Required
) && (Protocol
< PROTOCOL_NT1
)) {
569 exit_server("SMB signing is required and client negotiated a downlevel protocol");
572 END_PROFILE(SMBnegprot
);