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