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