]> git.ipfire.org Git - thirdparty/samba.git/blame - source3/smbd/process.c
s3:winbindd: s/struct timed_event/struct tevent_timer
[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"
b5e9ece1 42#include "serverid.h"
c3effa8b 43
6d84b24d
SM
44/* Internal message queue for deferred opens. */
45struct pending_message_list {
46 struct pending_message_list *next, *prev;
47 struct timeval request_time; /* When was this first issued? */
48 struct smbd_server_connection *sconn;
49 struct timed_event *te;
50 struct smb_perfcount_data pcd;
51 uint32_t seqnum;
52 bool encrypted;
53 bool processed;
54 DATA_BLOB buf;
55 DATA_BLOB private_data;
56};
57
ae0c6cff
VL
58static void construct_reply_common(struct smb_request *req, const char *inbuf,
59 char *outbuf);
cb69d105
VL
60static struct pending_message_list *get_deferred_open_message_smb(
61 struct smbd_server_connection *sconn, uint64_t mid);
3b2c9beb 62static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
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
c0288e06 78 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
cad0c004 79
da00021a
VL
80 do {
81 ok = fcntl_lock(
82 sconn->smb1.echo_handler.socket_lock_fd,
1ac7f071 83 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
7b0b1d6d 91 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
cad0c004 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,
1ac7f071 120 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
c0288e06 128 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
cad0c004 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
d5693d99 173 len = smb_len_large(buf_out) + 4;
9254bb4e 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",
c0288e06 184 (int)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{
faa8edcc
SM
517 struct smbXsrv_tcon *tcon;
518 NTSTATUS status;
519 NTTIME now;
ed70bc0d 520 size_t req_size = smb_len(inbuf) + 4;
d8b3687f 521
ed70bc0d 522 /* Ensure we have at least smb_size bytes. */
a1f593cd
JA
523 if (req_size < smb_size) {
524 DEBUG(0,("init_smb_request: invalid request size %u\n",
525 (unsigned int)req_size ));
b7898148 526 return false;
a1f593cd 527 }
d8b3687f
SM
528
529 req->request_time = timeval_current();
faa8edcc 530 now = timeval_to_nttime(&req->request_time);
d8b3687f 531
7808a259 532 req->cmd = CVAL(inbuf, smb_com);
0bc56a2e
VL
533 req->flags2 = SVAL(inbuf, smb_flg2);
534 req->smbpid = SVAL(inbuf, smb_pid);
79842437 535 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
9b4b9d26 536 req->seqnum = seqnum;
0bc56a2e 537 req->vuid = SVAL(inbuf, smb_uid);
cc6a4101
VL
538 req->tid = SVAL(inbuf, smb_tid);
539 req->wct = CVAL(inbuf, smb_wct);
f1dc8b28 540 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
7f9d6f80 541 req->buflen = smb_buflen(inbuf);
4f41be35 542 req->buf = (const uint8_t *)smb_buf_const(inbuf);
c3250149 543 req->unread_bytes = unread_bytes;
9254bb4e 544 req->encrypted = encrypted;
edfc7eaf 545 req->sconn = sconn;
faa8edcc
SM
546 status = smb1srv_tcon_lookup(sconn->conn, req->tid, now, &tcon);
547 if (NT_STATUS_IS_OK(status)) {
548 req->conn = tcon->compat;
549 } else {
550 req->conn = NULL;
551 }
d65afbe5 552 req->chain_fsp = NULL;
08b24e92 553 req->smb2req = NULL;
89c55485 554 req->priv_paths = NULL;
8f93068c 555 req->chain = NULL;
54c51a66 556 smb_init_perfcount_data(&req->pcd);
c3250149 557
a662a62e 558 /* Ensure we have at least wct words and 2 bytes of bcc. */
a1f593cd
JA
559 if (smb_size + req->wct*2 > req_size) {
560 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
561 (unsigned int)req->wct,
562 (unsigned int)req_size));
b7898148 563 return false;
a1f593cd 564 }
a662a62e 565 /* Ensure bcc is correct. */
4f41be35 566 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
a662a62e
JA
567 DEBUG(0,("init_smb_request: invalid bcc number %u "
568 "(wct = %u, size %u)\n",
7f9d6f80 569 (unsigned int)req->buflen,
a662a62e
JA
570 (unsigned int)req->wct,
571 (unsigned int)req_size));
b7898148 572 return false;
a662a62e 573 }
54c51a66 574
cc6a4101 575 req->outbuf = NULL;
b7898148 576 return true;
0bc56a2e
VL
577}
578
aeb798c3
SM
579static void process_smb(struct smbd_server_connection *conn,
580 uint8_t *inbuf, size_t nread, size_t unread_bytes,
c16c90a1
SM
581 uint32_t seqnum, bool encrypted,
582 struct smb_perfcount_data *deferred_pcd);
aeb798c3 583
415e8e05 584static void smbd_deferred_open_timer(struct tevent_context *ev,
aeb798c3
SM
585 struct timed_event *te,
586 struct timeval _tval,
587 void *private_data)
588{
589 struct pending_message_list *msg = talloc_get_type(private_data,
590 struct pending_message_list);
8b2b7d1c 591 struct smbd_server_connection *sconn = msg->sconn;
aeb798c3 592 TALLOC_CTX *mem_ctx = talloc_tos();
79842437 593 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
aeb798c3
SM
594 uint8_t *inbuf;
595
50aa8a4a
VL
596 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
597 msg->buf.length);
aeb798c3
SM
598 if (inbuf == NULL) {
599 exit_server("smbd_deferred_open_timer: talloc failed\n");
600 return;
601 }
602
603 /* We leave this message on the queue so the open code can
604 know this is a retry. */
79842437
JA
605 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
606 (unsigned long long)mid ));
8a6b90d4
JA
607
608 /* Mark the message as processed so this is not
609 * re-processed in error. */
610 msg->processed = true;
aeb798c3 611
8b2b7d1c 612 process_smb(sconn, inbuf,
aeb798c3 613 msg->buf.length, 0,
c16c90a1 614 msg->seqnum, msg->encrypted, &msg->pcd);
8a6b90d4
JA
615
616 /* If it's still there and was processed, remove it. */
8b2b7d1c 617 msg = get_deferred_open_message_smb(sconn, mid);
8a6b90d4 618 if (msg && msg->processed) {
8b2b7d1c 619 remove_deferred_open_message_smb(sconn, mid);
8a6b90d4 620 }
aeb798c3 621}
aab2fe02
JA
622
623/****************************************************************************
e5a95132
GJC
624 Function to push a message onto the tail of a linked list of smb messages ready
625 for processing.
aab2fe02
JA
626****************************************************************************/
627
30191d1a 628static bool push_queued_message(struct smb_request *req,
54abd2aa
GC
629 struct timeval request_time,
630 struct timeval end_time,
631 char *private_data, size_t private_len)
aab2fe02 632{
b578db69 633 int msg_len = smb_len(req->inbuf) + 4;
54abd2aa
GC
634 struct pending_message_list *msg;
635
ad0a07c5 636 msg = talloc_zero(NULL, struct pending_message_list);
aab2fe02 637
1eff0523
JA
638 if(msg == NULL) {
639 DEBUG(0,("push_message: malloc fail (1)\n"));
640 return False;
641 }
8b2b7d1c 642 msg->sconn = req->sconn;
aab2fe02 643
b578db69 644 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
2fc57c9a 645 if(msg->buf.data == NULL) {
1eff0523 646 DEBUG(0,("push_message: malloc fail (2)\n"));
fb5362c0 647 TALLOC_FREE(msg);
1eff0523
JA
648 return False;
649 }
aab2fe02 650
54abd2aa 651 msg->request_time = request_time;
c16c90a1 652 msg->seqnum = req->seqnum;
9254bb4e 653 msg->encrypted = req->encrypted;
8a6b90d4 654 msg->processed = false;
54c51a66 655 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
2fc57c9a 656
19ca97a7 657 if (private_data) {
54abd2aa
GC
658 msg->private_data = data_blob_talloc(msg, private_data,
659 private_len);
2fc57c9a
JA
660 if (msg->private_data.data == NULL) {
661 DEBUG(0,("push_message: malloc fail (3)\n"));
fb5362c0 662 TALLOC_FREE(msg);
b6fb0462 663 return False;
2fc57c9a
JA
664 }
665 }
aab2fe02 666
16cfc724
SM
667 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
668 msg,
669 end_time,
670 smbd_deferred_open_timer,
671 msg);
aeb798c3
SM
672 if (!msg->te) {
673 DEBUG(0,("push_message: event_add_timed failed\n"));
674 TALLOC_FREE(msg);
675 return false;
676 }
677
d20e968c
VL
678 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
679 struct pending_message_list *);
aab2fe02 680
54abd2aa
GC
681 DEBUG(10,("push_message: pushed message length %u on "
682 "deferred_open_queue\n", (unsigned int)msg_len));
2fc57c9a 683
1eff0523 684 return True;
aab2fe02
JA
685}
686
2fc57c9a
JA
687/****************************************************************************
688 Function to delete a sharing violation open message by mid.
689****************************************************************************/
690
04253dfd
VL
691void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
692 uint64_t mid)
2fc57c9a
JA
693{
694 struct pending_message_list *pml;
695
04253dfd
VL
696 if (sconn->using_smb2) {
697 remove_deferred_open_message_smb2(sconn, mid);
e15939b4
JA
698 return;
699 }
700
d20e968c 701 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
79842437 702 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
e15939b4 703 DEBUG(10,("remove_deferred_open_message_smb: "
79842437
JA
704 "deleting mid %llu len %u\n",
705 (unsigned long long)mid,
54abd2aa 706 (unsigned int)pml->buf.length ));
d20e968c 707 DLIST_REMOVE(sconn->deferred_open_queue, pml);
fb5362c0 708 TALLOC_FREE(pml);
2fc57c9a
JA
709 return;
710 }
711 }
712}
713
714/****************************************************************************
715 Move a sharing violation open retry message to the front of the list and
716 schedule it for immediate processing.
717****************************************************************************/
718
6617c2c1 719bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
502fdae7 720 uint64_t mid)
2fc57c9a
JA
721{
722 struct pending_message_list *pml;
723 int i = 0;
724
502fdae7 725 if (sconn->using_smb2) {
6617c2c1 726 return schedule_deferred_open_message_smb2(sconn, mid);
3413cf7a
JA
727 }
728
d20e968c 729 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
79842437 730 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
aeb798c3 731
79842437
JA
732 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
733 "msg_mid = %llu\n",
734 i++,
735 (unsigned long long)msg_mid ));
aeb798c3 736
2fc57c9a 737 if (mid == msg_mid) {
aeb798c3
SM
738 struct timed_event *te;
739
8a6b90d4
JA
740 if (pml->processed) {
741 /* A processed message should not be
742 * rescheduled. */
e15939b4 743 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
79842437
JA
744 "message mid %llu was already processed\n",
745 (unsigned long long)msg_mid ));
8a6b90d4
JA
746 continue;
747 }
748
79842437
JA
749 DEBUG(10,("schedule_deferred_open_message_smb: "
750 "scheduling mid %llu\n",
751 (unsigned long long)mid ));
aeb798c3 752
16cfc724
SM
753 te = tevent_add_timer(pml->sconn->ev_ctx,
754 pml,
755 timeval_zero(),
756 smbd_deferred_open_timer,
757 pml);
aeb798c3 758 if (!te) {
e15939b4 759 DEBUG(10,("schedule_deferred_open_message_smb: "
79842437
JA
760 "event_add_timed() failed, "
761 "skipping mid %llu\n",
762 (unsigned long long)msg_mid ));
aeb798c3
SM
763 }
764
765 TALLOC_FREE(pml->te);
766 pml->te = te;
d20e968c 767 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
6617c2c1 768 return true;
2fc57c9a
JA
769 }
770 }
771
79842437
JA
772 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
773 "find message mid %llu\n",
774 (unsigned long long)mid ));
6617c2c1
JA
775
776 return false;
2fc57c9a
JA
777}
778
779/****************************************************************************
8a6b90d4 780 Return true if this mid is on the deferred queue and was not yet processed.
2fc57c9a
JA
781****************************************************************************/
782
f9d183f9 783bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
2fc57c9a
JA
784{
785 struct pending_message_list *pml;
3e0f5862 786
f9d183f9
VL
787 if (sconn->using_smb2) {
788 return open_was_deferred_smb2(sconn, mid);
e15939b4
JA
789 }
790
d20e968c 791 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
79842437 792 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
2fc57c9a
JA
793 return True;
794 }
795 }
796 return False;
797}
798
799/****************************************************************************
800 Return the message queued by this mid.
801****************************************************************************/
802
cb69d105
VL
803static struct pending_message_list *get_deferred_open_message_smb(
804 struct smbd_server_connection *sconn, uint64_t mid)
2fc57c9a
JA
805{
806 struct pending_message_list *pml;
3e0f5862 807
d20e968c 808 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
79842437 809 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
2fc57c9a
JA
810 return pml;
811 }
812 }
813 return NULL;
814}
815
e15939b4
JA
816/****************************************************************************
817 Get the state data queued by this mid.
818****************************************************************************/
819
8f67f873 820bool get_deferred_open_message_state(struct smb_request *smbreq,
e15939b4
JA
821 struct timeval *p_request_time,
822 void **pp_state)
823{
824 struct pending_message_list *pml;
825
8b2b7d1c 826 if (smbreq->sconn->using_smb2) {
8f67f873 827 return get_deferred_open_message_state_smb2(smbreq->smb2req,
e15939b4
JA
828 p_request_time,
829 pp_state);
830 }
831
cb69d105 832 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
e15939b4
JA
833 if (!pml) {
834 return false;
835 }
836 if (p_request_time) {
837 *p_request_time = pml->request_time;
838 }
839 if (pp_state) {
840 *pp_state = (void *)pml->private_data.data;
841 }
842 return true;
843}
844
2fc57c9a 845/****************************************************************************
54abd2aa
GC
846 Function to push a deferred open smb message onto a linked list of local smb
847 messages ready for processing.
848****************************************************************************/
849
e15939b4 850bool push_deferred_open_message_smb(struct smb_request *req,
54abd2aa
GC
851 struct timeval request_time,
852 struct timeval timeout,
2bbb8c91 853 struct file_id id,
54abd2aa
GC
854 char *private_data, size_t priv_len)
855{
856 struct timeval end_time;
857
e15939b4 858 if (req->smb2req) {
8f67f873 859 return push_deferred_open_message_smb2(req->smb2req,
e15939b4
JA
860 request_time,
861 timeout,
2bbb8c91 862 id,
e15939b4
JA
863 private_data,
864 priv_len);
865 }
866
c3250149 867 if (req->unread_bytes) {
e15939b4 868 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
c3250149
JA
869 "unread_bytes = %u\n",
870 (unsigned int)req->unread_bytes ));
e15939b4 871 smb_panic("push_deferred_open_message_smb: "
c3250149
JA
872 "logic error unread_bytes != 0" );
873 }
874
54abd2aa
GC
875 end_time = timeval_sum(&request_time, &timeout);
876
79842437
JA
877 DEBUG(10,("push_deferred_open_message_smb: pushing message "
878 "len %u mid %llu timeout time [%u.%06u]\n",
879 (unsigned int) smb_len(req->inbuf)+4,
880 (unsigned long long)req->mid,
881 (unsigned int)end_time.tv_sec,
882 (unsigned int)end_time.tv_usec));
54abd2aa 883
b578db69 884 return push_queued_message(req, request_time, end_time,
54abd2aa
GC
885 private_data, priv_len);
886}
887
ac61f650
SM
888static void smbd_sig_term_handler(struct tevent_context *ev,
889 struct tevent_signal *se,
890 int signum,
891 int count,
892 void *siginfo,
893 void *private_data)
894{
895 exit_server_cleanly("termination signal");
896}
897
8a834642 898void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
ac61f650
SM
899{
900 struct tevent_signal *se;
901
8a834642
SM
902 se = tevent_add_signal(sconn->ev_ctx,
903 sconn,
ac61f650
SM
904 SIGTERM, 0,
905 smbd_sig_term_handler,
8a834642 906 sconn);
ac61f650
SM
907 if (!se) {
908 exit_server("failed to setup SIGTERM handler");
909 }
910}
911
912static void smbd_sig_hup_handler(struct tevent_context *ev,
913 struct tevent_signal *se,
914 int signum,
915 int count,
916 void *siginfo,
917 void *private_data)
918{
290ce331
SM
919 struct smbd_server_connection *sconn =
920 talloc_get_type_abort(private_data,
921 struct smbd_server_connection);
922
ac61f650
SM
923 change_to_root_user();
924 DEBUG(1,("Reloading services after SIGHUP\n"));
03455519 925 reload_services(sconn, conn_snum_used, false);
ac61f650
SM
926}
927
290ce331 928void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
ac61f650
SM
929{
930 struct tevent_signal *se;
931
290ce331
SM
932 se = tevent_add_signal(sconn->ev_ctx,
933 sconn,
934 SIGHUP, 0,
935 smbd_sig_hup_handler,
936 sconn);
ac61f650
SM
937 if (!se) {
938 exit_server("failed to setup SIGHUP handler");
939 }
940}
941
e412b8bf
SM
942static void smbd_conf_updated(struct messaging_context *msg,
943 void *private_data,
944 uint32_t msg_type,
945 struct server_id server_id,
946 DATA_BLOB *data)
947{
948 struct smbd_server_connection *sconn =
949 talloc_get_type_abort(private_data,
950 struct smbd_server_connection);
951
952 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
953 "updated. Reloading.\n"));
954 change_to_root_user();
03455519 955 reload_services(sconn, conn_snum_used, false);
e412b8bf
SM
956}
957
22dbd677
JA
958/*
959 * Only allow 5 outstanding trans requests. We're allocating memory, so
960 * prevent a DoS.
961 */
aab2fe02 962
79842437 963NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
c3effa8b 964{
22dbd677
JA
965 int count = 0;
966 for (; list != NULL; list = list->next) {
c3effa8b 967
22dbd677
JA
968 if (list->mid == mid) {
969 return NT_STATUS_INVALID_PARAMETER;
970 }
971
972 count += 1;
973 }
974 if (count > 5) {
975 return NT_STATUS_INSUFFICIENT_RESOURCES;
976 }
c3effa8b 977
22dbd677 978 return NT_STATUS_OK;
c3effa8b
AT
979}
980
c3effa8b
AT
981/*
982These flags determine some of the permissions required to do an operation
983
984Note that I don't set NEED_WRITE on some write operations because they
985are used by some brain-dead clients when printing, and I don't want to
986force write permissions on print services.
987*/
988#define AS_USER (1<<0)
ce61fb21 989#define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
c3effa8b 990#define TIME_INIT (1<<2)
ce61fb21
JA
991#define CAN_IPC (1<<3) /* Must be paired with AS_USER */
992#define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
54abd2aa 993#define DO_CHDIR (1<<6)
c3effa8b
AT
994
995/*
996 define a list of possible SMB messages and their corresponding
997 functions. Any message that has a NULL function is unimplemented -
998 please feel free to contribute implementations!
999*/
1eff0523
JA
1000static const struct smb_message_struct {
1001 const char *name;
48d3a1d2 1002 void (*fn)(struct smb_request *req);
1eff0523
JA
1003 int flags;
1004} smb_messages[256] = {
918c3ebe 1005
b578db69
VL
1006/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1007/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1008/* 0x02 */ { "SMBopen",reply_open,AS_USER },
1009/* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1010/* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1011/* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1012/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1013/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1014/* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1015/* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1016/* 0x0a */ { "SMBread",reply_read,AS_USER},
1017/* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1018/* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1019/* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1020/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1021/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1022/* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1023/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1024/* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1025/* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1026/* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1027/* 0x15 */ { NULL, NULL, 0 },
1028/* 0x16 */ { NULL, NULL, 0 },
1029/* 0x17 */ { NULL, NULL, 0 },
1030/* 0x18 */ { NULL, NULL, 0 },
1031/* 0x19 */ { NULL, NULL, 0 },
1032/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1033/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1034/* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1035/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1036/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1037/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1038/* 0x20 */ { "SMBwritec", NULL,0},
1039/* 0x21 */ { NULL, NULL, 0 },
1040/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1041/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1042/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1043/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1044/* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1045/* 0x27 */ { "SMBioctl",reply_ioctl,0},
1046/* 0x28 */ { "SMBioctls", NULL,AS_USER},
1047/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1048/* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1049/* 0x2b */ { "SMBecho",reply_echo,0},
1050/* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1051/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1052/* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1053/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1054/* 0x30 */ { NULL, NULL, 0 },
1055/* 0x31 */ { NULL, NULL, 0 },
1056/* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
7716ad68 1057/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
b578db69
VL
1058/* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1059/* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1060/* 0x36 */ { NULL, NULL, 0 },
1061/* 0x37 */ { NULL, NULL, 0 },
1062/* 0x38 */ { NULL, NULL, 0 },
1063/* 0x39 */ { NULL, NULL, 0 },
1064/* 0x3a */ { NULL, NULL, 0 },
1065/* 0x3b */ { NULL, NULL, 0 },
1066/* 0x3c */ { NULL, NULL, 0 },
1067/* 0x3d */ { NULL, NULL, 0 },
1068/* 0x3e */ { NULL, NULL, 0 },
1069/* 0x3f */ { NULL, NULL, 0 },
1070/* 0x40 */ { NULL, NULL, 0 },
1071/* 0x41 */ { NULL, NULL, 0 },
1072/* 0x42 */ { NULL, NULL, 0 },
1073/* 0x43 */ { NULL, NULL, 0 },
1074/* 0x44 */ { NULL, NULL, 0 },
1075/* 0x45 */ { NULL, NULL, 0 },
1076/* 0x46 */ { NULL, NULL, 0 },
1077/* 0x47 */ { NULL, NULL, 0 },
1078/* 0x48 */ { NULL, NULL, 0 },
1079/* 0x49 */ { NULL, NULL, 0 },
1080/* 0x4a */ { NULL, NULL, 0 },
1081/* 0x4b */ { NULL, NULL, 0 },
1082/* 0x4c */ { NULL, NULL, 0 },
1083/* 0x4d */ { NULL, NULL, 0 },
1084/* 0x4e */ { NULL, NULL, 0 },
1085/* 0x4f */ { NULL, NULL, 0 },
1086/* 0x50 */ { NULL, NULL, 0 },
1087/* 0x51 */ { NULL, NULL, 0 },
1088/* 0x52 */ { NULL, NULL, 0 },
1089/* 0x53 */ { NULL, NULL, 0 },
1090/* 0x54 */ { NULL, NULL, 0 },
1091/* 0x55 */ { NULL, NULL, 0 },
1092/* 0x56 */ { NULL, NULL, 0 },
1093/* 0x57 */ { NULL, NULL, 0 },
1094/* 0x58 */ { NULL, NULL, 0 },
1095/* 0x59 */ { NULL, NULL, 0 },
1096/* 0x5a */ { NULL, NULL, 0 },
1097/* 0x5b */ { NULL, NULL, 0 },
1098/* 0x5c */ { NULL, NULL, 0 },
1099/* 0x5d */ { NULL, NULL, 0 },
1100/* 0x5e */ { NULL, NULL, 0 },
1101/* 0x5f */ { NULL, NULL, 0 },
1102/* 0x60 */ { NULL, NULL, 0 },
1103/* 0x61 */ { NULL, NULL, 0 },
1104/* 0x62 */ { NULL, NULL, 0 },
1105/* 0x63 */ { NULL, NULL, 0 },
1106/* 0x64 */ { NULL, NULL, 0 },
1107/* 0x65 */ { NULL, NULL, 0 },
1108/* 0x66 */ { NULL, NULL, 0 },
1109/* 0x67 */ { NULL, NULL, 0 },
1110/* 0x68 */ { NULL, NULL, 0 },
1111/* 0x69 */ { NULL, NULL, 0 },
1112/* 0x6a */ { NULL, NULL, 0 },
1113/* 0x6b */ { NULL, NULL, 0 },
1114/* 0x6c */ { NULL, NULL, 0 },
1115/* 0x6d */ { NULL, NULL, 0 },
1116/* 0x6e */ { NULL, NULL, 0 },
1117/* 0x6f */ { NULL, NULL, 0 },
1118/* 0x70 */ { "SMBtcon",reply_tcon,0},
1119/* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1120/* 0x72 */ { "SMBnegprot",reply_negprot,0},
1121/* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1122/* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1123/* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1124/* 0x76 */ { NULL, NULL, 0 },
1125/* 0x77 */ { NULL, NULL, 0 },
1126/* 0x78 */ { NULL, NULL, 0 },
1127/* 0x79 */ { NULL, NULL, 0 },
1128/* 0x7a */ { NULL, NULL, 0 },
1129/* 0x7b */ { NULL, NULL, 0 },
1130/* 0x7c */ { NULL, NULL, 0 },
1131/* 0x7d */ { NULL, NULL, 0 },
1132/* 0x7e */ { NULL, NULL, 0 },
1133/* 0x7f */ { NULL, NULL, 0 },
1134/* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1135/* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1136/* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1137/* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1138/* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1139/* 0x85 */ { NULL, NULL, 0 },
1140/* 0x86 */ { NULL, NULL, 0 },
1141/* 0x87 */ { NULL, NULL, 0 },
1142/* 0x88 */ { NULL, NULL, 0 },
1143/* 0x89 */ { NULL, NULL, 0 },
1144/* 0x8a */ { NULL, NULL, 0 },
1145/* 0x8b */ { NULL, NULL, 0 },
1146/* 0x8c */ { NULL, NULL, 0 },
1147/* 0x8d */ { NULL, NULL, 0 },
1148/* 0x8e */ { NULL, NULL, 0 },
1149/* 0x8f */ { NULL, NULL, 0 },
1150/* 0x90 */ { NULL, NULL, 0 },
1151/* 0x91 */ { NULL, NULL, 0 },
1152/* 0x92 */ { NULL, NULL, 0 },
1153/* 0x93 */ { NULL, NULL, 0 },
1154/* 0x94 */ { NULL, NULL, 0 },
1155/* 0x95 */ { NULL, NULL, 0 },
1156/* 0x96 */ { NULL, NULL, 0 },
1157/* 0x97 */ { NULL, NULL, 0 },
1158/* 0x98 */ { NULL, NULL, 0 },
1159/* 0x99 */ { NULL, NULL, 0 },
1160/* 0x9a */ { NULL, NULL, 0 },
1161/* 0x9b */ { NULL, NULL, 0 },
1162/* 0x9c */ { NULL, NULL, 0 },
1163/* 0x9d */ { NULL, NULL, 0 },
1164/* 0x9e */ { NULL, NULL, 0 },
1165/* 0x9f */ { NULL, NULL, 0 },
1166/* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1167/* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1168/* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1169/* 0xa3 */ { NULL, NULL, 0 },
1170/* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1171/* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1172/* 0xa6 */ { NULL, NULL, 0 },
1173/* 0xa7 */ { NULL, NULL, 0 },
1174/* 0xa8 */ { NULL, NULL, 0 },
1175/* 0xa9 */ { NULL, NULL, 0 },
1176/* 0xaa */ { NULL, NULL, 0 },
1177/* 0xab */ { NULL, NULL, 0 },
1178/* 0xac */ { NULL, NULL, 0 },
1179/* 0xad */ { NULL, NULL, 0 },
1180/* 0xae */ { NULL, NULL, 0 },
1181/* 0xaf */ { NULL, NULL, 0 },
1182/* 0xb0 */ { NULL, NULL, 0 },
1183/* 0xb1 */ { NULL, NULL, 0 },
1184/* 0xb2 */ { NULL, NULL, 0 },
1185/* 0xb3 */ { NULL, NULL, 0 },
1186/* 0xb4 */ { NULL, NULL, 0 },
1187/* 0xb5 */ { NULL, NULL, 0 },
1188/* 0xb6 */ { NULL, NULL, 0 },
1189/* 0xb7 */ { NULL, NULL, 0 },
1190/* 0xb8 */ { NULL, NULL, 0 },
1191/* 0xb9 */ { NULL, NULL, 0 },
1192/* 0xba */ { NULL, NULL, 0 },
1193/* 0xbb */ { NULL, NULL, 0 },
1194/* 0xbc */ { NULL, NULL, 0 },
1195/* 0xbd */ { NULL, NULL, 0 },
1196/* 0xbe */ { NULL, NULL, 0 },
1197/* 0xbf */ { NULL, NULL, 0 },
1198/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1199/* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1200/* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1201/* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1202/* 0xc4 */ { NULL, NULL, 0 },
1203/* 0xc5 */ { NULL, NULL, 0 },
1204/* 0xc6 */ { NULL, NULL, 0 },
1205/* 0xc7 */ { NULL, NULL, 0 },
1206/* 0xc8 */ { NULL, NULL, 0 },
1207/* 0xc9 */ { NULL, NULL, 0 },
1208/* 0xca */ { NULL, NULL, 0 },
1209/* 0xcb */ { NULL, NULL, 0 },
1210/* 0xcc */ { NULL, NULL, 0 },
1211/* 0xcd */ { NULL, NULL, 0 },
1212/* 0xce */ { NULL, NULL, 0 },
1213/* 0xcf */ { NULL, NULL, 0 },
1214/* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1215/* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1216/* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1217/* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1218/* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1219/* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1220/* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1221/* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1222/* 0xd8 */ { NULL, NULL, 0 },
1223/* 0xd9 */ { NULL, NULL, 0 },
1224/* 0xda */ { NULL, NULL, 0 },
1225/* 0xdb */ { NULL, NULL, 0 },
1226/* 0xdc */ { NULL, NULL, 0 },
1227/* 0xdd */ { NULL, NULL, 0 },
1228/* 0xde */ { NULL, NULL, 0 },
1229/* 0xdf */ { NULL, NULL, 0 },
1230/* 0xe0 */ { NULL, NULL, 0 },
1231/* 0xe1 */ { NULL, NULL, 0 },
1232/* 0xe2 */ { NULL, NULL, 0 },
1233/* 0xe3 */ { NULL, NULL, 0 },
1234/* 0xe4 */ { NULL, NULL, 0 },
1235/* 0xe5 */ { NULL, NULL, 0 },
1236/* 0xe6 */ { NULL, NULL, 0 },
1237/* 0xe7 */ { NULL, NULL, 0 },
1238/* 0xe8 */ { NULL, NULL, 0 },
1239/* 0xe9 */ { NULL, NULL, 0 },
1240/* 0xea */ { NULL, NULL, 0 },
1241/* 0xeb */ { NULL, NULL, 0 },
1242/* 0xec */ { NULL, NULL, 0 },
1243/* 0xed */ { NULL, NULL, 0 },
1244/* 0xee */ { NULL, NULL, 0 },
1245/* 0xef */ { NULL, NULL, 0 },
1246/* 0xf0 */ { NULL, NULL, 0 },
1247/* 0xf1 */ { NULL, NULL, 0 },
1248/* 0xf2 */ { NULL, NULL, 0 },
1249/* 0xf3 */ { NULL, NULL, 0 },
1250/* 0xf4 */ { NULL, NULL, 0 },
1251/* 0xf5 */ { NULL, NULL, 0 },
1252/* 0xf6 */ { NULL, NULL, 0 },
1253/* 0xf7 */ { NULL, NULL, 0 },
1254/* 0xf8 */ { NULL, NULL, 0 },
1255/* 0xf9 */ { NULL, NULL, 0 },
1256/* 0xfa */ { NULL, NULL, 0 },
1257/* 0xfb */ { NULL, NULL, 0 },
1258/* 0xfc */ { NULL, NULL, 0 },
1259/* 0xfd */ { NULL, NULL, 0 },
1260/* 0xfe */ { NULL, NULL, 0 },
1261/* 0xff */ { NULL, NULL, 0 }
918c3ebe
JA
1262
1263};
c3effa8b 1264
cc6a4101
VL
1265/*******************************************************************
1266 allocate and initialize a reply packet
1267********************************************************************/
1268
ae0c6cff
VL
1269static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1270 const char *inbuf, char **outbuf, uint8_t num_words,
1271 uint32_t num_bytes)
cc6a4101 1272{
2fb27fcb
VL
1273 /*
1274 * Protect against integer wrap
1275 */
1276 if ((num_bytes > 0xffffff)
1277 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1278 char *msg;
a4c0812a
VL
1279 if (asprintf(&msg, "num_bytes too large: %u",
1280 (unsigned)num_bytes) == -1) {
4f41be35 1281 msg = discard_const_p(char, "num_bytes too large");
a4c0812a 1282 }
2fb27fcb
VL
1283 smb_panic(msg);
1284 }
1285
3d151376 1286 *outbuf = talloc_array(mem_ctx, char,
5cd8a427
VL
1287 smb_size + num_words*2 + num_bytes);
1288 if (*outbuf == NULL) {
1289 return false;
cc6a4101
VL
1290 }
1291
ae0c6cff 1292 construct_reply_common(req, inbuf, *outbuf);
5cd8a427 1293 srv_set_message(*outbuf, num_words, num_bytes, false);
cc6a4101
VL
1294 /*
1295 * Zero out the word area, the caller has to take care of the bcc area
1296 * himself
1297 */
1298 if (num_words != 0) {
5cd8a427 1299 memset(*outbuf + smb_vwv0, 0, num_words*2);
cc6a4101
VL
1300 }
1301
5cd8a427
VL
1302 return true;
1303}
1304
1305void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1306{
1307 char *outbuf;
4f41be35 1308 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
5cd8a427
VL
1309 num_bytes)) {
1310 smb_panic("could not allocate output buffer\n");
1311 }
1312 req->outbuf = (uint8_t *)outbuf;
cc6a4101
VL
1313}
1314
1315
712a30ed 1316/*******************************************************************
a834a73e
GC
1317 Dump a packet to a file.
1318********************************************************************/
1319
c99d2455 1320static void smb_dump(const char *name, int type, const char *data)
712a30ed 1321{
c99d2455 1322 size_t len;
712a30ed 1323 int fd, i;
d068bc64
JA
1324 char *fname = NULL;
1325 if (DEBUGLEVEL < 50) {
1326 return;
1327 }
712a30ed 1328
c99d2455 1329 len = smb_len_tcp(data)+4;
712a30ed 1330 for (i=1;i<100;i++) {
86a80cf4
JA
1331 fname = talloc_asprintf(talloc_tos(),
1332 "/tmp/%s.%d.%s",
1333 name,
1334 i,
1335 type ? "req" : "resp");
1336 if (fname == NULL) {
d068bc64
JA
1337 return;
1338 }
712a30ed
LL
1339 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1340 if (fd != -1 || errno != EEXIST) break;
86a80cf4 1341 TALLOC_FREE(fname);
712a30ed
LL
1342 }
1343 if (fd != -1) {
e400bfce
JA
1344 ssize_t ret = write(fd, data, len);
1345 if (ret != len)
1346 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
712a30ed 1347 close(fd);
9c8d23e5 1348 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
712a30ed 1349 }
86a80cf4 1350 TALLOC_FREE(fname);
712a30ed
LL
1351}
1352
c3effa8b 1353/****************************************************************************
cc6a4101
VL
1354 Prepare everything for calling the actual request function, and potentially
1355 call the request function via the "new" interface.
1356
1357 Return False if the "legacy" function needs to be called, everything is
1358 prepared.
1359
1360 Return True if we're done.
1361
1362 I know this API sucks, but it is the one with the least code change I could
1363 find.
c3effa8b 1364****************************************************************************/
a834a73e 1365
07386bb5 1366static connection_struct *switch_message(uint8 type, struct smb_request *req)
c3effa8b 1367{
941db29a 1368 int flags;
02d9ba6e 1369 uint64_t session_tag;
9254bb4e 1370 connection_struct *conn = NULL;
6b8db9b2 1371 struct smbd_server_connection *sconn = req->sconn;
e7700025
SM
1372 NTTIME now = timeval_to_nttime(&req->request_time);
1373 struct smbXsrv_session *session = NULL;
1374 NTSTATUS status;
24f8e973 1375
a834a73e 1376 errno = 0;
0557c6cb 1377
48d3a1d2 1378 if (smb_messages[type].fn == NULL) {
a834a73e 1379 DEBUG(0,("Unknown message type %d!\n",type));
c99d2455 1380 smb_dump("Unknown", 1, (const char *)req->inbuf);
cc6a4101 1381 reply_unknown_new(req, type);
9254bb4e 1382 return NULL;
941db29a 1383 }
a834a73e 1384
941db29a 1385 flags = smb_messages[type].flags;
a834a73e 1386
941db29a 1387 /* In share mode security we must ignore the vuid. */
d7bb9618 1388 session_tag = req->vuid;
9254bb4e 1389 conn = req->conn;
918c3ebe 1390
8579dd4d 1391 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
c0288e06 1392 (int)getpid(), (unsigned long)conn));
941db29a 1393
c99d2455 1394 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
918c3ebe 1395
941db29a 1396 /* Ensure this value is replaced in the incoming packet. */
4f41be35 1397 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
918c3ebe 1398
941db29a
VL
1399 /*
1400 * Ensure the correct username is in current_user_info. This is a
1401 * really ugly bugfix for problems with multiple session_setup_and_X's
1402 * being done and allowing %U and %G substitutions to work correctly.
1403 * There is a reason this code is done here, don't move it unless you
8579dd4d
VL
1404 * know what you're doing... :-).
1405 * JRA.
941db29a
VL
1406 */
1407
e7700025
SM
1408 /*
1409 * lookup an existing session
1410 *
1411 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1412 * here, the main check is still in change_to_user()
1413 */
1414 status = smb1srv_session_lookup(sconn->conn,
1415 session_tag,
1416 now,
1417 &session);
1418 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1419 switch (type) {
1420 case SMBsesssetupX:
1421 status = NT_STATUS_OK;
1422 break;
1423 default:
1424 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1425 (unsigned long long)session_tag,
1426 (unsigned long long)req->mid));
1427 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1428 return conn;
1429 }
1430 }
1431
356f0336 1432 if (session_tag != sconn->smb1.sessions.last_session_tag) {
f52e5738 1433 struct user_struct *vuser = NULL;
941db29a 1434
356f0336 1435 sconn->smb1.sessions.last_session_tag = session_tag;
e7700025
SM
1436 if (session) {
1437 vuser = session->compat;
1438 }
1439 if (vuser) {
1440 set_current_user_info(
1441 vuser->session_info->unix_info->sanitized_username,
1442 vuser->session_info->unix_info->unix_name,
1443 vuser->session_info->info->domain_name);
a59149b8 1444 }
941db29a 1445 }
d57e67f9 1446
941db29a
VL
1447 /* Does this call need to be run as the connected user? */
1448 if (flags & AS_USER) {
fcda2645 1449
941db29a
VL
1450 /* Does this call need a valid tree connection? */
1451 if (!conn) {
8579dd4d
VL
1452 /*
1453 * Amazingly, the error code depends on the command
1454 * (from Samba4).
1455 */
941db29a 1456 if (type == SMBntcreateX) {
cc6a4101 1457 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
941db29a 1458 } else {
642101ac 1459 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
ce61fb21 1460 }
9254bb4e 1461 return NULL;
941db29a 1462 }
d57e67f9 1463
941db29a 1464 if (!change_to_user(conn,session_tag)) {
5e9aade5 1465 DEBUG(0, ("Error: Could not change to user. Removing "
79842437
JA
1466 "deferred open, mid=%llu.\n",
1467 (unsigned long long)req->mid));
74deee3c 1468 reply_force_doserror(req, ERRSRV, ERRbaduid);
9254bb4e 1469 return conn;
941db29a 1470 }
c3effa8b 1471
941db29a 1472 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
918c3ebe 1473
941db29a
VL
1474 /* Does it need write permission? */
1475 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
cc6a4101 1476 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
9254bb4e 1477 return conn;
ce61fb21 1478 }
918c3ebe 1479
941db29a
VL
1480 /* IPC services are limited */
1481 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
642101ac 1482 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9254bb4e 1483 return conn;
f60ad8de 1484 }
941db29a
VL
1485 } else {
1486 /* This call needs to be run as root */
1487 change_to_root_user();
1488 }
918c3ebe 1489
941db29a
VL
1490 /* load service specific parameters */
1491 if (conn) {
9254bb4e
JA
1492 if (req->encrypted) {
1493 conn->encrypted_tid = true;
1494 /* encrypted required from now on. */
e5d4e8df 1495 conn->encrypt_level = SMB_SIGNING_REQUIRED;
9254bb4e 1496 } else if (ENCRYPTION_REQUIRED(conn)) {
7808a259 1497 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
9f1dfd8f
SM
1498 DEBUG(1,("service[%s] requires encryption"
1499 "%s ACCESS_DENIED. mid=%llu\n",
1500 lp_servicename(talloc_tos(), SNUM(conn)),
1501 smb_fn_name(type),
1502 (unsigned long long)req->mid));
1503 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9254bb4e
JA
1504 return conn;
1505 }
1506 }
1507
cc6a4101 1508 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
8579dd4d
VL
1509 (flags & (AS_USER|DO_CHDIR)
1510 ?True:False))) {
642101ac 1511 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9254bb4e 1512 return conn;
afce2b24 1513 }
941db29a
VL
1514 conn->num_smb_operations++;
1515 }
918c3ebe 1516
1f62df52
VL
1517 /*
1518 * Does this protocol need to be run as guest? (Only archane
1519 * messenger service requests have this...)
1520 */
1521 if (flags & AS_GUEST) {
1522 char *raddr;
1523 bool ok;
a513086c 1524
1f62df52
VL
1525 if (!change_to_guest()) {
1526 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1527 return conn;
1528 }
1529
1530 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1531 talloc_tos());
1532 if (raddr == NULL) {
1533 reply_nterror(req, NT_STATUS_NO_MEMORY);
1534 return conn;
1535 }
1536
1537 /*
1538 * Haven't we checked this in smbd_process already???
1539 */
1540
1541 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1542 sconn->remote_hostname, raddr);
1543 TALLOC_FREE(raddr);
1544
1545 if (!ok) {
1546 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1547 return conn;
1548 }
cc6a4101
VL
1549 }
1550
48d3a1d2 1551 smb_messages[type].fn(req);
9254bb4e 1552 return req->conn;
e9ea36e4
AT
1553}
1554
e9ea36e4 1555/****************************************************************************
a834a73e 1556 Construct a reply to the incoming packet.
e9ea36e4 1557****************************************************************************/
a834a73e 1558
c2533f94
VL
1559static void construct_reply(struct smbd_server_connection *sconn,
1560 char *inbuf, int size, size_t unread_bytes,
c16c90a1 1561 uint32_t seqnum, bool encrypted,
54c51a66 1562 struct smb_perfcount_data *deferred_pcd)
e9ea36e4 1563{
9254bb4e 1564 connection_struct *conn;
cc6a4101 1565 struct smb_request *req;
e9ea36e4 1566
929e1d99 1567 if (!(req = talloc(talloc_tos(), struct smb_request))) {
cc6a4101
VL
1568 smb_panic("could not allocate smb_request");
1569 }
54c51a66 1570
c2533f94
VL
1571 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1572 encrypted, seqnum)) {
b7898148
VL
1573 exit_server_cleanly("Invalid SMB request");
1574 }
1575
b8125663 1576 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
e9ea36e4 1577
54c51a66 1578 /* we popped this message off the queue - keep original perf data */
1579 if (deferred_pcd)
1580 req->pcd = *deferred_pcd;
1581 else {
1582 SMB_PERFCOUNT_START(&req->pcd);
1583 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1584 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1585 }
1586
07386bb5 1587 conn = switch_message(req->cmd, req);
e9ea36e4 1588
b578db69
VL
1589 if (req->outbuf == NULL) {
1590 return;
cc6a4101 1591 }
e9ea36e4 1592
b578db69
VL
1593 if (CVAL(req->outbuf,0) == 0) {
1594 show_msg((char *)req->outbuf);
1595 }
e9ea36e4 1596
1808dd0a 1597 if (!srv_send_smb(req->sconn,
9254bb4e 1598 (char *)req->outbuf,
c16c90a1 1599 true, req->seqnum+1,
54c51a66 1600 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1601 &req->pcd)) {
9254bb4e 1602 exit_server_cleanly("construct_reply: srv_send_smb failed.");
dc90cd89 1603 }
cc6a4101
VL
1604
1605 TALLOC_FREE(req);
1606
1607 return;
e9ea36e4
AT
1608}
1609
3b2c9beb
VL
1610static void construct_reply_chain(struct smbd_server_connection *sconn,
1611 char *inbuf, int size, uint32_t seqnum,
1612 bool encrypted,
1613 struct smb_perfcount_data *deferred_pcd)
1614{
3b2c9beb 1615 struct smb_request **reqs = NULL;
8f93068c
VL
1616 struct smb_request *req;
1617 unsigned num_reqs;
3b2c9beb
VL
1618 bool ok;
1619
1620 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1621 seqnum, &reqs, &num_reqs);
1622 if (!ok) {
8f93068c
VL
1623 char errbuf[smb_size];
1624 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1625 __LINE__, __FILE__);
1626 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1627 NULL)) {
1628 exit_server_cleanly("construct_reply_chain: "
1629 "srv_send_smb failed.");
1630 }
1631 return;
3b2c9beb
VL
1632 }
1633
8f93068c
VL
1634 req = reqs[0];
1635 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
3b2c9beb 1636
8f93068c 1637 req->conn = switch_message(req->cmd, req);
3b2c9beb 1638
8f93068c
VL
1639 if (req->outbuf == NULL) {
1640 /*
1641 * Request has suspended itself, will come
1642 * back here.
1643 */
1644 return;
1645 }
1646 smb_request_done(req);
1647}
3b2c9beb 1648
8f93068c
VL
1649/*
1650 * To be called from an async SMB handler that is potentially chained
1651 * when it is finished for shipping.
1652 */
1653
1654void smb_request_done(struct smb_request *req)
1655{
1656 struct smb_request **reqs = NULL;
1657 struct smb_request *first_req;
1658 size_t i, num_reqs, next_index;
1659 NTSTATUS status;
1660
1661 if (req->chain == NULL) {
1662 first_req = req;
1663 goto shipit;
3b2c9beb
VL
1664 }
1665
8f93068c
VL
1666 reqs = req->chain;
1667 num_reqs = talloc_array_length(reqs);
3b2c9beb 1668
8f93068c
VL
1669 for (i=0; i<num_reqs; i++) {
1670 if (reqs[i] == req) {
1671 break;
1672 }
1673 }
1674 if (i == num_reqs) {
3b2c9beb 1675 /*
8f93068c 1676 * Invalid chain, should not happen
3b2c9beb 1677 */
8f93068c
VL
1678 status = NT_STATUS_INTERNAL_ERROR;
1679 goto error;
1680 }
1681 next_index = i+1;
1682
1683 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1684 struct smb_request *next = reqs[next_index];
faa8edcc
SM
1685 struct smbXsrv_tcon *tcon;
1686 NTTIME now = timeval_to_nttime(&req->request_time);
8f93068c
VL
1687
1688 next->vuid = SVAL(req->outbuf, smb_uid);
1689 next->tid = SVAL(req->outbuf, smb_tid);
faa8edcc
SM
1690 status = smb1srv_tcon_lookup(req->sconn->conn, req->tid,
1691 now, &tcon);
1692 if (NT_STATUS_IS_OK(status)) {
1693 req->conn = tcon->compat;
1694 } else {
1695 req->conn = NULL;
1696 }
8f93068c
VL
1697 next->chain_fsp = req->chain_fsp;
1698 next->inbuf = (uint8_t *)req->inbuf;
1699
1700 req = next;
1701 req->conn = switch_message(req->cmd, req);
1702
1703 if (req->outbuf == NULL) {
1704 /*
1705 * Request has suspended itself, will come
1706 * back here.
1707 */
1708 return;
1709 }
1710 next_index += 1;
3b2c9beb
VL
1711 }
1712
8f93068c
VL
1713 first_req = reqs[0];
1714
3b2c9beb 1715 for (i=1; i<next_index; i++) {
8f93068c 1716 bool ok;
3b2c9beb 1717
8f93068c 1718 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
3b2c9beb
VL
1719 if (!ok) {
1720 status = NT_STATUS_INTERNAL_ERROR;
1721 goto error;
1722 }
3b2c9beb
VL
1723 }
1724
8f93068c
VL
1725 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1726 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
3b2c9beb
VL
1727
1728 /*
1729 * This scary statement intends to set the
1730 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1731 * to the value last_req->outbuf carries
1732 */
1733 SSVAL(first_req->outbuf, smb_flg2,
1734 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
8f93068c 1735 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
3b2c9beb
VL
1736
1737 /*
1738 * Transfer the error codes from the subrequest to the main one
1739 */
8f93068c
VL
1740 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1741 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
3b2c9beb 1742
8f93068c
VL
1743 _smb_setlen_large(
1744 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
3b2c9beb
VL
1745
1746shipit:
3b2c9beb
VL
1747 if (!srv_send_smb(first_req->sconn,
1748 (char *)first_req->outbuf,
1749 true, first_req->seqnum+1,
8f93068c 1750 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
3b2c9beb
VL
1751 &first_req->pcd)) {
1752 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1753 "failed.");
1754 }
8f93068c
VL
1755 TALLOC_FREE(req); /* non-chained case */
1756 TALLOC_FREE(reqs); /* chained case */
3b2c9beb
VL
1757 return;
1758
1759error:
1760 {
1761 char errbuf[smb_size];
1762 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
8f93068c
VL
1763 if (!srv_send_smb(req->sconn, errbuf, true,
1764 req->seqnum+1, req->encrypted,
3b2c9beb
VL
1765 NULL)) {
1766 exit_server_cleanly("construct_reply_chain: "
1767 "srv_send_smb failed.");
1768 }
1769 }
8f93068c
VL
1770 TALLOC_FREE(req); /* non-chained case */
1771 TALLOC_FREE(reqs); /* chained case */
3b2c9beb
VL
1772}
1773
e9ea36e4 1774/****************************************************************************
49ecd176 1775 Process an smb from the client
e9ea36e4 1776****************************************************************************/
81bdb591 1777static void process_smb(struct smbd_server_connection *sconn,
aeb798c3 1778 uint8_t *inbuf, size_t nread, size_t unread_bytes,
c16c90a1
SM
1779 uint32_t seqnum, bool encrypted,
1780 struct smb_perfcount_data *deferred_pcd)
e9ea36e4 1781{
1eff0523 1782 int msg_type = CVAL(inbuf,0);
1eff0523
JA
1783
1784 DO_PROFILE_INC(smb_count);
1785
cc6a4101
VL
1786 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1787 smb_len(inbuf) ) );
2d81721a 1788 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
81bdb591 1789 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1eff0523 1790
0633c0f6 1791 if (msg_type != NBSSmessage) {
cc6a4101
VL
1792 /*
1793 * NetBIOS session request, keepalive, etc.
1794 */
81bdb591 1795 reply_special(sconn, (char *)inbuf, nread);
aeb798c3 1796 goto done;
cc6a4101 1797 }
1eff0523 1798
81bdb591 1799 if (sconn->using_smb2) {
d28fa8fa
JA
1800 /* At this point we're not really using smb2,
1801 * we make the decision here.. */
688945a9 1802 if (smbd_is_smb2_header(inbuf, nread)) {
cac60a70 1803 smbd_smb2_first_negprot(sconn, inbuf, nread);
688945a9 1804 return;
b4b9918c 1805 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
c9a3661c
JA
1806 && CVAL(inbuf, smb_com) != 0x72) {
1807 /* This is a non-negprot SMB1 packet.
1808 Disable SMB2 from now on. */
cac60a70 1809 sconn->using_smb2 = false;
688945a9 1810 }
688945a9
SM
1811 }
1812
fed2fba0
VL
1813 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1814 * so subtract 4 from it. */
1815 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1816 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1817 smb_len(inbuf)));
1818
1819 /* special magic for immediate exit */
1820 if ((nread == 9) &&
1821 (IVAL(inbuf, 4) == 0x74697865) &&
1822 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1823 uint8_t exitcode = CVAL(inbuf, 8);
1824 DEBUG(1, ("Exiting immediately with code %d\n",
1825 (int)exitcode));
1826 exit(exitcode);
1827 }
1828
1829 exit_server_cleanly("Non-SMB packet");
1830 }
1831
aeb798c3 1832 show_msg((char *)inbuf);
cc6a4101 1833
3b2c9beb
VL
1834 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1835 construct_reply_chain(sconn, (char *)inbuf, nread,
1836 seqnum, encrypted, deferred_pcd);
1837 } else {
1838 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1839 seqnum, encrypted, deferred_pcd);
1840 }
1841
81bdb591 1842 sconn->trans_num++;
aeb798c3
SM
1843
1844done:
8dc70295 1845 sconn->num_requests++;
aeb798c3
SM
1846
1847 /* The timeout_processing function isn't run nearly
1848 often enough to implement 'max log size' without
1849 overrunning the size of the file by many megabytes.
1850 This is especially true if we are running at debug
1851 level 10. Checking every 50 SMBs is a nice
1852 tradeoff of performance vs log file size overrun. */
1853
8dc70295 1854 if ((sconn->num_requests % 50) == 0 &&
aeb798c3
SM
1855 need_to_check_log_size()) {
1856 change_to_root_user();
1857 check_log_size();
1858 }
e9ea36e4
AT
1859}
1860
e9ea36e4 1861/****************************************************************************
1eff0523 1862 Return a string containing the function name of a SMB command.
e9ea36e4 1863****************************************************************************/
1eff0523 1864
127e77e6 1865const char *smb_fn_name(int type)
e9ea36e4 1866{
634c5431 1867 const char *unknown_name = "SMBunknown";
e9ea36e4 1868
918c3ebe 1869 if (smb_messages[type].name == NULL)
e9ea36e4
AT
1870 return(unknown_name);
1871
918c3ebe 1872 return(smb_messages[type].name);
c3effa8b
AT
1873}
1874
dc76502c 1875/****************************************************************************
6bb8f54e 1876 Helper functions for contruct_reply.
dc76502c
JA
1877****************************************************************************/
1878
6219c997
JA
1879void add_to_common_flags2(uint32 v)
1880{
1881 common_flags2 |= v;
1882}
6bb8f54e 1883
27891bde 1884void remove_from_common_flags2(uint32 v)
6bb8f54e 1885{
27891bde 1886 common_flags2 &= ~v;
6bb8f54e
JA
1887}
1888
ae0c6cff
VL
1889static void construct_reply_common(struct smb_request *req, const char *inbuf,
1890 char *outbuf)
dc76502c 1891{
f205e4ca
SM
1892 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1893 uint16_t out_flags2 = common_flags2;
1894
1895 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1896 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1897 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1898
9254bb4e 1899 srv_set_message(outbuf,0,0,false);
8905b599 1900
ae0c6cff 1901 SCVAL(outbuf, smb_com, req->cmd);
fc13f284 1902 SIVAL(outbuf,smb_rcls,0);
b7280423 1903 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
f205e4ca 1904 SSVAL(outbuf,smb_flg2, out_flags2);
fc13f284 1905 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
f205e4ca 1906 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
b7280423 1907
b7280423
AT
1908 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1909 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1910 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1911 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
dc76502c 1912}
c3effa8b 1913
e4897a53
VL
1914void construct_reply_common_req(struct smb_request *req, char *outbuf)
1915{
4f41be35 1916 construct_reply_common(req, (const char *)req->inbuf, outbuf);
e4897a53
VL
1917}
1918
b6f446ca
VL
1919/**
1920 * @brief Find the smb_cmd offset of the last command pushed
1921 * @param[in] buf The buffer we're building up
1922 * @retval Where can we put our next andx cmd?
1923 *
1924 * While chaining requests, the "next" request we're looking at needs to put
1925 * its SMB_Command before the data the previous request already built up added
1926 * to the chain. Find the offset to the place where we have to put our cmd.
1927 */
1928
1929static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1930{
1931 uint8_t cmd;
1932 size_t ofs;
1933
1934 cmd = CVAL(buf, smb_com);
1935
947a8bc4
VL
1936 if (!is_andx_req(cmd)) {
1937 return false;
1938 }
b6f446ca
VL
1939
1940 ofs = smb_vwv0;
1941
1942 while (CVAL(buf, ofs) != 0xff) {
1943
1944 if (!is_andx_req(CVAL(buf, ofs))) {
1945 return false;
1946 }
1947
1948 /*
1949 * ofs is from start of smb header, so add the 4 length
1950 * bytes. The next cmd is right after the wct field.
1951 */
1952 ofs = SVAL(buf, ofs+2) + 4 + 1;
1953
947a8bc4
VL
1954 if (ofs+4 >= talloc_get_size(buf)) {
1955 return false;
1956 }
b6f446ca
VL
1957 }
1958
1959 *pofs = ofs;
1960 return true;
1961}
1962
1963/**
1964 * @brief Do the smb chaining at a buffer level
1965 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
da322e4f 1966 * @param[in] andx_buf Buffer to be appended
b6f446ca
VL
1967 */
1968
da322e4f 1969static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
b6f446ca 1970{
da322e4f
VL
1971 uint8_t smb_command = CVAL(andx_buf, smb_com);
1972 uint8_t wct = CVAL(andx_buf, smb_wct);
1973 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
da322e4f 1974 uint32_t num_bytes = smb_buflen(andx_buf);
adac8858 1975 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
da322e4f 1976
b6f446ca
VL
1977 uint8_t *outbuf;
1978 size_t old_size, new_size;
1979 size_t ofs;
1980 size_t chain_padding = 0;
61953ab3
VL
1981 size_t andx_cmd_ofs;
1982
b6f446ca
VL
1983
1984 old_size = talloc_get_size(*poutbuf);
1985
b07ae1ab 1986 if ((old_size % 4) != 0) {
b6f446ca
VL
1987 /*
1988 * Align the wct field of subsequent requests to a 4-byte
1989 * boundary
1990 */
1991 chain_padding = 4 - (old_size % 4);
1992 }
1993
1994 /*
1995 * After the old request comes the new wct field (1 byte), the vwv's
5b7609db 1996 * and the num_bytes field.
b6f446ca
VL
1997 */
1998
1999 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
4708b97c 2000 new_size += num_bytes;
b6f446ca
VL
2001
2002 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
28901acd 2003 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
b6f446ca
VL
2004 (unsigned)new_size));
2005 return false;
2006 }
2007
73b37743 2008 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
b6f446ca
VL
2009 if (outbuf == NULL) {
2010 DEBUG(0, ("talloc failed\n"));
2011 return false;
2012 }
2013 *poutbuf = outbuf;
2014
61953ab3
VL
2015 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2016 DEBUG(1, ("invalid command chain\n"));
2017 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2018 return false;
2019 }
b6f446ca 2020
61953ab3
VL
2021 if (chain_padding != 0) {
2022 memset(outbuf + old_size, 0, chain_padding);
2023 old_size += chain_padding;
b6f446ca
VL
2024 }
2025
61953ab3
VL
2026 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2027 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2028
b6f446ca
VL
2029 ofs = old_size;
2030
2031 /*
2032 * Push the chained request:
2033 *
2034 * wct field
2035 */
2036
2037 SCVAL(outbuf, ofs, wct);
2038 ofs += 1;
2039
2040 /*
2041 * vwv array
2042 */
2043
2044 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
12068d4a
VL
2045
2046 /*
2047 * HACK ALERT
2048 *
2049 * Read&X has an offset into its data buffer at
2050 * vwv[6]. reply_read_andx has no idea anymore that it's
2051 * running from within a chain, so we have to fix up the
2052 * offset here.
2053 *
2054 * Although it looks disgusting at this place, I want to keep
2055 * it here. The alternative would be to push knowledge about
2056 * the andx chain down into read&x again.
2057 */
2058
2059 if (smb_command == SMBreadX) {
2060 uint8_t *bytes_addr;
2061
2062 if (wct < 7) {
2063 /*
2064 * Invalid read&x response
2065 */
2066 return false;
2067 }
2068
2069 bytes_addr = outbuf + ofs /* vwv start */
2070 + sizeof(uint16_t) * wct /* vwv array */
2071 + sizeof(uint16_t); /* bcc */
2072
2073 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2074 bytes_addr - outbuf - 4);
2075 }
2076
b6f446ca
VL
2077 ofs += sizeof(uint16_t) * wct;
2078
2079 /*
2080 * bcc (byte count)
2081 */
2082
4708b97c 2083 SSVAL(outbuf, ofs, num_bytes);
b6f446ca
VL
2084 ofs += sizeof(uint16_t);
2085
b6f446ca
VL
2086 /*
2087 * The bytes field
2088 */
2089
2090 memcpy(outbuf + ofs, bytes, num_bytes);
2091
2092 return true;
2093}
2094
c9870a62
VL
2095bool smb1_is_chain(const uint8_t *buf)
2096{
2097 uint8_t cmd, wct, andx_cmd;
2098
2099 cmd = CVAL(buf, smb_com);
2100 if (!is_andx_req(cmd)) {
2101 return false;
2102 }
2103 wct = CVAL(buf, smb_wct);
2104 if (wct < 2) {
2105 return false;
2106 }
2107 andx_cmd = CVAL(buf, smb_vwv);
2108 return (andx_cmd != 0xFF);
2109}
2110
2111bool smb1_walk_chain(const uint8_t *buf,
2112 bool (*fn)(uint8_t cmd,
2113 uint8_t wct, const uint16_t *vwv,
2114 uint16_t num_bytes, const uint8_t *bytes,
2115 void *private_data),
2116 void *private_data)
2117{
2118 size_t smblen = smb_len(buf);
2119 const char *smb_buf = smb_base(buf);
2120 uint8_t cmd, chain_cmd;
2121 uint8_t wct;
2122 const uint16_t *vwv;
2123 uint16_t num_bytes;
2124 const uint8_t *bytes;
2125
2126 cmd = CVAL(buf, smb_com);
2127 wct = CVAL(buf, smb_wct);
2128 vwv = (const uint16_t *)(buf + smb_vwv);
2129 num_bytes = smb_buflen(buf);
2130 bytes = (uint8_t *)smb_buf_const(buf);
2131
2132 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2133 return false;
2134 }
2135
2136 if (!is_andx_req(cmd)) {
2137 return true;
2138 }
2139 if (wct < 2) {
2140 return false;
2141 }
2142
2143 chain_cmd = CVAL(vwv, 0);
2144
2145 while (chain_cmd != 0xff) {
2146 uint32_t chain_offset; /* uint32_t to avoid overflow */
2147 size_t length_needed;
2148 ptrdiff_t vwv_offset;
2149
2150 chain_offset = SVAL(vwv+1, 0);
2151
2152 /*
2153 * Check if the client tries to fool us. The chain
2154 * offset needs to point beyond the current request in
2155 * the chain, it needs to strictly grow. Otherwise we
2156 * might be tricked into an endless loop always
2157 * processing the same request over and over again. We
2158 * used to assume that vwv and the byte buffer array
2159 * in a chain are always attached, but OS/2 the
2160 * Write&X/Read&X chain puts the Read&X vwv array
2161 * right behind the Write&X vwv chain. The Write&X bcc
2162 * array is put behind the Read&X vwv array. So now we
2163 * check whether the chain offset points strictly
2164 * behind the previous vwv array. req->buf points
2165 * right after the vwv array of the previous
2166 * request. See
2167 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2168 * more information.
2169 */
2170
2171 vwv_offset = ((const char *)vwv - smb_buf);
2172 if (chain_offset <= vwv_offset) {
2173 return false;
2174 }
2175
2176 /*
2177 * Next check: Make sure the chain offset does not
2178 * point beyond the overall smb request length.
2179 */
2180
2181 length_needed = chain_offset+1; /* wct */
2182 if (length_needed > smblen) {
2183 return false;
2184 }
2185
2186 /*
2187 * Now comes the pointer magic. Goal here is to set up
2188 * vwv and buf correctly again. The chain offset (the
2189 * former vwv[1]) points at the new wct field.
2190 */
2191
2192 wct = CVAL(smb_buf, chain_offset);
2193
2194 if (is_andx_req(chain_cmd) && (wct < 2)) {
2195 return false;
2196 }
2197
2198 /*
2199 * Next consistency check: Make the new vwv array fits
2200 * in the overall smb request.
2201 */
2202
2203 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2204 if (length_needed > smblen) {
2205 return false;
2206 }
2207 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2208
2209 /*
2210 * Now grab the new byte buffer....
2211 */
2212
2213 num_bytes = SVAL(vwv+wct, 0);
2214
2215 /*
2216 * .. and check that it fits.
2217 */
2218
2219 length_needed += num_bytes;
2220 if (length_needed > smblen) {
2221 return false;
2222 }
2223 bytes = (const uint8_t *)(vwv+wct+1);
2224
2225 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2226 return false;
2227 }
2228
2229 if (!is_andx_req(chain_cmd)) {
2230 return true;
2231 }
2232 chain_cmd = CVAL(vwv, 0);
2233 }
2234 return true;
2235}
2236
2237static bool smb1_chain_length_cb(uint8_t cmd,
2238 uint8_t wct, const uint16_t *vwv,
2239 uint16_t num_bytes, const uint8_t *bytes,
2240 void *private_data)
2241{
2242 unsigned *count = (unsigned *)private_data;
2243 *count += 1;
2244 return true;
2245}
2246
2247unsigned smb1_chain_length(const uint8_t *buf)
2248{
2249 unsigned count = 0;
2250
2251 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2252 return 0;
2253 }
2254 return count;
2255}
2256
2257struct smb1_parse_chain_state {
2258 TALLOC_CTX *mem_ctx;
2259 const uint8_t *buf;
2260 struct smbd_server_connection *sconn;
2261 bool encrypted;
2262 uint32_t seqnum;
2263
2264 struct smb_request **reqs;
2265 unsigned num_reqs;
2266};
2267
2268static bool smb1_parse_chain_cb(uint8_t cmd,
2269 uint8_t wct, const uint16_t *vwv,
2270 uint16_t num_bytes, const uint8_t *bytes,
2271 void *private_data)
2272{
2273 struct smb1_parse_chain_state *state =
2274 (struct smb1_parse_chain_state *)private_data;
2275 struct smb_request **reqs;
2276 struct smb_request *req;
2277 bool ok;
2278
2279 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2280 struct smb_request *, state->num_reqs+1);
2281 if (reqs == NULL) {
2282 return false;
2283 }
2284 state->reqs = reqs;
2285
2286 req = talloc(reqs, struct smb_request);
2287 if (req == NULL) {
2288 return false;
2289 }
2290
2291 ok = init_smb_request(req, state->sconn, state->buf, 0,
2292 state->encrypted, state->seqnum);
2293 if (!ok) {
2294 return false;
2295 }
2296 req->cmd = cmd;
2297 req->wct = wct;
2298 req->vwv = vwv;
2299 req->buflen = num_bytes;
2300 req->buf = bytes;
2301
2302 reqs[state->num_reqs] = req;
2303 state->num_reqs += 1;
2304 return true;
2305}
2306
2307bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2308 struct smbd_server_connection *sconn,
2309 bool encrypted, uint32_t seqnum,
2310 struct smb_request ***reqs, unsigned *num_reqs)
2311{
2312 struct smb1_parse_chain_state state;
8f93068c 2313 unsigned i;
c9870a62
VL
2314
2315 state.mem_ctx = mem_ctx;
2316 state.buf = buf;
2317 state.sconn = sconn;
2318 state.encrypted = encrypted;
2319 state.seqnum = seqnum;
2320 state.reqs = NULL;
2321 state.num_reqs = 0;
2322
2323 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2324 TALLOC_FREE(state.reqs);
2325 return false;
2326 }
8f93068c
VL
2327 for (i=0; i<state.num_reqs; i++) {
2328 state.reqs[i]->chain = state.reqs;
2329 }
c9870a62
VL
2330 *reqs = state.reqs;
2331 *num_reqs = state.num_reqs;
2332 return true;
2333}
2334
3db52feb
AT
2335/****************************************************************************
2336 Check if services need reloading.
2337****************************************************************************/
2338
70df6fcb 2339static void check_reload(struct smbd_server_connection *sconn, time_t t)
3db52feb 2340{
3db52feb 2341
0b188e77 2342 if (last_smb_conf_reload_time == 0) {
1eff0523 2343 last_smb_conf_reload_time = t;
7ebd74e6
SS
2344 }
2345
ac61f650 2346 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
03455519 2347 reload_services(sconn, conn_snum_used, true);
1eff0523
JA
2348 last_smb_conf_reload_time = t;
2349 }
3db52feb 2350}
c3effa8b 2351
cad0c004
VL
2352static bool fd_is_readable(int fd)
2353{
0f082de5 2354 int ret, revents;
cad0c004 2355
0f082de5
VL
2356 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2357
2358 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
cad0c004 2359
cad0c004
VL
2360}
2361
fc79169c
VL
2362static void smbd_server_connection_write_handler(
2363 struct smbd_server_connection *sconn)
aeb798c3
SM
2364{
2365 /* TODO: make write nonblocking */
2366}
2367
cad0c004 2368static void smbd_server_connection_read_handler(
fc79169c 2369 struct smbd_server_connection *sconn, int fd)
aeb798c3
SM
2370{
2371 uint8_t *inbuf = NULL;
2372 size_t inbuf_len = 0;
2373 size_t unread_bytes = 0;
2374 bool encrypted = false;
2375 TALLOC_CTX *mem_ctx = talloc_tos();
2376 NTSTATUS status;
c16c90a1 2377 uint32_t seqnum;
aeb798c3 2378
5e0258fc
VL
2379 bool from_client;
2380
2381 if (lp_async_smb_echo_handler()
2382 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2383 /*
2384 * This is the super-ugly hack to prefer the packets
2385 * forwarded by the echo handler over the ones by the
2386 * client directly
2387 */
2388 fd = sconn->smb1.echo_handler.trusted_fd;
2389 }
2390
2391 from_client = (sconn->sock == fd);
977aa660 2392
cad0c004 2393 if (from_client) {
fc79169c 2394 smbd_lock_socket(sconn);
cad0c004 2395
5e0258fc
VL
2396 if (!fd_is_readable(fd)) {
2397 DEBUG(10,("the echo listener was faster\n"));
2398 smbd_unlock_socket(sconn);
2399 return;
cad0c004 2400 }
5e0258fc
VL
2401 }
2402
2403 /* TODO: make this completely nonblocking */
2404 status = receive_smb_talloc(mem_ctx, sconn, fd,
2405 (char **)(void *)&inbuf,
2406 0, /* timeout */
2407 &unread_bytes,
2408 &encrypted,
2409 &inbuf_len, &seqnum,
2410 false /* trusted channel */);
cad0c004 2411
5e0258fc 2412 if (from_client) {
fc79169c 2413 smbd_unlock_socket(sconn);
977aa660
SM
2414 }
2415
aeb798c3
SM
2416 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2417 goto process;
2418 }
2419 if (NT_STATUS_IS_ERR(status)) {
2420 exit_server_cleanly("failed to receive smb request");
2421 }
2422 if (!NT_STATUS_IS_OK(status)) {
2423 return;
2424 }
2425
2426process:
fc79169c 2427 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
c16c90a1 2428 seqnum, encrypted, NULL);
aeb798c3
SM
2429}
2430
415e8e05 2431static void smbd_server_connection_handler(struct tevent_context *ev,
aeb798c3
SM
2432 struct fd_event *fde,
2433 uint16_t flags,
2434 void *private_data)
2435{
2436 struct smbd_server_connection *conn = talloc_get_type(private_data,
2437 struct smbd_server_connection);
2438
2439 if (flags & EVENT_FD_WRITE) {
2440 smbd_server_connection_write_handler(conn);
c7a2e52e
VL
2441 return;
2442 }
2443 if (flags & EVENT_FD_READ) {
a2bf46e9 2444 smbd_server_connection_read_handler(conn, conn->sock);
c7a2e52e 2445 return;
aeb798c3
SM
2446 }
2447}
2448
415e8e05 2449static void smbd_server_echo_handler(struct tevent_context *ev,
cad0c004
VL
2450 struct fd_event *fde,
2451 uint16_t flags,
2452 void *private_data)
2453{
2454 struct smbd_server_connection *conn = talloc_get_type(private_data,
2455 struct smbd_server_connection);
2456
2457 if (flags & EVENT_FD_WRITE) {
2458 smbd_server_connection_write_handler(conn);
c672797a
VL
2459 return;
2460 }
2461 if (flags & EVENT_FD_READ) {
cad0c004
VL
2462 smbd_server_connection_read_handler(
2463 conn, conn->smb1.echo_handler.trusted_fd);
c672797a 2464 return;
cad0c004
VL
2465 }
2466}
27f812f3 2467
06fb2585 2468#ifdef CLUSTER_SUPPORT
35c0f164
SM
2469
2470struct smbd_release_ip_state {
2471 struct smbd_server_connection *sconn;
2472 char addr[INET6_ADDRSTRLEN];
2473};
2474
27f812f3
SM
2475/****************************************************************************
2476received when we should release a specific IP
2477****************************************************************************/
2478static void release_ip(const char *ip, void *priv)
2479{
35c0f164
SM
2480 struct smbd_release_ip_state *state =
2481 talloc_get_type_abort(priv,
2482 struct smbd_release_ip_state);
2483 const char *addr = state->addr;
467208e9 2484 const char *p = addr;
e86a534f
MA
2485
2486 if (strncmp("::ffff:", addr, 7) == 0) {
2487 p = addr + 7;
2488 }
2489
642c6ba2
CA
2490 DEBUG(10, ("Got release IP message for %s, "
2491 "our address is %s\n", ip, p));
2492
7d6e4c7e 2493 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
27f812f3
SM
2494 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2495 ip));
35c0f164
SM
2496 /*
2497 * With SMB2 we should do a clean disconnect,
2498 * the previous_session_id in the session setup
2499 * will cleanup the old session, tcons and opens.
2500 *
2501 * A clean disconnect is needed in order to support
2502 * durable handles.
2503 *
2504 * Note: typically this is never triggered
2505 * as we got a TCP RST (triggered by ctdb event scripts)
2506 * before we get CTDB_SRVID_RELEASE_IP.
2507 *
2508 * We used to call _exit(1) here, but as this was mostly never
2509 * triggered and has implication on our process model,
2510 * we can just use smbd_server_connection_terminate()
2511 * (also for SMB1).
2512 */
2513 smbd_server_connection_terminate(state->sconn,
2514 "CTDB_SRVID_RELEASE_IP");
2515 return;
27f812f3
SM
2516 }
2517}
2518
13de233f
SM
2519static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2520 struct sockaddr_storage *srv,
2521 struct sockaddr_storage *clnt)
2522{
35c0f164 2523 struct smbd_release_ip_state *state;
13de233f 2524 struct ctdbd_connection *cconn;
13de233f
SM
2525
2526 cconn = messaging_ctdbd_connection();
2527 if (cconn == NULL) {
2528 return NT_STATUS_NO_MEMORY;
2529 }
2530
35c0f164
SM
2531 state = talloc_zero(sconn, struct smbd_release_ip_state);
2532 if (state == NULL) {
13de233f
SM
2533 return NT_STATUS_NO_MEMORY;
2534 }
35c0f164
SM
2535 state->sconn = sconn;
2536 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
13de233f
SM
2537 return NT_STATUS_NO_MEMORY;
2538 }
35c0f164
SM
2539
2540 return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
13de233f
SM
2541}
2542
f83e7d8f 2543static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
27f812f3
SM
2544 struct sockaddr_storage *client)
2545{
2546 socklen_t length;
27f812f3 2547 length = sizeof(*server);
f83e7d8f 2548 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
27f812f3
SM
2549 return -1;
2550 }
2551 length = sizeof(*client);
f83e7d8f 2552 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
27f812f3
SM
2553 return -1;
2554 }
2555 return 0;
2556}
2557#endif
2558
2559/*
2560 * Send keepalive packets to our client
2561 */
2562static bool keepalive_fn(const struct timeval *now, void *private_data)
2563{
d911bd5c
VL
2564 struct smbd_server_connection *sconn = talloc_get_type_abort(
2565 private_data, struct smbd_server_connection);
c1653e3b
SM
2566 bool ret;
2567
d28fa8fa 2568 if (sconn->using_smb2) {
efd0c35a
JA
2569 /* Don't do keepalives on an SMB2 connection. */
2570 return false;
2571 }
2572
bf35606b 2573 smbd_lock_socket(sconn);
bb867df2 2574 ret = send_keepalive(sconn->sock);
bf35606b 2575 smbd_unlock_socket(sconn);
c1653e3b
SM
2576
2577 if (!ret) {
40ae8b74
VL
2578 char addr[INET6_ADDRSTRLEN];
2579 /*
2580 * Try and give an error message saying what
2581 * client failed.
2582 */
2583 DEBUG(0, ("send_keepalive failed for client %s. "
2584 "Error %s - exiting\n",
2585 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2586 strerror(errno)));
27f812f3
SM
2587 return False;
2588 }
2589 return True;
2590}
2591
2592/*
2593 * Do the recurring check if we're idle
2594 */
2595static bool deadtime_fn(const struct timeval *now, void *private_data)
2596{
72fd7fb4
VL
2597 struct smbd_server_connection *sconn =
2598 (struct smbd_server_connection *)private_data;
6f30b9a6 2599
c8620180
SM
2600 if ((conn_num_open(sconn) == 0)
2601 || (conn_idle_all(sconn, now->tv_sec))) {
e7d0f478 2602 DEBUG( 2, ( "Closing idle connection\n" ) );
790ad3d1
VL
2603 messaging_send(sconn->msg_ctx,
2604 messaging_server_id(sconn->msg_ctx),
27f812f3
SM
2605 MSG_SHUTDOWN, &data_blob_null);
2606 return False;
2607 }
2608
2609 return True;
2610}
2611
2612/*
2613 * Do the recurring log file and smb.conf reload checks.
2614 */
2615
2616static bool housekeeping_fn(const struct timeval *now, void *private_data)
2617{
babfe237
VL
2618 struct smbd_server_connection *sconn = talloc_get_type_abort(
2619 private_data, struct smbd_server_connection);
0b188e77
DD
2620
2621 DEBUG(5, ("housekeeping\n"));
2622
27f812f3
SM
2623 change_to_root_user();
2624
2625 /* update printer queue caches if necessary */
babfe237 2626 update_monitored_printq_cache(sconn->msg_ctx);
27f812f3
SM
2627
2628 /* check if we need to reload services */
0b188e77 2629 check_reload(sconn, time_mono(NULL));
27f812f3 2630
27f812f3
SM
2631 /*
2632 * Force a log file check.
2633 */
2634 force_check_log_size();
2635 check_log_size();
2636 return true;
2637}
2638
27afb891
VL
2639/*
2640 * Read an smb packet in the echo handler child, giving the parent
2641 * smbd one second to react once the socket becomes readable.
2642 */
2643
2644struct smbd_echo_read_state {
2645 struct tevent_context *ev;
2646 struct smbd_server_connection *sconn;
2647
2648 char *buf;
2649 size_t buflen;
2650 uint32_t seqnum;
2651};
2652
2653static void smbd_echo_read_readable(struct tevent_req *subreq);
2654static void smbd_echo_read_waited(struct tevent_req *subreq);
2655
2656static struct tevent_req *smbd_echo_read_send(
2657 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2658 struct smbd_server_connection *sconn)
2659{
2660 struct tevent_req *req, *subreq;
2661 struct smbd_echo_read_state *state;
2662
2663 req = tevent_req_create(mem_ctx, &state,
2664 struct smbd_echo_read_state);
2665 if (req == NULL) {
2666 return NULL;
2667 }
2668 state->ev = ev;
2669 state->sconn = sconn;
2670
2671 subreq = wait_for_read_send(state, ev, sconn->sock);
2672 if (tevent_req_nomem(subreq, req)) {
2673 return tevent_req_post(req, ev);
2674 }
2675 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2676 return req;
2677}
2678
2679static void smbd_echo_read_readable(struct tevent_req *subreq)
2680{
2681 struct tevent_req *req = tevent_req_callback_data(
2682 subreq, struct tevent_req);
2683 struct smbd_echo_read_state *state = tevent_req_data(
2684 req, struct smbd_echo_read_state);
2685 bool ok;
2686 int err;
2687
2688 ok = wait_for_read_recv(subreq, &err);
2689 TALLOC_FREE(subreq);
2690 if (!ok) {
2691 tevent_req_nterror(req, map_nt_error_from_unix(err));
2692 return;
2693 }
2694
2695 /*
2696 * Give the parent smbd one second to step in
2697 */
2698
2699 subreq = tevent_wakeup_send(
2700 state, state->ev, timeval_current_ofs(1, 0));
2701 if (tevent_req_nomem(subreq, req)) {
2702 return;
2703 }
2704 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2705}
2706
2707static void smbd_echo_read_waited(struct tevent_req *subreq)
2708{
2709 struct tevent_req *req = tevent_req_callback_data(
2710 subreq, struct tevent_req);
2711 struct smbd_echo_read_state *state = tevent_req_data(
2712 req, struct smbd_echo_read_state);
2713 struct smbd_server_connection *sconn = state->sconn;
2714 bool ok;
2715 NTSTATUS status;
2716 size_t unread = 0;
2717 bool encrypted;
2718
2719 ok = tevent_wakeup_recv(subreq);
2720 TALLOC_FREE(subreq);
2721 if (!ok) {
2722 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2723 return;
2724 }
2725
2726 ok = smbd_lock_socket_internal(sconn);
2727 if (!ok) {
2728 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2729 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2730 return;
2731 }
2732
2733 if (!fd_is_readable(sconn->sock)) {
2734 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
c0288e06 2735 (int)getpid()));
27afb891
VL
2736
2737 ok = smbd_unlock_socket_internal(sconn);
2738 if (!ok) {
2739 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2740 DEBUG(1, ("%s: failed to unlock socket\n",
2741 __location__));
2742 return;
2743 }
2744
2745 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2746 if (tevent_req_nomem(subreq, req)) {
2747 return;
2748 }
2749 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2750 return;
2751 }
2752
2753 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2754 0 /* timeout */,
2755 &unread,
2756 &encrypted,
2757 &state->buflen,
2758 &state->seqnum,
2759 false /* trusted_channel*/);
2760
2761 if (tevent_req_nterror(req, status)) {
2762 tevent_req_nterror(req, status);
2763 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
c0288e06 2764 (int)getpid(), nt_errstr(status)));
27afb891
VL
2765 return;
2766 }
2767
2768 ok = smbd_unlock_socket_internal(sconn);
2769 if (!ok) {
2770 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2771 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2772 return;
2773 }
2774 tevent_req_done(req);
2775}
2776
2777static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2778 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2779{
2780 struct smbd_echo_read_state *state = tevent_req_data(
2781 req, struct smbd_echo_read_state);
2782 NTSTATUS status;
2783
2784 if (tevent_req_is_nterror(req, &status)) {
2785 return status;
2786 }
2787 *pbuf = talloc_move(mem_ctx, &state->buf);
2788 *pbuflen = state->buflen;
2789 *pseqnum = state->seqnum;
2790 return NT_STATUS_OK;
2791}
2792
cad0c004
VL
2793struct smbd_echo_state {
2794 struct tevent_context *ev;
2795 struct iovec *pending;
2796 struct smbd_server_connection *sconn;
2797 int parent_pipe;
2798
2799 struct tevent_fd *parent_fde;
2800
cad0c004
VL
2801 struct tevent_req *write_req;
2802};
2803
2804static void smbd_echo_writer_done(struct tevent_req *req);
2805
2806static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2807{
2808 int num_pending;
2809
2810 if (state->write_req != NULL) {
2811 return;
2812 }
2813
2814 num_pending = talloc_array_length(state->pending);
2815 if (num_pending == 0) {
2816 return;
2817 }
2818
2819 state->write_req = writev_send(state, state->ev, NULL,
2820 state->parent_pipe, false,
2821 state->pending, num_pending);
2822 if (state->write_req == NULL) {
2823 DEBUG(1, ("writev_send failed\n"));
2824 exit(1);
2825 }
2826
2827 talloc_steal(state->write_req, state->pending);
2828 state->pending = NULL;
2829
2830 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2831 state);
2832}
2833
2834static void smbd_echo_writer_done(struct tevent_req *req)
2835{
2836 struct smbd_echo_state *state = tevent_req_callback_data(
2837 req, struct smbd_echo_state);
2838 ssize_t written;
2839 int err;
2840
2841 written = writev_recv(req, &err);
2842 TALLOC_FREE(req);
2843 state->write_req = NULL;
2844 if (written == -1) {
2845 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2846 exit(1);
2847 }
c0288e06 2848 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
cad0c004
VL
2849 smbd_echo_activate_writer(state);
2850}
2851
0b8eeb1e
SM
2852static bool smbd_echo_reply(struct smbd_echo_state *state,
2853 uint8_t *inbuf, size_t inbuf_len,
cad0c004
VL
2854 uint32_t seqnum)
2855{
2856 struct smb_request req;
2857 uint16_t num_replies;
cad0c004
VL
2858 char *outbuf;
2859 bool ok;
2860
0633c0f6 2861 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
fd9effce
VL
2862 DEBUG(10, ("Got netbios keepalive\n"));
2863 /*
2864 * Just swallow it
2865 */
2866 return true;
2867 }
2868
cad0c004
VL
2869 if (inbuf_len < smb_size) {
2870 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2871 return false;
2872 }
0b8eeb1e 2873 if (!valid_smb_header(state->sconn, inbuf)) {
cad0c004
VL
2874 DEBUG(10, ("Got invalid SMB header\n"));
2875 return false;
2876 }
2877
0b8eeb1e 2878 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
d7bc5fe7 2879 seqnum)) {
cad0c004
VL
2880 return false;
2881 }
2882 req.inbuf = inbuf;
2883
2884 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2885 smb_messages[req.cmd].name
2886 ? smb_messages[req.cmd].name : "unknown"));
2887
2888 if (req.cmd != SMBecho) {
2889 return false;
2890 }
2891 if (req.wct < 1) {
2892 return false;
2893 }
2894
2895 num_replies = SVAL(req.vwv+0, 0);
2896 if (num_replies != 1) {
2897 /* Not a Windows "Hey, you're still there?" request */
2898 return false;
2899 }
2900
4f41be35 2901 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
cad0c004
VL
2902 1, req.buflen)) {
2903 DEBUG(10, ("create_outbuf failed\n"));
2904 return false;
2905 }
2906 req.outbuf = (uint8_t *)outbuf;
2907
2908 SSVAL(req.outbuf, smb_vwv0, num_replies);
2909
2910 if (req.buflen > 0) {
2911 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2912 }
2913
1808dd0a 2914 ok = srv_send_smb(req.sconn,
cad0c004
VL
2915 (char *)outbuf,
2916 true, seqnum+1,
2917 false, &req.pcd);
2918 TALLOC_FREE(outbuf);
2919 if (!ok) {
2920 exit(1);
2921 }
2922
2923 return true;
2924}
2925
2926static void smbd_echo_exit(struct tevent_context *ev,
2927 struct tevent_fd *fde, uint16_t flags,
2928 void *private_data)
2929{
2930 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2931 exit(0);
2932}
2933
710e5d92
VL
2934static void smbd_echo_got_packet(struct tevent_req *req);
2935
cad0c004
VL
2936static void smbd_echo_loop(struct smbd_server_connection *sconn,
2937 int parent_pipe)
2938{
2939 struct smbd_echo_state *state;
710e5d92 2940 struct tevent_req *read_req;
cad0c004
VL
2941
2942 state = talloc_zero(sconn, struct smbd_echo_state);
2943 if (state == NULL) {
2944 DEBUG(1, ("talloc failed\n"));
2945 return;
2946 }
2947 state->sconn = sconn;
2948 state->parent_pipe = parent_pipe;
2949 state->ev = s3_tevent_context_init(state);
2950 if (state->ev == NULL) {
2951 DEBUG(1, ("tevent_context_init failed\n"));
2952 TALLOC_FREE(state);
2953 return;
2954 }
2955 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2956 TEVENT_FD_READ, smbd_echo_exit,
2957 state);
2958 if (state->parent_fde == NULL) {
2959 DEBUG(1, ("tevent_add_fd failed\n"));
2960 TALLOC_FREE(state);
2961 return;
2962 }
710e5d92
VL
2963
2964 read_req = smbd_echo_read_send(state, state->ev, sconn);
2965 if (read_req == NULL) {
2966 DEBUG(1, ("smbd_echo_read_send failed\n"));
cad0c004
VL
2967 TALLOC_FREE(state);
2968 return;
2969 }
710e5d92 2970 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
cad0c004
VL
2971
2972 while (true) {
2973 if (tevent_loop_once(state->ev) == -1) {
2974 DEBUG(1, ("tevent_loop_once failed: %s\n",
2975 strerror(errno)));
2976 break;
2977 }
2978 }
2979 TALLOC_FREE(state);
2980}
2981
710e5d92
VL
2982static void smbd_echo_got_packet(struct tevent_req *req)
2983{
2984 struct smbd_echo_state *state = tevent_req_callback_data(
2985 req, struct smbd_echo_state);
2986 NTSTATUS status;
2987 char *buf = NULL;
2988 size_t buflen = 0;
2989 uint32_t seqnum = 0;
2990 bool reply;
2991
2992 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2993 TALLOC_FREE(req);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2996 nt_errstr(status)));
2997 exit(1);
2998 }
2999
0b8eeb1e 3000 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
710e5d92
VL
3001 if (!reply) {
3002 size_t num_pending;
3003 struct iovec *tmp;
3004 struct iovec *iov;
3005
3006 num_pending = talloc_array_length(state->pending);
3007 tmp = talloc_realloc(state, state->pending, struct iovec,
3008 num_pending+1);
3009 if (tmp == NULL) {
3010 DEBUG(1, ("talloc_realloc failed\n"));
3011 exit(1);
3012 }
3013 state->pending = tmp;
3014
3015 if (buflen >= smb_size) {
3016 /*
3017 * place the seqnum in the packet so that the main process
3018 * can reply with signing
3019 */
3020 SIVAL(buf, smb_ss_field, seqnum);
3021 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3022 }
3023
3024 iov = &state->pending[num_pending];
3d5c534f 3025 iov->iov_base = talloc_move(state->pending, &buf);
710e5d92
VL
3026 iov->iov_len = buflen;
3027
3028 DEBUG(10,("echo_handler[%d]: forward to main\n",
c0288e06 3029 (int)getpid()));
710e5d92
VL
3030 smbd_echo_activate_writer(state);
3031 }
3032
3033 req = smbd_echo_read_send(state, state->ev, state->sconn);
3034 if (req == NULL) {
3035 DEBUG(1, ("smbd_echo_read_send failed\n"));
3036 exit(1);
3037 }
3038 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3039}
3040
3041
cad0c004
VL
3042/*
3043 * Handle SMBecho requests in a forked child process
3044 */
8a2eff87 3045bool fork_echo_handler(struct smbd_server_connection *sconn)
cad0c004
VL
3046{
3047 int listener_pipe[2];
3048 int res;
3049 pid_t child;
3050
3051 res = pipe(listener_pipe);
3052 if (res == -1) {
3053 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3054 return false;
3055 }
3056 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
3057 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
3058 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
3059 goto fail;
3060 }
3061
c0288e06 3062 child = fork();
cad0c004
VL
3063 if (child == 0) {
3064 NTSTATUS status;
3065
3066 close(listener_pipe[0]);
342c79e2 3067 set_blocking(listener_pipe[1], false);
cad0c004 3068
72fd7fb4 3069 status = reinit_after_fork(sconn->msg_ctx,
bf8cce18 3070 sconn->ev_ctx,
0fa31296 3071 true);
cad0c004
VL
3072 if (!NT_STATUS_IS_OK(status)) {
3073 DEBUG(1, ("reinit_after_fork failed: %s\n",
3074 nt_errstr(status)));
3075 exit(1);
3076 }
3077 smbd_echo_loop(sconn, listener_pipe[1]);
3078 exit(0);
3079 }
3080 close(listener_pipe[1]);
3081 listener_pipe[1] = -1;
3082 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3083
c0288e06 3084 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child));
cad0c004
VL
3085
3086 /*
3087 * Without smb signing this is the same as the normal smbd
3088 * listener. This needs to change once signing comes in.
3089 */
bf8cce18 3090 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
cad0c004
VL
3091 sconn,
3092 sconn->smb1.echo_handler.trusted_fd,
bf8cce18 3093 TEVENT_FD_READ,
cad0c004
VL
3094 smbd_server_echo_handler,
3095 sconn);
3096 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3097 DEBUG(1, ("event_add_fd failed\n"));
3098 goto fail;
3099 }
3100
3101 return true;
3102
3103fail:
3104 if (listener_pipe[0] != -1) {
3105 close(listener_pipe[0]);
3106 }
3107 if (listener_pipe[1] != -1) {
3108 close(listener_pipe[1]);
3109 }
3110 sconn->smb1.echo_handler.trusted_fd = -1;
3111 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3112 close(sconn->smb1.echo_handler.socket_lock_fd);
3113 }
3114 sconn->smb1.echo_handler.trusted_fd = -1;
3115 sconn->smb1.echo_handler.socket_lock_fd = -1;
3116 return false;
3117}
3118
715933a3
SM
3119static bool uid_in_use(const struct user_struct *user, uid_t uid)
3120{
3121 while (user) {
3122 if (user->session_info &&
3123 (user->session_info->unix_token->uid == uid)) {
3124 return true;
3125 }
3126 user = user->next;
3127 }
3128 return false;
3129}
3130
3131static bool gid_in_use(const struct user_struct *user, gid_t gid)
3132{
3133 while (user) {
3134 if (user->session_info != NULL) {
3135 int i;
3136 struct security_unix_token *utok;
3137
3138 utok = user->session_info->unix_token;
3139 if (utok->gid == gid) {
3140 return true;
3141 }
3142 for(i=0; i<utok->ngroups; i++) {
3143 if (utok->groups[i] == gid) {
3144 return true;
3145 }
3146 }
3147 }
3148 user = user->next;
3149 }
3150 return false;
3151}
3152
3153static bool sid_in_use(const struct user_struct *user,
3154 const struct dom_sid *psid)
3155{
3156 while (user) {
3157 struct security_token *tok;
3158
3159 if (user->session_info == NULL) {
3160 continue;
3161 }
3162 tok = user->session_info->security_token;
3163 if (tok == NULL) {
3164 /*
3165 * Not sure session_info->security_token can
3166 * ever be NULL. This check might be not
3167 * necessary.
3168 */
3169 continue;
3170 }
3171 if (security_token_has_sid(tok, psid)) {
3172 return true;
3173 }
3174 user = user->next;
3175 }
3176 return false;
3177}
3178
3179static bool id_in_use(const struct user_struct *user,
3180 const struct id_cache_ref *id)
3181{
3182 switch(id->type) {
3183 case UID:
3184 return uid_in_use(user, id->id.uid);
3185 case GID:
3186 return gid_in_use(user, id->id.gid);
3187 case SID:
3188 return sid_in_use(user, &id->id.sid);
3189 default:
3190 break;
3191 }
3192 return false;
3193}
3194
3195static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3196 void *private_data,
3197 uint32_t msg_type,
3198 struct server_id server_id,
3199 DATA_BLOB* data)
3200{
3201 const char *msg = (data && data->data)
3202 ? (const char *)data->data : "<NULL>";
715933a3
SM
3203 struct id_cache_ref id;
3204 struct smbd_server_connection *sconn =
3205 talloc_get_type_abort(private_data,
3206 struct smbd_server_connection);
3207
715933a3
SM
3208 if (!id_cache_ref_parse(msg, &id)) {
3209 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3210 return;
3211 }
3212
6ce72a01 3213 if (id_in_use(sconn->users, &id)) {
715933a3
SM
3214 exit_server_cleanly(msg);
3215 }
3216 id_cache_delete_from_cache(&id);
3217}
3218
b3235d48
SM
3219NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3220 enum protocol_types protocol)
3221{
02d206ee
SM
3222 NTSTATUS status;
3223
b3235d48
SM
3224 set_Protocol(protocol);
3225 conn->protocol = protocol;
3226
02d206ee
SM
3227 if (protocol >= PROTOCOL_SMB2_02) {
3228 status = smb2srv_session_table_init(conn);
3229 if (!NT_STATUS_IS_OK(status)) {
3230 return status;
3231 }
7d139553
SM
3232
3233 status = smb2srv_open_table_init(conn);
3234 if (!NT_STATUS_IS_OK(status)) {
3235 return status;
3236 }
faa8edcc 3237 } else {
a129e271
SM
3238 status = smb1srv_session_table_init(conn);
3239 if (!NT_STATUS_IS_OK(status)) {
3240 return status;
3241 }
3242
faa8edcc
SM
3243 status = smb1srv_tcon_table_init(conn);
3244 if (!NT_STATUS_IS_OK(status)) {
3245 return status;
3246 }
7d139553
SM
3247
3248 status = smb1srv_open_table_init(conn);
3249 if (!NT_STATUS_IS_OK(status)) {
3250 return status;
3251 }
02d206ee
SM
3252 }
3253
b3235d48
SM
3254 return NT_STATUS_OK;
3255}
3256
fc96488c
SM
3257static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3258 void *private_data)
3259{
cd260391
SM
3260 struct smbXsrv_connection *conn =
3261 talloc_get_type_abort(private_data,
3262 struct smbXsrv_connection);
3263
fc96488c
SM
3264 switch (point) {
3265 case TEVENT_TRACE_BEFORE_WAIT:
b40fa943
SM
3266 /*
3267 * This just removes compiler warning
3268 * without profile support
3269 */
3270 conn->smbd_idle_profstamp = 0;
cd260391 3271 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
fc96488c
SM
3272 break;
3273 case TEVENT_TRACE_AFTER_WAIT:
cd260391 3274 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
fc96488c
SM
3275 break;
3276 }
3277}
3278
f2f55d70
JA
3279/****************************************************************************
3280 Process commands from the client
3281****************************************************************************/
3282
dd3a9279 3283void smbd_process(struct tevent_context *ev_ctx,
b5e9ece1
SM
3284 struct messaging_context *msg_ctx,
3285 int sock_fd,
3286 bool interactive)
f2f55d70 3287{
27f812f3 3288 TALLOC_CTX *frame = talloc_stackframe();
b5e9ece1
SM
3289 struct smbXsrv_connection *conn;
3290 struct smbd_server_connection *sconn;
b764145a
SM
3291 struct sockaddr_storage ss;
3292 struct sockaddr *sa = NULL;
db6d1c62 3293 socklen_t sa_socklen;
b764145a
SM
3294 struct tsocket_address *local_address = NULL;
3295 struct tsocket_address *remote_address = NULL;
3d7521c8 3296 const char *locaddr = NULL;
b764145a 3297 const char *remaddr = NULL;
a513086c 3298 char *rhost;
b764145a 3299 int ret;
27f812f3 3300
b5e9ece1
SM
3301 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3302 if (conn == NULL) {
b3235d48
SM
3303 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3304 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3305 }
3306
b5e9ece1
SM
3307 conn->ev_ctx = ev_ctx;
3308 conn->msg_ctx = msg_ctx;
3309
3310 sconn = talloc_zero(conn, struct smbd_server_connection);
3311 if (!sconn) {
3312 exit_server("failed to create smbd_server_connection");
3313 }
3314
3315 conn->sconn = sconn;
3316 sconn->conn = conn;
3317
3318 /*
3319 * TODO: remove this...:-)
3320 */
3321 global_smbXsrv_connection = conn;
3322
3323 sconn->ev_ctx = ev_ctx;
3324 sconn->msg_ctx = msg_ctx;
3325 sconn->sock = sock_fd;
3326 sconn->smb1.echo_handler.trusted_fd = -1;
3327 sconn->smb1.echo_handler.socket_lock_fd = -1;
3328
3329 if (!interactive) {
3330 smbd_setup_sig_term_handler(sconn);
3331 smbd_setup_sig_hup_handler(sconn);
3332
3333 if (!serverid_register(messaging_server_id(msg_ctx),
3334 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3335 |FLAG_MSG_DBWRAP
3336 |FLAG_MSG_PRINT_GENERAL)) {
3337 exit_server_cleanly("Could not register myself in "
3338 "serverid.tdb");
3339 }
3340 }
3341
c318c941 3342 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
d28fa8fa 3343 /*
15d6c707 3344 * We're not making the decision here,
d28fa8fa
JA
3345 * we're just allowing the client
3346 * to decide between SMB1 and SMB2
3347 * with the first negprot
3348 * packet.
3349 */
37d71a56 3350 sconn->using_smb2 = true;
688945a9
SM
3351 }
3352
27f812f3 3353 /* Ensure child is set to blocking mode */
68e86969 3354 set_blocking(sconn->sock,True);
27f812f3 3355
68e86969
VL
3356 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3357 set_socket_options(sconn->sock, lp_socket_options());
27f812f3 3358
b764145a 3359 sa = (struct sockaddr *)(void *)&ss;
db6d1c62
SM
3360 sa_socklen = sizeof(ss);
3361 ret = getpeername(sconn->sock, sa, &sa_socklen);
b764145a
SM
3362 if (ret != 0) {
3363 int level = (errno == ENOTCONN)?2:0;
3364 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3549425b 3365 exit_server_cleanly("getpeername() failed.\n");
b764145a 3366 }
37d71a56 3367 ret = tsocket_address_bsd_from_sockaddr(sconn,
db6d1c62 3368 sa, sa_socklen,
b764145a
SM
3369 &remote_address);
3370 if (ret != 0) {
3371 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3372 __location__, strerror(errno)));
3549425b 3373 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
b764145a
SM
3374 }
3375
3376 sa = (struct sockaddr *)(void *)&ss;
db6d1c62
SM
3377 sa_socklen = sizeof(ss);
3378 ret = getsockname(sconn->sock, sa, &sa_socklen);
b764145a
SM
3379 if (ret != 0) {
3380 int level = (errno == ENOTCONN)?2:0;
3381 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3549425b 3382 exit_server_cleanly("getsockname() failed.\n");
b764145a 3383 }
37d71a56 3384 ret = tsocket_address_bsd_from_sockaddr(sconn,
db6d1c62 3385 sa, sa_socklen,
b764145a
SM
3386 &local_address);
3387 if (ret != 0) {
3388 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3389 __location__, strerror(errno)));
3549425b 3390 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
b764145a
SM
3391 }
3392
37d71a56
VL
3393 sconn->local_address = local_address;
3394 sconn->remote_address = remote_address;
b764145a 3395
3d7521c8
SM
3396 if (tsocket_address_is_inet(local_address, "ip")) {
3397 locaddr = tsocket_address_inet_addr_string(
3398 sconn->local_address,
3399 talloc_tos());
3400 if (locaddr == NULL) {
3401 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3402 __location__, strerror(errno)));
3403 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3404 }
3405 } else {
3406 locaddr = "0.0.0.0";
3407 }
3408
b764145a
SM
3409 if (tsocket_address_is_inet(remote_address, "ip")) {
3410 remaddr = tsocket_address_inet_addr_string(
37d71a56 3411 sconn->remote_address,
b764145a
SM
3412 talloc_tos());
3413 if (remaddr == NULL) {
ad0f765a
AS
3414 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3415 __location__, strerror(errno)));
3416 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
b764145a
SM
3417 }
3418 } else {
3419 remaddr = "0.0.0.0";
3420 }
3421
27f812f3
SM
3422 /* this is needed so that we get decent entries
3423 in smbstatus for port 445 connects */
b764145a 3424 set_remote_machine_name(remaddr, false);
03455519 3425 reload_services(sconn, conn_snum_used, true);
27f812f3 3426
ac647d03
VL
3427 /*
3428 * Before the first packet, check the global hosts allow/ hosts deny
3429 * parameters before doing any parsing of packets passed to us by the
3430 * client. This prevents attacks on our parsing code from hosts not in
3431 * the hosts allow list.
3432 */
3433
a513086c
AS
3434 ret = get_remote_hostname(remote_address,
3435 &rhost,
3436 talloc_tos());
3437 if (ret < 0) {
3438 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3439 __location__, strerror(errno)));
3440 exit_server_cleanly("get_remote_hostname failed.\n");
3441 }
3442 if (strequal(rhost, "UNKNOWN")) {
3443 rhost = talloc_strdup(talloc_tos(), remaddr);
3444 }
3445 sconn->remote_hostname = talloc_move(sconn, &rhost);
3446
3d7521c8
SM
3447 sub_set_socket_ids(remaddr,
3448 sconn->remote_hostname,
3449 locaddr);
3450
70c5bed4 3451 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
a513086c
AS
3452 sconn->remote_hostname,
3453 remaddr)) {
ac647d03
VL
3454 /*
3455 * send a negative session response "not listening on calling
3456 * name"
3457 */
3458 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
b764145a
SM
3459 DEBUG( 1, ("Connection denied from %s to %s\n",
3460 tsocket_address_string(remote_address, talloc_tos()),
3461 tsocket_address_string(local_address, talloc_tos())));
1808dd0a 3462 (void)srv_send_smb(sconn,(char *)buf, false,
c16c90a1 3463 0, false, NULL);
ac647d03
VL
3464 exit_server_cleanly("connection denied");
3465 }
3466
b764145a
SM
3467 DEBUG(10, ("Connection allowed from %s to %s\n",
3468 tsocket_address_string(remote_address, talloc_tos()),
3469 tsocket_address_string(local_address, talloc_tos())));
3470
c3638158
AB
3471 if (lp_preload_modules()) {
3472 smb_load_modules(lp_preload_modules());
3473 }
27f812f3 3474
54c51a66 3475 smb_perfcount_init();
3476
27f812f3
SM
3477 if (!init_account_policy()) {
3478 exit_server("Could not open account policy tdb.\n");
3479 }
3480
fe72740e
RR
3481 if (*lp_rootdir(talloc_tos())) {
3482 if (chroot(lp_rootdir(talloc_tos())) != 0) {
3483 DEBUG(0,("Failed to change root to %s\n",
3484 lp_rootdir(talloc_tos())));
f6821a15
JA
3485 exit_server("Failed to chroot()");
3486 }
3487 if (chdir("/") == -1) {
fe72740e 3488 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir(talloc_tos())));
27f812f3
SM
3489 exit_server("Failed to chroot()");
3490 }
fe72740e 3491 DEBUG(0,("Changed root to %s\n", lp_rootdir(talloc_tos())));
27f812f3
SM
3492 }
3493
37d71a56 3494 if (!srv_init_signing(sconn)) {
c16c90a1
SM
3495 exit_server("Failed to init smb_signing");
3496 }
3497
288a75d8
SM
3498 if (!file_init(sconn)) {
3499 exit_server("file_init() failed");
3500 }
3501
27f812f3 3502 /* Setup oplocks */
21de6735 3503 if (!init_oplocks(sconn))
27f812f3
SM
3504 exit_server("Failed to init oplocks");
3505
27f812f3 3506 /* register our message handlers */
d492a437 3507 messaging_register(sconn->msg_ctx, sconn,
27f812f3 3508 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4d44f879 3509 messaging_register(sconn->msg_ctx, sconn,
27f812f3 3510 MSG_SMB_CLOSE_FILE, msg_close_file);
e09c6755 3511 messaging_register(sconn->msg_ctx, sconn,
173ea716 3512 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
27f812f3 3513
715933a3
SM
3514 id_cache_register_msgs(sconn->msg_ctx);
3515 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3516 messaging_register(sconn->msg_ctx, sconn,
3517 ID_CACHE_KILL, smbd_id_cache_kill);
3518
e412b8bf
SM
3519 messaging_deregister(sconn->msg_ctx,
3520 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3521 messaging_register(sconn->msg_ctx, sconn,
3522 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3523
5a4d6181
AS
3524 /*
3525 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3526 * MSGs to all child processes
3527 */
b71f2af1 3528 messaging_deregister(sconn->msg_ctx,
5a4d6181 3529 MSG_DEBUG, NULL);
b71f2af1 3530 messaging_register(sconn->msg_ctx, NULL,
5a4d6181
AS
3531 MSG_DEBUG, debug_message);
3532
27f812f3 3533 if ((lp_keepalive() != 0)
dd3a9279 3534 && !(event_add_idle(ev_ctx, NULL,
27f812f3
SM
3535 timeval_set(lp_keepalive(), 0),
3536 "keepalive", keepalive_fn,
d911bd5c 3537 sconn))) {
27f812f3
SM
3538 DEBUG(0, ("Could not add keepalive event\n"));
3539 exit(1);
3540 }
3541
dd3a9279 3542 if (!(event_add_idle(ev_ctx, NULL,
27f812f3 3543 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
37d71a56 3544 "deadtime", deadtime_fn, sconn))) {
27f812f3
SM
3545 DEBUG(0, ("Could not add deadtime event\n"));
3546 exit(1);
aeb798c3 3547 }
27f812f3 3548
dd3a9279 3549 if (!(event_add_idle(ev_ctx, NULL,
0b188e77 3550 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
babfe237 3551 "housekeeping", housekeeping_fn, sconn))) {
27f812f3
SM
3552 DEBUG(0, ("Could not add housekeeping event\n"));
3553 exit(1);
3554 }
3555
3556#ifdef CLUSTER_SUPPORT
3557
3558 if (lp_clustering()) {
3559 /*
3560 * We need to tell ctdb about our client's TCP
3561 * connection, so that for failover ctdbd can send
3562 * tickle acks, triggering a reconnection by the
3563 * client.
3564 */
3565
3566 struct sockaddr_storage srv, clnt;
3567
f83e7d8f 3568 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
27f812f3 3569 NTSTATUS status;
744cc264 3570 status = smbd_register_ips(sconn, &srv, &clnt);
27f812f3
SM
3571 if (!NT_STATUS_IS_OK(status)) {
3572 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3573 nt_errstr(status)));
3574 }
3575 } else
3576 {
3577 DEBUG(0,("Unable to get tcp info for "
3578 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3579 strerror(errno)));
3580 }
3581 }
3582
3583#endif
3584
37d71a56 3585 sconn->nbt.got_session = false;
f554af18 3586
9f4b6fa0 3587 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
27f812f3 3588
37d71a56
VL
3589 sconn->smb1.sessions.done_sesssetup = false;
3590 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3591 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
356f0336 3592
37d71a56 3593 if (!init_dptrs(sconn)) {
59c3f5e3
SM
3594 exit_server("init_dptrs() failed");
3595 }
c8620180 3596
dd3a9279 3597 sconn->smb1.fde = event_add_fd(ev_ctx,
37d71a56 3598 sconn,
68e86969 3599 sconn->sock,
ebc860eb
SM
3600 EVENT_FD_READ,
3601 smbd_server_connection_handler,
37d71a56
VL
3602 sconn);
3603 if (!sconn->smb1.fde) {
aeb798c3
SM
3604 exit_server("failed to create smbd_server_connection fde");
3605 }
3606
b3235d48
SM
3607 sconn->conn->local_address = sconn->local_address;
3608 sconn->conn->remote_address = sconn->remote_address;
3609 sconn->conn->remote_hostname = sconn->remote_hostname;
3610 sconn->conn->protocol = PROTOCOL_NONE;
3611
27f812f3
SM
3612 TALLOC_FREE(frame);
3613
cd260391 3614 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
fc96488c 3615
b2d01bd2 3616 while (True) {
27f812f3 3617 frame = talloc_stackframe_pool(8192);
dc76502c 3618
c3250149 3619 errno = 0;
ed85e9fe
JA
3620 if (tevent_loop_once(ev_ctx) == -1) {
3621 if (errno != EINTR) {
3622 DEBUG(3, ("tevent_loop_once failed: %s,"
3623 " exiting\n", strerror(errno) ));
3624 break;
3625 }
b2d01bd2
AT
3626 }
3627
929e1d99 3628 TALLOC_FREE(frame);
b2d01bd2 3629 }
27f812f3
SM
3630
3631 exit_server_cleanly(NULL);
c3effa8b 3632}
d94e9c80
VL
3633
3634bool req_is_in_chain(struct smb_request *req)
3635{
4f41be35 3636 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
d94e9c80
VL
3637 /*
3638 * We're right now handling a subsequent request, so we must
3639 * be in a chain
3640 */
3641 return true;
3642 }
3643
3644 if (!is_andx_req(req->cmd)) {
3645 return false;
3646 }
3647
3648 if (req->wct < 2) {
3649 /*
3650 * Okay, an illegal request, but definitely not chained :-)
3651 */
3652 return false;
3653 }
3654
3655 return (CVAL(req->vwv+0, 0) != 0xFF);
3656}