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