Changeset 988 for vendor/current/source4/smb_server
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/smb_server
- Files:
-
- 1 deleted
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/smb_server/blob.c
r740 r988 181 181 int flags) 182 182 { 183 s ize_t ret;183 ssize_t ret; 184 184 uint32_t offset; 185 185 const int max_bytes_per_char = 3; … … 293 293 return NT_STATUS_OK; 294 294 } 295 296 case RAW_QFS_SECTOR_SIZE_INFORMATION: 297 BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 28)); 298 SIVAL(blob->data, 0, 299 fsinfo->sector_size_info.out.logical_bytes_per_sector); 300 SIVAL(blob->data, 4, 301 fsinfo->sector_size_info.out.phys_bytes_per_sector_atomic); 302 SIVAL(blob->data, 8, 303 fsinfo->sector_size_info.out.phys_bytes_per_sector_perf); 304 SIVAL(blob->data, 12, 305 fsinfo->sector_size_info.out.fs_effective_phys_bytes_per_sector_atomic); 306 SIVAL(blob->data, 16, 307 fsinfo->sector_size_info.out.flags); 308 SIVAL(blob->data, 20, 309 fsinfo->sector_size_info.out.byte_off_sector_align); 310 SIVAL(blob->data, 24, 311 fsinfo->sector_size_info.out.byte_off_partition_align); 312 313 return NT_STATUS_OK; 314 295 315 default: 296 316 return NT_STATUS_INVALID_LEVEL; … … 626 646 return NT_STATUS_OK; 627 647 648 case RAW_SFILEINFO_FULL_EA_INFORMATION: 649 return ea_pull_list_chained(blob, 650 mem_ctx, 651 &st->full_ea_information.in.eas.num_eas, 652 &st->full_ea_information.in.eas.eas); 653 628 654 case RAW_SFILEINFO_MODE_INFORMATION: 629 655 BLOB_CHECK_MIN_SIZE(blob, 4); -
vendor/current/source4/smb_server/service_smb.c
r740 r988 34 34 #include "dsdb/samdb/samdb.h" 35 35 #include "param/param.h" 36 #include "file_server/file_server.h" 36 37 37 38 /* … … 49 50 struct interface *ifaces; 50 51 51 load_interface s(task, lpcfg_interfaces(task->lp_ctx), &ifaces);52 load_interface_list(task, task->lp_ctx, &ifaces); 52 53 53 num_interfaces = iface_ count(ifaces);54 num_interfaces = iface_list_count(ifaces); 54 55 55 56 /* We have been given an interfaces line, and been … … 58 59 */ 59 60 for(i = 0; i < num_interfaces; i++) { 60 const char *address = iface_ n_ip(ifaces, i);61 const char *address = iface_list_n_ip(ifaces, i); 61 62 status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, address); 62 63 if (!NT_STATUS_IS_OK(status)) goto failed; 63 64 } 64 65 } else { 65 /* Just bind to lpcfg_socket_address() (usually 0.0.0.0) */ 66 status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, 67 lpcfg_socket_address(task->lp_ctx)); 68 if (!NT_STATUS_IS_OK(status)) goto failed; 66 char **wcard; 67 int i; 68 wcard = iface_list_wildcard(task); 69 if (wcard == NULL) { 70 DEBUG(0,("No wildcard addresses available\n")); 71 goto failed; 72 } 73 for (i=0; wcard[i]; i++) { 74 status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, wcard[i]); 75 if (!NT_STATUS_IS_OK(status)) goto failed; 76 } 77 talloc_free(wcard); 69 78 } 70 79 80 irpc_add_name(task->msg_ctx, "smb_server"); 71 81 return; 72 82 failed: -
vendor/current/source4/smb_server/session.c
r414 r988 86 86 if (!p) return NULL; 87 87 88 /* only return an unfinished session */ 89 sess = talloc_get_type(p, struct smbsrv_session); 90 if (sess && !sess->session_info) { 91 return sess; 92 } 93 return NULL; 88 sess = talloc_get_type_abort(p, struct smbsrv_session); 89 90 return sess; 94 91 } 95 92 … … 141 138 int i; 142 139 143 /* Ensure no vuid gets registered in share level security. */144 if (smb_conn->config.security == SEC_SHARE) return NULL;145 146 140 sess = talloc_zero(mem_ctx, struct smbsrv_session); 147 141 if (!sess) return NULL; -
vendor/current/source4/smb_server/smb/negprot.c
r740 r988 19 19 20 20 #include "includes.h" 21 #include "system/filesys.h" 21 22 #include "auth/credentials/credentials.h" 22 23 #include "auth/gensec/gensec.h" … … 89 90 static void reply_coreplus(struct smbsrv_request *req, uint16_t choice) 90 91 { 91 uint16_t raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0); 92 uint16_t raw; 93 if (lpcfg_async_smb_echo_handler(req->smb_conn->lp_ctx)) { 94 raw = 0; 95 } else { 96 raw = (lpcfg_read_raw(req->smb_conn->lp_ctx)?1:0) | 97 (lpcfg_write_raw(req->smb_conn->lp_ctx)?2:0); 98 } 92 99 93 100 smbsrv_setup_reply(req, 13, 0); … … 120 127 static void reply_lanman1(struct smbsrv_request *req, uint16_t choice) 121 128 { 122 int raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0);123 129 int secword=0; 124 130 time_t t = req->request_time.tv_sec; 125 126 req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypted_passwords(req->smb_conn->lp_ctx); 127 128 if (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE) 129 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 131 uint16_t raw; 132 133 if (lpcfg_async_smb_echo_handler(req->smb_conn->lp_ctx)) { 134 raw = 0; 135 } else { 136 raw = (lpcfg_read_raw(req->smb_conn->lp_ctx)?1:0) | 137 (lpcfg_write_raw(req->smb_conn->lp_ctx)?2:0); 138 } 139 140 req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypt_passwords(req->smb_conn->lp_ctx); 130 141 131 142 if (req->smb_conn->negotiate.encrypted_passwords) … … 143 154 SSVAL(req->out.vwv, VWV(1), secword); 144 155 SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv); 145 SSVAL(req->out.vwv, VWV(3), lpcfg_max mux(req->smb_conn->lp_ctx));156 SSVAL(req->out.vwv, VWV(3), lpcfg_max_mux(req->smb_conn->lp_ctx)); 146 157 SSVAL(req->out.vwv, VWV(4), 1); 147 158 SSVAL(req->out.vwv, VWV(5), raw); 148 SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id. id);159 SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.pid); 149 160 srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t); 150 161 SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60); … … 178 189 static void reply_lanman2(struct smbsrv_request *req, uint16_t choice) 179 190 { 180 int raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0);181 191 int secword=0; 182 192 time_t t = req->request_time.tv_sec; 183 184 req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypted_passwords(req->smb_conn->lp_ctx); 193 uint16_t raw; 194 if (lpcfg_async_smb_echo_handler(req->smb_conn->lp_ctx)) { 195 raw = 0; 196 } else { 197 raw = (lpcfg_read_raw(req->smb_conn->lp_ctx)?1:0) | 198 (lpcfg_write_raw(req->smb_conn->lp_ctx)?2:0); 199 } 200 201 req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypt_passwords(req->smb_conn->lp_ctx); 185 202 186 if (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE)187 secword |= NEGOTIATE_SECURITY_USER_LEVEL;188 189 203 if (req->smb_conn->negotiate.encrypted_passwords) 190 204 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; … … 197 211 SSVAL(req->out.vwv, VWV(1), secword); 198 212 SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv); 199 SSVAL(req->out.vwv, VWV(3), lpcfg_max mux(req->smb_conn->lp_ctx));213 SSVAL(req->out.vwv, VWV(3), lpcfg_max_mux(req->smb_conn->lp_ctx)); 200 214 SSVAL(req->out.vwv, VWV(4), 1); 201 215 SSVAL(req->out.vwv, VWV(5), raw); 202 SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id. id);216 SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.pid); 203 217 srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t); 204 218 SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60); … … 239 253 } 240 254 255 /* 256 try to determine if the filesystem supports large files 257 */ 258 static bool large_file_support(const char *path) 259 { 260 int fd; 261 ssize_t ret; 262 char c; 263 264 fd = open(path, O_RDWR|O_CREAT, 0600); 265 unlink(path); 266 if (fd == -1) { 267 /* have to assume large files are OK */ 268 return true; 269 } 270 ret = pread(fd, &c, 1, ((uint64_t)1)<<32); 271 close(fd); 272 return ret == 0; 273 } 274 241 275 /**************************************************************************** 242 276 Reply for the nt protocol. … … 258 292 CAP_LEVEL_II_OPLOCKS | CAP_NT_SMBS | CAP_RPC_REMOTE_APIS; 259 293 260 req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypt ed_passwords(req->smb_conn->lp_ctx);294 req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypt_passwords(req->smb_conn->lp_ctx); 261 295 262 296 /* do spnego in user level security if the client … … 264 298 265 299 if (req->smb_conn->negotiate.encrypted_passwords && 266 (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE) &&267 300 lpcfg_use_spnego(req->smb_conn->lp_ctx) && 268 301 (req->flags2 & FLAGS2_EXTENDED_SECURITY)) { … … 271 304 } 272 305 273 if (lpcfg_unix_extensions(req->smb_conn->lp_ctx)) {274 capabilities |= CAP_UNIX;275 }276 277 306 if (lpcfg_large_readwrite(req->smb_conn->lp_ctx)) { 278 307 capabilities |= CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS; 279 308 } 280 309 281 large_test_path = l ock_path(req, req->smb_conn->lp_ctx, "large_test.dat");310 large_test_path = lpcfg_lock_path(req, req->smb_conn->lp_ctx, "large_test.dat"); 282 311 if (large_file_support(large_test_path)) { 283 312 capabilities |= CAP_LARGE_FILES; 284 313 } 285 314 286 if (lpcfg_readraw(req->smb_conn->lp_ctx) && 287 lpcfg_writeraw(req->smb_conn->lp_ctx)) { 315 if (!lpcfg_async_smb_echo_handler(req->smb_conn->lp_ctx) && 316 lpcfg_read_raw(req->smb_conn->lp_ctx) && 317 lpcfg_write_raw(req->smb_conn->lp_ctx)) { 288 318 capabilities |= CAP_RAW_MODE; 289 319 } … … 302 332 } 303 333 304 if (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE) { 305 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 306 } 334 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 307 335 308 336 if (req->smb_conn->negotiate.encrypted_passwords) { … … 329 357 the specification - all the command words after the secword 330 358 are offset by 1 byte */ 331 SSVAL(req->out.vwv+1, VWV(1), lpcfg_max mux(req->smb_conn->lp_ctx));359 SSVAL(req->out.vwv+1, VWV(1), lpcfg_max_mux(req->smb_conn->lp_ctx)); 332 360 SSVAL(req->out.vwv+1, VWV(2), 1); /* num vcs */ 333 361 SIVAL(req->out.vwv+1, VWV(3), req->smb_conn->negotiate.max_recv); 334 362 SIVAL(req->out.vwv+1, VWV(5), 0x10000); /* raw size. full 64k */ 335 SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->server_id.id); /* session key */ 363 SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->server_id.pid); /* session key */ 364 336 365 SIVAL(req->out.vwv+1, VWV(9), capabilities); 337 366 push_nttime(req->out.vwv+1, VWV(11), nttime); … … 359 388 if (!NT_STATUS_IS_OK(nt_status)) { 360 389 DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); 361 talloc_free(server_credentials); 362 server_credentials = NULL; 390 /* 391 * We keep the server_credentials as anonymous 392 * this is required for the spoolss.notify test 393 */ 363 394 } 364 395 … … 383 414 req->smb_conn->negotiate.server_credentials = talloc_reparent(req, req->smb_conn, server_credentials); 384 415 385 gensec_set_target_service(gensec_security, "cifs");386 387 gensec_set_credentials(gensec_security, server_credentials);388 389 416 oid = GENSEC_OID_SPNEGO; 390 417 nt_status = gensec_start_mech_by_oid(gensec_security, oid); … … 392 419 if (NT_STATUS_IS_OK(nt_status)) { 393 420 /* Get and push the proposed OID list into the packets */ 394 nt_status = gensec_update (gensec_security, req, null_data_blob, &blob);421 nt_status = gensec_update_ev(gensec_security, req, req->smb_conn->connection->event.ctx, null_data_blob, &blob); 395 422 396 423 if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { … … 465 492 int protocol_level; 466 493 } supported_protocols[] = { 467 {"SMB 2.002", "SMB2", reply_smb2, PROTOCOL_SMB2 },494 {"SMB 2.002", "SMB2", reply_smb2, PROTOCOL_SMB2_02}, 468 495 {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1}, 469 496 {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1}, … … 489 516 uint8_t *p; 490 517 uint32_t protos_count = 0; 491 c har **protos = NULL;518 const char **protos = NULL; 492 519 493 520 if (req->smb_conn->negotiate.done_negprot) { … … 501 528 size_t len; 502 529 503 protos = talloc_realloc(req, protos, c har *, protos_count + 1);530 protos = talloc_realloc(req, protos, const char *, protos_count + 1); 504 531 if (!protos) { 505 532 smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY)); … … 507 534 } 508 535 protos[protos_count] = NULL; 509 len = req_pull_ascii4(&req->in.bufinfo, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);536 len = req_pull_ascii4(&req->in.bufinfo, &protos[protos_count], p, STR_ASCII|STR_TERMINATE); 510 537 p += len; 511 538 if (len == 0 || !protos[protos_count]) break; … … 519 546 int i; 520 547 521 if (supported_protocols[protocol].protocol_level > lpcfg_s rv_maxprotocol(req->smb_conn->lp_ctx))548 if (supported_protocols[protocol].protocol_level > lpcfg_server_max_protocol(req->smb_conn->lp_ctx)) 522 549 continue; 523 if (supported_protocols[protocol].protocol_level < lpcfg_s rv_minprotocol(req->smb_conn->lp_ctx))550 if (supported_protocols[protocol].protocol_level < lpcfg_server_min_protocol(req->smb_conn->lp_ctx)) 524 551 continue; 525 552 -
vendor/current/source4/smb_server/smb/receive.c
r740 r988 26 26 #include "system/filesys.h" 27 27 #include "param/param.h" 28 28 #include "cluster/cluster.h" 29 29 30 30 /* … … 104 104 /* 0x0e */ { "SMBctemp", smbsrv_reply_ctemp, NEED_SESS|NEED_TCON }, 105 105 /* 0x0f */ { "SMBmknew", smbsrv_reply_mknew, NEED_SESS|NEED_TCON }, 106 /* 0x10 */ { "SMBch kpth", smbsrv_reply_chkpth, NEED_SESS|NEED_TCON },106 /* 0x10 */ { "SMBcheckpath", smbsrv_reply_chkpth, NEED_SESS|NEED_TCON }, 107 107 /* 0x11 */ { "SMBexit", smbsrv_reply_exit, NEED_SESS }, 108 108 /* 0x12 */ { "SMBlseek", smbsrv_reply_lseek, NEED_SESS|NEED_TCON }, … … 472 472 struct smbsrv_connection *smb_conn = req->smb_conn; 473 473 NTSTATUS status; 474 struct server_id_buf idbuf; 474 475 475 476 type &= 0xff; … … 492 493 chaining) */ 493 494 494 /* In share mode security we must ignore the vuid. */ 495 if (smb_conn->config.security == SEC_SHARE) { 496 if (req->tcon) { 497 req->session = req->tcon->sec_share.session; 498 } 499 } else { 500 req->session = smbsrv_session_find(req->smb_conn, SVAL(req->in.hdr,HDR_UID), req->request_time); 501 } 502 } 503 504 DEBUG(5,("switch message %s (task_id %u)\n", 505 smb_fn_name(type), (unsigned)req->smb_conn->connection->server_id.id)); 495 req->session = smbsrv_session_find(req->smb_conn, SVAL(req->in.hdr,HDR_UID), req->request_time); 496 } 497 498 DEBUG(5, ("switch message %s (task_id %s)\n", 499 smb_fn_name(type), 500 server_id_str_buf(req->smb_conn->connection->server_id, 501 &idbuf))); 506 502 507 503 /* this must be called before we do any reply */ … … 638 634 639 635 /* cleanup somestuff for the next request */ 640 talloc_free(req->ntvfs); 636 DLIST_REMOVE(req->smb_conn->requests, req); 637 talloc_unlink(req, req->ntvfs); 641 638 req->ntvfs = NULL; 642 639 talloc_free(req->io_ptr); … … 668 665 smb_conn->negotiate.zone_offset = get_time_zone(time(NULL)); 669 666 670 smb_conn->config.security = lpcfg_security(lp_ctx);671 667 smb_conn->config.nt_status_support = lpcfg_nt_status_support(lp_ctx); 672 668 -
vendor/current/source4/smb_server/smb/reply.c
r740 r988 28 28 #include "ntvfs/ntvfs.h" 29 29 #include "librpc/gen_ndr/ndr_nbt.h" 30 #include "libcli/nbt/libnbt.h" 30 31 31 32 … … 848 849 { 849 850 union smb_read *io; 851 uint16_t high_part = 0; 850 852 851 853 /* parse request */ … … 869 871 } 870 872 871 if (req->smb_conn->negotiate.client_caps & CAP_LARGE_READX) { 872 uint32_t high_part = IVAL(req->in.vwv, VWV(7)); 873 if (high_part == 1) { 874 io->readx.in.maxcnt |= high_part << 16; 875 } 876 } 877 873 if (req->smb_conn->negotiate.protocol == PROTOCOL_NT1) { 874 high_part = SVAL(req->in.vwv, VWV(7)); 875 } 876 if (high_part != UINT16_MAX) { 877 io->readx.in.maxcnt |= high_part << 16; 878 } 879 880 /* 881 * Windows truncates the length to 0x10000 882 */ 883 io->readx.in.maxcnt = MIN(io->readx.in.maxcnt, 0x10000); 884 878 885 /* the 64 bit variant */ 879 886 if (req->in.wct == 12) { … … 2334 2341 2335 2342 switch (msg_type) { 2336 case 0x81: /* session request */2343 case NBSSrequest: /* session request */ 2337 2344 if (req->smb_conn->negotiate.done_nbt_session) { 2338 2345 DEBUG(0,("Warning: ignoring secondary session request\n")); … … 2354 2361 case 0x89: /* session keepalive request 2355 2362 (some old clients produce this?) */ 2356 SCVAL(buf, 0, SMBkeepalive);2363 SCVAL(buf, 0, NBSSkeepalive); 2357 2364 SCVAL(buf, 3, 0); 2358 2365 req->out.buffer = buf; … … 2361 2368 return; 2362 2369 2363 case SMBkeepalive:2370 case NBSSkeepalive: 2364 2371 /* session keepalive - swallow it */ 2365 2372 talloc_free(req); -
vendor/current/source4/smb_server/smb/request.c
r740 r988 312 312 313 313 if (req->out.size > NBT_HDR_SIZE) { 314 _smb_setlen (req->out.buffer, req->out.size - NBT_HDR_SIZE);314 _smb_setlen_nbt(req->out.buffer, req->out.size - NBT_HDR_SIZE); 315 315 } 316 316 … … 484 484 bool ret; 485 485 char *dest2; 486 size_t converted_size = 0; 486 487 487 488 if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) { … … 513 514 } 514 515 515 ret = convert_string_talloc(bufinfo->mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2, NULL, false);516 ret = convert_string_talloc(bufinfo->mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2, &converted_size); 516 517 517 518 if (!ret) { … … 542 543 bool ret; 543 544 char *dest2; 545 size_t converted_size = 0; 544 546 545 547 if (flags & STR_NO_RANGE_CHECK) { … … 562 564 } 563 565 564 ret = convert_string_talloc(bufinfo->mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2, NULL, false);566 ret = convert_string_talloc(bufinfo->mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2, &converted_size); 565 567 566 568 if (!ret) { -
vendor/current/source4/smb_server/smb/service.c
r740 r988 112 112 const char *type_str; 113 113 struct share_config *scfg; 114 c onst char *sharetype;114 char *sharetype; 115 115 116 116 /* the service might be of the form \\SERVER\SHARE. Should we put … … 125 125 status = share_get_config(req, req->smb_conn->share_context, service, &scfg); 126 126 if (!NT_STATUS_IS_OK(status)) { 127 DEBUG(0,("make_connection: couldn't find service %s \n", service));127 DEBUG(0,("make_connection: couldn't find service %s: %s\n", service, nt_errstr(status))); 128 128 return NT_STATUS_BAD_NETWORK_NAME; 129 129 } … … 139 139 140 140 /* work out what sort of connection this is */ 141 sharetype = share_string_option( scfg, "type", "DISK");141 sharetype = share_string_option(req, scfg, "type", "DISK"); 142 142 if (sharetype && strcmp(sharetype, "IPC") == 0) { 143 143 type = NTVFS_IPC; … … 150 150 type_str = "A:"; 151 151 } 152 TALLOC_FREE(sharetype); 152 153 153 154 if (strcmp(dev, "?????") != 0 && strcasecmp(type_str, dev) != 0) { -
vendor/current/source4/smb_server/smb/sesssetup.c
r740 r988 35 35 36 36 struct sesssetup_context { 37 struct auth _context *auth_context;37 struct auth4_context *auth_context; 38 38 struct smbsrv_request *req; 39 39 }; … … 84 84 } 85 85 /* This references user_info_dc into session_info */ 86 status = req->smb_conn->negotiate.auth_context->generate_session_info(req, 87 req->smb_conn->negotiate.auth_context, 88 user_info_dc, flags, &session_info); 86 status = req->smb_conn->negotiate.auth_context->generate_session_info(req->smb_conn->negotiate.auth_context, 87 req, 88 user_info_dc, sess->old.in.user, 89 flags, &session_info); 89 90 if (!NT_STATUS_IS_OK(status)) goto failed; 90 91 … … 215 216 } 216 217 /* This references user_info_dc into session_info */ 217 status = state->auth_context->generate_session_info( req,218 state->auth_context,218 status = state->auth_context->generate_session_info(state->auth_context, 219 req, 219 220 user_info_dc, 221 sess->nt1.in.user, 220 222 flags, 221 223 &session_info); … … 262 264 struct tevent_req *subreq; 263 265 struct sesssetup_context *state; 266 bool allow_raw = lpcfg_raw_ntlmv2_auth(req->smb_conn->lp_ctx); 264 267 265 268 sess->nt1.out.vuid = 0; … … 337 340 user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data); 338 341 342 if (!allow_raw && user_info->password.response.nt.length >= 48) { 343 /* 344 * NTLMv2_RESPONSE has at least 48 bytes 345 * and should only be supported via NTLMSSP. 346 */ 347 status = NT_STATUS_INVALID_PARAMETER; 348 goto failed; 349 } 350 339 351 subreq = auth_check_password_send(state, 340 352 req->smb_conn->connection->event.ctx, … … 380 392 } 381 393 382 status = gensec_session_info(smb_sess->gensec_ctx, &session_info); 383 if (!NT_STATUS_IS_OK(status)) goto failed; 384 385 skey_status = gensec_session_key(smb_sess->gensec_ctx, &session_key); 394 status = gensec_session_info(smb_sess->gensec_ctx, smb_sess, &session_info); 395 if (!NT_STATUS_IS_OK(status)) goto failed; 396 397 /* The session_key is only needed until the end of the smbsrv_setup_signing() call */ 398 skey_status = gensec_session_key(smb_sess->gensec_ctx, req, &session_key); 386 399 if (NT_STATUS_IS_OK(skey_status)) { 387 400 smbsrv_setup_signing(req->smb_conn, &session_key, NULL); … … 413 426 NTSTATUS status; 414 427 struct smbsrv_session *smb_sess = NULL; 428 bool is_smb_sess_new = false; 415 429 struct sesssetup_spnego_state *s = NULL; 416 430 uint16_t vuid; … … 433 447 434 448 /* lookup an existing session */ 435 smb_sess = smbsrv_session_find_sesssetup(req->smb_conn, vuid); 436 if (!smb_sess) { 449 if (vuid == 0) { 437 450 struct gensec_security *gensec_ctx; 438 451 … … 464 477 goto failed; 465 478 } 479 is_smb_sess_new = true; 480 } else { 481 smb_sess = smbsrv_session_find_sesssetup(req->smb_conn, vuid); 466 482 } 467 483 468 484 if (!smb_sess) { 469 status = NT_STATUS_ACCESS_DENIED; 485 status = NT_STATUS_DOS(ERRSRV, ERRbaduid); 486 goto failed; 487 } 488 489 if (smb_sess->session_info) { 490 status = NT_STATUS_INVALID_PARAMETER; 470 491 goto failed; 471 492 } … … 502 523 status = NT_STATUS_NO_MEMORY; 503 524 failed: 504 talloc_free(smb_sess); 525 if (is_smb_sess_new) { 526 talloc_free(smb_sess); 527 } 505 528 status = nt_status_squash(status); 506 529 smbsrv_sesssetup_backend_send(req, sess, status); -
vendor/current/source4/smb_server/smb/signing.c
r740 r988 82 82 return false; 83 83 } 84 85 switch (lpcfg_server_signing(smb_conn->lp_ctx)) {86 case SMB_SIGNING_OFF:87 smb_conn->signing.allow_smb_signing = false;88 break;89 case SMB_SIGNING_SUPPORTED:90 smb_conn->signing.allow_smb_signing = true;91 break;92 case SMB_SIGNING_REQUIRED:93 smb_conn->signing.allow_smb_signing = true;94 smb_conn->signing.mandatory_signing = true;95 break;96 case SMB_SIGNING_AUTO:97 /* If we are a domain controller, SMB signing is98 * really important, as it can prevent a number of99 * attacks on communications between us and the100 * clients */101 84 102 if (lpcfg_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) { 103 smb_conn->signing.allow_smb_signing = true; 104 smb_conn->signing.mandatory_signing = true; 105 } else { 106 /* However, it really sucks (no sendfile, CPU 107 * overhead) performance-wise when used on a 108 * file server, so disable it by default (auto 109 * is the default) on non-DCs */ 110 smb_conn->signing.allow_smb_signing = false; 111 } 112 break; 113 } 85 smb_conn->signing.allow_smb_signing 86 = lpcfg_server_signing_allowed(smb_conn->lp_ctx, 87 &smb_conn->signing.mandatory_signing); 114 88 return true; 115 89 } -
vendor/current/source4/smb_server/smb/trans2.c
r740 r988 3 3 transaction2 handling 4 4 Copyright (C) Andrew Tridgell 2003 5 Copyright Matthieu Patou 2010 mat@matws.net5 Copyright Matthieu Patou <mat@matws.net> 2010-2011 6 6 7 7 This program is free software; you can redistribute it and/or modify … … 34 34 #include "param/param.h" 35 35 #include "lib/tsocket/tsocket.h" 36 #include "dfs_server/dfs_server_ad.h" 36 37 37 38 #define MAX_DFS_RESPONSE 56*1024 /* 56 Kb */ … … 64 65 void *op_info; 65 66 }; 66 /* A DC set is a group of DC, they might have been grouped together 67 because they belong to the same site, or to site with same cost ... 68 */ 69 struct dc_set { 70 const char **names; 71 uint32_t count; 72 }; 67 73 68 #define CHECK_MIN_BLOB_SIZE(blob, size) do { \ 74 69 if ((blob)->length < (size)) { \ … … 859 854 } 860 855 861 862 /*863 fill a referral type structure864 */865 static NTSTATUS fill_normal_dfs_referraltype(struct dfs_referral_type *ref,866 uint16_t version,867 const char *dfs_path,868 const char *server_path, int isfirstoffset)869 {870 871 switch (version) {872 case 3:873 ZERO_STRUCTP(ref);874 ref->version = version;875 ref->referral.v3.data.server_type = DFS_SERVER_NON_ROOT;876 /* "normal" referral seems to always include the GUID */877 ref->referral.v3.size = 34;878 879 ref->referral.v3.data.entry_flags = 0;880 ref->referral.v3.data.ttl = 600; /* As w2k3 */881 ref->referral.v3.data.referrals.r1.DFS_path = dfs_path;882 ref->referral.v3.data.referrals.r1.DFS_alt_path = dfs_path;883 ref->referral.v3.data.referrals.r1.netw_address = server_path;884 return NT_STATUS_OK;885 case 4:886 ZERO_STRUCTP(ref);887 ref->version = version;888 ref->referral.v4.server_type = DFS_SERVER_NON_ROOT;889 /* "normal" referral seems to always include the GUID */890 ref->referral.v4.size = 34;891 892 if (isfirstoffset) {893 ref->referral.v4.entry_flags = DFS_HEADER_FLAG_TARGET_BCK;894 }895 ref->referral.v4.ttl = 600; /* As w2k3 */896 ref->referral.v4.r1.DFS_path = dfs_path;897 ref->referral.v4.r1.DFS_alt_path = dfs_path;898 ref->referral.v4.r1.netw_address = server_path;899 900 return NT_STATUS_OK;901 }902 return NT_STATUS_INVALID_LEVEL;903 }904 905 /*906 fill a domain refererral907 */908 static NTSTATUS fill_domain_dfs_referraltype(struct dfs_referral_type *ref,909 uint16_t version,910 const char *domain,911 const char **names,912 uint16_t numnames)913 {914 switch (version) {915 case 3:916 ZERO_STRUCTP(ref);917 ref->version = version;918 ref->referral.v3.data.server_type = DFS_SERVER_NON_ROOT;919 /* It's hard coded ... don't think it's a good way but the sizeof return not the920 * correct values921 *922 * We have 18 if the GUID is not included 34 otherwise923 */924 ref->referral.v3.size = 18;925 ref->referral.v3.data.entry_flags = DFS_FLAG_REFERRAL_DOMAIN_RESP;926 ref->referral.v3.data.ttl = 600; /* As w2k3 */927 ref->referral.v3.data.referrals.r2.special_name = domain;928 ref->referral.v3.data.referrals.r2.nb_expanded_names = numnames;929 /* Put the final terminator */930 if (names) {931 const char **names2 = talloc_array(ref, const char *, numnames+1);932 NT_STATUS_HAVE_NO_MEMORY(names2);933 int i;934 for (i = 0; i<numnames; i++) {935 names2[i] = talloc_asprintf(names2, "\\%s", names[i]);936 NT_STATUS_HAVE_NO_MEMORY(names2[i]);937 }938 names2[numnames] = 0;939 ref->referral.v3.data.referrals.r2.expanded_names = names2;940 }941 return NT_STATUS_OK;942 }943 return NT_STATUS_INVALID_LEVEL;944 }945 946 /*947 get the DCs list within a site948 */949 static NTSTATUS get_dcs_insite(TALLOC_CTX *ctx, struct ldb_context *ldb,950 struct ldb_dn *sitedn, struct dc_set *list,951 bool dofqdn)952 {953 static const char *attrs[] = { "serverReference", NULL };954 static const char *attrs2[] = { "dNSHostName", "sAMAccountName", NULL };955 struct ldb_result *r;956 unsigned int i;957 int ret;958 const char **dc_list;959 960 ret = ldb_search(ldb, ctx, &r, sitedn, LDB_SCOPE_SUBTREE, attrs,961 "(&(objectClass=server)(serverReference=*))");962 if (ret != LDB_SUCCESS) {963 DEBUG(2,(__location__ ": Failed to get list of servers - %s\n",964 ldb_errstring(ldb)));965 return NT_STATUS_INTERNAL_ERROR;966 }967 968 if (r->count == 0) {969 /* none in this site */970 talloc_free(r);971 return NT_STATUS_OK;972 }973 974 /*975 * need to search for all server object to know the size of the array.976 * Search all the object of class server in this site977 */978 dc_list = talloc_array(r, const char *, r->count);979 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dc_list, r);980 981 /* TODO put some random here in the order */982 list->names = talloc_realloc(list, list->names, const char *, list->count + r->count);983 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(list->names, r);984 985 for (i = 0; i<r->count; i++) {986 struct ldb_dn *dn;987 struct ldb_result *r2;988 989 dn = ldb_msg_find_attr_as_dn(ldb, ctx, r->msgs[i], "serverReference");990 if (!dn) {991 return NT_STATUS_INTERNAL_ERROR;992 }993 994 ret = ldb_search(ldb, r, &r2, dn, LDB_SCOPE_BASE, attrs2, "(objectClass=computer)");995 if (ret != LDB_SUCCESS) {996 DEBUG(2,(__location__ ": Search for computer on %s failed - %s\n",997 ldb_dn_get_linearized(dn), ldb_errstring(ldb)));998 return NT_STATUS_INTERNAL_ERROR;999 }1000 1001 if (dofqdn) {1002 const char *dns = ldb_msg_find_attr_as_string(r2->msgs[0], "dNSHostName", NULL);1003 if (dns == NULL) {1004 DEBUG(2,(__location__ ": dNSHostName missing on %s\n",1005 ldb_dn_get_linearized(dn)));1006 talloc_free(r);1007 return NT_STATUS_INTERNAL_ERROR;1008 }1009 1010 list->names[list->count] = talloc_strdup(list->names, dns);1011 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(list->names[list->count], r);1012 } else {1013 char *tmp;1014 const char *acct = ldb_msg_find_attr_as_string(r2->msgs[0], "sAMAccountName", NULL);1015 if (acct == NULL) {1016 DEBUG(2,(__location__ ": sAMAccountName missing on %s\n",1017 ldb_dn_get_linearized(dn)));1018 talloc_free(r);1019 return NT_STATUS_INTERNAL_ERROR;1020 }1021 1022 tmp = talloc_strdup(list->names, acct);1023 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(tmp, r);1024 1025 /* Netbios name is also the sAMAccountName for1026 computer but without the final $ */1027 tmp[strlen(tmp) - 1] = '\0';1028 list->names[list->count] = tmp;1029 }1030 list->count++;1031 talloc_free(r2);1032 }1033 1034 talloc_free(r);1035 return NT_STATUS_OK;1036 }1037 1038 1039 /*1040 get all DCs1041 */1042 static NTSTATUS get_dcs(TALLOC_CTX *ctx, struct ldb_context *ldb,1043 const char *searched_site, bool need_fqdn,1044 struct dc_set ***pset_list, uint32_t flags)1045 {1046 /*1047 * Flags will be used later to indicate things like least-expensive1048 * or same-site options1049 */1050 const char *attrs_none[] = { NULL };1051 const char *attrs3[] = { "name", NULL };1052 struct ldb_dn *configdn, *sitedn, *dn, *sitescontainerdn;1053 struct ldb_result *r;1054 struct dc_set **set_list = NULL;1055 uint32_t i;1056 int ret;1057 uint32_t current_pos = 0;1058 NTSTATUS status;1059 TALLOC_CTX *subctx = talloc_new(ctx);1060 1061 *pset_list = set_list = NULL;1062 1063 subctx = talloc_new(ctx);1064 NT_STATUS_HAVE_NO_MEMORY(subctx);1065 1066 configdn = ldb_get_config_basedn(ldb);1067 1068 /* Let's search for the Site container */1069 ret = ldb_search(ldb, subctx, &r, configdn, LDB_SCOPE_SUBTREE, attrs_none,1070 "(objectClass=sitesContainer)");1071 if (ret != LDB_SUCCESS) {1072 DEBUG(2,(__location__ ": Failed to find sitesContainer within %s - %s\n",1073 ldb_dn_get_linearized(configdn), ldb_errstring(ldb)));1074 talloc_free(subctx);1075 return NT_STATUS_INTERNAL_ERROR;1076 }1077 if (r->count > 1) {1078 DEBUG(2,(__location__ ": Expected 1 sitesContainer - found %u within %s\n",1079 r->count, ldb_dn_get_linearized(configdn)));1080 talloc_free(subctx);1081 return NT_STATUS_INTERNAL_ERROR;1082 }1083 1084 sitescontainerdn = talloc_steal(subctx, r->msgs[0]->dn);1085 talloc_free(r);1086 1087 /*1088 * TODO: Here we should have a more subtle handling1089 * for the case "same-site"1090 */1091 ret = ldb_search(ldb, subctx, &r, sitescontainerdn, LDB_SCOPE_SUBTREE,1092 attrs_none, "(objectClass=server)");1093 if (ret != LDB_SUCCESS) {1094 DEBUG(2,(__location__ ": Failed to find servers within %s - %s\n",1095 ldb_dn_get_linearized(sitescontainerdn), ldb_errstring(ldb)));1096 talloc_free(subctx);1097 return NT_STATUS_INTERNAL_ERROR;1098 }1099 talloc_free(r);1100 1101 if (searched_site != NULL) {1102 ret = ldb_search(ldb, subctx, &r, configdn, LDB_SCOPE_SUBTREE,1103 attrs_none, "(&(name=%s)(objectClass=site))", searched_site);1104 if (ret != LDB_SUCCESS) {1105 talloc_free(subctx);1106 return NT_STATUS_FOOBAR;1107 } else if (r->count != 1) {1108 talloc_free(subctx);1109 return NT_STATUS_FOOBAR;1110 }1111 1112 /* All of this was to get the DN of the searched_site */1113 sitedn = r->msgs[0]->dn;1114 1115 set_list = talloc_realloc(subctx, set_list, struct dc_set *, current_pos+1);1116 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(set_list, subctx);1117 1118 set_list[current_pos] = talloc(set_list, struct dc_set);1119 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(set_list[current_pos], subctx);1120 1121 set_list[current_pos]->names = NULL;1122 set_list[current_pos]->count = 0;1123 status = get_dcs_insite(subctx, ldb, sitedn,1124 set_list[current_pos], need_fqdn);1125 if (!NT_STATUS_IS_OK(status)) {1126 DEBUG(2,(__location__ ": Failed to get DC from site %s - %s\n",1127 ldb_dn_get_linearized(sitedn), nt_errstr(status)));1128 talloc_free(subctx);1129 return status;1130 }1131 talloc_free(r);1132 current_pos++;1133 }1134 1135 /* Let's find all the sites */1136 ret = ldb_search(ldb, subctx, &r, configdn, LDB_SCOPE_SUBTREE, attrs3, "(objectClass=site)");1137 if (ret != LDB_SUCCESS) {1138 DEBUG(2,(__location__ ": Failed to find any site containers in %s\n",1139 ldb_dn_get_linearized(configdn)));1140 talloc_free(subctx);1141 return NT_STATUS_INTERNAL_DB_CORRUPTION;1142 }1143 1144 /*1145 * TODO:1146 * We should randomize the order in the main site,1147 * it's mostly needed for sysvol/netlogon referral.1148 * Depending of flag we either randomize order of the1149 * not "in the same site DCs"1150 * or we randomize by group of site that have the same cost1151 * In the long run we want to manipulate an array of site_set1152 * All the site in one set have the same cost (if least-expansive options is selected)1153 * and we will put all the dc related to 1 site set into 1 DCs set.1154 * Within a site set, site order has to be randomized1155 *1156 * But for the moment we just return the list of sites1157 */1158 if (r->count) {1159 /*1160 * We will realloc + 2 because we will need one additional place1161 * for element at current_pos + 1 for the NULL element1162 */1163 set_list = talloc_realloc(subctx, set_list, struct dc_set *,1164 current_pos+2);1165 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(set_list, subctx);1166 1167 set_list[current_pos] = talloc(ctx, struct dc_set);1168 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(set_list[current_pos], subctx);1169 1170 set_list[current_pos]->names = NULL;1171 set_list[current_pos]->count = 0;1172 1173 set_list[current_pos+1] = NULL;1174 }1175 1176 for (i=0; i<r->count; i++) {1177 const char *site_name = ldb_msg_find_attr_as_string(r->msgs[i], "name", NULL);1178 if (site_name == NULL) {1179 DEBUG(2,(__location__ ": Failed to find name attribute in %s\n",1180 ldb_dn_get_linearized(r->msgs[i]->dn)));1181 talloc_free(subctx);1182 return NT_STATUS_INTERNAL_DB_CORRUPTION;1183 }1184 1185 if (searched_site == NULL ||1186 strcmp(searched_site, site_name) != 0) {1187 DEBUG(2,(__location__ ": Site: %s %s\n",1188 searched_site, site_name));1189 1190 /*1191 * Do all the site but the one of the client1192 * (because it has already been done ...)1193 */1194 dn = r->msgs[i]->dn;1195 1196 status = get_dcs_insite(subctx, ldb, dn,1197 set_list[current_pos],1198 need_fqdn);1199 if (!NT_STATUS_IS_OK(status)) {1200 talloc_free(subctx);1201 return status;1202 }1203 }1204 }1205 current_pos++;1206 set_list[current_pos] = NULL;1207 1208 *pset_list = talloc_move(ctx, &set_list);1209 talloc_free(subctx);1210 return NT_STATUS_OK;1211 }1212 1213 static NTSTATUS dodomain_referral(TALLOC_CTX *ctx,1214 const struct dfs_GetDFSReferral_in *dfsreq,1215 struct ldb_context *ldb,1216 struct smb_trans2 *trans,1217 struct loadparm_context *lp_ctx)1218 {1219 /*1220 * TODO for the moment we just return the local domain1221 */1222 DATA_BLOB outblob;1223 enum ndr_err_code ndr_err;1224 NTSTATUS status;1225 const char *dns_domain = lpcfg_dnsdomain(lp_ctx);1226 const char *netbios_domain = lpcfg_workgroup(lp_ctx);1227 struct dfs_referral_resp resp;1228 struct dfs_referral_type *tab;1229 struct dfs_referral_type *referral;1230 const char *referral_str;1231 /* In the future this needs to be fetched from the ldb */1232 uint32_t found_domain = 2;1233 uint32_t current_pos = 0;1234 TALLOC_CTX *context;1235 1236 if (lpcfg_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {1237 DEBUG(10 ,("Received a domain referral request on a non DC\n"));1238 return NT_STATUS_INVALID_PARAMETER;1239 }1240 1241 if (dfsreq->max_referral_level < 3) {1242 DEBUG(2,("invalid max_referral_level %u\n",1243 dfsreq->max_referral_level));1244 return NT_STATUS_UNSUCCESSFUL;1245 }1246 1247 context = talloc_new(ctx);1248 NT_STATUS_HAVE_NO_MEMORY(context);1249 1250 resp.path_consumed = 0;1251 resp.header_flags = 0; /* Do like w2k3 */1252 resp.nb_referrals = found_domain; /* the fqdn one + the NT domain */1253 1254 tab = talloc_array(context, struct dfs_referral_type, found_domain);1255 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(tab, context);1256 1257 referral = talloc(tab, struct dfs_referral_type);1258 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context);1259 referral_str = talloc_asprintf(referral, "\\%s", netbios_domain);1260 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context);1261 status = fill_domain_dfs_referraltype(referral, 3,1262 referral_str,1263 NULL, 0);1264 if (!NT_STATUS_IS_OK(status)) {1265 DEBUG(2,(__location__ ":Unable to fill domain referral structure\n"));1266 talloc_free(context);1267 return NT_STATUS_UNSUCCESSFUL;1268 }1269 1270 tab[current_pos] = *referral;1271 current_pos++;1272 1273 referral = talloc(tab, struct dfs_referral_type);1274 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context);1275 referral_str = talloc_asprintf(referral, "\\%s", dns_domain);1276 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context);1277 status = fill_domain_dfs_referraltype(referral, 3,1278 referral_str,1279 NULL, 0);1280 if (!NT_STATUS_IS_OK(status)) {1281 DEBUG(2,(__location__ ":Unable to fill domain referral structure\n"));1282 talloc_free(context);1283 return NT_STATUS_UNSUCCESSFUL;1284 }1285 tab[current_pos] = *referral;1286 current_pos++;1287 1288 /*1289 * Put here the code from filling the array for trusted domain1290 */1291 resp.referral_entries = tab;1292 1293 ndr_err = ndr_push_struct_blob(&outblob, context,1294 &resp,1295 (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);1296 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {1297 DEBUG(2,(__location__ ":NDR marchalling of domain deferral response failed\n"));1298 talloc_free(context);1299 return NT_STATUS_INTERNAL_ERROR;1300 }1301 1302 if (outblob.length > trans->in.max_data) {1303 bool ok = false;1304 1305 DEBUG(3, ("Blob is too big for the output buffer "1306 "size %u max %u\n",1307 (unsigned int)outblob.length, trans->in.max_data));1308 1309 if (trans->in.max_data != MAX_DFS_RESPONSE) {1310 /* As specified in MS-DFSC.pdf 3.3.5.2 */1311 talloc_free(context);1312 return STATUS_BUFFER_OVERFLOW;1313 }1314 1315 /*1316 * The answer is too big, so let's remove some answers1317 */1318 while (!ok && resp.nb_referrals > 2) {1319 data_blob_free(&outblob);1320 1321 /*1322 * Let's scrap the first referral (for now)1323 */1324 resp.nb_referrals -= 1;1325 resp.referral_entries += 1;1326 1327 ndr_err = ndr_push_struct_blob(&outblob, context,1328 &resp,1329 (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);1330 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {1331 talloc_free(context);1332 return NT_STATUS_INTERNAL_ERROR;1333 }1334 1335 if (outblob.length <= MAX_DFS_RESPONSE) {1336 DEBUG(10,("DFS: managed to reduce the size of referral initial"1337 "number of referral %d, actual count: %d",1338 found_domain, resp.nb_referrals));1339 ok = true;1340 break;1341 }1342 }1343 1344 if (!ok && resp.nb_referrals == 2) {1345 DEBUG(0, (__location__ "; Not able to fit the domain and realm in DFS a "1346 " 56K buffer, something must be broken"));1347 talloc_free(context);1348 return NT_STATUS_INTERNAL_ERROR;1349 }1350 }1351 1352 TRANS2_CHECK(trans2_setup_reply(trans, 0, outblob.length, 0));1353 1354 trans->out.data = outblob;1355 talloc_steal(ctx, outblob.data);1356 talloc_free(context);1357 return NT_STATUS_OK;1358 }1359 1360 /*1361 * Handle the logic for dfs referral request like \\domain1362 * or \\domain\sysvol or \\fqdn or \\fqdn\netlogon1363 */1364 static NTSTATUS dodc_or_sysvol_referral(TALLOC_CTX *ctx,1365 const struct dfs_GetDFSReferral_in dfsreq,1366 const char* requestedname,1367 struct ldb_context *ldb,1368 struct smb_trans2 *trans,1369 struct smbsrv_request *req,1370 struct loadparm_context *lp_ctx)1371 {1372 /*1373 * It's not a "standard" DFS referral but a referral to get the DC list1374 * or sysvol/netlogon1375 * Let's check that it's for one of our domain ...1376 */1377 DATA_BLOB outblob;1378 NTSTATUS status;1379 unsigned int num_domain = 1;1380 enum ndr_err_code ndr_err;1381 const char *requesteddomain;1382 const char *realm = lpcfg_realm(lp_ctx);1383 const char *domain = lpcfg_workgroup(lp_ctx);1384 const char *site_name = NULL; /* Name of the site where the client is */1385 char *share = NULL;1386 bool found = false;1387 bool need_fqdn = false;1388 bool dc_referral = true;1389 unsigned int i;1390 char *tmp;1391 struct dc_set **set;1392 char const **domain_list;1393 struct tsocket_address *remote_address;1394 char *client_addr = NULL;1395 TALLOC_CTX *context;1396 1397 if (lpcfg_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {1398 return NT_STATUS_INVALID_PARAMETER;1399 }1400 1401 if (dfsreq.max_referral_level < 3) {1402 DEBUG(2,("invalid max_referral_level %u\n",1403 dfsreq.max_referral_level));1404 return NT_STATUS_UNSUCCESSFUL;1405 }1406 1407 context = talloc_new(ctx);1408 NT_STATUS_HAVE_NO_MEMORY(context);1409 1410 if (requestedname[0] == '\\' && !strchr(requestedname+1,'\\')) {1411 requestedname++;1412 }1413 requesteddomain = requestedname;1414 1415 if (strchr(requestedname,'\\')) {1416 char *subpart;1417 /* we have a second part */1418 requesteddomain = talloc_strdup(context, requestedname+1);1419 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(requesteddomain, context);1420 subpart = strchr(requesteddomain,'\\');1421 subpart[0] = '\0';1422 }1423 tmp = strchr(requestedname + 1,'\\'); /* To get second \ if any */1424 1425 if (tmp != NULL) {1426 /* There was a share */1427 share = tmp+1;1428 dc_referral = false;1429 }1430 1431 /*1432 * We will fetch the trusted domain list soon with something like this:1433 *1434 * "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)1435 * (trustPartner=%s))(objectclass=trustedDomain))"1436 *1437 * Allocate for num_domain + 1 so that the last element will be NULL)1438 */1439 domain_list = talloc_array(context, const char*, num_domain+1);1440 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_list, context);1441 1442 domain_list[0] = realm;1443 domain_list[1] = domain;1444 for (i=0; i<=num_domain; i++) {1445 if (strncasecmp(domain_list[i], requesteddomain, strlen(domain_list[i])) == 0) {1446 found = true;1447 break;1448 }1449 }1450 1451 if (!found) {1452 /* The requested domain is not one that we support */1453 DEBUG(3,("Requested referral for domain %s, but we don't handle it",1454 requesteddomain));1455 return NT_STATUS_INVALID_PARAMETER;1456 }1457 1458 if (strchr(requestedname,'.')) {1459 need_fqdn = 1;1460 }1461 1462 remote_address = req->smb_conn->connection->remote_address;1463 if (tsocket_address_is_inet(remote_address, "ip")) {1464 client_addr = tsocket_address_inet_addr_string(remote_address, context);1465 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(client_addr, context);1466 }1467 1468 status = get_dcs(context, ldb, site_name, need_fqdn, &set, 0);1469 if (!NT_STATUS_IS_OK(status)) {1470 DEBUG(3,("Unable to get list of DCs\n"));1471 talloc_free(context);1472 return status;1473 }1474 1475 if (dc_referral) {1476 const char **dc_list = NULL;1477 uint32_t num_dcs = 0;1478 struct dfs_referral_type *referral;1479 const char *referral_str;1480 struct dfs_referral_resp resp;1481 1482 for(i=0; set[i]; i++) {1483 uint32_t j;1484 1485 dc_list = talloc_realloc(context, dc_list, const char*,1486 num_dcs + set[i]->count + 1);1487 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dc_list, context);1488 1489 for(j=0; j<set[i]->count; j++) {1490 dc_list[num_dcs + j] = talloc_move(context, &set[i]->names[j]);1491 }1492 num_dcs = num_dcs + set[i]->count;1493 TALLOC_FREE(set[i]);1494 dc_list[num_dcs] = NULL;1495 }1496 1497 resp.path_consumed = 0;1498 resp.header_flags = 0; /* Do like w2k3 and like in 3.3.5.3 of MS-DFSC*/1499 1500 /*1501 * The NumberOfReferrals field MUST be set to 1,1502 * independent of the number of DC names1503 * returned. (as stated in 3.3.5.3 of MS-DFSC)1504 */1505 resp.nb_referrals = 1;1506 1507 /* Put here the code from filling the array for trusted domain */1508 referral = talloc(context, struct dfs_referral_type);1509 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context);1510 1511 referral_str = talloc_asprintf(referral, "\\%s",1512 requestedname);1513 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context);1514 1515 status = fill_domain_dfs_referraltype(referral, 3,1516 referral_str,1517 dc_list, num_dcs);1518 if (!NT_STATUS_IS_OK(status)) {1519 DEBUG(2,(__location__ ":Unable to fill domain referral structure\n"));1520 talloc_free(context);1521 return NT_STATUS_UNSUCCESSFUL;1522 }1523 resp.referral_entries = referral;1524 1525 ndr_err = ndr_push_struct_blob(&outblob, context,1526 &resp,1527 (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);1528 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {1529 DEBUG(2,(__location__ ":NDR marshalling of dfs referral response failed\n"));1530 talloc_free(context);1531 return NT_STATUS_INTERNAL_ERROR;1532 }1533 } else {1534 unsigned int nb_entries = 0;1535 unsigned int current = 0;1536 struct dfs_referral_type *tab;1537 struct dfs_referral_resp resp;1538 1539 for(i=0; set[i]; i++) {1540 nb_entries = nb_entries + set[i]->count;1541 }1542 1543 resp.path_consumed = 2*strlen(requestedname); /* The length is expected in bytes */1544 resp.header_flags = DFS_HEADER_FLAG_STORAGE_SVR; /* Do like w2k3 and like in 3.3.5.3 of MS-DFSC*/1545 1546 /*1547 * The NumberOfReferrals field MUST be set to 1,1548 * independent of the number of DC names1549 * returned. (as stated in 3.3.5.3 of MS-DFSC)1550 */1551 resp.nb_referrals = nb_entries;1552 1553 tab = talloc_array(context, struct dfs_referral_type, nb_entries);1554 NT_STATUS_HAVE_NO_MEMORY(tab);1555 1556 for(i=0; set[i]; i++) {1557 uint32_t j;1558 1559 for(j=0; j< set[i]->count; j++) {1560 struct dfs_referral_type *referral;1561 const char *referral_str;1562 1563 referral = talloc(tab, struct dfs_referral_type);1564 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context);1565 1566 referral_str = talloc_asprintf(referral, "\\%s\\%s",1567 set[i]->names[j], share);1568 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context);1569 1570 status = fill_normal_dfs_referraltype(referral,1571 dfsreq.max_referral_level,1572 requestedname, referral_str, j==0);1573 if (!NT_STATUS_IS_OK(status)) {1574 DEBUG(2, (__location__ ": Unable to fill a normal dfs referral object"));1575 talloc_free(context);1576 return NT_STATUS_UNSUCCESSFUL;1577 }1578 tab[current] = *referral;1579 current++;1580 }1581 }1582 resp.referral_entries = tab;1583 1584 ndr_err = ndr_push_struct_blob(&outblob, context,1585 &resp,1586 (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);1587 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {1588 DEBUG(2,(__location__ ":NDR marchalling of domain deferral response failed\n"));1589 talloc_free(context);1590 return NT_STATUS_INTERNAL_ERROR;1591 }1592 }1593 1594 TRANS2_CHECK(trans2_setup_reply(trans, 0, outblob.length, 0));1595 1596 /*1597 * TODO If the size is too big we should remove1598 * some DC from the answer or return STATUS_BUFFER_OVERFLOW1599 */1600 trans->out.data = outblob;1601 talloc_steal(ctx, outblob.data);1602 talloc_free(context);1603 return NT_STATUS_OK;1604 }1605 1606 856 /* 1607 857 trans2 getdfsreferral implementation … … 1612 862 enum ndr_err_code ndr_err; 1613 863 struct smb_trans2 *trans = op->trans; 1614 struct dfs_GetDFSReferral_in dfsreq;1615 TALLOC_CTX *context;1616 864 struct ldb_context *ldb; 1617 865 struct loadparm_context *lp_ctx; 1618 const char *realm, *nbname, *requestedname;1619 char *fqdn, *tmp;1620 866 NTSTATUS status; 867 struct dfs_GetDFSReferral *r; 868 DATA_BLOB outblob = data_blob_null; 869 uint16_t nb_referrals = 0; 1621 870 1622 871 lp_ctx = req->tcon->ntvfs->lp_ctx; … … 1625 874 } 1626 875 1627 context = talloc_new(req);1628 NT_STATUS_HAVE_NO_MEMORY( context);1629 1630 ldb = samdb_connect( context, req->tcon->ntvfs->event_ctx, lp_ctx, system_session(lp_ctx), 0);876 r = talloc_zero(req, struct dfs_GetDFSReferral); 877 NT_STATUS_HAVE_NO_MEMORY(r); 878 879 ldb = samdb_connect(r, req->tcon->ntvfs->event_ctx, lp_ctx, system_session(lp_ctx), 0); 1631 880 if (ldb == NULL) { 1632 881 DEBUG(2,(__location__ ": Failed to open samdb\n")); 1633 talloc_free( context);882 talloc_free(r); 1634 883 return NT_STATUS_INTERNAL_ERROR; 1635 884 } 1636 885 1637 ndr_err = ndr_pull_struct_blob(&trans->in.params, op,1638 & dfsreq,886 ndr_err = ndr_pull_struct_blob(&trans->in.params, r, 887 &r->in.req, 1639 888 (ndr_pull_flags_fn_t)ndr_pull_dfs_GetDFSReferral_in); 1640 889 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 1642 891 DEBUG(2,(__location__ ": Failed to parse GetDFSReferral_in - %s\n", 1643 892 nt_errstr(status))); 1644 talloc_free( context);893 talloc_free(r); 1645 894 return status; 1646 895 } 1647 896 1648 DEBUG(10, ("Requested DFS name: %s length: %u\n", 1649 dfsreq.servername, (unsigned int)strlen(dfsreq.servername))); 1650 1651 /* 1652 * If the servername is "" then we are in a case of domain dfs 1653 * and the client just searches for the list of local domain 1654 * it is attached and also trusted ones. 1655 */ 1656 requestedname = dfsreq.servername; 1657 if (requestedname == NULL || requestedname[0] == '\0') { 1658 return dodomain_referral(op, &dfsreq, ldb, trans, lp_ctx); 1659 } 1660 1661 realm = lpcfg_realm(lp_ctx); 1662 nbname = lpcfg_netbios_name(lp_ctx); 1663 fqdn = talloc_asprintf(context, "%s.%s", nbname, realm); 1664 1665 if ((strncasecmp(requestedname+1, nbname, strlen(nbname)) == 0) || 1666 (strncasecmp(requestedname+1, fqdn, strlen(fqdn)) == 0) ) { 897 DEBUG(8, ("Requested DFS name: %s length: %u\n", 898 r->in.req.servername, 899 (unsigned int)strlen_m(r->in.req.servername)*2)); 900 901 status = dfs_server_ad_get_referrals(lp_ctx, ldb, 902 req->smb_conn->connection->remote_address, r); 903 if (!NT_STATUS_IS_OK(status)) { 904 talloc_free(r); 905 return status; 906 } 907 908 ndr_err = ndr_push_struct_blob(&outblob, trans, 909 r->out.resp, 910 (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp); 911 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 912 DEBUG(2,(__location__ ":NDR marchalling of domain deferral response failed\n")); 913 talloc_free(r); 914 return NT_STATUS_INTERNAL_ERROR; 915 } 916 917 nb_referrals = r->out.resp->nb_referrals; 918 919 if (outblob.length > trans->in.max_data) { 920 bool ok = false; 921 922 DEBUG(3, ("Blob is too big for the output buffer " 923 "size %u max %u\n", 924 (unsigned int)outblob.length, trans->in.max_data)); 925 926 if (trans->in.max_data != MAX_DFS_RESPONSE) { 927 /* As specified in MS-DFSC.pdf 3.3.5.2 */ 928 talloc_free(r); 929 return STATUS_BUFFER_OVERFLOW; 930 } 931 1667 932 /* 1668 * the referral request starts with \NETBIOSNAME or \fqdn 1669 * it's a standalone referral we do not do it 1670 * (TODO correct this) 1671 * If a DFS link that is a complete prefix of the DFS referral 1672 * request path is identified, the server MUST return a DFS link 1673 * referral response; otherwise, if it has a match for the DFS root, 1674 * it MUST return a root referral response. 933 * The answer is too big, so let's remove some answers 1675 934 */ 1676 DEBUG(3, ("Received a standalone request for %s, we do not support standalone referral yet",requestedname)); 1677 talloc_free(context); 1678 return NT_STATUS_NOT_FOUND; 1679 } 1680 talloc_free(fqdn); 1681 1682 tmp = strchr(requestedname + 1,'\\'); /* To get second \ if any */ 1683 1684 /* 1685 * If we have no slash at the first position or (foo.bar.domain.net) 1686 * a slash at the first position but no other slash (\foo.bar.domain.net) 1687 * or a slash at the first position and another slash 1688 * and netlogon or sysvol after the second slash 1689 * (\foo.bar.domain.net\sysvol) then we will handle it because 1690 * it's either a dc referral or a sysvol/netlogon referral 1691 */ 1692 if (requestedname[0] != '\\' || 1693 tmp == NULL || 1694 strcasecmp(tmp+1, "sysvol") == 0 || 1695 strcasecmp(tmp+1, "netlogon") == 0) { 1696 status = dodc_or_sysvol_referral(op, dfsreq, requestedname, 1697 ldb, trans, req, lp_ctx); 1698 talloc_free(context); 1699 return status; 1700 } 1701 1702 if (requestedname[0] == '\\' && 1703 tmp && 1704 strchr(tmp+1, '\\') && 1705 (strncasecmp(tmp+1, "sysvol", 6) == 0 || 1706 strncasecmp(tmp+1, "netlogon", 8) == 0)) { 1707 /* 1708 * We have more than two \ so it something like 1709 * \domain\sysvol\foobar 1710 */ 1711 talloc_free(context); 1712 return NT_STATUS_NOT_FOUND; 1713 } 1714 1715 talloc_free(context); 1716 /* By default until all the case are handled*/ 1717 return NT_STATUS_NOT_FOUND; 935 while (!ok && r->out.resp->nb_referrals > 2) { 936 data_blob_free(&outblob); 937 938 /* 939 * Let's scrap the last referral (for now) 940 */ 941 r->out.resp->nb_referrals -= 1; 942 943 ndr_err = ndr_push_struct_blob(&outblob, trans, 944 r->out.resp, 945 (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp); 946 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 947 talloc_free(r); 948 return NT_STATUS_INTERNAL_ERROR; 949 } 950 951 if (outblob.length <= MAX_DFS_RESPONSE) { 952 DEBUG(10,("DFS: managed to reduce the size of referral initial" 953 "number of referral %d, actual count: %d", 954 nb_referrals, r->out.resp->nb_referrals)); 955 ok = true; 956 break; 957 } 958 } 959 960 if (!ok && r->out.resp->nb_referrals <= 2) { 961 DEBUG(8, (__location__ "; Not able to fit the domain and realm in DFS a " 962 " 56K buffer, something must be broken")); 963 talloc_free(r); 964 return NT_STATUS_INTERNAL_ERROR; 965 } 966 } 967 968 TRANS2_CHECK(trans2_setup_reply(trans, 0, outblob.length, 0)); 969 970 trans->out.data = outblob; 971 talloc_free(r); 972 return NT_STATUS_OK; 1718 973 } 1719 974 -
vendor/current/source4/smb_server/smb/wscript_build
r740 r988 4 4 source='receive.c negprot.c nttrans.c reply.c request.c search.c service.c sesssetup.c srvtime.c trans2.c signing.c', 5 5 autoproto='smb_proto.h', 6 public_deps='ntvfs LIBPACKET credentials samba_server_gensec' 6 deps='dfs_server_ad', 7 public_deps='ntvfs LIBPACKET samba-credentials samba_server_gensec', 8 enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER') 7 9 ) 8 10 -
vendor/current/source4/smb_server/smb2/fileinfo.c
r740 r988 251 251 SMB2SRV_CHECK_ASYNC_STATUS(op, struct smb2srv_setinfo_op); 252 252 253 SMB2SRV_CHECK(smb2srv_setup_reply( req, 0x02, false, 0));253 SMB2SRV_CHECK(smb2srv_setup_reply(op->req, 0x02, false, 0)); 254 254 255 255 smb2srv_send_reply(req); -
vendor/current/source4/smb_server/smb2/keepalive.c
r414 r988 52 52 void smb2srv_keepalive_recv(struct smb2srv_request *req) 53 53 { 54 uint16_t _pad;55 56 54 if (req->in.body_size != 0x04) { 57 55 smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); … … 64 62 } 65 63 66 _pad = SVAL(req->in.body, 0x02);67 68 64 req->status = smb2srv_keepalive_backend(req); 69 65 -
vendor/current/source4/smb_server/smb2/negprot.c
r740 r988 50 50 if (!NT_STATUS_IS_OK(nt_status)) { 51 51 DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); 52 talloc_free(server_credentials); 53 server_credentials = NULL; 52 /* 53 * We keep the server_credentials as anonymous 54 * this is required for the spoolss.notify test 55 */ 54 56 } 55 57 … … 80 82 } 81 83 82 nt_status = gensec_update (gensec_security, req, null_data_blob, &blob);84 nt_status = gensec_update_ev(gensec_security, req, req->smb_conn->connection->event.ctx, null_data_blob, &blob); 83 85 if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 84 86 DEBUG(0, ("Failed to get SPNEGO to give us the first token: %s\n", nt_errstr(nt_status))); … … 98 100 uint16_t i; 99 101 uint16_t dialect = 0; 102 enum smb_signing_setting signing_setting; 103 struct loadparm_context *lp_ctx = req->smb_conn->lp_ctx; 100 104 101 105 /* we only do one dialect for now */ … … 114 118 } 115 119 116 req->smb_conn->negotiate.protocol = PROTOCOL_SMB2 ;120 req->smb_conn->negotiate.protocol = PROTOCOL_SMB2_02; 117 121 118 122 current_time = timeval_current(); /* TODO: handle timezone?! */ … … 120 124 121 125 ZERO_STRUCT(io->out); 122 switch (lpcfg_server_signing(req->smb_conn->lp_ctx)) { 126 127 signing_setting = lpcfg_server_signing(lp_ctx); 128 if (signing_setting == SMB_SIGNING_DEFAULT) { 129 /* 130 * If we are a domain controller, SMB signing is 131 * really important, as it can prevent a number of 132 * attacks on communications between us and the 133 * clients 134 * 135 * However, it really sucks (no sendfile, CPU 136 * overhead) performance-wise when used on a 137 * file server, so disable it by default 138 * on non-DCs 139 */ 140 141 if (lpcfg_server_role(lp_ctx) >= ROLE_ACTIVE_DIRECTORY_DC) { 142 signing_setting = SMB_SIGNING_REQUIRED; 143 } else { 144 signing_setting = SMB_SIGNING_OFF; 145 } 146 } 147 148 switch (signing_setting) { 149 case SMB_SIGNING_DEFAULT: 150 case SMB_SIGNING_IPC_DEFAULT: 151 smb_panic(__location__); 152 break; 123 153 case SMB_SIGNING_OFF: 124 154 io->out.security_mode = 0; 125 155 break; 126 case SMB_SIGNING_ SUPPORTED:127 case SMB_SIGNING_ AUTO:156 case SMB_SIGNING_DESIRED: 157 case SMB_SIGNING_IF_REQUIRED: 128 158 io->out.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; 129 159 break; -
vendor/current/source4/smb_server/smb2/receive.c
r740 r988 70 70 req->smb_conn = smb_conn; 71 71 72 req->chained_session_id = UINT64_MAX; 73 req->chained_tree_id = UINT32_MAX; 74 72 75 talloc_set_destructor(req, smb2srv_request_destructor); 73 76 … … 78 81 bool body_dynamic_present, uint32_t body_dynamic_size) 79 82 { 80 uint32_t flags = SMB2_HDR_FLAG_REDIRECT;83 uint32_t flags = IVAL(req->in.hdr, SMB2_HDR_FLAGS); 81 84 uint32_t pid = IVAL(req->in.hdr, SMB2_HDR_PID); 82 85 uint32_t tid = IVAL(req->in.hdr, SMB2_HDR_TID); 86 uint16_t credits = SVAL(req->in.hdr, SMB2_HDR_CREDIT); 87 88 if (credits == 0) { 89 credits = 1; 90 } 91 92 flags |= SMB2_HDR_FLAG_REDIRECT; 83 93 84 94 if (req->pending_id) { … … 86 96 pid = req->pending_id; 87 97 tid = 0; 98 credits = 0; 88 99 } 89 100 … … 111 122 SIVAL(req->out.hdr, 0, SMB2_MAGIC); 112 123 SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); 113 SSVAL(req->out.hdr, SMB2_HDR_EPOCH, 0); 124 SSVAL(req->out.hdr, SMB2_HDR_CREDIT_CHARGE, 125 SVAL(req->in.hdr, SMB2_HDR_CREDIT_CHARGE)); 114 126 SIVAL(req->out.hdr, SMB2_HDR_STATUS, NT_STATUS_V(req->status)); 115 127 SSVAL(req->out.hdr, SMB2_HDR_OPCODE, SVAL(req->in.hdr, SMB2_HDR_OPCODE)); 116 SSVAL(req->out.hdr, SMB2_HDR_CREDIT, 0x0001);128 SSVAL(req->out.hdr, SMB2_HDR_CREDIT, credits); 117 129 SIVAL(req->out.hdr, SMB2_HDR_FLAGS, flags); 118 130 SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND, 0); … … 121 133 SIVAL(req->out.hdr, SMB2_HDR_TID, tid); 122 134 SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, BVAL(req->in.hdr, SMB2_HDR_SESSION_ID)); 123 memset(req->out.hdr+SMB2_HDR_SIGNATURE, 0, 16); 135 memcpy(req->out.hdr+SMB2_HDR_SIGNATURE, 136 req->in.hdr+SMB2_HDR_SIGNATURE, 16); 124 137 125 138 /* set the length of the fixed body part and +1 if there's a dynamic part also */ … … 143 156 { 144 157 NTSTATUS status; 158 struct smbsrv_connection *smb_conn = p_req->smb_conn; 145 159 struct smb2srv_request *req; 146 160 uint32_t chain_offset; … … 159 173 DEBUG(2,("Invalid SMB2 chained packet at offset 0x%X from last hdr 0x%X\n", 160 174 chain_offset, last_hdr_offset)); 161 smbsrv_terminate_connection( p_req->smb_conn, "Invalid SMB2 chained packet");175 smbsrv_terminate_connection(smb_conn, "Invalid SMB2 chained packet"); 162 176 return; 163 177 } … … 167 181 DEBUG(2,("Invalid SMB chained packet: protocol prefix: 0x%08X\n", 168 182 protocol_version)); 169 smbsrv_terminate_connection( p_req->smb_conn, "NON-SMB2 chained packet");170 return; 171 } 172 173 req = smb2srv_init_request( p_req->smb_conn);183 smbsrv_terminate_connection(smb_conn, "NON-SMB2 chained packet"); 184 return; 185 } 186 187 req = smb2srv_init_request(smb_conn); 174 188 if (!req) { 175 smbsrv_terminate_connection(p_req->smb_conn, "SMB2 chained packet - no memory"); 176 return; 177 } 189 smbsrv_terminate_connection(smb_conn, "SMB2 chained packet - no memory"); 190 return; 191 } 192 193 talloc_steal(req, p_req); 178 194 179 195 req->in.buffer = talloc_steal(req, p_req->in.buffer); … … 194 210 uint16_t opcode = SVAL(req->in.hdr, SMB2_HDR_OPCODE); 195 211 if (opcode == SMB2_OP_NEGPROT) { 196 smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot"); 212 smbsrv_terminate_connection(smb_conn, "Bad body size in SMB2 negprot"); 213 return; 197 214 } else { 198 215 smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); 216 return; 199 217 } 200 218 } … … 224 242 req->chained_file_handle = req->_chained_file_handle; 225 243 } 244 req->chained_session_id = p_req->chained_session_id; 245 req->chained_tree_id = p_req->chained_tree_id; 226 246 req->chain_status = p_req->chain_status; 227 247 } … … 234 254 status = smb2srv_reply(req); 235 255 if (!NT_STATUS_IS_OK(status)) { 236 smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); 237 talloc_free(req); 256 smbsrv_terminate_connection(smb_conn, nt_errstr(status)); 238 257 return; 239 258 } … … 252 271 253 272 if (req->out.size > NBT_HDR_SIZE) { 254 _smb 2_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);273 _smb_setlen_tcp(req->out.buffer, req->out.size - NBT_HDR_SIZE); 255 274 } 256 275 … … 270 289 if (!NT_STATUS_IS_OK(status)) { 271 290 smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); 291 return; 272 292 } 273 293 if (req->chain_offset) { … … 333 353 } 334 354 355 if (flags & SMB2_HDR_FLAG_CHAINED) { 356 uid = req->chained_session_id; 357 tid = req->chained_tree_id; 358 } 359 335 360 req->session = smbsrv_session_find(req->smb_conn, uid, req->request_time); 336 361 req->tcon = smbsrv_smb2_tcon_find(req->session, tid, req->request_time); 362 363 req->chained_session_id = uid; 364 req->chained_tree_id = tid; 337 365 338 366 errno = 0; … … 425 453 smb2srv_keepalive_recv(req); 426 454 return NT_STATUS_OK; 427 case SMB2_OP_ FIND:455 case SMB2_OP_QUERY_DIRECTORY: 428 456 if (!req->session) goto nosession; 429 457 if (!req->tcon) goto notcon; … … 570 598 bool signing_used = false; 571 599 int id; 600 uint16_t credits = SVAL(req->in.hdr, SMB2_HDR_CREDIT); 601 602 if (credits == 0) { 603 credits = 1; 604 } 572 605 573 606 if (req->pending_id) { 574 607 return NT_STATUS_INTERNAL_ERROR; 608 } 609 610 if (req->smb_conn->connection->event.fde == NULL) { 611 /* the socket has been destroyed - no point trying to send an error! */ 612 return NT_STATUS_REMOTE_DISCONNECT; 575 613 } 576 614 … … 581 619 } 582 620 583 DLIST_ADD_END(req->smb_conn->requests2.list, req , struct smb2srv_request *);621 DLIST_ADD_END(req->smb_conn->requests2.list, req); 584 622 req->pending_id = id; 585 586 if (req->smb_conn->connection->event.fde == NULL) {587 /* the socket has been destroyed - no point trying to send an error! */588 return NT_STATUS_REMOTE_DISCONNECT;589 }590 623 591 624 talloc_set_destructor(req, smb2srv_request_deny_destructor); … … 597 630 598 631 SIVAL(req->out.hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING)); 632 SSVAL(req->out.hdr, SMB2_HDR_CREDIT, credits); 599 633 600 634 SSVAL(req->out.body, 0x02, 0); … … 664 698 smb_conn->negotiate.zone_offset = get_time_zone(time(NULL)); 665 699 666 smb_conn->config.security = SEC_USER;667 700 smb_conn->config.nt_status_support = true; 668 701 -
vendor/current/source4/smb_server/smb2/sesssetup.c
r740 r988 32 32 static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io) 33 33 { 34 uint16_t credit;35 36 34 if (NT_STATUS_IS_OK(req->status)) { 37 credit = 0x0003;35 /* nothing */ 38 36 } else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 39 credit = 0x0002;37 /* nothing */ 40 38 } else { 41 39 smb2srv_send_error(req, req->status); … … 45 43 SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, io->smb2.out.secblob.length)); 46 44 47 SSVAL(req->out.hdr, SMB2_HDR_CREDIT, credit);48 45 SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, io->smb2.out.uid); 49 46 … … 68 65 struct smbsrv_session *smb_sess = ctx->smb_sess; 69 66 struct auth_session_info *session_info = NULL; 67 enum security_user_level user_level; 70 68 NTSTATUS status; 71 69 … … 80 78 } 81 79 82 status = gensec_session_info(smb_sess->gensec_ctx, &session_info);80 status = gensec_session_info(smb_sess->gensec_ctx, smb_sess, &session_info); 83 81 if (!NT_STATUS_IS_OK(status)) { 84 82 goto failed; … … 93 91 req->session = smb_sess; 94 92 95 if (smb_sess->smb2_signing.required) { 96 /* activate smb2 signing on the session */ 97 smb_sess->smb2_signing.active = true; 98 } 93 user_level = security_session_user_level(smb_sess->session_info, NULL); 94 if (user_level >= SECURITY_USER) { 95 if (smb_sess->smb2_signing.required) { 96 /* activate smb2 signing on the session */ 97 smb_sess->smb2_signing.active = true; 98 } 99 /* we need to sign the session setup response */ 100 req->is_signed = true; 101 } 102 99 103 done: 100 104 io->smb2.out.uid = smb_sess->vuid; … … 164 168 165 169 if (!smb_sess) { 170 status = NT_STATUS_USER_SESSION_DELETED; 171 goto failed; 172 } 173 174 if (smb_sess->session_info) { 166 175 /* see WSPP test suite - test 11 */ 167 176 status = NT_STATUS_REQUEST_NOT_ACCEPTED; … … 193 202 if (io->smb2.in.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { 194 203 smb_sess->smb2_signing.required = true; 195 } else if (req->smb_conn->smb2_signing_required) {196 /*197 * if required signing was negotiates in SMB2 Negotiate198 * then the client made an error not using it here199 */200 DEBUG(1, ("SMB2 signing required on the connection but not used on session\n"));201 req->status = NT_STATUS_FOOBAR;202 goto failed;203 204 } 204 205 … … 274 275 void smb2srv_logoff_recv(struct smb2srv_request *req) 275 276 { 276 uint16_t _pad;277 278 277 SMB2SRV_CHECK_BODY_SIZE(req, 0x04, false); 279 280 _pad = SVAL(req->in.body, 0x02);281 278 282 279 req->status = smb2srv_logoff_backend(req); -
vendor/current/source4/smb_server/smb2/smb2_server.h
r414 r988 65 65 uint8_t _chained_file_handle[16]; 66 66 uint8_t *chained_file_handle; 67 uint64_t chained_session_id; 68 uint32_t chained_tree_id; 67 69 68 70 bool is_signed; -
vendor/current/source4/smb_server/smb2/tcon.c
r740 r988 242 242 const char *service = io->smb2.in.path; 243 243 struct share_config *scfg; 244 c onst char *sharetype;244 char *sharetype; 245 245 uint64_t ntvfs_caps = 0; 246 246 … … 266 266 267 267 /* work out what sort of connection this is */ 268 sharetype = share_string_option( scfg, SHARE_TYPE, "DISK");268 sharetype = share_string_option(req, scfg, SHARE_TYPE, "DISK"); 269 269 if (sharetype && strcmp(sharetype, "IPC") == 0) { 270 270 type = NTVFS_IPC; … … 274 274 type = NTVFS_DISK; 275 275 } 276 TALLOC_FREE(sharetype); 276 277 277 278 tcon = smbsrv_smb2_tcon_new(req->session, scfg->name); … … 360 361 static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io) 361 362 { 362 uint16_t credit;363 364 363 if (!NT_STATUS_IS_OK(req->status)) { 365 364 smb2srv_send_error(req, req->status); 366 365 return; 367 366 } 368 if (io->smb2.out.share_type == NTVFS_IPC) {369 /* if it's an IPC share vista returns 0x0005 */370 credit = 0x0005;371 } else {372 credit = 0x0001;373 }374 367 375 368 SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x10, false, 0)); 376 369 377 370 SIVAL(req->out.hdr, SMB2_HDR_TID, io->smb2.out.tid); 378 SSVAL(req->out.hdr, SMB2_HDR_CREDIT,credit);379 371 380 372 SCVAL(req->out.body, 0x02, io->smb2.out.share_type); … … 443 435 void smb2srv_tdis_recv(struct smb2srv_request *req) 444 436 { 445 uint16_t _pad;446 447 437 SMB2SRV_CHECK_BODY_SIZE(req, 0x04, false); 448 449 _pad = SVAL(req->in.body, 0x02);450 438 451 439 req->status = smb2srv_tdis_backend(req); -
vendor/current/source4/smb_server/smb2/wscript_build
r740 r988 4 4 source='receive.c negprot.c sesssetup.c tcon.c fileio.c fileinfo.c find.c keepalive.c', 5 5 autoproto='smb2_proto.h', 6 public_deps='ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec NDR_DFSBLOBS' 6 public_deps='ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec NDR_DFSBLOBS', 7 enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER') 7 8 ) 8 9 -
vendor/current/source4/smb_server/smb_server.c
r740 r988 64 64 return smbsrv_recv_smb_request(smb_conn, blob); 65 65 case SMB2_MAGIC: 66 if (lpcfg_s rv_maxprotocol(smb_conn->lp_ctx) < PROTOCOL_SMB2) break;66 if (lpcfg_server_max_protocol(smb_conn->lp_ctx) < PROTOCOL_SMB2_02) break; 67 67 status = smbsrv_init_smb2_connection(smb_conn); 68 68 NT_STATUS_NOT_OK_RETURN(status); … … 191 191 status = stream_setup_socket(mem_ctx, event_context, lp_ctx, 192 192 model_ops, &smb_stream_ops, 193 "ip v4", address, &port,193 "ip", address, &port, 194 194 lpcfg_socket_options(lp_ctx), 195 195 NULL); -
vendor/current/source4/smb_server/smb_server.h
r740 r988 23 23 #include "libcli/raw/interfaces.h" 24 24 #include "lib/socket/socket.h" 25 #include "libds/common/roles.h" 25 26 #include "../lib/util/dlinklist.h" 26 27 #include "../librpc/gen_ndr/nbt.h" … … 265 266 struct smb_request_buffer out; 266 267 }; 267 268 enum security_types {SEC_SHARE,SEC_USER};269 268 270 269 /* smb server context structure. This should contain all the state … … 301 300 302 301 /* authentication context for multi-part negprot */ 303 struct auth _context *auth_context;302 struct auth4_context *auth_context; 304 303 305 304 /* reference to the kerberos keytab, or machine trust account */ … … 372 371 /* configuration parameters */ 373 372 struct { 374 enum security_types security;375 373 bool nt_status_support; 376 374 } config; … … 478 476 req->ntvfs->async_states->status = cmd; \ 479 477 if (req->ntvfs->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { \ 480 DLIST_ADD_END(req->smb_conn->requests, req , struct smbsrv_request *); \478 DLIST_ADD_END(req->smb_conn->requests, req); \ 481 479 } else { \ 482 480 req->ntvfs->async_states->send_fn(req->ntvfs); \ -
vendor/current/source4/smb_server/wscript_build
r740 r988 8 8 deps='SMB_SERVER netif shares samba-hostconfig', 9 9 internal_module=False, 10 enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER') 10 11 ) 11 12 13 bld.SAMBA_MODULE('service_samba3_smb',14 source='smb_samba3.c',15 subsystem='service',16 init_function='server_service_samba3_smb_init',17 deps='talloc',18 internal_module=False,19 )20 21 12 22 13 bld.SAMBA_SUBSYSTEM('SMB_SERVER', 23 14 source='handle.c tcon.c session.c blob.c management.c smb_server.c', 24 15 autoproto='smb_server_proto.h', 25 public_deps='share LIBPACKET SMB_PROTOCOL SMB2_PROTOCOL' 16 public_deps='share LIBPACKET SMB_PROTOCOL SMB2_PROTOCOL', 17 enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER') 26 18 ) 27 19
Note:
See TracChangeset
for help on using the changeset viewer.