]> git.ipfire.org Git - thirdparty/samba.git/blame - source3/smbd/process.c
s3:smbd: fix the maxentries calculation depending on the max_send.
[thirdparty/samba.git] / source3 / smbd / process.c
CommitLineData
c3effa8b 1/*
cd68afe3 2 Unix SMB/CIFS implementation.
c3effa8b
AT
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
b91704d4 5 Copyright (C) Volker Lendecke 2005-2007
8af7400d 6
c3effa8b
AT
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
d824b98f 9 the Free Software Foundation; either version 3 of the License, or
c3effa8b 10 (at your option) any later version.
8af7400d 11
c3effa8b
AT
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
8af7400d 16
c3effa8b 17 You should have received a copy of the GNU General Public License
5e54558c 18 along with this program. If not, see <http://www.gnu.org/licenses/>.
c3effa8b
AT
19*/
20
21#include "includes.h"
12476223 22#include "../lib/tsocket/tsocket.h"
0e771263 23#include "system/filesys.h"
8c24ebf3 24#include "smbd/smbd.h"
3dde0cbb 25#include "smbd/globals.h"
aff002e8 26#include "librpc/gen_ndr/netlogon.h"
c7fe04ab 27#include "../lib/async_req/async_sock.h"
8e16d6db 28#include "ctdbd_conn.h"
b38d0542 29#include "../lib/util/select.h"
2e8a85ec 30#include "printing/queue_process.h"
9758afd4 31#include "system/select.h"
235f1485 32#include "passdb.h"
af300a9f 33#include "auth.h"
b2af281e 34#include "messages.h"
165521e2 35#include "smbprofile.h"
c233c214 36#include "rpc_server/spoolss/srv_spoolss_nt.h"
27022587 37#include "libsmb/libsmb.h"
27afb891 38#include "../lib/util/tevent_ntstatus.h"
715933a3
SM
39#include "../libcli/security/dom_sid.h"
40#include "../libcli/security/security_token.h"
41#include "lib/id_cache.h"
b5e9ece1 42#include "serverid.h"
c3effa8b 43
6d84b24d
SM
44/* Internal message queue for deferred opens. */
45struct pending_message_list {
46 struct pending_message_list *next, *prev;
47 struct timeval request_time; /* When was this first issued? */
48 struct smbd_server_connection *sconn;
ae1cb5ca 49 struct tevent_timer *te;
6d84b24d
SM
50 struct smb_perfcount_data pcd;
51 uint32_t seqnum;
52 bool encrypted;
53 bool processed;
54 DATA_BLOB buf;
55 DATA_BLOB private_data;
56};
57
ae0c6cff
VL
58static void construct_reply_common(struct smb_request *req, const char *inbuf,
59 char *outbuf);
cb69d105
VL
60static struct pending_message_list *get_deferred_open_message_smb(
61 struct smbd_server_connection *sconn, uint64_t mid);
3b2c9beb 62static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
5a33e906 63
6800fdbb 64static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
8de85546 65{
cad0c004
VL
66 bool ok;
67
46a48edc 68 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
cad0c004
VL
69 return true;
70 }
71
46a48edc 72 sconn->smb1.echo_handler.ref_count++;
6800fdbb 73
46a48edc 74 if (sconn->smb1.echo_handler.ref_count > 1) {
6800fdbb
JA
75 return true;
76 }
77
c0288e06 78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
cad0c004 79
da00021a
VL
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
1ac7f071 83 F_SETLKW, 0, 0, F_WRLCK);
da00021a
VL
84 } while (!ok && (errno == EINTR));
85
cad0c004 86 if (!ok) {
efb22bf7 87 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
cad0c004
VL
88 return false;
89 }
90
7b0b1d6d 91 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
cad0c004 92
8de85546
SM
93 return true;
94}
95
6800fdbb
JA
96void smbd_lock_socket(struct smbd_server_connection *sconn)
97{
98 if (!smbd_lock_socket_internal(sconn)) {
99 exit_server_cleanly("failed to lock socket");
100 }
101}
102
103static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
8de85546 104{
cad0c004
VL
105 bool ok;
106
46a48edc 107 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
cad0c004
VL
108 return true;
109 }
110
46a48edc 111 sconn->smb1.echo_handler.ref_count--;
6800fdbb 112
46a48edc 113 if (sconn->smb1.echo_handler.ref_count > 0) {
6800fdbb
JA
114 return true;
115 }
116
da00021a
VL
117 do {
118 ok = fcntl_lock(
119 sconn->smb1.echo_handler.socket_lock_fd,
1ac7f071 120 F_SETLKW, 0, 0, F_UNLCK);
da00021a
VL
121 } while (!ok && (errno == EINTR));
122
cad0c004 123 if (!ok) {
efb22bf7 124 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
cad0c004
VL
125 return false;
126 }
127
c0288e06 128 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
cad0c004 129
8de85546
SM
130 return true;
131}
132
6800fdbb
JA
133void smbd_unlock_socket(struct smbd_server_connection *sconn)
134{
135 if (!smbd_unlock_socket_internal(sconn)) {
136 exit_server_cleanly("failed to unlock socket");
137 }
138}
139
36441da4
JA
140/* Accessor function for smb_read_error for smbd functions. */
141
9254bb4e
JA
142/****************************************************************************
143 Send an smb to a fd.
144****************************************************************************/
145
1808dd0a 146bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
c16c90a1
SM
147 bool do_signing, uint32_t seqnum,
148 bool do_encrypt,
149 struct smb_perfcount_data *pcd)
9254bb4e 150{
54c51a66 151 size_t len = 0;
9254bb4e
JA
152 ssize_t ret;
153 char *buf_out = buffer;
977aa660 154
52ccb40d
SM
155 if (!NT_STATUS_IS_OK(sconn->status)) {
156 /*
157 * we're not supposed to do any io
158 */
159 return true;
160 }
161
1808dd0a 162 smbd_lock_socket(sconn);
9254bb4e 163
c16c90a1
SM
164 if (do_signing) {
165 /* Sign the outgoing packet if required. */
1808dd0a 166 srv_calculate_sign_mac(sconn, buf_out, seqnum);
c16c90a1 167 }
9254bb4e
JA
168
169 if (do_encrypt) {
7e70f853 170 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
9254bb4e
JA
171 if (!NT_STATUS_IS_OK(status)) {
172 DEBUG(0, ("send_smb: SMB encryption failed "
173 "on outgoing packet! Error %s\n",
174 nt_errstr(status) ));
cc983c9a 175 ret = -1;
54c51a66 176 goto out;
9254bb4e
JA
177 }
178 }
179
d5693d99 180 len = smb_len_large(buf_out) + 4;
9254bb4e 181
7d8a1b1e 182 ret = write_data(sconn->sock, buf_out, len);
c344ad30 183 if (ret <= 0) {
40ae8b74
VL
184
185 char addr[INET6_ADDRSTRLEN];
186 /*
187 * Try and give an error message saying what
188 * client failed.
189 */
51bc104c 190 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
c0288e06 191 (int)getpid(), (int)len,
1808dd0a 192 get_peer_addr(sconn->sock, addr, sizeof(addr)),
40ae8b74
VL
193 (int)ret, strerror(errno) ));
194
08262fe9 195 srv_free_enc_buffer(sconn, buf_out);
c344ad30 196 goto out;
9254bb4e
JA
197 }
198
54c51a66 199 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
08262fe9 200 srv_free_enc_buffer(sconn, buf_out);
54c51a66 201out:
202 SMB_PERFCOUNT_END(pcd);
977aa660 203
1808dd0a 204 smbd_unlock_socket(sconn);
852c9ac3 205 return (ret > 0);
9254bb4e
JA
206}
207
afc93255
JA
208/*******************************************************************
209 Setup the word count and byte count for a smb message.
afc93255
JA
210********************************************************************/
211
9254bb4e 212int srv_set_message(char *buf,
afc93255
JA
213 int num_words,
214 int num_bytes,
215 bool zero)
216{
217 if (zero && (num_words || num_bytes)) {
218 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
219 }
220 SCVAL(buf,smb_wct,num_words);
221 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
9254bb4e 222 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
afc93255
JA
223 return (smb_size + num_words*2 + num_bytes);
224}
225
b4b9918c
VL
226static bool valid_smb_header(struct smbd_server_connection *sconn,
227 const uint8_t *inbuf)
afc93255 228{
f9ef138e 229 if (is_encrypted_packet(sconn, inbuf)) {
9254bb4e 230 return true;
afc93255 231 }
1510b7b8
VL
232 /*
233 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
234 * but it just looks weird to call strncmp for this one.
235 */
236 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
afc93255
JA
237}
238
695c4a7a
JA
239/* Socket functions for smbd packet processing. */
240
58fbb512 241static bool valid_packet_size(size_t len)
695c4a7a
JA
242{
243 /*
244 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
245 * of header. Don't print the error if this fits.... JRA.
246 */
247
248 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
249 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
250 (unsigned long)len));
d36434f3 251 return false;
695c4a7a
JA
252 }
253 return true;
254}
255
e604e137
VL
256static NTSTATUS read_packet_remainder(int fd, char *buffer,
257 unsigned int timeout, ssize_t len)
695c4a7a 258{
9671547d
VL
259 NTSTATUS status;
260
48b1ee61 261 if (len <= 0) {
e604e137 262 return NT_STATUS_OK;
48b1ee61 263 }
695c4a7a 264
9671547d
VL
265 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
266 if (!NT_STATUS_IS_OK(status)) {
267 char addr[INET6_ADDRSTRLEN];
268 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
269 "error = %s.\n",
270 get_peer_addr(fd, addr, sizeof(addr)),
271 nt_errstr(status)));
272 }
273 return status;
695c4a7a
JA
274}
275
276/****************************************************************************
277 Attempt a zerocopy writeX read. We know here that len > smb_size-4
278****************************************************************************/
279
280/*
281 * Unfortunately, earlier versions of smbclient/libsmbclient
282 * don't send this "standard" writeX header. I've fixed this
283 * for 3.2 but we'll use the old method with earlier versions.
284 * Windows and CIFSFS at least use this standard size. Not
285 * sure about MacOSX.
286 */
287
288#define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
289 (2*14) + /* word count (including bcc) */ \
290 1 /* pad byte */)
291
250b2b64
VL
292static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
293 const char lenbuf[4],
fa0de395 294 struct smbd_server_connection *sconn,
8b5d163d 295 int sock,
fa0de395 296 char **buffer,
250b2b64
VL
297 unsigned int timeout,
298 size_t *p_unread,
299 size_t *len_ret)
695c4a7a
JA
300{
301 /* Size of a WRITEX call (+4 byte len). */
302 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
303 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
304 ssize_t toread;
250b2b64 305 NTSTATUS status;
695c4a7a 306
227718cd 307 memcpy(writeX_header, lenbuf, 4);
695c4a7a 308
43c766a1 309 status = read_fd_with_timeout(
8b5d163d 310 sock, writeX_header + 4,
250b2b64
VL
311 STANDARD_WRITE_AND_X_HEADER_SIZE,
312 STANDARD_WRITE_AND_X_HEADER_SIZE,
313 timeout, NULL);
695c4a7a 314
250b2b64 315 if (!NT_STATUS_IS_OK(status)) {
9671547d 316 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
a513086c
AS
317 "error = %s.\n",
318 tsocket_address_string(sconn->remote_address,
319 talloc_tos()),
9671547d 320 nt_errstr(status)));
250b2b64 321 return status;
695c4a7a
JA
322 }
323
324 /*
325 * Ok - now try and see if this is a possible
326 * valid writeX call.
327 */
328
fa0de395 329 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
695c4a7a
JA
330 /*
331 * If the data offset is beyond what
332 * we've read, drain the extra bytes.
333 */
334 uint16_t doff = SVAL(writeX_header,smb_vwv11);
335 ssize_t newlen;
336
337 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
338 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
8b5d163d 339 if (drain_socket(sock, drain) != drain) {
695c4a7a
JA
340 smb_panic("receive_smb_raw_talloc_partial_read:"
341 " failed to drain pending bytes");
342 }
343 } else {
344 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
345 }
346
347 /* Spoof down the length and null out the bcc. */
348 set_message_bcc(writeX_header, 0);
349 newlen = smb_len(writeX_header);
350
351 /* Copy the header we've written. */
352
8d4a8389 353 *buffer = (char *)talloc_memdup(mem_ctx,
695c4a7a
JA
354 writeX_header,
355 sizeof(writeX_header));
356
357 if (*buffer == NULL) {
358 DEBUG(0, ("Could not allocate inbuf of length %d\n",
359 (int)sizeof(writeX_header)));
250b2b64 360 return NT_STATUS_NO_MEMORY;
695c4a7a
JA
361 }
362
363 /* Work out the remaining bytes. */
364 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
250b2b64
VL
365 *len_ret = newlen + 4;
366 return NT_STATUS_OK;
695c4a7a
JA
367 }
368
369 if (!valid_packet_size(len)) {
250b2b64 370 return NT_STATUS_INVALID_PARAMETER;
695c4a7a
JA
371 }
372
373 /*
374 * Not a valid writeX call. Just do the standard
375 * talloc and return.
376 */
377
3d151376 378 *buffer = talloc_array(mem_ctx, char, len+4);
695c4a7a
JA
379
380 if (*buffer == NULL) {
381 DEBUG(0, ("Could not allocate inbuf of length %d\n",
382 (int)len+4));
250b2b64 383 return NT_STATUS_NO_MEMORY;
695c4a7a
JA
384 }
385
386 /* Copy in what we already read. */
387 memcpy(*buffer,
388 writeX_header,
389 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
390 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
391
392 if(toread > 0) {
e604e137 393 status = read_packet_remainder(
8b5d163d 394 sock,
fa0de395 395 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
e604e137
VL
396 timeout, toread);
397
398 if (!NT_STATUS_IS_OK(status)) {
8ca459e0
JA
399 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
400 nt_errstr(status)));
250b2b64 401 return status;
695c4a7a
JA
402 }
403 }
404
250b2b64
VL
405 *len_ret = len + 4;
406 return NT_STATUS_OK;
695c4a7a
JA
407}
408
a2db154c
VL
409static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
410 struct smbd_server_connection *sconn,
8b5d163d 411 int sock,
9fe66ddd
VL
412 char **buffer, unsigned int timeout,
413 size_t *p_unread, size_t *plen)
695c4a7a
JA
414{
415 char lenbuf[4];
0afbfa42 416 size_t len;
695c4a7a 417 int min_recv_size = lp_min_receive_file_size();
0afbfa42 418 NTSTATUS status;
695c4a7a 419
695c4a7a
JA
420 *p_unread = 0;
421
8b5d163d 422 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
a2db154c 423 &len);
0afbfa42 424 if (!NT_STATUS_IS_OK(status)) {
9fe66ddd 425 return status;
695c4a7a
JA
426 }
427
dea223ba
TP
428 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
429 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
430 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
a2db154c
VL
431 !srv_is_signing_active(sconn) &&
432 sconn->smb1.echo_handler.trusted_fde == NULL) {
695c4a7a 433
8ca459e0 434 return receive_smb_raw_talloc_partial_read(
8b5d163d 435 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
fa0de395 436 p_unread, plen);
695c4a7a
JA
437 }
438
439 if (!valid_packet_size(len)) {
9fe66ddd 440 return NT_STATUS_INVALID_PARAMETER;
695c4a7a
JA
441 }
442
443 /*
444 * The +4 here can't wrap, we've checked the length above already.
445 */
446
3d151376 447 *buffer = talloc_array(mem_ctx, char, len+4);
695c4a7a
JA
448
449 if (*buffer == NULL) {
450 DEBUG(0, ("Could not allocate inbuf of length %d\n",
451 (int)len+4));
9fe66ddd 452 return NT_STATUS_NO_MEMORY;
695c4a7a
JA
453 }
454
455 memcpy(*buffer, lenbuf, sizeof(lenbuf));
456
8b5d163d 457 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
e604e137 458 if (!NT_STATUS_IS_OK(status)) {
9fe66ddd 459 return status;
695c4a7a
JA
460 }
461
9fe66ddd
VL
462 *plen = len + 4;
463 return NT_STATUS_OK;
695c4a7a
JA
464}
465
63e08ef8
VL
466static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
467 struct smbd_server_connection *sconn,
8b5d163d 468 int sock,
e514cd0a
VL
469 char **buffer, unsigned int timeout,
470 size_t *p_unread, bool *p_encrypted,
c16c90a1 471 size_t *p_len,
b2c107ff
SM
472 uint32_t *seqnum,
473 bool trusted_channel)
695c4a7a 474{
47666c93 475 size_t len = 0;
9fe66ddd 476 NTSTATUS status;
695c4a7a 477
9254bb4e
JA
478 *p_encrypted = false;
479
8b5d163d 480 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
63e08ef8 481 p_unread, &len);
9fe66ddd 482 if (!NT_STATUS_IS_OK(status)) {
b99becd4
CA
483 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
484 ("receive_smb_raw_talloc failed for client %s "
485 "read error = %s.\n",
486 tsocket_address_string(sconn->remote_address,
487 talloc_tos()),
488 nt_errstr(status)) );
e514cd0a 489 return status;
695c4a7a
JA
490 }
491
f9ef138e 492 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
d4c4705e 493 status = srv_decrypt_buffer(sconn, *buffer);
afc93255
JA
494 if (!NT_STATUS_IS_OK(status)) {
495 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
496 "incoming packet! Error %s\n",
497 nt_errstr(status) ));
e514cd0a 498 return status;
afc93255 499 }
9254bb4e 500 *p_encrypted = true;
afc93255
JA
501 }
502
695c4a7a 503 /* Check the incoming SMB signature. */
63e08ef8 504 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
695c4a7a
JA
505 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
506 "incoming packet!\n"));
e514cd0a 507 return NT_STATUS_INVALID_NETWORK_RESPONSE;
695c4a7a
JA
508 }
509
e514cd0a
VL
510 *p_len = len;
511 return NT_STATUS_OK;
695c4a7a
JA
512}
513
0bc56a2e
VL
514/*
515 * Initialize a struct smb_request from an inbuf
516 */
517
d7bc5fe7
VL
518static bool init_smb_request(struct smb_request *req,
519 struct smbd_server_connection *sconn,
520 const uint8 *inbuf,
9b4b9d26
VL
521 size_t unread_bytes, bool encrypted,
522 uint32_t seqnum)
0bc56a2e 523{
faa8edcc
SM
524 struct smbXsrv_tcon *tcon;
525 NTSTATUS status;
526 NTTIME now;
ed70bc0d 527 size_t req_size = smb_len(inbuf) + 4;
d8b3687f 528
ed70bc0d 529 /* Ensure we have at least smb_size bytes. */
a1f593cd
JA
530 if (req_size < smb_size) {
531 DEBUG(0,("init_smb_request: invalid request size %u\n",
532 (unsigned int)req_size ));
b7898148 533 return false;
a1f593cd 534 }
d8b3687f
SM
535
536 req->request_time = timeval_current();
faa8edcc 537 now = timeval_to_nttime(&req->request_time);
d8b3687f 538
7808a259 539 req->cmd = CVAL(inbuf, smb_com);
0bc56a2e
VL
540 req->flags2 = SVAL(inbuf, smb_flg2);
541 req->smbpid = SVAL(inbuf, smb_pid);
79842437 542 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
9b4b9d26 543 req->seqnum = seqnum;
0bc56a2e 544 req->vuid = SVAL(inbuf, smb_uid);
cc6a4101
VL
545 req->tid = SVAL(inbuf, smb_tid);
546 req->wct = CVAL(inbuf, smb_wct);
f1dc8b28 547 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
7f9d6f80 548 req->buflen = smb_buflen(inbuf);
4f41be35 549 req->buf = (const uint8_t *)smb_buf_const(inbuf);
c3250149 550 req->unread_bytes = unread_bytes;
9254bb4e 551 req->encrypted = encrypted;
edfc7eaf 552 req->sconn = sconn;
faa8edcc
SM
553 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
554 if (NT_STATUS_IS_OK(status)) {
555 req->conn = tcon->compat;
556 } else {
557 req->conn = NULL;
558 }
d65afbe5 559 req->chain_fsp = NULL;
08b24e92 560 req->smb2req = NULL;
89c55485 561 req->priv_paths = NULL;
8f93068c 562 req->chain = NULL;
54c51a66 563 smb_init_perfcount_data(&req->pcd);
c3250149 564
a662a62e 565 /* Ensure we have at least wct words and 2 bytes of bcc. */
a1f593cd
JA
566 if (smb_size + req->wct*2 > req_size) {
567 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
568 (unsigned int)req->wct,
569 (unsigned int)req_size));
b7898148 570 return false;
a1f593cd 571 }
a662a62e 572 /* Ensure bcc is correct. */
4f41be35 573 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
a662a62e
JA
574 DEBUG(0,("init_smb_request: invalid bcc number %u "
575 "(wct = %u, size %u)\n",
7f9d6f80 576 (unsigned int)req->buflen,
a662a62e
JA
577 (unsigned int)req->wct,
578 (unsigned int)req_size));
b7898148 579 return false;
a662a62e 580 }
54c51a66 581
cc6a4101 582 req->outbuf = NULL;
b7898148 583 return true;
0bc56a2e
VL
584}
585
aeb798c3
SM
586static void process_smb(struct smbd_server_connection *conn,
587 uint8_t *inbuf, size_t nread, size_t unread_bytes,
c16c90a1
SM
588 uint32_t seqnum, bool encrypted,
589 struct smb_perfcount_data *deferred_pcd);
aeb798c3 590
415e8e05 591static void smbd_deferred_open_timer(struct tevent_context *ev,
ae1cb5ca 592 struct tevent_timer *te,
aeb798c3
SM
593 struct timeval _tval,
594 void *private_data)
595{
596 struct pending_message_list *msg = talloc_get_type(private_data,
597 struct pending_message_list);
8b2b7d1c 598 struct smbd_server_connection *sconn = msg->sconn;
aeb798c3 599 TALLOC_CTX *mem_ctx = talloc_tos();
79842437 600 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
aeb798c3
SM
601 uint8_t *inbuf;
602
50aa8a4a
VL
603 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
604 msg->buf.length);
aeb798c3
SM
605 if (inbuf == NULL) {
606 exit_server("smbd_deferred_open_timer: talloc failed\n");
607 return;
608 }
609
610 /* We leave this message on the queue so the open code can
611 know this is a retry. */
79842437
JA
612 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
613 (unsigned long long)mid ));
8a6b90d4
JA
614
615 /* Mark the message as processed so this is not
616 * re-processed in error. */
617 msg->processed = true;
aeb798c3 618
8b2b7d1c 619 process_smb(sconn, inbuf,
aeb798c3 620 msg->buf.length, 0,
c16c90a1 621 msg->seqnum, msg->encrypted, &msg->pcd);
8a6b90d4
JA
622
623 /* If it's still there and was processed, remove it. */
8b2b7d1c 624 msg = get_deferred_open_message_smb(sconn, mid);
8a6b90d4 625 if (msg && msg->processed) {
8b2b7d1c 626 remove_deferred_open_message_smb(sconn, mid);
8a6b90d4 627 }
aeb798c3 628}
aab2fe02
JA
629
630/****************************************************************************
e5a95132
GJC
631 Function to push a message onto the tail of a linked list of smb messages ready
632 for processing.
aab2fe02
JA
633****************************************************************************/
634
30191d1a 635static bool push_queued_message(struct smb_request *req,
54abd2aa
GC
636 struct timeval request_time,
637 struct timeval end_time,
638 char *private_data, size_t private_len)
aab2fe02 639{
b578db69 640 int msg_len = smb_len(req->inbuf) + 4;
54abd2aa
GC
641 struct pending_message_list *msg;
642
ad0a07c5 643 msg = talloc_zero(NULL, struct pending_message_list);
aab2fe02 644
1eff0523
JA
645 if(msg == NULL) {
646 DEBUG(0,("push_message: malloc fail (1)\n"));
647 return False;
648 }
8b2b7d1c 649 msg->sconn = req->sconn;
aab2fe02 650
b578db69 651 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
2fc57c9a 652 if(msg->buf.data == NULL) {
1eff0523 653 DEBUG(0,("push_message: malloc fail (2)\n"));
fb5362c0 654 TALLOC_FREE(msg);
1eff0523
JA
655 return False;
656 }
aab2fe02 657
54abd2aa 658 msg->request_time = request_time;
c16c90a1 659 msg->seqnum = req->seqnum;
9254bb4e 660 msg->encrypted = req->encrypted;
8a6b90d4 661 msg->processed = false;
54c51a66 662 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
2fc57c9a 663
19ca97a7 664 if (private_data) {
54abd2aa
GC
665 msg->private_data = data_blob_talloc(msg, private_data,
666 private_len);
2fc57c9a
JA
667 if (msg->private_data.data == NULL) {
668 DEBUG(0,("push_message: malloc fail (3)\n"));
fb5362c0 669 TALLOC_FREE(msg);
b6fb0462 670 return False;
2fc57c9a
JA
671 }
672 }
aab2fe02 673
4e437616 674#if 0
16cfc724
SM
675 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
676 msg,
677 end_time,
678 smbd_deferred_open_timer,
679 msg);
aeb798c3
SM
680 if (!msg->te) {
681 DEBUG(0,("push_message: event_add_timed failed\n"));
682 TALLOC_FREE(msg);
683 return false;
684 }
4e437616 685#endif
aeb798c3 686
d20e968c
VL
687 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
688 struct pending_message_list *);
aab2fe02 689
54abd2aa
GC
690 DEBUG(10,("push_message: pushed message length %u on "
691 "deferred_open_queue\n", (unsigned int)msg_len));
2fc57c9a 692
1eff0523 693 return True;
aab2fe02
JA
694}
695
2fc57c9a
JA
696/****************************************************************************
697 Function to delete a sharing violation open message by mid.
698****************************************************************************/
699
04253dfd
VL
700void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
701 uint64_t mid)
2fc57c9a
JA
702{
703 struct pending_message_list *pml;
704
04253dfd
VL
705 if (sconn->using_smb2) {
706 remove_deferred_open_message_smb2(sconn, mid);
e15939b4
JA
707 return;
708 }
709
d20e968c 710 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
79842437 711 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
e15939b4 712 DEBUG(10,("remove_deferred_open_message_smb: "
79842437
JA
713 "deleting mid %llu len %u\n",
714 (unsigned long long)mid,
54abd2aa 715 (unsigned int)pml->buf.length ));
d20e968c 716 DLIST_REMOVE(sconn->deferred_open_queue, pml);
fb5362c0 717 TALLOC_FREE(pml);
2fc57c9a
JA
718 return;
719 }
720 }
721}
722
723/****************************************************************************
724 Move a sharing violation open retry message to the front of the list and
725 schedule it for immediate processing.
726****************************************************************************/
727
6617c2c1 728bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
502fdae7 729 uint64_t mid)
2fc57c9a
JA
730{
731 struct pending_message_list *pml;
732 int i = 0;
733
502fdae7 734 if (sconn->using_smb2) {
6617c2c1 735 return schedule_deferred_open_message_smb2(sconn, mid);
3413cf7a
JA
736 }
737
d20e968c 738 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
79842437 739 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
aeb798c3 740
79842437
JA
741 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
742 "msg_mid = %llu\n",
743 i++,
744 (unsigned long long)msg_mid ));
aeb798c3 745
2fc57c9a 746 if (mid == msg_mid) {
ae1cb5ca 747 struct tevent_timer *te;
aeb798c3 748
8a6b90d4
JA
749 if (pml->processed) {
750 /* A processed message should not be
751 * rescheduled. */
e15939b4 752 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
79842437
JA
753 "message mid %llu was already processed\n",
754 (unsigned long long)msg_mid ));
8a6b90d4
JA
755 continue;
756 }
757
79842437
JA
758 DEBUG(10,("schedule_deferred_open_message_smb: "
759 "scheduling mid %llu\n",
760 (unsigned long long)mid ));
aeb798c3 761
16cfc724
SM
762 te = tevent_add_timer(pml->sconn->ev_ctx,
763 pml,
764 timeval_zero(),
765 smbd_deferred_open_timer,
766 pml);
aeb798c3 767 if (!te) {
e15939b4 768 DEBUG(10,("schedule_deferred_open_message_smb: "
79842437
JA
769 "event_add_timed() failed, "
770 "skipping mid %llu\n",
771 (unsigned long long)msg_mid ));
aeb798c3
SM
772 }
773
774 TALLOC_FREE(pml->te);
775 pml->te = te;
d20e968c 776 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
6617c2c1 777 return true;
2fc57c9a
JA
778 }
779 }
780
79842437
JA
781 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
782 "find message mid %llu\n",
783 (unsigned long long)mid ));
6617c2c1
JA
784
785 return false;
2fc57c9a
JA
786}
787
788/****************************************************************************
8a6b90d4 789 Return true if this mid is on the deferred queue and was not yet processed.
2fc57c9a
JA
790****************************************************************************/
791
f9d183f9 792bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
2fc57c9a
JA
793{
794 struct pending_message_list *pml;
3e0f5862 795
f9d183f9
VL
796 if (sconn->using_smb2) {
797 return open_was_deferred_smb2(sconn, mid);
e15939b4
JA
798 }
799
d20e968c 800 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
79842437 801 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
2fc57c9a
JA
802 return True;
803 }
804 }
805 return False;
806}
807
808/****************************************************************************
809 Return the message queued by this mid.
810****************************************************************************/
811
cb69d105
VL
812static struct pending_message_list *get_deferred_open_message_smb(
813 struct smbd_server_connection *sconn, uint64_t mid)
2fc57c9a
JA
814{
815 struct pending_message_list *pml;
3e0f5862 816
d20e968c 817 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
79842437 818 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
2fc57c9a
JA
819 return pml;
820 }
821 }
822 return NULL;
823}
824
e15939b4
JA
825/****************************************************************************
826 Get the state data queued by this mid.
827****************************************************************************/
828
8f67f873 829bool get_deferred_open_message_state(struct smb_request *smbreq,
e15939b4
JA
830 struct timeval *p_request_time,
831 void **pp_state)
832{
833 struct pending_message_list *pml;
834
8b2b7d1c 835 if (smbreq->sconn->using_smb2) {
8f67f873 836 return get_deferred_open_message_state_smb2(smbreq->smb2req,
e15939b4
JA
837 p_request_time,
838 pp_state);
839 }
840
cb69d105 841 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
e15939b4
JA
842 if (!pml) {
843 return false;
844 }
845 if (p_request_time) {
846 *p_request_time = pml->request_time;
847 }
848 if (pp_state) {
849 *pp_state = (void *)pml->private_data.data;
850 }
851 return true;
852}
853
2fc57c9a 854/****************************************************************************
54abd2aa
GC
855 Function to push a deferred open smb message onto a linked list of local smb
856 messages ready for processing.
857****************************************************************************/
858
e15939b4 859bool push_deferred_open_message_smb(struct smb_request *req,
54abd2aa
GC
860 struct timeval request_time,
861 struct timeval timeout,
2bbb8c91 862 struct file_id id,
54abd2aa
GC
863 char *private_data, size_t priv_len)
864{
865 struct timeval end_time;
866
e15939b4 867 if (req->smb2req) {
8f67f873 868 return push_deferred_open_message_smb2(req->smb2req,
e15939b4
JA
869 request_time,
870 timeout,
2bbb8c91 871 id,
e15939b4
JA
872 private_data,
873 priv_len);
874 }
875
c3250149 876 if (req->unread_bytes) {
e15939b4 877 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
c3250149
JA
878 "unread_bytes = %u\n",
879 (unsigned int)req->unread_bytes ));
e15939b4 880 smb_panic("push_deferred_open_message_smb: "
c3250149
JA
881 "logic error unread_bytes != 0" );
882 }
883
54abd2aa
GC
884 end_time = timeval_sum(&request_time, &timeout);
885
79842437
JA
886 DEBUG(10,("push_deferred_open_message_smb: pushing message "
887 "len %u mid %llu timeout time [%u.%06u]\n",
888 (unsigned int) smb_len(req->inbuf)+4,
889 (unsigned long long)req->mid,
890 (unsigned int)end_time.tv_sec,
891 (unsigned int)end_time.tv_usec));
54abd2aa 892
b578db69 893 return push_queued_message(req, request_time, end_time,
54abd2aa
GC
894 private_data, priv_len);
895}
896
ac61f650
SM
897static void smbd_sig_term_handler(struct tevent_context *ev,
898 struct tevent_signal *se,
899 int signum,
900 int count,
901 void *siginfo,
902 void *private_data)
903{
904 exit_server_cleanly("termination signal");
905}
906
8a834642 907void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
ac61f650
SM
908{
909 struct tevent_signal *se;
910
8a834642
SM
911 se = tevent_add_signal(sconn->ev_ctx,
912 sconn,
ac61f650
SM
913 SIGTERM, 0,
914 smbd_sig_term_handler,
8a834642 915 sconn);
ac61f650
SM
916 if (!se) {
917 exit_server("failed to setup SIGTERM handler");
918 }
919}
920
921static void smbd_sig_hup_handler(struct tevent_context *ev,
922 struct tevent_signal *se,
923 int signum,
924 int count,
925 void *siginfo,
926 void *private_data)
927{
290ce331
SM
928 struct smbd_server_connection *sconn =
929 talloc_get_type_abort(private_data,
930 struct smbd_server_connection);
931
ac61f650
SM
932 change_to_root_user();
933 DEBUG(1,("Reloading services after SIGHUP\n"));
03455519 934 reload_services(sconn, conn_snum_used, false);
ac61f650
SM
935}
936
290ce331 937void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
ac61f650
SM
938{
939 struct tevent_signal *se;
940
290ce331
SM
941 se = tevent_add_signal(sconn->ev_ctx,
942 sconn,
943 SIGHUP, 0,
944 smbd_sig_hup_handler,
945 sconn);
ac61f650
SM
946 if (!se) {
947 exit_server("failed to setup SIGHUP handler");
948 }
949}
950
e412b8bf
SM
951static void smbd_conf_updated(struct messaging_context *msg,
952 void *private_data,
953 uint32_t msg_type,
954 struct server_id server_id,
955 DATA_BLOB *data)
956{
957 struct smbd_server_connection *sconn =
958 talloc_get_type_abort(private_data,
959 struct smbd_server_connection);
960
961 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
962 "updated. Reloading.\n"));
963 change_to_root_user();
03455519 964 reload_services(sconn, conn_snum_used, false);
e412b8bf
SM
965}
966
22dbd677
JA
967/*
968 * Only allow 5 outstanding trans requests. We're allocating memory, so
969 * prevent a DoS.
970 */
aab2fe02 971
79842437 972NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
c3effa8b 973{
22dbd677
JA
974 int count = 0;
975 for (; list != NULL; list = list->next) {
c3effa8b 976
22dbd677
JA
977 if (list->mid == mid) {
978 return NT_STATUS_INVALID_PARAMETER;
979 }
980
981 count += 1;
982 }
983 if (count > 5) {
984 return NT_STATUS_INSUFFICIENT_RESOURCES;
985 }
c3effa8b 986
22dbd677 987 return NT_STATUS_OK;
c3effa8b
AT
988}
989
c3effa8b
AT
990/*
991These flags determine some of the permissions required to do an operation
992
993Note that I don't set NEED_WRITE on some write operations because they
994are used by some brain-dead clients when printing, and I don't want to
995force write permissions on print services.
996*/
997#define AS_USER (1<<0)
ce61fb21 998#define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
c3effa8b 999#define TIME_INIT (1<<2)
ce61fb21
JA
1000#define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1001#define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
54abd2aa 1002#define DO_CHDIR (1<<6)
c3effa8b
AT
1003
1004/*
1005 define a list of possible SMB messages and their corresponding
1006 functions. Any message that has a NULL function is unimplemented -
1007 please feel free to contribute implementations!
1008*/
1eff0523
JA
1009static const struct smb_message_struct {
1010 const char *name;
48d3a1d2 1011 void (*fn)(struct smb_request *req);
1eff0523
JA
1012 int flags;
1013} smb_messages[256] = {
918c3ebe 1014
b578db69
VL
1015/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1016/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1017/* 0x02 */ { "SMBopen",reply_open,AS_USER },
1018/* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1019/* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1020/* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1021/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1022/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1023/* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1024/* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1025/* 0x0a */ { "SMBread",reply_read,AS_USER},
1026/* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1027/* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1028/* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1029/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1030/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1031/* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1032/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1033/* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1034/* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1035/* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1036/* 0x15 */ { NULL, NULL, 0 },
1037/* 0x16 */ { NULL, NULL, 0 },
1038/* 0x17 */ { NULL, NULL, 0 },
1039/* 0x18 */ { NULL, NULL, 0 },
1040/* 0x19 */ { NULL, NULL, 0 },
1041/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1042/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1043/* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1044/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1045/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1046/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1047/* 0x20 */ { "SMBwritec", NULL,0},
1048/* 0x21 */ { NULL, NULL, 0 },
1049/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1050/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1051/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1052/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1053/* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1054/* 0x27 */ { "SMBioctl",reply_ioctl,0},
1055/* 0x28 */ { "SMBioctls", NULL,AS_USER},
1056/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1057/* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1058/* 0x2b */ { "SMBecho",reply_echo,0},
1059/* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1060/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1061/* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1062/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1063/* 0x30 */ { NULL, NULL, 0 },
1064/* 0x31 */ { NULL, NULL, 0 },
1065/* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
7716ad68 1066/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
b578db69
VL
1067/* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1068/* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1069/* 0x36 */ { NULL, NULL, 0 },
1070/* 0x37 */ { NULL, NULL, 0 },
1071/* 0x38 */ { NULL, NULL, 0 },
1072/* 0x39 */ { NULL, NULL, 0 },
1073/* 0x3a */ { NULL, NULL, 0 },
1074/* 0x3b */ { NULL, NULL, 0 },
1075/* 0x3c */ { NULL, NULL, 0 },
1076/* 0x3d */ { NULL, NULL, 0 },
1077/* 0x3e */ { NULL, NULL, 0 },
1078/* 0x3f */ { NULL, NULL, 0 },
1079/* 0x40 */ { NULL, NULL, 0 },
1080/* 0x41 */ { NULL, NULL, 0 },
1081/* 0x42 */ { NULL, NULL, 0 },
1082/* 0x43 */ { NULL, NULL, 0 },
1083/* 0x44 */ { NULL, NULL, 0 },
1084/* 0x45 */ { NULL, NULL, 0 },
1085/* 0x46 */ { NULL, NULL, 0 },
1086/* 0x47 */ { NULL, NULL, 0 },
1087/* 0x48 */ { NULL, NULL, 0 },
1088/* 0x49 */ { NULL, NULL, 0 },
1089/* 0x4a */ { NULL, NULL, 0 },
1090/* 0x4b */ { NULL, NULL, 0 },
1091/* 0x4c */ { NULL, NULL, 0 },
1092/* 0x4d */ { NULL, NULL, 0 },
1093/* 0x4e */ { NULL, NULL, 0 },
1094/* 0x4f */ { NULL, NULL, 0 },
1095/* 0x50 */ { NULL, NULL, 0 },
1096/* 0x51 */ { NULL, NULL, 0 },
1097/* 0x52 */ { NULL, NULL, 0 },
1098/* 0x53 */ { NULL, NULL, 0 },
1099/* 0x54 */ { NULL, NULL, 0 },
1100/* 0x55 */ { NULL, NULL, 0 },
1101/* 0x56 */ { NULL, NULL, 0 },
1102/* 0x57 */ { NULL, NULL, 0 },
1103/* 0x58 */ { NULL, NULL, 0 },
1104/* 0x59 */ { NULL, NULL, 0 },
1105/* 0x5a */ { NULL, NULL, 0 },
1106/* 0x5b */ { NULL, NULL, 0 },
1107/* 0x5c */ { NULL, NULL, 0 },
1108/* 0x5d */ { NULL, NULL, 0 },
1109/* 0x5e */ { NULL, NULL, 0 },
1110/* 0x5f */ { NULL, NULL, 0 },
1111/* 0x60 */ { NULL, NULL, 0 },
1112/* 0x61 */ { NULL, NULL, 0 },
1113/* 0x62 */ { NULL, NULL, 0 },
1114/* 0x63 */ { NULL, NULL, 0 },
1115/* 0x64 */ { NULL, NULL, 0 },
1116/* 0x65 */ { NULL, NULL, 0 },
1117/* 0x66 */ { NULL, NULL, 0 },
1118/* 0x67 */ { NULL, NULL, 0 },
1119/* 0x68 */ { NULL, NULL, 0 },
1120/* 0x69 */ { NULL, NULL, 0 },
1121/* 0x6a */ { NULL, NULL, 0 },
1122/* 0x6b */ { NULL, NULL, 0 },
1123/* 0x6c */ { NULL, NULL, 0 },
1124/* 0x6d */ { NULL, NULL, 0 },
1125/* 0x6e */ { NULL, NULL, 0 },
1126/* 0x6f */ { NULL, NULL, 0 },
1127/* 0x70 */ { "SMBtcon",reply_tcon,0},
1128/* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1129/* 0x72 */ { "SMBnegprot",reply_negprot,0},
1130/* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1131/* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1132/* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1133/* 0x76 */ { NULL, NULL, 0 },
1134/* 0x77 */ { NULL, NULL, 0 },
1135/* 0x78 */ { NULL, NULL, 0 },
1136/* 0x79 */ { NULL, NULL, 0 },
1137/* 0x7a */ { NULL, NULL, 0 },
1138/* 0x7b */ { NULL, NULL, 0 },
1139/* 0x7c */ { NULL, NULL, 0 },
1140/* 0x7d */ { NULL, NULL, 0 },
1141/* 0x7e */ { NULL, NULL, 0 },
1142/* 0x7f */ { NULL, NULL, 0 },
1143/* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1144/* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1145/* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1146/* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1147/* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1148/* 0x85 */ { NULL, NULL, 0 },
1149/* 0x86 */ { NULL, NULL, 0 },
1150/* 0x87 */ { NULL, NULL, 0 },
1151/* 0x88 */ { NULL, NULL, 0 },
1152/* 0x89 */ { NULL, NULL, 0 },
1153/* 0x8a */ { NULL, NULL, 0 },
1154/* 0x8b */ { NULL, NULL, 0 },
1155/* 0x8c */ { NULL, NULL, 0 },
1156/* 0x8d */ { NULL, NULL, 0 },
1157/* 0x8e */ { NULL, NULL, 0 },
1158/* 0x8f */ { NULL, NULL, 0 },
1159/* 0x90 */ { NULL, NULL, 0 },
1160/* 0x91 */ { NULL, NULL, 0 },
1161/* 0x92 */ { NULL, NULL, 0 },
1162/* 0x93 */ { NULL, NULL, 0 },
1163/* 0x94 */ { NULL, NULL, 0 },
1164/* 0x95 */ { NULL, NULL, 0 },
1165/* 0x96 */ { NULL, NULL, 0 },
1166/* 0x97 */ { NULL, NULL, 0 },
1167/* 0x98 */ { NULL, NULL, 0 },
1168/* 0x99 */ { NULL, NULL, 0 },
1169/* 0x9a */ { NULL, NULL, 0 },
1170/* 0x9b */ { NULL, NULL, 0 },
1171/* 0x9c */ { NULL, NULL, 0 },
1172/* 0x9d */ { NULL, NULL, 0 },
1173/* 0x9e */ { NULL, NULL, 0 },
1174/* 0x9f */ { NULL, NULL, 0 },
1175/* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1176/* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1177/* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1178/* 0xa3 */ { NULL, NULL, 0 },
1179/* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1180/* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1181/* 0xa6 */ { NULL, NULL, 0 },
1182/* 0xa7 */ { NULL, NULL, 0 },
1183/* 0xa8 */ { NULL, NULL, 0 },
1184/* 0xa9 */ { NULL, NULL, 0 },
1185/* 0xaa */ { NULL, NULL, 0 },
1186/* 0xab */ { NULL, NULL, 0 },
1187/* 0xac */ { NULL, NULL, 0 },
1188/* 0xad */ { NULL, NULL, 0 },
1189/* 0xae */ { NULL, NULL, 0 },
1190/* 0xaf */ { NULL, NULL, 0 },
1191/* 0xb0 */ { NULL, NULL, 0 },
1192/* 0xb1 */ { NULL, NULL, 0 },
1193/* 0xb2 */ { NULL, NULL, 0 },
1194/* 0xb3 */ { NULL, NULL, 0 },
1195/* 0xb4 */ { NULL, NULL, 0 },
1196/* 0xb5 */ { NULL, NULL, 0 },
1197/* 0xb6 */ { NULL, NULL, 0 },
1198/* 0xb7 */ { NULL, NULL, 0 },
1199/* 0xb8 */ { NULL, NULL, 0 },
1200/* 0xb9 */ { NULL, NULL, 0 },
1201/* 0xba */ { NULL, NULL, 0 },
1202/* 0xbb */ { NULL, NULL, 0 },
1203/* 0xbc */ { NULL, NULL, 0 },
1204/* 0xbd */ { NULL, NULL, 0 },
1205/* 0xbe */ { NULL, NULL, 0 },
1206/* 0xbf */ { NULL, NULL, 0 },
1207/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1208/* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1209/* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1210/* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1211/* 0xc4 */ { NULL, NULL, 0 },
1212/* 0xc5 */ { NULL, NULL, 0 },
1213/* 0xc6 */ { NULL, NULL, 0 },
1214/* 0xc7 */ { NULL, NULL, 0 },
1215/* 0xc8 */ { NULL, NULL, 0 },
1216/* 0xc9 */ { NULL, NULL, 0 },
1217/* 0xca */ { NULL, NULL, 0 },
1218/* 0xcb */ { NULL, NULL, 0 },
1219/* 0xcc */ { NULL, NULL, 0 },
1220/* 0xcd */ { NULL, NULL, 0 },
1221/* 0xce */ { NULL, NULL, 0 },
1222/* 0xcf */ { NULL, NULL, 0 },
1223/* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1224/* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1225/* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1226/* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1227/* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1228/* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1229/* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1230/* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1231/* 0xd8 */ { NULL, NULL, 0 },
1232/* 0xd9 */ { NULL, NULL, 0 },
1233/* 0xda */ { NULL, NULL, 0 },
1234/* 0xdb */ { NULL, NULL, 0 },
1235/* 0xdc */ { NULL, NULL, 0 },
1236/* 0xdd */ { NULL, NULL, 0 },
1237/* 0xde */ { NULL, NULL, 0 },
1238/* 0xdf */ { NULL, NULL, 0 },
1239/* 0xe0 */ { NULL, NULL, 0 },
1240/* 0xe1 */ { NULL, NULL, 0 },
1241/* 0xe2 */ { NULL, NULL, 0 },
1242/* 0xe3 */ { NULL, NULL, 0 },
1243/* 0xe4 */ { NULL, NULL, 0 },
1244/* 0xe5 */ { NULL, NULL, 0 },
1245/* 0xe6 */ { NULL, NULL, 0 },
1246/* 0xe7 */ { NULL, NULL, 0 },
1247/* 0xe8 */ { NULL, NULL, 0 },
1248/* 0xe9 */ { NULL, NULL, 0 },
1249/* 0xea */ { NULL, NULL, 0 },
1250/* 0xeb */ { NULL, NULL, 0 },
1251/* 0xec */ { NULL, NULL, 0 },
1252/* 0xed */ { NULL, NULL, 0 },
1253/* 0xee */ { NULL, NULL, 0 },
1254/* 0xef */ { NULL, NULL, 0 },
1255/* 0xf0 */ { NULL, NULL, 0 },
1256/* 0xf1 */ { NULL, NULL, 0 },
1257/* 0xf2 */ { NULL, NULL, 0 },
1258/* 0xf3 */ { NULL, NULL, 0 },
1259/* 0xf4 */ { NULL, NULL, 0 },
1260/* 0xf5 */ { NULL, NULL, 0 },
1261/* 0xf6 */ { NULL, NULL, 0 },
1262/* 0xf7 */ { NULL, NULL, 0 },
1263/* 0xf8 */ { NULL, NULL, 0 },
1264/* 0xf9 */ { NULL, NULL, 0 },
1265/* 0xfa */ { NULL, NULL, 0 },
1266/* 0xfb */ { NULL, NULL, 0 },
1267/* 0xfc */ { NULL, NULL, 0 },
1268/* 0xfd */ { NULL, NULL, 0 },
1269/* 0xfe */ { NULL, NULL, 0 },
1270/* 0xff */ { NULL, NULL, 0 }
918c3ebe
JA
1271
1272};
c3effa8b 1273
cc6a4101
VL
1274/*******************************************************************
1275 allocate and initialize a reply packet
1276********************************************************************/
1277
ae0c6cff
VL
1278static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1279 const char *inbuf, char **outbuf, uint8_t num_words,
1280 uint32_t num_bytes)
cc6a4101 1281{
36f6a8ab
JA
1282 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1283
2fb27fcb 1284 /*
36f6a8ab
JA
1285 * Protect against integer wrap.
1286 * The SMB layer reply can be up to 0xFFFFFF bytes.
1287 */
1288 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
2fb27fcb 1289 char *msg;
a4c0812a
VL
1290 if (asprintf(&msg, "num_bytes too large: %u",
1291 (unsigned)num_bytes) == -1) {
4f41be35 1292 msg = discard_const_p(char, "num_bytes too large");
a4c0812a 1293 }
2fb27fcb
VL
1294 smb_panic(msg);
1295 }
1296
36f6a8ab
JA
1297 /*
1298 * Here we include the NBT header for now.
1299 */
3d151376 1300 *outbuf = talloc_array(mem_ctx, char,
36f6a8ab 1301 NBT_HDR_SIZE + smb_len);
5cd8a427
VL
1302 if (*outbuf == NULL) {
1303 return false;
cc6a4101
VL
1304 }
1305
ae0c6cff 1306 construct_reply_common(req, inbuf, *outbuf);
5cd8a427 1307 srv_set_message(*outbuf, num_words, num_bytes, false);
cc6a4101
VL
1308 /*
1309 * Zero out the word area, the caller has to take care of the bcc area
1310 * himself
1311 */
1312 if (num_words != 0) {
36f6a8ab 1313 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
cc6a4101
VL
1314 }
1315
5cd8a427
VL
1316 return true;
1317}
1318
1319void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1320{
1321 char *outbuf;
4f41be35 1322 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
5cd8a427
VL
1323 num_bytes)) {
1324 smb_panic("could not allocate output buffer\n");
1325 }
1326 req->outbuf = (uint8_t *)outbuf;
cc6a4101
VL
1327}
1328
1329
712a30ed 1330/*******************************************************************
a834a73e
GC
1331 Dump a packet to a file.
1332********************************************************************/
1333
c99d2455 1334static void smb_dump(const char *name, int type, const char *data)
712a30ed 1335{
c99d2455 1336 size_t len;
712a30ed 1337 int fd, i;
d068bc64
JA
1338 char *fname = NULL;
1339 if (DEBUGLEVEL < 50) {
1340 return;
1341 }
712a30ed 1342
c99d2455 1343 len = smb_len_tcp(data)+4;
712a30ed 1344 for (i=1;i<100;i++) {
86a80cf4
JA
1345 fname = talloc_asprintf(talloc_tos(),
1346 "/tmp/%s.%d.%s",
1347 name,
1348 i,
1349 type ? "req" : "resp");
1350 if (fname == NULL) {
d068bc64
JA
1351 return;
1352 }
712a30ed
LL
1353 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1354 if (fd != -1 || errno != EEXIST) break;
86a80cf4 1355 TALLOC_FREE(fname);
712a30ed
LL
1356 }
1357 if (fd != -1) {
e400bfce
JA
1358 ssize_t ret = write(fd, data, len);
1359 if (ret != len)
1360 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
712a30ed 1361 close(fd);
9c8d23e5 1362 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
712a30ed 1363 }
86a80cf4 1364 TALLOC_FREE(fname);
712a30ed
LL
1365}
1366
c3effa8b 1367/****************************************************************************
cc6a4101
VL
1368 Prepare everything for calling the actual request function, and potentially
1369 call the request function via the "new" interface.
1370
1371 Return False if the "legacy" function needs to be called, everything is
1372 prepared.
1373
1374 Return True if we're done.
1375
1376 I know this API sucks, but it is the one with the least code change I could
1377 find.
c3effa8b 1378****************************************************************************/
a834a73e 1379
07386bb5 1380static connection_struct *switch_message(uint8 type, struct smb_request *req)
c3effa8b 1381{
941db29a 1382 int flags;
02d9ba6e 1383 uint64_t session_tag;
9254bb4e 1384 connection_struct *conn = NULL;
6b8db9b2 1385 struct smbd_server_connection *sconn = req->sconn;
e7700025
SM
1386 NTTIME now = timeval_to_nttime(&req->request_time);
1387 struct smbXsrv_session *session = NULL;
1388 NTSTATUS status;
24f8e973 1389
a834a73e 1390 errno = 0;
0557c6cb 1391
48d3a1d2 1392 if (smb_messages[type].fn == NULL) {
a834a73e 1393 DEBUG(0,("Unknown message type %d!\n",type));
c99d2455 1394 smb_dump("Unknown", 1, (const char *)req->inbuf);
cc6a4101 1395 reply_unknown_new(req, type);
9254bb4e 1396 return NULL;
941db29a 1397 }
a834a73e 1398
941db29a 1399 flags = smb_messages[type].flags;
a834a73e 1400
941db29a 1401 /* In share mode security we must ignore the vuid. */
d7bb9618 1402 session_tag = req->vuid;
9254bb4e 1403 conn = req->conn;
918c3ebe 1404
8579dd4d 1405 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
c0288e06 1406 (int)getpid(), (unsigned long)conn));
941db29a 1407
c99d2455 1408 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
918c3ebe 1409
941db29a 1410 /* Ensure this value is replaced in the incoming packet. */
4f41be35 1411 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
918c3ebe 1412
941db29a
VL
1413 /*
1414 * Ensure the correct username is in current_user_info. This is a
1415 * really ugly bugfix for problems with multiple session_setup_and_X's
1416 * being done and allowing %U and %G substitutions to work correctly.
1417 * There is a reason this code is done here, don't move it unless you
8579dd4d
VL
1418 * know what you're doing... :-).
1419 * JRA.
941db29a
VL
1420 */
1421
e7700025
SM
1422 /*
1423 * lookup an existing session
1424 *
1425 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1426 * here, the main check is still in change_to_user()
1427 */
1428 status = smb1srv_session_lookup(sconn->conn,
1429 session_tag,
1430 now,
1431 &session);
1432 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1433 switch (type) {
1434 case SMBsesssetupX:
1435 status = NT_STATUS_OK;
1436 break;
1437 default:
1438 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1439 (unsigned long long)session_tag,
1440 (unsigned long long)req->mid));
1441 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1442 return conn;
1443 }
1444 }
1445
3cc0651d 1446 if (session_tag != sconn->conn->last_session_id) {
f52e5738 1447 struct user_struct *vuser = NULL;
941db29a 1448
3cc0651d 1449 sconn->conn->last_session_id = session_tag;
e7700025
SM
1450 if (session) {
1451 vuser = session->compat;
1452 }
1453 if (vuser) {
1454 set_current_user_info(
1455 vuser->session_info->unix_info->sanitized_username,
1456 vuser->session_info->unix_info->unix_name,
1457 vuser->session_info->info->domain_name);
a59149b8 1458 }
941db29a 1459 }
d57e67f9 1460
941db29a
VL
1461 /* Does this call need to be run as the connected user? */
1462 if (flags & AS_USER) {
fcda2645 1463
941db29a
VL
1464 /* Does this call need a valid tree connection? */
1465 if (!conn) {
8579dd4d
VL
1466 /*
1467 * Amazingly, the error code depends on the command
1468 * (from Samba4).
1469 */
941db29a 1470 if (type == SMBntcreateX) {
cc6a4101 1471 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
941db29a 1472 } else {
642101ac 1473 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
ce61fb21 1474 }
9254bb4e 1475 return NULL;
941db29a 1476 }
d57e67f9 1477
941db29a 1478 if (!change_to_user(conn,session_tag)) {
5e9aade5 1479 DEBUG(0, ("Error: Could not change to user. Removing "
79842437
JA
1480 "deferred open, mid=%llu.\n",
1481 (unsigned long long)req->mid));
74deee3c 1482 reply_force_doserror(req, ERRSRV, ERRbaduid);
9254bb4e 1483 return conn;
941db29a 1484 }
c3effa8b 1485
941db29a 1486 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
918c3ebe 1487
941db29a
VL
1488 /* Does it need write permission? */
1489 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
cc6a4101 1490 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
9254bb4e 1491 return conn;
ce61fb21 1492 }
918c3ebe 1493
941db29a
VL
1494 /* IPC services are limited */
1495 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
642101ac 1496 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9254bb4e 1497 return conn;
f60ad8de 1498 }
941db29a
VL
1499 } else {
1500 /* This call needs to be run as root */
1501 change_to_root_user();
1502 }
918c3ebe 1503
941db29a
VL
1504 /* load service specific parameters */
1505 if (conn) {
9254bb4e
JA
1506 if (req->encrypted) {
1507 conn->encrypted_tid = true;
1508 /* encrypted required from now on. */
e5d4e8df 1509 conn->encrypt_level = SMB_SIGNING_REQUIRED;
9254bb4e 1510 } else if (ENCRYPTION_REQUIRED(conn)) {
7808a259 1511 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
9f1dfd8f
SM
1512 DEBUG(1,("service[%s] requires encryption"
1513 "%s ACCESS_DENIED. mid=%llu\n",
1514 lp_servicename(talloc_tos(), SNUM(conn)),
1515 smb_fn_name(type),
1516 (unsigned long long)req->mid));
1517 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9254bb4e
JA
1518 return conn;
1519 }
1520 }
1521
cc6a4101 1522 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
8579dd4d
VL
1523 (flags & (AS_USER|DO_CHDIR)
1524 ?True:False))) {
642101ac 1525 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9254bb4e 1526 return conn;
afce2b24 1527 }
941db29a
VL
1528 conn->num_smb_operations++;
1529 }
918c3ebe 1530
1f62df52
VL
1531 /*
1532 * Does this protocol need to be run as guest? (Only archane
1533 * messenger service requests have this...)
1534 */
1535 if (flags & AS_GUEST) {
1536 char *raddr;
1537 bool ok;
a513086c 1538
1f62df52
VL
1539 if (!change_to_guest()) {
1540 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1541 return conn;
1542 }
1543
1544 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1545 talloc_tos());
1546 if (raddr == NULL) {
1547 reply_nterror(req, NT_STATUS_NO_MEMORY);
1548 return conn;
1549 }
1550
1551 /*
1552 * Haven't we checked this in smbd_process already???
1553 */
1554
cdb6af95 1555 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1f62df52
VL
1556 sconn->remote_hostname, raddr);
1557 TALLOC_FREE(raddr);
1558
1559 if (!ok) {
1560 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1561 return conn;
1562 }
cc6a4101
VL
1563 }
1564
48d3a1d2 1565 smb_messages[type].fn(req);
9254bb4e 1566 return req->conn;
e9ea36e4
AT
1567}
1568
e9ea36e4 1569/****************************************************************************
a834a73e 1570 Construct a reply to the incoming packet.
e9ea36e4 1571****************************************************************************/
a834a73e 1572
c2533f94
VL
1573static void construct_reply(struct smbd_server_connection *sconn,
1574 char *inbuf, int size, size_t unread_bytes,
c16c90a1 1575 uint32_t seqnum, bool encrypted,
54c51a66 1576 struct smb_perfcount_data *deferred_pcd)
e9ea36e4 1577{
9254bb4e 1578 connection_struct *conn;
cc6a4101 1579 struct smb_request *req;
e9ea36e4 1580
929e1d99 1581 if (!(req = talloc(talloc_tos(), struct smb_request))) {
cc6a4101
VL
1582 smb_panic("could not allocate smb_request");
1583 }
54c51a66 1584
c2533f94
VL
1585 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1586 encrypted, seqnum)) {
b7898148
VL
1587 exit_server_cleanly("Invalid SMB request");
1588 }
1589
b8125663 1590 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
e9ea36e4 1591
54c51a66 1592 /* we popped this message off the queue - keep original perf data */
1593 if (deferred_pcd)
1594 req->pcd = *deferred_pcd;
1595 else {
1596 SMB_PERFCOUNT_START(&req->pcd);
1597 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1598 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1599 }
1600
07386bb5 1601 conn = switch_message(req->cmd, req);
e9ea36e4 1602
b578db69
VL
1603 if (req->outbuf == NULL) {
1604 return;
cc6a4101 1605 }
e9ea36e4 1606
b578db69
VL
1607 if (CVAL(req->outbuf,0) == 0) {
1608 show_msg((char *)req->outbuf);
1609 }
e9ea36e4 1610
1808dd0a 1611 if (!srv_send_smb(req->sconn,
9254bb4e 1612 (char *)req->outbuf,
c16c90a1 1613 true, req->seqnum+1,
54c51a66 1614 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1615 &req->pcd)) {
9254bb4e 1616 exit_server_cleanly("construct_reply: srv_send_smb failed.");
dc90cd89 1617 }
cc6a4101
VL
1618
1619 TALLOC_FREE(req);
1620
1621 return;
e9ea36e4
AT
1622}
1623
3b2c9beb
VL
1624static void construct_reply_chain(struct smbd_server_connection *sconn,
1625 char *inbuf, int size, uint32_t seqnum,
1626 bool encrypted,
1627 struct smb_perfcount_data *deferred_pcd)
1628{
3b2c9beb 1629 struct smb_request **reqs = NULL;
8f93068c
VL
1630 struct smb_request *req;
1631 unsigned num_reqs;
3b2c9beb
VL
1632 bool ok;
1633
1634 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1635 seqnum, &reqs, &num_reqs);
1636 if (!ok) {
8f93068c
VL
1637 char errbuf[smb_size];
1638 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1639 __LINE__, __FILE__);
1640 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1641 NULL)) {
1642 exit_server_cleanly("construct_reply_chain: "
1643 "srv_send_smb failed.");
1644 }
1645 return;
3b2c9beb
VL
1646 }
1647
8f93068c
VL
1648 req = reqs[0];
1649 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
3b2c9beb 1650
8f93068c 1651 req->conn = switch_message(req->cmd, req);
3b2c9beb 1652
8f93068c
VL
1653 if (req->outbuf == NULL) {
1654 /*
1655 * Request has suspended itself, will come
1656 * back here.
1657 */
1658 return;
1659 }
1660 smb_request_done(req);
1661}
3b2c9beb 1662
8f93068c
VL
1663/*
1664 * To be called from an async SMB handler that is potentially chained
1665 * when it is finished for shipping.
1666 */
1667
1668void smb_request_done(struct smb_request *req)
1669{
1670 struct smb_request **reqs = NULL;
1671 struct smb_request *first_req;
1672 size_t i, num_reqs, next_index;
1673 NTSTATUS status;
1674
1675 if (req->chain == NULL) {
1676 first_req = req;
1677 goto shipit;
3b2c9beb
VL
1678 }
1679
8f93068c
VL
1680 reqs = req->chain;
1681 num_reqs = talloc_array_length(reqs);
3b2c9beb 1682
8f93068c
VL
1683 for (i=0; i<num_reqs; i++) {
1684 if (reqs[i] == req) {
1685 break;
1686 }
1687 }
1688 if (i == num_reqs) {
3b2c9beb 1689 /*
8f93068c 1690 * Invalid chain, should not happen
3b2c9beb 1691 */
8f93068c
VL
1692 status = NT_STATUS_INTERNAL_ERROR;
1693 goto error;
1694 }
1695 next_index = i+1;
1696
1697 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1698 struct smb_request *next = reqs[next_index];
faa8edcc
SM
1699 struct smbXsrv_tcon *tcon;
1700 NTTIME now = timeval_to_nttime(&req->request_time);
8f93068c
VL
1701
1702 next->vuid = SVAL(req->outbuf, smb_uid);
1703 next->tid = SVAL(req->outbuf, smb_tid);
faa8edcc
SM
1704 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1705 now, &tcon);
1706 if (NT_STATUS_IS_OK(status)) {
1707 req->conn = tcon->compat;
1708 } else {
1709 req->conn = NULL;
1710 }
8f93068c 1711 next->chain_fsp = req->chain_fsp;
fc5e5845 1712 next->inbuf = req->inbuf;
8f93068c
VL
1713
1714 req = next;
1715 req->conn = switch_message(req->cmd, req);
1716
1717 if (req->outbuf == NULL) {
1718 /*
1719 * Request has suspended itself, will come
1720 * back here.
1721 */
1722 return;
1723 }
1724 next_index += 1;
3b2c9beb
VL
1725 }
1726
8f93068c
VL
1727 first_req = reqs[0];
1728
3b2c9beb 1729 for (i=1; i<next_index; i++) {
8f93068c 1730 bool ok;
3b2c9beb 1731
8f93068c 1732 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
3b2c9beb
VL
1733 if (!ok) {
1734 status = NT_STATUS_INTERNAL_ERROR;
1735 goto error;
1736 }
3b2c9beb
VL
1737 }
1738
8f93068c
VL
1739 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1740 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
3b2c9beb
VL
1741
1742 /*
1743 * This scary statement intends to set the
1744 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1745 * to the value last_req->outbuf carries
1746 */
1747 SSVAL(first_req->outbuf, smb_flg2,
1748 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
8f93068c 1749 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
3b2c9beb
VL
1750
1751 /*
1752 * Transfer the error codes from the subrequest to the main one
1753 */
8f93068c
VL
1754 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1755 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
3b2c9beb 1756
8f93068c
VL
1757 _smb_setlen_large(
1758 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
3b2c9beb
VL
1759
1760shipit:
3b2c9beb
VL
1761 if (!srv_send_smb(first_req->sconn,
1762 (char *)first_req->outbuf,
1763 true, first_req->seqnum+1,
8f93068c 1764 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
3b2c9beb
VL
1765 &first_req->pcd)) {
1766 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1767 "failed.");
1768 }
8f93068c
VL
1769 TALLOC_FREE(req); /* non-chained case */
1770 TALLOC_FREE(reqs); /* chained case */
3b2c9beb
VL
1771 return;
1772
1773error:
1774 {
1775 char errbuf[smb_size];
1776 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
8f93068c
VL
1777 if (!srv_send_smb(req->sconn, errbuf, true,
1778 req->seqnum+1, req->encrypted,
3b2c9beb
VL
1779 NULL)) {
1780 exit_server_cleanly("construct_reply_chain: "
1781 "srv_send_smb failed.");
1782 }
1783 }
8f93068c
VL
1784 TALLOC_FREE(req); /* non-chained case */
1785 TALLOC_FREE(reqs); /* chained case */
3b2c9beb
VL
1786}
1787
e9ea36e4 1788/****************************************************************************
49ecd176 1789 Process an smb from the client
e9ea36e4 1790****************************************************************************/
81bdb591 1791static void process_smb(struct smbd_server_connection *sconn,
aeb798c3 1792 uint8_t *inbuf, size_t nread, size_t unread_bytes,
c16c90a1
SM
1793 uint32_t seqnum, bool encrypted,
1794 struct smb_perfcount_data *deferred_pcd)
e9ea36e4 1795{
1eff0523 1796 int msg_type = CVAL(inbuf,0);
1eff0523
JA
1797
1798 DO_PROFILE_INC(smb_count);
1799
cc6a4101
VL
1800 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1801 smb_len(inbuf) ) );
2d81721a 1802 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
81bdb591 1803 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1eff0523 1804
0633c0f6 1805 if (msg_type != NBSSmessage) {
cc6a4101
VL
1806 /*
1807 * NetBIOS session request, keepalive, etc.
1808 */
81bdb591 1809 reply_special(sconn, (char *)inbuf, nread);
aeb798c3 1810 goto done;
cc6a4101 1811 }
1eff0523 1812
81bdb591 1813 if (sconn->using_smb2) {
d28fa8fa
JA
1814 /* At this point we're not really using smb2,
1815 * we make the decision here.. */
688945a9 1816 if (smbd_is_smb2_header(inbuf, nread)) {
cac60a70 1817 smbd_smb2_first_negprot(sconn, inbuf, nread);
688945a9 1818 return;
b4b9918c 1819 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
c9a3661c
JA
1820 && CVAL(inbuf, smb_com) != 0x72) {
1821 /* This is a non-negprot SMB1 packet.
1822 Disable SMB2 from now on. */
cac60a70 1823 sconn->using_smb2 = false;
688945a9 1824 }
688945a9
SM
1825 }
1826
fed2fba0
VL
1827 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1828 * so subtract 4 from it. */
1829 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1830 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1831 smb_len(inbuf)));
1832
1833 /* special magic for immediate exit */
1834 if ((nread == 9) &&
1835 (IVAL(inbuf, 4) == 0x74697865) &&
1836 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1837 uint8_t exitcode = CVAL(inbuf, 8);
1838 DEBUG(1, ("Exiting immediately with code %d\n",
1839 (int)exitcode));
1840 exit(exitcode);
1841 }
1842
1843 exit_server_cleanly("Non-SMB packet");
1844 }
1845
aeb798c3 1846 show_msg((char *)inbuf);
cc6a4101 1847
3b2c9beb
VL
1848 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1849 construct_reply_chain(sconn, (char *)inbuf, nread,
1850 seqnum, encrypted, deferred_pcd);
1851 } else {
1852 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1853 seqnum, encrypted, deferred_pcd);
1854 }
1855
81bdb591 1856 sconn->trans_num++;
aeb798c3
SM
1857
1858done:
8dc70295 1859 sconn->num_requests++;
aeb798c3
SM
1860
1861 /* The timeout_processing function isn't run nearly
1862 often enough to implement 'max log size' without
1863 overrunning the size of the file by many megabytes.
1864 This is especially true if we are running at debug
1865 level 10. Checking every 50 SMBs is a nice
1866 tradeoff of performance vs log file size overrun. */
1867
8dc70295 1868 if ((sconn->num_requests % 50) == 0 &&
aeb798c3
SM
1869 need_to_check_log_size()) {
1870 change_to_root_user();
1871 check_log_size();
1872 }
e9ea36e4
AT
1873}
1874
e9ea36e4 1875/****************************************************************************
1eff0523 1876 Return a string containing the function name of a SMB command.
e9ea36e4 1877****************************************************************************/
1eff0523 1878
127e77e6 1879const char *smb_fn_name(int type)
e9ea36e4 1880{
634c5431 1881 const char *unknown_name = "SMBunknown";
e9ea36e4 1882
918c3ebe 1883 if (smb_messages[type].name == NULL)
e9ea36e4
AT
1884 return(unknown_name);
1885
918c3ebe 1886 return(smb_messages[type].name);
c3effa8b
AT
1887}
1888
dc76502c 1889/****************************************************************************
6bb8f54e 1890 Helper functions for contruct_reply.
dc76502c
JA
1891****************************************************************************/
1892
6219c997
JA
1893void add_to_common_flags2(uint32 v)
1894{
1895 common_flags2 |= v;
1896}
6bb8f54e 1897
27891bde 1898void remove_from_common_flags2(uint32 v)
6bb8f54e 1899{
27891bde 1900 common_flags2 &= ~v;
6bb8f54e
JA
1901}
1902
ae0c6cff
VL
1903static void construct_reply_common(struct smb_request *req, const char *inbuf,
1904 char *outbuf)
dc76502c 1905{
f205e4ca
SM
1906 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1907 uint16_t out_flags2 = common_flags2;
1908
1909 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1910 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1911 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1912
9254bb4e 1913 srv_set_message(outbuf,0,0,false);
8905b599 1914
ae0c6cff 1915 SCVAL(outbuf, smb_com, req->cmd);
fc13f284 1916 SIVAL(outbuf,smb_rcls,0);
b7280423 1917 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
f205e4ca 1918 SSVAL(outbuf,smb_flg2, out_flags2);
fc13f284 1919 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
f205e4ca 1920 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
b7280423 1921
b7280423
AT
1922 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1923 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1924 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1925 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
dc76502c 1926}
c3effa8b 1927
e4897a53
VL
1928void construct_reply_common_req(struct smb_request *req, char *outbuf)
1929{
4f41be35 1930 construct_reply_common(req, (const char *)req->inbuf, outbuf);
e4897a53
VL
1931}
1932
b6f446ca
VL
1933/**
1934 * @brief Find the smb_cmd offset of the last command pushed
1935 * @param[in] buf The buffer we're building up
1936 * @retval Where can we put our next andx cmd?
1937 *
1938 * While chaining requests, the "next" request we're looking at needs to put
1939 * its SMB_Command before the data the previous request already built up added
1940 * to the chain. Find the offset to the place where we have to put our cmd.
1941 */
1942
1943static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1944{
1945 uint8_t cmd;
1946 size_t ofs;
1947
1948 cmd = CVAL(buf, smb_com);
1949
947a8bc4
VL
1950 if (!is_andx_req(cmd)) {
1951 return false;
1952 }
b6f446ca
VL
1953
1954 ofs = smb_vwv0;
1955
1956 while (CVAL(buf, ofs) != 0xff) {
1957
1958 if (!is_andx_req(CVAL(buf, ofs))) {
1959 return false;
1960 }
1961
1962 /*
1963 * ofs is from start of smb header, so add the 4 length
1964 * bytes. The next cmd is right after the wct field.
1965 */
1966 ofs = SVAL(buf, ofs+2) + 4 + 1;
1967
947a8bc4
VL
1968 if (ofs+4 >= talloc_get_size(buf)) {
1969 return false;
1970 }
b6f446ca
VL
1971 }
1972
1973 *pofs = ofs;
1974 return true;
1975}
1976
1977/**
1978 * @brief Do the smb chaining at a buffer level
1979 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
da322e4f 1980 * @param[in] andx_buf Buffer to be appended
b6f446ca
VL
1981 */
1982
da322e4f 1983static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
b6f446ca 1984{
da322e4f
VL
1985 uint8_t smb_command = CVAL(andx_buf, smb_com);
1986 uint8_t wct = CVAL(andx_buf, smb_wct);
1987 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
da322e4f 1988 uint32_t num_bytes = smb_buflen(andx_buf);
adac8858 1989 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
da322e4f 1990
b6f446ca
VL
1991 uint8_t *outbuf;
1992 size_t old_size, new_size;
1993 size_t ofs;
1994 size_t chain_padding = 0;
61953ab3
VL
1995 size_t andx_cmd_ofs;
1996
b6f446ca
VL
1997
1998 old_size = talloc_get_size(*poutbuf);
1999
b07ae1ab 2000 if ((old_size % 4) != 0) {
b6f446ca
VL
2001 /*
2002 * Align the wct field of subsequent requests to a 4-byte
2003 * boundary
2004 */
2005 chain_padding = 4 - (old_size % 4);
2006 }
2007
2008 /*
2009 * After the old request comes the new wct field (1 byte), the vwv's
5b7609db 2010 * and the num_bytes field.
b6f446ca
VL
2011 */
2012
2013 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
4708b97c 2014 new_size += num_bytes;
b6f446ca
VL
2015
2016 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
28901acd 2017 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
b6f446ca
VL
2018 (unsigned)new_size));
2019 return false;
2020 }
2021
73b37743 2022 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
b6f446ca
VL
2023 if (outbuf == NULL) {
2024 DEBUG(0, ("talloc failed\n"));
2025 return false;
2026 }
2027 *poutbuf = outbuf;
2028
61953ab3
VL
2029 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2030 DEBUG(1, ("invalid command chain\n"));
2031 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2032 return false;
2033 }
b6f446ca 2034
61953ab3
VL
2035 if (chain_padding != 0) {
2036 memset(outbuf + old_size, 0, chain_padding);
2037 old_size += chain_padding;
b6f446ca
VL
2038 }
2039
61953ab3
VL
2040 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2041 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2042
b6f446ca
VL
2043 ofs = old_size;
2044
2045 /*
2046 * Push the chained request:
2047 *
2048 * wct field
2049 */
2050
2051 SCVAL(outbuf, ofs, wct);
2052 ofs += 1;
2053
2054 /*
2055 * vwv array
2056 */
2057
2058 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
12068d4a
VL
2059
2060 /*
2061 * HACK ALERT
2062 *
2063 * Read&X has an offset into its data buffer at
2064 * vwv[6]. reply_read_andx has no idea anymore that it's
2065 * running from within a chain, so we have to fix up the
2066 * offset here.
2067 *
2068 * Although it looks disgusting at this place, I want to keep
2069 * it here. The alternative would be to push knowledge about
2070 * the andx chain down into read&x again.
2071 */
2072
2073 if (smb_command == SMBreadX) {
2074 uint8_t *bytes_addr;
2075
2076 if (wct < 7) {
2077 /*
2078 * Invalid read&x response
2079 */
2080 return false;
2081 }
2082
2083 bytes_addr = outbuf + ofs /* vwv start */
2084 + sizeof(uint16_t) * wct /* vwv array */
2085 + sizeof(uint16_t); /* bcc */
2086
2087 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2088 bytes_addr - outbuf - 4);
2089 }
2090
b6f446ca
VL
2091 ofs += sizeof(uint16_t) * wct;
2092
2093 /*
2094 * bcc (byte count)
2095 */
2096
4708b97c 2097 SSVAL(outbuf, ofs, num_bytes);
b6f446ca
VL
2098 ofs += sizeof(uint16_t);
2099
b6f446ca
VL
2100 /*
2101 * The bytes field
2102 */
2103
2104 memcpy(outbuf + ofs, bytes, num_bytes);
2105
2106 return true;
2107}
2108
c9870a62
VL
2109bool smb1_is_chain(const uint8_t *buf)
2110{
2111 uint8_t cmd, wct, andx_cmd;
2112
2113 cmd = CVAL(buf, smb_com);
2114 if (!is_andx_req(cmd)) {
2115 return false;
2116 }
2117 wct = CVAL(buf, smb_wct);
2118 if (wct < 2) {
2119 return false;
2120 }
2121 andx_cmd = CVAL(buf, smb_vwv);
2122 return (andx_cmd != 0xFF);
2123}
2124
2125bool smb1_walk_chain(const uint8_t *buf,
2126 bool (*fn)(uint8_t cmd,
2127 uint8_t wct, const uint16_t *vwv,
2128 uint16_t num_bytes, const uint8_t *bytes,
2129 void *private_data),
2130 void *private_data)
2131{
2132 size_t smblen = smb_len(buf);
2133 const char *smb_buf = smb_base(buf);
2134 uint8_t cmd, chain_cmd;
2135 uint8_t wct;
2136 const uint16_t *vwv;
2137 uint16_t num_bytes;
2138 const uint8_t *bytes;
2139
2140 cmd = CVAL(buf, smb_com);
2141 wct = CVAL(buf, smb_wct);
2142 vwv = (const uint16_t *)(buf + smb_vwv);
2143 num_bytes = smb_buflen(buf);
1b740e50 2144 bytes = (const uint8_t *)smb_buf_const(buf);
c9870a62
VL
2145
2146 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2147 return false;
2148 }
2149
2150 if (!is_andx_req(cmd)) {
2151 return true;
2152 }
2153 if (wct < 2) {
2154 return false;
2155 }
2156
2157 chain_cmd = CVAL(vwv, 0);
2158
2159 while (chain_cmd != 0xff) {
2160 uint32_t chain_offset; /* uint32_t to avoid overflow */
2161 size_t length_needed;
2162 ptrdiff_t vwv_offset;
2163
2164 chain_offset = SVAL(vwv+1, 0);
2165
2166 /*
2167 * Check if the client tries to fool us. The chain
2168 * offset needs to point beyond the current request in
2169 * the chain, it needs to strictly grow. Otherwise we
2170 * might be tricked into an endless loop always
2171 * processing the same request over and over again. We
2172 * used to assume that vwv and the byte buffer array
2173 * in a chain are always attached, but OS/2 the
2174 * Write&X/Read&X chain puts the Read&X vwv array
2175 * right behind the Write&X vwv chain. The Write&X bcc
2176 * array is put behind the Read&X vwv array. So now we
2177 * check whether the chain offset points strictly
2178 * behind the previous vwv array. req->buf points
2179 * right after the vwv array of the previous
2180 * request. See
2181 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2182 * more information.
2183 */
2184
2185 vwv_offset = ((const char *)vwv - smb_buf);
2186 if (chain_offset <= vwv_offset) {
2187 return false;
2188 }
2189
2190 /*
2191 * Next check: Make sure the chain offset does not
2192 * point beyond the overall smb request length.
2193 */
2194
2195 length_needed = chain_offset+1; /* wct */
2196 if (length_needed > smblen) {
2197 return false;
2198 }
2199
2200 /*
2201 * Now comes the pointer magic. Goal here is to set up
2202 * vwv and buf correctly again. The chain offset (the
2203 * former vwv[1]) points at the new wct field.
2204 */
2205
2206 wct = CVAL(smb_buf, chain_offset);
2207
2208 if (is_andx_req(chain_cmd) && (wct < 2)) {
2209 return false;
2210 }
2211
2212 /*
2213 * Next consistency check: Make the new vwv array fits
2214 * in the overall smb request.
2215 */
2216
2217 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2218 if (length_needed > smblen) {
2219 return false;
2220 }
2221 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2222
2223 /*
2224 * Now grab the new byte buffer....
2225 */
2226
2227 num_bytes = SVAL(vwv+wct, 0);
2228
2229 /*
2230 * .. and check that it fits.
2231 */
2232
2233 length_needed += num_bytes;
2234 if (length_needed > smblen) {
2235 return false;
2236 }
2237 bytes = (const uint8_t *)(vwv+wct+1);
2238
2239 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2240 return false;
2241 }
2242
2243 if (!is_andx_req(chain_cmd)) {
2244 return true;
2245 }
2246 chain_cmd = CVAL(vwv, 0);
2247 }
2248 return true;
2249}
2250
2251static bool smb1_chain_length_cb(uint8_t cmd,
2252 uint8_t wct, const uint16_t *vwv,
2253 uint16_t num_bytes, const uint8_t *bytes,
2254 void *private_data)
2255{
2256 unsigned *count = (unsigned *)private_data;
2257 *count += 1;
2258 return true;
2259}
2260
2261unsigned smb1_chain_length(const uint8_t *buf)
2262{
2263 unsigned count = 0;
2264
2265 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2266 return 0;
2267 }
2268 return count;
2269}
2270
2271struct smb1_parse_chain_state {
2272 TALLOC_CTX *mem_ctx;
2273 const uint8_t *buf;
2274 struct smbd_server_connection *sconn;
2275 bool encrypted;
2276 uint32_t seqnum;
2277
2278 struct smb_request **reqs;
2279 unsigned num_reqs;
2280};
2281
2282static bool smb1_parse_chain_cb(uint8_t cmd,
2283 uint8_t wct, const uint16_t *vwv,
2284 uint16_t num_bytes, const uint8_t *bytes,
2285 void *private_data)
2286{
2287 struct smb1_parse_chain_state *state =
2288 (struct smb1_parse_chain_state *)private_data;
2289 struct smb_request **reqs;
2290 struct smb_request *req;
2291 bool ok;
2292
2293 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2294 struct smb_request *, state->num_reqs+1);
2295 if (reqs == NULL) {
2296 return false;
2297 }
2298 state->reqs = reqs;
2299
2300 req = talloc(reqs, struct smb_request);
2301 if (req == NULL) {
2302 return false;
2303 }
2304
2305 ok = init_smb_request(req, state->sconn, state->buf, 0,
2306 state->encrypted, state->seqnum);
2307 if (!ok) {
2308 return false;
2309 }
2310 req->cmd = cmd;
2311 req->wct = wct;
2312 req->vwv = vwv;
2313 req->buflen = num_bytes;
2314 req->buf = bytes;
2315
2316 reqs[state->num_reqs] = req;
2317 state->num_reqs += 1;
2318 return true;
2319}
2320
2321bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2322 struct smbd_server_connection *sconn,
2323 bool encrypted, uint32_t seqnum,
2324 struct smb_request ***reqs, unsigned *num_reqs)
2325{
2326 struct smb1_parse_chain_state state;
8f93068c 2327 unsigned i;
c9870a62
VL
2328
2329 state.mem_ctx = mem_ctx;
2330 state.buf = buf;
2331 state.sconn = sconn;
2332 state.encrypted = encrypted;
2333 state.seqnum = seqnum;
2334 state.reqs = NULL;
2335 state.num_reqs = 0;
2336
2337 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2338 TALLOC_FREE(state.reqs);
2339 return false;
2340 }
8f93068c
VL
2341 for (i=0; i<state.num_reqs; i++) {
2342 state.reqs[i]->chain = state.reqs;
2343 }
c9870a62
VL
2344 *reqs = state.reqs;
2345 *num_reqs = state.num_reqs;
2346 return true;
2347}
2348
3db52feb
AT
2349/****************************************************************************
2350 Check if services need reloading.
2351****************************************************************************/
2352
70df6fcb 2353static void check_reload(struct smbd_server_connection *sconn, time_t t)
3db52feb 2354{
3db52feb 2355
0b188e77 2356 if (last_smb_conf_reload_time == 0) {
1eff0523 2357 last_smb_conf_reload_time = t;
7ebd74e6
SS
2358 }
2359
ac61f650 2360 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
03455519 2361 reload_services(sconn, conn_snum_used, true);
1eff0523
JA
2362 last_smb_conf_reload_time = t;
2363 }
3db52feb 2364}
c3effa8b 2365
cad0c004
VL
2366static bool fd_is_readable(int fd)
2367{
0f082de5 2368 int ret, revents;
cad0c004 2369
0f082de5
VL
2370 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2371
2372 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
cad0c004 2373
cad0c004
VL
2374}
2375
fc79169c
VL
2376static void smbd_server_connection_write_handler(
2377 struct smbd_server_connection *sconn)
aeb798c3
SM
2378{
2379 /* TODO: make write nonblocking */
2380}
2381
cad0c004 2382static void smbd_server_connection_read_handler(
fc79169c 2383 struct smbd_server_connection *sconn, int fd)
aeb798c3
SM
2384{
2385 uint8_t *inbuf = NULL;
2386 size_t inbuf_len = 0;
2387 size_t unread_bytes = 0;
2388 bool encrypted = false;
2389 TALLOC_CTX *mem_ctx = talloc_tos();
2390 NTSTATUS status;
c16c90a1 2391 uint32_t seqnum;
aeb798c3 2392
0c7f36d2
SM
2393 bool async_echo = lp_async_smb_echo_handler();
2394 bool from_client = false;
5e0258fc 2395
0c7f36d2
SM
2396 if (async_echo) {
2397 if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2398 /*
2399 * This is the super-ugly hack to prefer the packets
2400 * forwarded by the echo handler over the ones by the
2401 * client directly
2402 */
2403 fd = sconn->smb1.echo_handler.trusted_fd;
2404 }
5e0258fc
VL
2405 }
2406
2407 from_client = (sconn->sock == fd);
977aa660 2408
0c7f36d2 2409 if (async_echo && from_client) {
fc79169c 2410 smbd_lock_socket(sconn);
cad0c004 2411
5e0258fc
VL
2412 if (!fd_is_readable(fd)) {
2413 DEBUG(10,("the echo listener was faster\n"));
2414 smbd_unlock_socket(sconn);
2415 return;
cad0c004 2416 }
5e0258fc
VL
2417 }
2418
2419 /* TODO: make this completely nonblocking */
2420 status = receive_smb_talloc(mem_ctx, sconn, fd,
2421 (char **)(void *)&inbuf,
2422 0, /* timeout */
2423 &unread_bytes,
2424 &encrypted,
2425 &inbuf_len, &seqnum,
5aa9e552 2426 !from_client /* trusted channel */);
cad0c004 2427
0c7f36d2 2428 if (async_echo && from_client) {
fc79169c 2429 smbd_unlock_socket(sconn);
977aa660
SM
2430 }
2431
aeb798c3
SM
2432 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2433 goto process;
2434 }
2435 if (NT_STATUS_IS_ERR(status)) {
2436 exit_server_cleanly("failed to receive smb request");
2437 }
2438 if (!NT_STATUS_IS_OK(status)) {
2439 return;
2440 }
2441
2442process:
fc79169c 2443 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
c16c90a1 2444 seqnum, encrypted, NULL);
aeb798c3
SM
2445}
2446
415e8e05 2447static void smbd_server_connection_handler(struct tevent_context *ev,
a0d96b53 2448 struct tevent_fd *fde,
aeb798c3
SM
2449 uint16_t flags,
2450 void *private_data)
2451{
2452 struct smbd_server_connection *conn = talloc_get_type(private_data,
2453 struct smbd_server_connection);
2454
52ccb40d
SM
2455 if (!NT_STATUS_IS_OK(conn->status)) {
2456 /*
2457 * we're not supposed to do any io
2458 */
2459 TEVENT_FD_NOT_READABLE(conn->smb1.fde);
2460 TEVENT_FD_NOT_WRITEABLE(conn->smb1.fde);
2461 return;
2462 }
2463
2672c37a 2464 if (flags & TEVENT_FD_WRITE) {
aeb798c3 2465 smbd_server_connection_write_handler(conn);
c7a2e52e
VL
2466 return;
2467 }
2672c37a 2468 if (flags & TEVENT_FD_READ) {
a2bf46e9 2469 smbd_server_connection_read_handler(conn, conn->sock);
c7a2e52e 2470 return;
aeb798c3
SM
2471 }
2472}
2473
415e8e05 2474static void smbd_server_echo_handler(struct tevent_context *ev,
a0d96b53 2475 struct tevent_fd *fde,
cad0c004
VL
2476 uint16_t flags,
2477 void *private_data)
2478{
2479 struct smbd_server_connection *conn = talloc_get_type(private_data,
2480 struct smbd_server_connection);
2481
52ccb40d
SM
2482 if (!NT_STATUS_IS_OK(conn->status)) {
2483 /*
2484 * we're not supposed to do any io
2485 */
2486 TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
2487 TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
2488 return;
2489 }
2490
2672c37a 2491 if (flags & TEVENT_FD_WRITE) {
cad0c004 2492 smbd_server_connection_write_handler(conn);
c672797a
VL
2493 return;
2494 }
2672c37a 2495 if (flags & TEVENT_FD_READ) {
cad0c004
VL
2496 smbd_server_connection_read_handler(
2497 conn, conn->smb1.echo_handler.trusted_fd);
c672797a 2498 return;
cad0c004
VL
2499 }
2500}
27f812f3 2501
06fb2585 2502#ifdef CLUSTER_SUPPORT
35c0f164
SM
2503
2504struct smbd_release_ip_state {
2505 struct smbd_server_connection *sconn;
33f10d06 2506 struct tevent_immediate *im;
35c0f164
SM
2507 char addr[INET6_ADDRSTRLEN];
2508};
2509
33f10d06
SM
2510static void smbd_release_ip_immediate(struct tevent_context *ctx,
2511 struct tevent_immediate *im,
2512 void *private_data)
2513{
2514 struct smbd_release_ip_state *state =
2515 talloc_get_type_abort(private_data,
2516 struct smbd_release_ip_state);
2517
2518 if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
2519 /*
2520 * smbd_server_connection_terminate() already triggered ?
2521 */
2522 return;
2523 }
2524
2525 smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
2526}
2527
27f812f3
SM
2528/****************************************************************************
2529received when we should release a specific IP
2530****************************************************************************/
9677fae6 2531static bool release_ip(const char *ip, void *priv)
27f812f3 2532{
35c0f164
SM
2533 struct smbd_release_ip_state *state =
2534 talloc_get_type_abort(priv,
2535 struct smbd_release_ip_state);
2536 const char *addr = state->addr;
467208e9 2537 const char *p = addr;
e86a534f 2538
33f10d06
SM
2539 if (!NT_STATUS_IS_OK(state->sconn->status)) {
2540 /* avoid recursion */
2541 return false;
2542 }
2543
e86a534f
MA
2544 if (strncmp("::ffff:", addr, 7) == 0) {
2545 p = addr + 7;
2546 }
2547
642c6ba2
CA
2548 DEBUG(10, ("Got release IP message for %s, "
2549 "our address is %s\n", ip, p));
2550
7d6e4c7e 2551 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
27f812f3
SM
2552 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2553 ip));
35c0f164
SM
2554 /*
2555 * With SMB2 we should do a clean disconnect,
2556 * the previous_session_id in the session setup
2557 * will cleanup the old session, tcons and opens.
2558 *
2559 * A clean disconnect is needed in order to support
2560 * durable handles.
2561 *
2562 * Note: typically this is never triggered
2563 * as we got a TCP RST (triggered by ctdb event scripts)
2564 * before we get CTDB_SRVID_RELEASE_IP.
2565 *
2566 * We used to call _exit(1) here, but as this was mostly never
2567 * triggered and has implication on our process model,
2568 * we can just use smbd_server_connection_terminate()
2569 * (also for SMB1).
33f10d06
SM
2570 *
2571 * We don't call smbd_server_connection_terminate() directly
2572 * as we might be called from within ctdbd_migrate(),
2573 * we need to defer our action to the next event loop
35c0f164 2574 */
33f10d06
SM
2575 tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
2576 smbd_release_ip_immediate, state);
2577
2578 /*
2579 * Make sure we don't get any io on the connection.
2580 */
2581 state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
9677fae6 2582 return true;
27f812f3 2583 }
9677fae6
SM
2584
2585 return false;
27f812f3
SM
2586}
2587
13de233f
SM
2588static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2589 struct sockaddr_storage *srv,
2590 struct sockaddr_storage *clnt)
2591{
35c0f164 2592 struct smbd_release_ip_state *state;
13de233f 2593 struct ctdbd_connection *cconn;
13de233f
SM
2594
2595 cconn = messaging_ctdbd_connection();
2596 if (cconn == NULL) {
2597 return NT_STATUS_NO_MEMORY;
2598 }
2599
35c0f164
SM
2600 state = talloc_zero(sconn, struct smbd_release_ip_state);
2601 if (state == NULL) {
13de233f
SM
2602 return NT_STATUS_NO_MEMORY;
2603 }
35c0f164 2604 state->sconn = sconn;
33f10d06
SM
2605 state->im = tevent_create_immediate(state);
2606 if (state->im == NULL) {
2607 return NT_STATUS_NO_MEMORY;
2608 }
35c0f164 2609 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
13de233f
SM
2610 return NT_STATUS_NO_MEMORY;
2611 }
35c0f164
SM
2612
2613 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
13de233f
SM
2614}
2615
f83e7d8f 2616static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
27f812f3
SM
2617 struct sockaddr_storage *client)
2618{
2619 socklen_t length;
27f812f3 2620 length = sizeof(*server);
f83e7d8f 2621 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
27f812f3
SM
2622 return -1;
2623 }
2624 length = sizeof(*client);
f83e7d8f 2625 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
27f812f3
SM
2626 return -1;
2627 }
2628 return 0;
2629}
2630#endif
2631
a26003dd
CA
2632static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2633 void *private_data, uint32_t msg_type,
2634 struct server_id server_id, DATA_BLOB *data)
2635{
2636 struct smbd_server_connection *sconn = talloc_get_type_abort(
2637 private_data, struct smbd_server_connection);
2638 const char *ip = (char *) data->data;
2639 char *client_ip;
2640
2641 DEBUG(10, ("Got kill request for client IP %s\n", ip));
2642
2643 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2644 talloc_tos());
2645 if (client_ip == NULL) {
2646 return;
2647 }
2648
2649 if (strequal(ip, client_ip)) {
2650 DEBUG(1, ("Got kill client message for %s - "
2651 "exiting immediately\n", ip));
2652 exit_server_cleanly("Forced disconnect for client");
2653 }
2654
2655 TALLOC_FREE(client_ip);
2656}
2657
27f812f3
SM
2658/*
2659 * Send keepalive packets to our client
2660 */
2661static bool keepalive_fn(const struct timeval *now, void *private_data)
2662{
d911bd5c
VL
2663 struct smbd_server_connection *sconn = talloc_get_type_abort(
2664 private_data, struct smbd_server_connection);
c1653e3b
SM
2665 bool ret;
2666
d28fa8fa 2667 if (sconn->using_smb2) {
efd0c35a
JA
2668 /* Don't do keepalives on an SMB2 connection. */
2669 return false;
2670 }
2671
bf35606b 2672 smbd_lock_socket(sconn);
bb867df2 2673 ret = send_keepalive(sconn->sock);
bf35606b 2674 smbd_unlock_socket(sconn);
c1653e3b
SM
2675
2676 if (!ret) {
40ae8b74
VL
2677 char addr[INET6_ADDRSTRLEN];
2678 /*
2679 * Try and give an error message saying what
2680 * client failed.
2681 */
2682 DEBUG(0, ("send_keepalive failed for client %s. "
2683 "Error %s - exiting\n",
2684 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2685 strerror(errno)));
27f812f3
SM
2686 return False;
2687 }
2688 return True;
2689}
2690
2691/*
2692 * Do the recurring check if we're idle
2693 */
2694static bool deadtime_fn(const struct timeval *now, void *private_data)
2695{
72fd7fb4
VL
2696 struct smbd_server_connection *sconn =
2697 (struct smbd_server_connection *)private_data;
6f30b9a6 2698
c8620180
SM
2699 if ((conn_num_open(sconn) == 0)
2700 || (conn_idle_all(sconn, now->tv_sec))) {
e7d0f478 2701 DEBUG( 2, ( "Closing idle connection\n" ) );
790ad3d1
VL
2702 messaging_send(sconn->msg_ctx,
2703 messaging_server_id(sconn->msg_ctx),
27f812f3
SM
2704 MSG_SHUTDOWN, &data_blob_null);
2705 return False;
2706 }
2707
2708 return True;
2709}
2710
2711/*
2712 * Do the recurring log file and smb.conf reload checks.
2713 */
2714
2715static bool housekeeping_fn(const struct timeval *now, void *private_data)
2716{
babfe237
VL
2717 struct smbd_server_connection *sconn = talloc_get_type_abort(
2718 private_data, struct smbd_server_connection);
0b188e77
DD
2719
2720 DEBUG(5, ("housekeeping\n"));
2721
27f812f3
SM
2722 change_to_root_user();
2723
2724 /* update printer queue caches if necessary */
babfe237 2725 update_monitored_printq_cache(sconn->msg_ctx);
27f812f3
SM
2726
2727 /* check if we need to reload services */
0b188e77 2728 check_reload(sconn, time_mono(NULL));
27f812f3 2729
27f812f3
SM
2730 /*
2731 * Force a log file check.
2732 */
2733 force_check_log_size();
2734 check_log_size();
2735 return true;
2736}
2737
27afb891
VL
2738/*
2739 * Read an smb packet in the echo handler child, giving the parent
2740 * smbd one second to react once the socket becomes readable.
2741 */
2742
2743struct smbd_echo_read_state {
2744 struct tevent_context *ev;
2745 struct smbd_server_connection *sconn;
2746
2747 char *buf;
2748 size_t buflen;
2749 uint32_t seqnum;
2750};
2751
2752static void smbd_echo_read_readable(struct tevent_req *subreq);
2753static void smbd_echo_read_waited(struct tevent_req *subreq);
2754
2755static struct tevent_req *smbd_echo_read_send(
2756 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2757 struct smbd_server_connection *sconn)
2758{
2759 struct tevent_req *req, *subreq;
2760 struct smbd_echo_read_state *state;
2761
2762 req = tevent_req_create(mem_ctx, &state,
2763 struct smbd_echo_read_state);
2764 if (req == NULL) {
2765 return NULL;
2766 }
2767 state->ev = ev;
2768 state->sconn = sconn;
2769
2770 subreq = wait_for_read_send(state, ev, sconn->sock);
2771 if (tevent_req_nomem(subreq, req)) {
2772 return tevent_req_post(req, ev);
2773 }
2774 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2775 return req;
2776}
2777
2778static void smbd_echo_read_readable(struct tevent_req *subreq)
2779{
2780 struct tevent_req *req = tevent_req_callback_data(
2781 subreq, struct tevent_req);
2782 struct smbd_echo_read_state *state = tevent_req_data(
2783 req, struct smbd_echo_read_state);
2784 bool ok;
2785 int err;
2786
2787 ok = wait_for_read_recv(subreq, &err);
2788 TALLOC_FREE(subreq);
2789 if (!ok) {
2790 tevent_req_nterror(req, map_nt_error_from_unix(err));
2791 return;
2792 }
2793
2794 /*
2795 * Give the parent smbd one second to step in
2796 */
2797
2798 subreq = tevent_wakeup_send(
2799 state, state->ev, timeval_current_ofs(1, 0));
2800 if (tevent_req_nomem(subreq, req)) {
2801 return;
2802 }
2803 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2804}
2805
2806static void smbd_echo_read_waited(struct tevent_req *subreq)
2807{
2808 struct tevent_req *req = tevent_req_callback_data(
2809 subreq, struct tevent_req);
2810 struct smbd_echo_read_state *state = tevent_req_data(
2811 req, struct smbd_echo_read_state);
2812 struct smbd_server_connection *sconn = state->sconn;
2813 bool ok;
2814 NTSTATUS status;
2815 size_t unread = 0;
2816 bool encrypted;
2817
2818 ok = tevent_wakeup_recv(subreq);
2819 TALLOC_FREE(subreq);
2820 if (!ok) {
2821 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2822 return;
2823 }
2824
2825 ok = smbd_lock_socket_internal(sconn);
2826 if (!ok) {
2827 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2828 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2829 return;
2830 }
2831
2832 if (!fd_is_readable(sconn->sock)) {
2833 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
c0288e06 2834 (int)getpid()));
27afb891
VL
2835
2836 ok = smbd_unlock_socket_internal(sconn);
2837 if (!ok) {
2838 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2839 DEBUG(1, ("%s: failed to unlock socket\n",
2840 __location__));
2841 return;
2842 }
2843
2844 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2845 if (tevent_req_nomem(subreq, req)) {
2846 return;
2847 }
2848 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2849 return;
2850 }
2851
2852 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2853 0 /* timeout */,
2854 &unread,
2855 &encrypted,
2856 &state->buflen,
2857 &state->seqnum,
2858 false /* trusted_channel*/);
2859
2860 if (tevent_req_nterror(req, status)) {
2861 tevent_req_nterror(req, status);
2862 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
c0288e06 2863 (int)getpid(), nt_errstr(status)));
27afb891
VL
2864 return;
2865 }
2866
2867 ok = smbd_unlock_socket_internal(sconn);
2868 if (!ok) {
2869 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2870 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2871 return;
2872 }
2873 tevent_req_done(req);
2874}
2875
2876static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2877 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2878{
2879 struct smbd_echo_read_state *state = tevent_req_data(
2880 req, struct smbd_echo_read_state);
2881 NTSTATUS status;
2882
2883 if (tevent_req_is_nterror(req, &status)) {
2884 return status;
2885 }
2886 *pbuf = talloc_move(mem_ctx, &state->buf);
2887 *pbuflen = state->buflen;
2888 *pseqnum = state->seqnum;
2889 return NT_STATUS_OK;
2890}
2891
cad0c004
VL
2892struct smbd_echo_state {
2893 struct tevent_context *ev;
2894 struct iovec *pending;
2895 struct smbd_server_connection *sconn;
2896 int parent_pipe;
2897
2898 struct tevent_fd *parent_fde;
2899
cad0c004
VL
2900 struct tevent_req *write_req;
2901};
2902
2903static void smbd_echo_writer_done(struct tevent_req *req);
2904
2905static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2906{
2907 int num_pending;
2908
2909 if (state->write_req != NULL) {
2910 return;
2911 }
2912
2913 num_pending = talloc_array_length(state->pending);
2914 if (num_pending == 0) {
2915 return;
2916 }
2917
2918 state->write_req = writev_send(state, state->ev, NULL,
2919 state->parent_pipe, false,
2920 state->pending, num_pending);
2921 if (state->write_req == NULL) {
2922 DEBUG(1, ("writev_send failed\n"));
2923 exit(1);
2924 }
2925
2926 talloc_steal(state->write_req, state->pending);
2927 state->pending = NULL;
2928
2929 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2930 state);
2931}
2932
2933static void smbd_echo_writer_done(struct tevent_req *req)
2934{
2935 struct smbd_echo_state *state = tevent_req_callback_data(
2936 req, struct smbd_echo_state);
2937 ssize_t written;
2938 int err;
2939
2940 written = writev_recv(req, &err);
2941 TALLOC_FREE(req);
2942 state->write_req = NULL;
2943 if (written == -1) {
2944 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2945 exit(1);
2946 }
c0288e06 2947 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
cad0c004
VL
2948 smbd_echo_activate_writer(state);
2949}
2950
0b8eeb1e
SM
2951static bool smbd_echo_reply(struct smbd_echo_state *state,
2952 uint8_t *inbuf, size_t inbuf_len,
cad0c004
VL
2953 uint32_t seqnum)
2954{
2955 struct smb_request req;
2956 uint16_t num_replies;
cad0c004
VL
2957 char *outbuf;
2958 bool ok;
2959
0633c0f6 2960 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
fd9effce
VL
2961 DEBUG(10, ("Got netbios keepalive\n"));
2962 /*
2963 * Just swallow it
2964 */
2965 return true;
2966 }
2967
cad0c004
VL
2968 if (inbuf_len < smb_size) {
2969 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2970 return false;
2971 }
0b8eeb1e 2972 if (!valid_smb_header(state->sconn, inbuf)) {
cad0c004
VL
2973 DEBUG(10, ("Got invalid SMB header\n"));
2974 return false;
2975 }
2976
0b8eeb1e 2977 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
d7bc5fe7 2978 seqnum)) {
cad0c004
VL
2979 return false;
2980 }
2981 req.inbuf = inbuf;
2982
2983 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2984 smb_messages[req.cmd].name
2985 ? smb_messages[req.cmd].name : "unknown"));
2986
2987 if (req.cmd != SMBecho) {
2988 return false;
2989 }
2990 if (req.wct < 1) {
2991 return false;
2992 }
2993
2994 num_replies = SVAL(req.vwv+0, 0);
2995 if (num_replies != 1) {
2996 /* Not a Windows "Hey, you're still there?" request */
2997 return false;
2998 }
2999
4f41be35 3000 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
cad0c004
VL
3001 1, req.buflen)) {
3002 DEBUG(10, ("create_outbuf failed\n"));
3003 return false;
3004 }
3005 req.outbuf = (uint8_t *)outbuf;
3006
3007 SSVAL(req.outbuf, smb_vwv0, num_replies);
3008
3009 if (req.buflen > 0) {
3010 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3011 }
3012
1808dd0a 3013 ok = srv_send_smb(req.sconn,
cad0c004
VL
3014 (char *)outbuf,
3015 true, seqnum+1,
3016 false, &req.pcd);
3017 TALLOC_FREE(outbuf);
3018 if (!ok) {
3019 exit(1);
3020 }
3021
3022 return true;
3023}
3024
3025static void smbd_echo_exit(struct tevent_context *ev,
3026 struct tevent_fd *fde, uint16_t flags,
3027 void *private_data)
3028{
3029 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3030 exit(0);
3031}
3032
710e5d92
VL
3033static void smbd_echo_got_packet(struct tevent_req *req);
3034
cad0c004
VL
3035static void smbd_echo_loop(struct smbd_server_connection *sconn,
3036 int parent_pipe)
3037{
3038 struct smbd_echo_state *state;
710e5d92 3039 struct tevent_req *read_req;
cad0c004
VL
3040
3041 state = talloc_zero(sconn, struct smbd_echo_state);
3042 if (state == NULL) {
3043 DEBUG(1, ("talloc failed\n"));
3044 return;
3045 }
3046 state->sconn = sconn;
3047 state->parent_pipe = parent_pipe;
3048 state->ev = s3_tevent_context_init(state);
3049 if (state->ev == NULL) {
3050 DEBUG(1, ("tevent_context_init failed\n"));
3051 TALLOC_FREE(state);
3052 return;
3053 }
3054 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3055 TEVENT_FD_READ, smbd_echo_exit,
3056 state);
3057 if (state->parent_fde == NULL) {
3058 DEBUG(1, ("tevent_add_fd failed\n"));
3059 TALLOC_FREE(state);
3060 return;
3061 }
710e5d92
VL
3062
3063 read_req = smbd_echo_read_send(state, state->ev, sconn);
3064 if (read_req == NULL) {
3065 DEBUG(1, ("smbd_echo_read_send failed\n"));
cad0c004
VL
3066 TALLOC_FREE(state);
3067 return;
3068 }
710e5d92 3069 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
cad0c004
VL
3070
3071 while (true) {
3072 if (tevent_loop_once(state->ev) == -1) {
3073 DEBUG(1, ("tevent_loop_once failed: %s\n",
3074 strerror(errno)));
3075 break;
3076 }
3077 }
3078 TALLOC_FREE(state);
3079}
3080
710e5d92
VL
3081static void smbd_echo_got_packet(struct tevent_req *req)
3082{
3083 struct smbd_echo_state *state = tevent_req_callback_data(
3084 req, struct smbd_echo_state);
3085 NTSTATUS status;
3086 char *buf = NULL;
3087 size_t buflen = 0;
3088 uint32_t seqnum = 0;
3089 bool reply;
3090
3091 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3092 TALLOC_FREE(req);
3093 if (!NT_STATUS_IS_OK(status)) {
3094 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3095 nt_errstr(status)));
3096 exit(1);
3097 }
3098
0b8eeb1e 3099 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
710e5d92
VL
3100 if (!reply) {
3101 size_t num_pending;
3102 struct iovec *tmp;
3103 struct iovec *iov;
3104
3105 num_pending = talloc_array_length(state->pending);
3106 tmp = talloc_realloc(state, state->pending, struct iovec,
3107 num_pending+1);
3108 if (tmp == NULL) {
3109 DEBUG(1, ("talloc_realloc failed\n"));
3110 exit(1);
3111 }
3112 state->pending = tmp;
3113
3114 if (buflen >= smb_size) {
3115 /*
3116 * place the seqnum in the packet so that the main process
3117 * can reply with signing
3118 */
3119 SIVAL(buf, smb_ss_field, seqnum);
3120 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3121 }
3122
3123 iov = &state->pending[num_pending];
3d5c534f 3124 iov->iov_base = talloc_move(state->pending, &buf);
710e5d92
VL
3125 iov->iov_len = buflen;
3126
3127 DEBUG(10,("echo_handler[%d]: forward to main\n",
c0288e06 3128 (int)getpid()));
710e5d92
VL
3129 smbd_echo_activate_writer(state);
3130 }
3131
3132 req = smbd_echo_read_send(state, state->ev, state->sconn);
3133 if (req == NULL) {
3134 DEBUG(1, ("smbd_echo_read_send failed\n"));
3135 exit(1);
3136 }
3137 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3138}
3139
3140
cad0c004
VL
3141/*
3142 * Handle SMBecho requests in a forked child process
3143 */
8a2eff87 3144bool fork_echo_handler(struct smbd_server_connection *sconn)
cad0c004
VL
3145{
3146 int listener_pipe[2];
3147 int res;
3148 pid_t child;
3149
3150 res = pipe(listener_pipe);
3151 if (res == -1) {
3152 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3153 return false;
3154 }
63c24977 3155 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lock_directory());
cad0c004
VL
3156 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3157 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3158 goto fail;
3159 }
3160
c0288e06 3161 child = fork();
cad0c004
VL
3162 if (child == 0) {
3163 NTSTATUS status;
3164
3165 close(listener_pipe[0]);
342c79e2 3166 set_blocking(listener_pipe[1], false);
cad0c004 3167
72fd7fb4 3168 status = reinit_after_fork(sconn->msg_ctx,
bf8cce18 3169 sconn->ev_ctx,
0fa31296 3170 true);
cad0c004
VL
3171 if (!NT_STATUS_IS_OK(status)) {
3172 DEBUG(1, ("reinit_after_fork failed: %s\n",
3173 nt_errstr(status)));
3174 exit(1);
3175 }
3176 smbd_echo_loop(sconn, listener_pipe[1]);
3177 exit(0);
3178 }
3179 close(listener_pipe[1]);
3180 listener_pipe[1] = -1;
3181 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3182
1fba1406 3183 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
cad0c004
VL
3184
3185 /*
3186 * Without smb signing this is the same as the normal smbd
3187 * listener. This needs to change once signing comes in.
3188 */
bf8cce18 3189 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
cad0c004
VL
3190 sconn,
3191 sconn->smb1.echo_handler.trusted_fd,
bf8cce18 3192 TEVENT_FD_READ,
cad0c004
VL
3193 smbd_server_echo_handler,
3194 sconn);
3195 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3196 DEBUG(1, ("event_add_fd failed\n"));
3197 goto fail;
3198 }
3199
3200 return true;
3201
3202fail:
3203 if (listener_pipe[0] != -1) {
3204 close(listener_pipe[0]);
3205 }
3206 if (listener_pipe[1] != -1) {
3207 close(listener_pipe[1]);
3208 }
3209 sconn->smb1.echo_handler.trusted_fd = -1;
3210 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3211 close(sconn->smb1.echo_handler.socket_lock_fd);
3212 }
3213 sconn->smb1.echo_handler.trusted_fd = -1;
3214 sconn->smb1.echo_handler.socket_lock_fd = -1;
3215 return false;
3216}
3217
715933a3
SM
3218static bool uid_in_use(const struct user_struct *user, uid_t uid)
3219{
3220 while (user) {
3221 if (user->session_info &&
3222 (user->session_info->unix_token->uid == uid)) {
3223 return true;
3224 }
3225 user = user->next;
3226 }
3227 return false;
3228}
3229
3230static bool gid_in_use(const struct user_struct *user, gid_t gid)
3231{
3232 while (user) {
3233 if (user->session_info != NULL) {
3234 int i;
3235 struct security_unix_token *utok;
3236
3237 utok = user->session_info->unix_token;
3238 if (utok->gid == gid) {
3239 return true;
3240 }
3241 for(i=0; i<utok->ngroups; i++) {
3242 if (utok->groups[i] == gid) {
3243 return true;
3244 }
3245 }
3246 }
3247 user = user->next;
3248 }
3249 return false;
3250}
3251
3252static bool sid_in_use(const struct user_struct *user,
3253 const struct dom_sid *psid)
3254{
3255 while (user) {
3256 struct security_token *tok;
3257
3258 if (user->session_info == NULL) {
3259 continue;
3260 }
3261 tok = user->session_info->security_token;
3262 if (tok == NULL) {
3263 /*
3264 * Not sure session_info->security_token can
3265 * ever be NULL. This check might be not
3266 * necessary.
3267 */
3268 continue;
3269 }
3270 if (security_token_has_sid(tok, psid)) {
3271 return true;
3272 }
3273 user = user->next;
3274 }
3275 return false;
3276}
3277
3278static bool id_in_use(const struct user_struct *user,
3279 const struct id_cache_ref *id)
3280{
3281 switch(id->type) {
3282 case UID:
3283 return uid_in_use(user, id->id.uid);
3284 case GID:
3285 return gid_in_use(user, id->id.gid);
3286 case SID:
3287 return sid_in_use(user, &id->id.sid);
3288 default:
3289 break;
3290 }
3291 return false;
3292}
3293
3294static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3295 void *private_data,
3296 uint32_t msg_type,
3297 struct server_id server_id,
3298 DATA_BLOB* data)
3299{
3300 const char *msg = (data && data->data)
3301 ? (const char *)data->data : "<NULL>";
715933a3
SM
3302 struct id_cache_ref id;
3303 struct smbd_server_connection *sconn =
3304 talloc_get_type_abort(private_data,
3305 struct smbd_server_connection);
3306
715933a3
SM
3307 if (!id_cache_ref_parse(msg, &id)) {
3308 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3309 return;
3310 }
3311
6ce72a01 3312 if (id_in_use(sconn->users, &id)) {
715933a3
SM
3313 exit_server_cleanly(msg);
3314 }
3315 id_cache_delete_from_cache(&id);
3316}
3317
b3235d48
SM
3318NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3319 enum protocol_types protocol)
3320{
02d206ee
SM
3321 NTSTATUS status;
3322
b3235d48
SM
3323 set_Protocol(protocol);
3324 conn->protocol = protocol;
3325
02d206ee
SM
3326 if (protocol >= PROTOCOL_SMB2_02) {
3327 status = smb2srv_session_table_init(conn);
3328 if (!NT_STATUS_IS_OK(status)) {
3329 return status;
3330 }
7d139553
SM
3331
3332 status = smb2srv_open_table_init(conn);
3333 if (!NT_STATUS_IS_OK(status)) {
3334 return status;
3335 }
faa8edcc 3336 } else {
a129e271
SM
3337 status = smb1srv_session_table_init(conn);
3338 if (!NT_STATUS_IS_OK(status)) {
3339 return status;
3340 }
3341
faa8edcc
SM
3342 status = smb1srv_tcon_table_init(conn);
3343 if (!NT_STATUS_IS_OK(status)) {
3344 return status;
3345 }
7d139553
SM
3346
3347 status = smb1srv_open_table_init(conn);
3348 if (!NT_STATUS_IS_OK(status)) {
3349 return status;
3350 }
02d206ee
SM
3351 }
3352
b3235d48
SM
3353 return NT_STATUS_OK;
3354}
3355
fc96488c
SM
3356static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3357 void *private_data)
3358{
cd260391
SM
3359 struct smbXsrv_connection *conn =
3360 talloc_get_type_abort(private_data,
3361 struct smbXsrv_connection);
3362
fc96488c
SM
3363 switch (point) {
3364 case TEVENT_TRACE_BEFORE_WAIT:
b40fa943
SM
3365 /*
3366 * This just removes compiler warning
3367 * without profile support
3368 */
3369 conn->smbd_idle_profstamp = 0;
cd260391 3370 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
fc96488c
SM
3371 break;
3372 case TEVENT_TRACE_AFTER_WAIT:
cd260391 3373 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
fc96488c
SM
3374 break;
3375 }
3376}
3377
f2f55d70
JA
3378/****************************************************************************
3379 Process commands from the client
3380****************************************************************************/
3381
dd3a9279 3382void smbd_process(struct tevent_context *ev_ctx,
b5e9ece1
SM
3383 struct messaging_context *msg_ctx,
3384 int sock_fd,
3385 bool interactive)
f2f55d70 3386{
27f812f3 3387 TALLOC_CTX *frame = talloc_stackframe();
b5e9ece1
SM
3388 struct smbXsrv_connection *conn;
3389 struct smbd_server_connection *sconn;
b764145a
SM
3390 struct sockaddr_storage ss;
3391 struct sockaddr *sa = NULL;
db6d1c62 3392 socklen_t sa_socklen;
b764145a
SM
3393 struct tsocket_address *local_address = NULL;
3394 struct tsocket_address *remote_address = NULL;
3d7521c8 3395 const char *locaddr = NULL;
b764145a 3396 const char *remaddr = NULL;
a513086c 3397 char *rhost;
b764145a 3398 int ret;
a349b0be 3399 int tmp;
27f812f3 3400
b5e9ece1
SM
3401 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3402 if (conn == NULL) {
b3235d48
SM
3403 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3404 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3405 }
3406
b5e9ece1
SM
3407 conn->ev_ctx = ev_ctx;
3408 conn->msg_ctx = msg_ctx;
3409
3410 sconn = talloc_zero(conn, struct smbd_server_connection);
3411 if (!sconn) {
3412 exit_server("failed to create smbd_server_connection");
3413 }
3414
3415 conn->sconn = sconn;
3416 sconn->conn = conn;
3417
3418 /*
3419 * TODO: remove this...:-)
3420 */
3421 global_smbXsrv_connection = conn;
3422
3423 sconn->ev_ctx = ev_ctx;
3424 sconn->msg_ctx = msg_ctx;
3425 sconn->sock = sock_fd;
3426 sconn->smb1.echo_handler.trusted_fd = -1;
3427 sconn->smb1.echo_handler.socket_lock_fd = -1;
3428
3429 if (!interactive) {
3430 smbd_setup_sig_term_handler(sconn);
3431 smbd_setup_sig_hup_handler(sconn);
3432
3433 if (!serverid_register(messaging_server_id(msg_ctx),
3434 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3435 |FLAG_MSG_DBWRAP
3436 |FLAG_MSG_PRINT_GENERAL)) {
3437 exit_server_cleanly("Could not register myself in "
3438 "serverid.tdb");
3439 }
3440 }
3441
64dc4b59 3442 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
d28fa8fa 3443 /*
15d6c707 3444 * We're not making the decision here,
d28fa8fa
JA
3445 * we're just allowing the client
3446 * to decide between SMB1 and SMB2
3447 * with the first negprot
3448 * packet.
3449 */
37d71a56 3450 sconn->using_smb2 = true;
688945a9
SM
3451 }
3452
27f812f3 3453 /* Ensure child is set to blocking mode */
68e86969 3454 set_blocking(sconn->sock,True);
27f812f3 3455
68e86969
VL
3456 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3457 set_socket_options(sconn->sock, lp_socket_options());
27f812f3 3458
b764145a 3459 sa = (struct sockaddr *)(void *)&ss;
db6d1c62
SM
3460 sa_socklen = sizeof(ss);
3461 ret = getpeername(sconn->sock, sa, &sa_socklen);
b764145a
SM
3462 if (ret != 0) {
3463 int level = (errno == ENOTCONN)?2:0;
3464 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3549425b 3465 exit_server_cleanly("getpeername() failed.\n");
b764145a 3466 }
37d71a56 3467 ret = tsocket_address_bsd_from_sockaddr(sconn,
db6d1c62 3468 sa, sa_socklen,
b764145a
SM
3469 &remote_address);
3470 if (ret != 0) {
3471 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3472 __location__, strerror(errno)));
3549425b 3473 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
b764145a
SM
3474 }
3475
3476 sa = (struct sockaddr *)(void *)&ss;
db6d1c62
SM
3477 sa_socklen = sizeof(ss);
3478 ret = getsockname(sconn->sock, sa, &sa_socklen);
b764145a
SM
3479 if (ret != 0) {
3480 int level = (errno == ENOTCONN)?2:0;
3481 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3549425b 3482 exit_server_cleanly("getsockname() failed.\n");
b764145a 3483 }
37d71a56 3484 ret = tsocket_address_bsd_from_sockaddr(sconn,
db6d1c62 3485 sa, sa_socklen,
b764145a
SM
3486 &local_address);
3487 if (ret != 0) {
3488 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3489 __location__, strerror(errno)));
3549425b 3490 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
b764145a
SM
3491 }
3492
37d71a56
VL
3493 sconn->local_address = local_address;
3494 sconn->remote_address = remote_address;
b764145a 3495
3d7521c8
SM
3496 if (tsocket_address_is_inet(local_address, "ip")) {
3497 locaddr = tsocket_address_inet_addr_string(
3498 sconn->local_address,
3499 talloc_tos());
3500 if (locaddr == NULL) {
3501 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3502 __location__, strerror(errno)));
3503 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3504 }
3505 } else {
3506 locaddr = "0.0.0.0";
3507 }
3508
b764145a
SM
3509 if (tsocket_address_is_inet(remote_address, "ip")) {
3510 remaddr = tsocket_address_inet_addr_string(
37d71a56 3511 sconn->remote_address,
b764145a
SM
3512 talloc_tos());
3513 if (remaddr == NULL) {
ad0f765a
AS
3514 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3515 __location__, strerror(errno)));
3516 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
b764145a
SM
3517 }
3518 } else {
3519 remaddr = "0.0.0.0";
3520 }
3521
27f812f3
SM
3522 /* this is needed so that we get decent entries
3523 in smbstatus for port 445 connects */
b764145a 3524 set_remote_machine_name(remaddr, false);
03455519 3525 reload_services(sconn, conn_snum_used, true);
27f812f3 3526
ac647d03
VL
3527 /*
3528 * Before the first packet, check the global hosts allow/ hosts deny
3529 * parameters before doing any parsing of packets passed to us by the
3530 * client. This prevents attacks on our parsing code from hosts not in
3531 * the hosts allow list.
3532 */
3533
a513086c
AS
3534 ret = get_remote_hostname(remote_address,
3535 &rhost,
3536 talloc_tos());
3537 if (ret < 0) {
3538 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3539 __location__, strerror(errno)));
3540 exit_server_cleanly("get_remote_hostname failed.\n");
3541 }
3542 if (strequal(rhost, "UNKNOWN")) {
3543 rhost = talloc_strdup(talloc_tos(), remaddr);
3544 }
3545 sconn->remote_hostname = talloc_move(sconn, &rhost);
3546
3d7521c8
SM
3547 sub_set_socket_ids(remaddr,
3548 sconn->remote_hostname,
3549 locaddr);
3550
cdb6af95 3551 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
a513086c
AS
3552 sconn->remote_hostname,
3553 remaddr)) {
ac647d03
VL
3554 /*
3555 * send a negative session response "not listening on calling
3556 * name"
3557 */
3558 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
b764145a
SM
3559 DEBUG( 1, ("Connection denied from %s to %s\n",
3560 tsocket_address_string(remote_address, talloc_tos()),
3561 tsocket_address_string(local_address, talloc_tos())));
1808dd0a 3562 (void)srv_send_smb(sconn,(char *)buf, false,
c16c90a1 3563 0, false, NULL);
ac647d03
VL
3564 exit_server_cleanly("connection denied");
3565 }
3566
b764145a
SM
3567 DEBUG(10, ("Connection allowed from %s to %s\n",
3568 tsocket_address_string(remote_address, talloc_tos()),
3569 tsocket_address_string(local_address, talloc_tos())));
3570
c3638158
AB
3571 if (lp_preload_modules()) {
3572 smb_load_modules(lp_preload_modules());
3573 }
27f812f3 3574
54c51a66 3575 smb_perfcount_init();
3576
27f812f3
SM
3577 if (!init_account_policy()) {
3578 exit_server("Could not open account policy tdb.\n");
3579 }
3580
73bac10c
GS
3581 if (*lp_root_directory(talloc_tos())) {
3582 if (chroot(lp_root_directory(talloc_tos())) != 0) {
fe72740e 3583 DEBUG(0,("Failed to change root to %s\n",
73bac10c 3584 lp_root_directory(talloc_tos())));
f6821a15
JA
3585 exit_server("Failed to chroot()");
3586 }
3587 if (chdir("/") == -1) {
73bac10c 3588 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
27f812f3
SM
3589 exit_server("Failed to chroot()");
3590 }
73bac10c 3591 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
27f812f3
SM
3592 }
3593
37d71a56 3594 if (!srv_init_signing(sconn)) {
c16c90a1
SM
3595 exit_server("Failed to init smb_signing");
3596 }
3597
288a75d8
SM
3598 if (!file_init(sconn)) {
3599 exit_server("file_init() failed");
3600 }
3601
27f812f3 3602 /* Setup oplocks */
21de6735 3603 if (!init_oplocks(sconn))
27f812f3
SM
3604 exit_server("Failed to init oplocks");
3605
27f812f3 3606 /* register our message handlers */
d492a437 3607 messaging_register(sconn->msg_ctx, sconn,
27f812f3 3608 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4d44f879 3609 messaging_register(sconn->msg_ctx, sconn,
27f812f3 3610 MSG_SMB_CLOSE_FILE, msg_close_file);
e09c6755 3611 messaging_register(sconn->msg_ctx, sconn,
173ea716 3612 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
27f812f3 3613
715933a3
SM
3614 id_cache_register_msgs(sconn->msg_ctx);
3615 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3616 messaging_register(sconn->msg_ctx, sconn,
3617 ID_CACHE_KILL, smbd_id_cache_kill);
3618
e412b8bf
SM
3619 messaging_deregister(sconn->msg_ctx,
3620 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3621 messaging_register(sconn->msg_ctx, sconn,
3622 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3623
a26003dd
CA
3624 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
3625 NULL);
3626 messaging_register(sconn->msg_ctx, sconn,
3627 MSG_SMB_KILL_CLIENT_IP,
3628 msg_kill_client_ip);
3629
84d8b2b0
VL
3630 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
3631
5a4d6181
AS
3632 /*
3633 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3634 * MSGs to all child processes
3635 */
b71f2af1 3636 messaging_deregister(sconn->msg_ctx,
5a4d6181 3637 MSG_DEBUG, NULL);
b71f2af1 3638 messaging_register(sconn->msg_ctx, NULL,
5a4d6181
AS
3639 MSG_DEBUG, debug_message);
3640
27f812f3 3641 if ((lp_keepalive() != 0)
dd3a9279 3642 && !(event_add_idle(ev_ctx, NULL,
27f812f3
SM
3643 timeval_set(lp_keepalive(), 0),
3644 "keepalive", keepalive_fn,
d911bd5c 3645 sconn))) {
27f812f3
SM
3646 DEBUG(0, ("Could not add keepalive event\n"));
3647 exit(1);
3648 }
3649
dd3a9279 3650 if (!(event_add_idle(ev_ctx, NULL,
27f812f3 3651 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
37d71a56 3652 "deadtime", deadtime_fn, sconn))) {
27f812f3
SM
3653 DEBUG(0, ("Could not add deadtime event\n"));
3654 exit(1);
aeb798c3 3655 }
27f812f3 3656
dd3a9279 3657 if (!(event_add_idle(ev_ctx, NULL,
0b188e77 3658 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
babfe237 3659 "housekeeping", housekeeping_fn, sconn))) {
27f812f3
SM
3660 DEBUG(0, ("Could not add housekeeping event\n"));
3661 exit(1);
3662 }
3663
3664#ifdef CLUSTER_SUPPORT
3665
3666 if (lp_clustering()) {
3667 /*
3668 * We need to tell ctdb about our client's TCP
3669 * connection, so that for failover ctdbd can send
3670 * tickle acks, triggering a reconnection by the
3671 * client.
3672 */
3673
3674 struct sockaddr_storage srv, clnt;
3675
f83e7d8f 3676 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
27f812f3 3677 NTSTATUS status;
744cc264 3678 status = smbd_register_ips(sconn, &srv, &clnt);
27f812f3
SM
3679 if (!NT_STATUS_IS_OK(status)) {
3680 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3681 nt_errstr(status)));
3682 }
58275be0
CA
3683 } else {
3684 int level = (errno == ENOTCONN)?2:0;
3685 DEBUG(level,("Unable to get tcp info for "
3686 "smbd_register_ips: %s\n",
3687 strerror(errno)));
165b7aa5 3688 exit_server_cleanly("client_get_tcp_info() failed.\n");
27f812f3
SM
3689 }
3690 }
3691
3692#endif
3693
37d71a56 3694 sconn->nbt.got_session = false;
f554af18 3695
a349b0be
SM
3696 tmp = lp_max_xmit();
3697 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3698 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3699
3700 sconn->smb1.negprot.max_recv = tmp;
27f812f3 3701
37d71a56 3702 sconn->smb1.sessions.done_sesssetup = false;
5cd5c161 3703 sconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
356f0336 3704
37d71a56 3705 if (!init_dptrs(sconn)) {
59c3f5e3
SM
3706 exit_server("init_dptrs() failed");
3707 }
c8620180 3708
e5f6250a 3709 sconn->smb1.fde = tevent_add_fd(ev_ctx,
37d71a56 3710 sconn,
68e86969 3711 sconn->sock,
e5f6250a 3712 TEVENT_FD_READ,
ebc860eb 3713 smbd_server_connection_handler,
37d71a56
VL
3714 sconn);
3715 if (!sconn->smb1.fde) {
aeb798c3
SM
3716 exit_server("failed to create smbd_server_connection fde");
3717 }
3718
b3235d48
SM
3719 sconn->conn->local_address = sconn->local_address;
3720 sconn->conn->remote_address = sconn->remote_address;
3721 sconn->conn->remote_hostname = sconn->remote_hostname;
3722 sconn->conn->protocol = PROTOCOL_NONE;
3723
27f812f3
SM
3724 TALLOC_FREE(frame);
3725
cd260391 3726 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
fc96488c 3727
b2d01bd2 3728 while (True) {
27f812f3 3729 frame = talloc_stackframe_pool(8192);
dc76502c 3730
c3250149 3731 errno = 0;
ed85e9fe
JA
3732 if (tevent_loop_once(ev_ctx) == -1) {
3733 if (errno != EINTR) {
3734 DEBUG(3, ("tevent_loop_once failed: %s,"
3735 " exiting\n", strerror(errno) ));
3736 break;
3737 }
b2d01bd2
AT
3738 }
3739
929e1d99 3740 TALLOC_FREE(frame);
b2d01bd2 3741 }
27f812f3
SM
3742
3743 exit_server_cleanly(NULL);
c3effa8b 3744}
d94e9c80 3745
b80111ad 3746bool req_is_in_chain(const struct smb_request *req)
d94e9c80 3747{
4f41be35 3748 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
d94e9c80
VL
3749 /*
3750 * We're right now handling a subsequent request, so we must
3751 * be in a chain
3752 */
3753 return true;
3754 }
3755
3756 if (!is_andx_req(req->cmd)) {
3757 return false;
3758 }
3759
3760 if (req->wct < 2) {
3761 /*
3762 * Okay, an illegal request, but definitely not chained :-)
3763 */
3764 return false;
3765 }
3766
3767 return (CVAL(req->vwv+0, 0) != 0xFF);
3768}