1/* 2 Unix SMB/CIFS implementation. 3 negprot reply code 4 Copyright (C) Andrew Tridgell 1992-1998 5 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. 10 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. 15 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/>. 18*/ 19 20#include "includes.h" 21#include "auth/credentials/credentials.h" 22#include "auth/gensec/gensec.h" 23#include "auth/auth.h" 24#include "smb_server/smb_server.h" 25#include "libcli/smb2/smb2.h" 26#include "smb_server/smb2/smb2_server.h" 27#include "smbd/service_stream.h" 28#include "lib/stream/packet.h" 29#include "param/param.h" 30 31 32/* initialise the auth_context for this server and return the cryptkey */ 33static NTSTATUS get_challenge(struct smbsrv_connection *smb_conn, uint8_t buff[8]) 34{ 35 NTSTATUS nt_status; 36 const uint8_t *challenge; 37 38 /* muliple negprots are not premitted */ 39 if (smb_conn->negotiate.auth_context) { 40 DEBUG(3,("get challenge: is this a secondary negprot? auth_context is non-NULL!\n")); 41 return NT_STATUS_FOOBAR; 42 } 43 44 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n")); 45 46 nt_status = auth_context_create(smb_conn, 47 smb_conn->connection->event.ctx, 48 smb_conn->connection->msg_ctx, 49 smb_conn->lp_ctx, 50 &smb_conn->negotiate.auth_context); 51 if (!NT_STATUS_IS_OK(nt_status)) { 52 DEBUG(0, ("auth_context_create() returned %s", nt_errstr(nt_status))); 53 return nt_status; 54 } 55 56 nt_status = auth_get_challenge(smb_conn->negotiate.auth_context, &challenge); 57 if (!NT_STATUS_IS_OK(nt_status)) { 58 DEBUG(0, ("auth_get_challenge() returned %s", nt_errstr(nt_status))); 59 return nt_status; 60 } 61 62 memcpy(buff, challenge, 8); 63 64 return NT_STATUS_OK; 65} 66 67/**************************************************************************** 68 Reply for the core protocol. 69****************************************************************************/ 70static void reply_corep(struct smbsrv_request *req, uint16_t choice) 71{ 72 smbsrv_setup_reply(req, 1, 0); 73 74 SSVAL(req->out.vwv, VWV(0), choice); 75 76 req->smb_conn->negotiate.protocol = PROTOCOL_CORE; 77 78 if (req->smb_conn->signing.mandatory_signing) { 79 smbsrv_terminate_connection(req->smb_conn, 80 "CORE does not support SMB signing, and it is mandatory\n"); 81 return; 82 } 83 84 smbsrv_send_reply(req); 85} 86 87/**************************************************************************** 88 Reply for the coreplus protocol. 89this is quite incomplete - we only fill in a small part of the reply, but as nobody uses 90this any more it probably doesn't matter 91****************************************************************************/ 92static void reply_coreplus(struct smbsrv_request *req, uint16_t choice) 93{ 94 uint16_t raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0); 95 96 smbsrv_setup_reply(req, 13, 0); 97 98 /* Reply, SMBlockread, SMBwritelock supported. */ 99 SCVAL(req->out.hdr,HDR_FLG, 100 CVAL(req->out.hdr, HDR_FLG) | FLAG_SUPPORT_LOCKREAD); 101 102 SSVAL(req->out.vwv, VWV(0), choice); 103 SSVAL(req->out.vwv, VWV(1), 0x1); /* user level security, don't encrypt */ 104 105 /* tell redirector we support 106 readbraw and writebraw (possibly) */ 107 SSVAL(req->out.vwv, VWV(5), raw); 108 109 req->smb_conn->negotiate.protocol = PROTOCOL_COREPLUS; 110 111 if (req->smb_conn->signing.mandatory_signing) { 112 smbsrv_terminate_connection(req->smb_conn, 113 "COREPLUS does not support SMB signing, and it is mandatory\n"); 114 return; 115 } 116 117 smbsrv_send_reply(req); 118} 119 120/**************************************************************************** 121 Reply for the lanman 1.0 protocol. 122****************************************************************************/ 123static void reply_lanman1(struct smbsrv_request *req, uint16_t choice) 124{ 125 int raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0); 126 int secword=0; 127 time_t t = req->request_time.tv_sec; 128 129 req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx); 130 131 if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) 132 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 133 134 if (req->smb_conn->negotiate.encrypted_passwords) 135 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; 136 137 req->smb_conn->negotiate.protocol = PROTOCOL_LANMAN1; 138 139 smbsrv_setup_reply(req, 13, req->smb_conn->negotiate.encrypted_passwords ? 8 : 0); 140 141 /* SMBlockread, SMBwritelock supported. */ 142 SCVAL(req->out.hdr,HDR_FLG, 143 CVAL(req->out.hdr, HDR_FLG) | FLAG_SUPPORT_LOCKREAD); 144 145 SSVAL(req->out.vwv, VWV(0), choice); 146 SSVAL(req->out.vwv, VWV(1), secword); 147 SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv); 148 SSVAL(req->out.vwv, VWV(3), lp_maxmux(req->smb_conn->lp_ctx)); 149 SSVAL(req->out.vwv, VWV(4), 1); 150 SSVAL(req->out.vwv, VWV(5), raw); 151 SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id); 152 srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t); 153 SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60); 154 SIVAL(req->out.vwv, VWV(11), 0); /* reserved */ 155 156 /* Create a token value and add it to the outgoing packet. */ 157 if (req->smb_conn->negotiate.encrypted_passwords) { 158 NTSTATUS nt_status; 159 160 SSVAL(req->out.vwv, VWV(11), 8); 161 162 nt_status = get_challenge(req->smb_conn, req->out.data); 163 if (!NT_STATUS_IS_OK(nt_status)) { 164 smbsrv_terminate_connection(req->smb_conn, "LANMAN1 get_challenge failed\n"); 165 return; 166 } 167 } 168 169 if (req->smb_conn->signing.mandatory_signing) { 170 smbsrv_terminate_connection(req->smb_conn, 171 "LANMAN1 does not support SMB signing, and it is mandatory\n"); 172 return; 173 } 174 175 smbsrv_send_reply(req); 176} 177 178/**************************************************************************** 179 Reply for the lanman 2.0 protocol. 180****************************************************************************/ 181static void reply_lanman2(struct smbsrv_request *req, uint16_t choice) 182{ 183 int raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0); 184 int secword=0; 185 time_t t = req->request_time.tv_sec; 186 187 req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx); 188 189 if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) 190 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 191 192 if (req->smb_conn->negotiate.encrypted_passwords) 193 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; 194 195 req->smb_conn->negotiate.protocol = PROTOCOL_LANMAN2; 196 197 smbsrv_setup_reply(req, 13, 0); 198 199 SSVAL(req->out.vwv, VWV(0), choice); 200 SSVAL(req->out.vwv, VWV(1), secword); 201 SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv); 202 SSVAL(req->out.vwv, VWV(3), lp_maxmux(req->smb_conn->lp_ctx)); 203 SSVAL(req->out.vwv, VWV(4), 1); 204 SSVAL(req->out.vwv, VWV(5), raw); 205 SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id); 206 srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t); 207 SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60); 208 SIVAL(req->out.vwv, VWV(11), 0); 209 210 /* Create a token value and add it to the outgoing packet. */ 211 if (req->smb_conn->negotiate.encrypted_passwords) { 212 SSVAL(req->out.vwv, VWV(11), 8); 213 req_grow_data(req, 8); 214 get_challenge(req->smb_conn, req->out.data); 215 } 216 217 req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_TERMINATE); 218 219 if (req->smb_conn->signing.mandatory_signing) { 220 smbsrv_terminate_connection(req->smb_conn, 221 "LANMAN2 does not support SMB signing, and it is mandatory\n"); 222 return; 223 } 224 225 smbsrv_send_reply(req); 226} 227 228static void reply_nt1_orig(struct smbsrv_request *req) 229{ 230 /* Create a token value and add it to the outgoing packet. */ 231 if (req->smb_conn->negotiate.encrypted_passwords) { 232 req_grow_data(req, 8); 233 /* note that we do not send a challenge at all if 234 we are using plaintext */ 235 get_challenge(req->smb_conn, req->out.ptr); 236 req->out.ptr += 8; 237 SCVAL(req->out.vwv+1, VWV(16), 8); 238 } 239 req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); 240 req_push_str(req, NULL, lp_netbios_name(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); 241 DEBUG(3,("not using extended security (SPNEGO or NTLMSSP)\n")); 242} 243 244/**************************************************************************** 245 Reply for the nt protocol. 246****************************************************************************/ 247static void reply_nt1(struct smbsrv_request *req, uint16_t choice) 248{ 249 /* dual names + lock_and_read + nt SMBs + remote API calls */ 250 int capabilities; 251 int secword=0; 252 time_t t = req->request_time.tv_sec; 253 NTTIME nttime; 254 bool negotiate_spnego = false; 255 char *large_test_path; 256 257 unix_to_nt_time(&nttime, t); 258 259 capabilities = 260 CAP_NT_FIND | CAP_LOCK_AND_READ | 261 CAP_LEVEL_II_OPLOCKS | CAP_NT_SMBS | CAP_RPC_REMOTE_APIS; 262 263 req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx); 264 265 /* do spnego in user level security if the client 266 supports it and we can do encrypted passwords */ 267 268 if (req->smb_conn->negotiate.encrypted_passwords && 269 (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) && 270 lp_use_spnego(req->smb_conn->lp_ctx) && 271 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) { 272 negotiate_spnego = true; 273 capabilities |= CAP_EXTENDED_SECURITY; 274 } 275 276 if (lp_unix_extensions(req->smb_conn->lp_ctx)) { 277 capabilities |= CAP_UNIX; 278 } 279 280 if (lp_large_readwrite(req->smb_conn->lp_ctx)) { 281 capabilities |= CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS; 282 } 283 284 large_test_path = lock_path(req, req->smb_conn->lp_ctx, "large_test.dat"); 285 if (large_file_support(large_test_path)) { 286 capabilities |= CAP_LARGE_FILES; 287 } 288 289 if (lp_readraw(req->smb_conn->lp_ctx) && 290 lp_writeraw(req->smb_conn->lp_ctx)) { 291 capabilities |= CAP_RAW_MODE; 292 } 293 294 /* allow for disabling unicode */ 295 if (lp_unicode(req->smb_conn->lp_ctx)) { 296 capabilities |= CAP_UNICODE; 297 } 298 299 if (lp_nt_status_support(req->smb_conn->lp_ctx)) { 300 capabilities |= CAP_STATUS32; 301 } 302 303 if (lp_host_msdfs(req->smb_conn->lp_ctx)) { 304 capabilities |= CAP_DFS; 305 } 306 307 if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) { 308 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 309 } 310 311 if (req->smb_conn->negotiate.encrypted_passwords) { 312 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; 313 } 314 315 if (req->smb_conn->signing.allow_smb_signing) { 316 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED; 317 } 318 319 if (req->smb_conn->signing.mandatory_signing) { 320 secword |= NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; 321 } 322 323 req->smb_conn->negotiate.protocol = PROTOCOL_NT1; 324 325 smbsrv_setup_reply(req, 17, 0); 326 327 SSVAL(req->out.vwv, VWV(0), choice); 328 SCVAL(req->out.vwv, VWV(1), secword); 329 330 /* notice the strange +1 on vwv here? That's because 331 this is the one and only SMB packet that is malformed in 332 the specification - all the command words after the secword 333 are offset by 1 byte */ 334 SSVAL(req->out.vwv+1, VWV(1), lp_maxmux(req->smb_conn->lp_ctx)); 335 SSVAL(req->out.vwv+1, VWV(2), 1); /* num vcs */ 336 SIVAL(req->out.vwv+1, VWV(3), req->smb_conn->negotiate.max_recv); 337 SIVAL(req->out.vwv+1, VWV(5), 0x10000); /* raw size. full 64k */ 338 SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->server_id.id); /* session key */ 339 SIVAL(req->out.vwv+1, VWV(9), capabilities); 340 push_nttime(req->out.vwv+1, VWV(11), nttime); 341 SSVALS(req->out.vwv+1,VWV(15), req->smb_conn->negotiate.zone_offset/60); 342 343 if (!negotiate_spnego) { 344 reply_nt1_orig(req); 345 } else { 346 struct cli_credentials *server_credentials; 347 struct gensec_security *gensec_security; 348 DATA_BLOB null_data_blob = data_blob(NULL, 0); 349 DATA_BLOB blob; 350 const char *oid; 351 NTSTATUS nt_status; 352 353 server_credentials 354 = cli_credentials_init(req); 355 if (!server_credentials) { 356 smbsrv_terminate_connection(req->smb_conn, "Failed to init server credentials\n"); 357 return; 358 } 359 360 cli_credentials_set_conf(server_credentials, req->smb_conn->lp_ctx); 361 nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx); 362 if (!NT_STATUS_IS_OK(nt_status)) { 363 DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); 364 talloc_free(server_credentials); 365 server_credentials = NULL; 366 } 367 368 nt_status = samba_server_gensec_start(req, 369 req->smb_conn->connection->event.ctx, 370 req->smb_conn->connection->msg_ctx, 371 req->smb_conn->lp_ctx, 372 server_credentials, 373 "cifs", 374 &gensec_security); 375 376 if (!NT_STATUS_IS_OK(nt_status)) { 377 DEBUG(0, ("Failed to start GENSEC: %s\n", nt_errstr(nt_status))); 378 smbsrv_terminate_connection(req->smb_conn, "Failed to start GENSEC\n"); 379 return; 380 } 381 382 if (req->smb_conn->negotiate.auth_context) { 383 smbsrv_terminate_connection(req->smb_conn, "reply_nt1: is this a secondary negprot? auth_context is non-NULL!\n"); 384 return; 385 } 386 req->smb_conn->negotiate.server_credentials = talloc_reparent(req, req->smb_conn, server_credentials); 387 388 gensec_set_target_service(gensec_security, "cifs"); 389 390 gensec_set_credentials(gensec_security, server_credentials); 391 392 oid = GENSEC_OID_SPNEGO; 393 nt_status = gensec_start_mech_by_oid(gensec_security, oid); 394 395 if (NT_STATUS_IS_OK(nt_status)) { 396 /* Get and push the proposed OID list into the packets */ 397 nt_status = gensec_update(gensec_security, req, null_data_blob, &blob); 398 399 if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 400 DEBUG(1, ("Failed to get SPNEGO to give us the first token: %s\n", nt_errstr(nt_status))); 401 } 402 } 403 404 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 405 DEBUG(3,("using SPNEGO\n")); 406 } else { 407 DEBUG(5, ("Failed to start SPNEGO, falling back to NTLMSSP only: %s\n", nt_errstr(nt_status))); 408 oid = GENSEC_OID_NTLMSSP; 409 nt_status = gensec_start_mech_by_oid(gensec_security, oid); 410 411 if (!NT_STATUS_IS_OK(nt_status)) { 412 DEBUG(0, ("Failed to start SPNEGO as well as NTLMSSP fallback: %s\n", nt_errstr(nt_status))); 413 reply_nt1_orig(req); 414 return; 415 } 416 /* NTLMSSP is a client-first exchange */ 417 blob = data_blob(NULL, 0); 418 DEBUG(3,("using raw-NTLMSSP\n")); 419 } 420 421 req->smb_conn->negotiate.oid = oid; 422 423 req_grow_data(req, blob.length + 16); 424 /* a NOT very random guid, perhaps we should get it 425 * from the credentials (kitchen sink...) */ 426 memset(req->out.ptr, '\0', 16); 427 req->out.ptr += 16; 428 429 memcpy(req->out.ptr, blob.data, blob.length); 430 SCVAL(req->out.vwv+1, VWV(16), blob.length + 16); 431 req->out.ptr += blob.length; 432 } 433 434 smbsrv_send_reply_nosign(req); 435} 436 437/**************************************************************************** 438 Reply for the SMB2 2.001 protocol 439****************************************************************************/ 440static void reply_smb2(struct smbsrv_request *req, uint16_t choice) 441{ 442 struct smbsrv_connection *smb_conn = req->smb_conn; 443 NTSTATUS status; 444 445 talloc_free(smb_conn->sessions.idtree_vuid); 446 ZERO_STRUCT(smb_conn->sessions); 447 talloc_free(smb_conn->smb_tcons.idtree_tid); 448 ZERO_STRUCT(smb_conn->smb_tcons); 449 ZERO_STRUCT(smb_conn->signing); 450 451 /* reply with a SMB2 packet */ 452 status = smbsrv_init_smb2_connection(smb_conn); 453 if (!NT_STATUS_IS_OK(status)) { 454 smbsrv_terminate_connection(smb_conn, nt_errstr(status)); 455 talloc_free(req); 456 return; 457 } 458 packet_set_callback(smb_conn->packet, smbsrv_recv_smb2_request); 459 smb2srv_reply_smb_negprot(req); 460 req = NULL; 461} 462 463/* List of supported protocols, most desired first */ 464static const struct { 465 const char *proto_name; 466 const char *short_name; 467 void (*proto_reply_fn)(struct smbsrv_request *req, uint16_t choice); 468 int protocol_level; 469} supported_protocols[] = { 470 {"SMB 2.002", "SMB2", reply_smb2, PROTOCOL_SMB2}, 471 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1}, 472 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1}, 473 {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2}, 474 {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2}, 475 {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2}, 476 {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2}, 477 {"Windows for Workgroups 3.1a", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1}, 478 {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1}, 479 {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1}, 480 {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS}, 481 {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE}, 482 {NULL,NULL,NULL,0}, 483}; 484 485/**************************************************************************** 486 Reply to a negprot. 487****************************************************************************/ 488 489void smbsrv_reply_negprot(struct smbsrv_request *req) 490{ 491 int protocol; 492 uint8_t *p; 493 uint32_t protos_count = 0; 494 char **protos = NULL; 495 496 if (req->smb_conn->negotiate.done_negprot) { 497 smbsrv_terminate_connection(req->smb_conn, "multiple negprot's are not permitted"); 498 return; 499 } 500 req->smb_conn->negotiate.done_negprot = true; 501 502 p = req->in.data; 503 while (true) { 504 size_t len; 505 506 protos = talloc_realloc(req, protos, char *, protos_count + 1); 507 if (!protos) { 508 smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY)); 509 return; 510 } 511 protos[protos_count] = NULL; 512 len = req_pull_ascii4(&req->in.bufinfo, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE); 513 p += len; 514 if (len == 0 || !protos[protos_count]) break; 515 516 DEBUG(5,("Requested protocol [%d][%s]\n", protos_count, protos[protos_count])); 517 protos_count++; 518 } 519 520 /* Check for protocols, most desirable first */ 521 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) { 522 int i; 523 524 if (supported_protocols[protocol].protocol_level > lp_srv_maxprotocol(req->smb_conn->lp_ctx)) 525 continue; 526 if (supported_protocols[protocol].protocol_level < lp_srv_minprotocol(req->smb_conn->lp_ctx)) 527 continue; 528 529 for (i = 0; i < protos_count; i++) { 530 if (strcmp(supported_protocols[protocol].proto_name, protos[i]) != 0) continue; 531 532 supported_protocols[protocol].proto_reply_fn(req, i); 533 DEBUG(3,("Selected protocol [%d][%s]\n", 534 i, supported_protocols[protocol].proto_name)); 535 return; 536 } 537 } 538 539 smbsrv_terminate_connection(req->smb_conn, "No protocol supported !"); 540} 541