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