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