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