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