source: vendor/current/source3/smbd/process.c

Last change on this file was 989, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.7

File size: 106.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "includes.h"
22#include "../lib/tsocket/tsocket.h"
23#include "system/filesys.h"
24#include "smbd/smbd.h"
25#include "smbd/globals.h"
26#include "librpc/gen_ndr/netlogon.h"
27#include "../lib/async_req/async_sock.h"
28#include "ctdbd_conn.h"
29#include "../lib/util/select.h"
30#include "printing/queue_process.h"
31#include "system/select.h"
32#include "passdb.h"
33#include "auth.h"
34#include "messages.h"
35#include "smbprofile.h"
36#include "rpc_server/spoolss/srv_spoolss_nt.h"
37#include "libsmb/libsmb.h"
38#include "../lib/util/tevent_ntstatus.h"
39#include "../libcli/security/dom_sid.h"
40#include "../libcli/security/security_token.h"
41#include "lib/id_cache.h"
42#include "lib/util/sys_rw_data.h"
43#include "serverid.h"
44#include "system/threads.h"
45
46/* Internal message queue for deferred opens. */
47struct pending_message_list {
48 struct pending_message_list *next, *prev;
49 struct timeval request_time; /* When was this first issued? */
50 struct smbd_server_connection *sconn;
51 struct smbXsrv_connection *xconn;
52 struct tevent_timer *te;
53 struct smb_perfcount_data pcd;
54 uint32_t seqnum;
55 bool encrypted;
56 bool processed;
57 DATA_BLOB buf;
58 struct deferred_open_record *open_rec;
59};
60
61static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
62 char *outbuf);
63static struct pending_message_list *get_deferred_open_message_smb(
64 struct smbd_server_connection *sconn, uint64_t mid);
65static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
66
67static void smbd_echo_init(struct smbXsrv_connection *xconn)
68{
69 xconn->smb1.echo_handler.trusted_fd = -1;
70 xconn->smb1.echo_handler.socket_lock_fd = -1;
71#ifdef HAVE_ROBUST_MUTEXES
72 xconn->smb1.echo_handler.socket_mutex = NULL;
73#endif
74}
75
76static bool smbd_echo_active(struct smbXsrv_connection *xconn)
77{
78 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
79 return true;
80 }
81
82#ifdef HAVE_ROBUST_MUTEXES
83 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
84 return true;
85 }
86#endif
87
88 return false;
89}
90
91static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
92{
93 if (!smbd_echo_active(xconn)) {
94 return true;
95 }
96
97 xconn->smb1.echo_handler.ref_count++;
98
99 if (xconn->smb1.echo_handler.ref_count > 1) {
100 return true;
101 }
102
103 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
104
105#ifdef HAVE_ROBUST_MUTEXES
106 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
107 int ret = EINTR;
108
109 while (ret == EINTR) {
110 ret = pthread_mutex_lock(
111 xconn->smb1.echo_handler.socket_mutex);
112 if (ret == 0) {
113 break;
114 }
115 }
116 if (ret != 0) {
117 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
118 strerror(ret)));
119 return false;
120 }
121 }
122#endif
123
124 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
125 bool ok;
126
127 do {
128 ok = fcntl_lock(
129 xconn->smb1.echo_handler.socket_lock_fd,
130 F_SETLKW, 0, 0, F_WRLCK);
131 } while (!ok && (errno == EINTR));
132
133 if (!ok) {
134 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
135 return false;
136 }
137 }
138
139 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
140
141 return true;
142}
143
144void smbd_lock_socket(struct smbXsrv_connection *xconn)
145{
146 if (!smbd_lock_socket_internal(xconn)) {
147 exit_server_cleanly("failed to lock socket");
148 }
149}
150
151static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
152{
153 if (!smbd_echo_active(xconn)) {
154 return true;
155 }
156
157 xconn->smb1.echo_handler.ref_count--;
158
159 if (xconn->smb1.echo_handler.ref_count > 0) {
160 return true;
161 }
162
163#ifdef HAVE_ROBUST_MUTEXES
164 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
165 int ret = EINTR;
166
167 while (ret == EINTR) {
168 ret = pthread_mutex_unlock(
169 xconn->smb1.echo_handler.socket_mutex);
170 if (ret == 0) {
171 break;
172 }
173 }
174 if (ret != 0) {
175 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
176 strerror(ret)));
177 return false;
178 }
179 }
180#endif
181
182 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
183 bool ok;
184
185 do {
186 ok = fcntl_lock(
187 xconn->smb1.echo_handler.socket_lock_fd,
188 F_SETLKW, 0, 0, F_UNLCK);
189 } while (!ok && (errno == EINTR));
190
191 if (!ok) {
192 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
193 return false;
194 }
195 }
196
197 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
198
199 return true;
200}
201
202void smbd_unlock_socket(struct smbXsrv_connection *xconn)
203{
204 if (!smbd_unlock_socket_internal(xconn)) {
205 exit_server_cleanly("failed to unlock socket");
206 }
207}
208
209/* Accessor function for smb_read_error for smbd functions. */
210
211/****************************************************************************
212 Send an smb to a fd.
213****************************************************************************/
214
215bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
216 bool do_signing, uint32_t seqnum,
217 bool do_encrypt,
218 struct smb_perfcount_data *pcd)
219{
220 size_t len = 0;
221 ssize_t ret;
222 char *buf_out = buffer;
223
224 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
225 /*
226 * we're not supposed to do any io
227 */
228 return true;
229 }
230
231 smbd_lock_socket(xconn);
232
233 if (do_signing) {
234 /* Sign the outgoing packet if required. */
235 srv_calculate_sign_mac(xconn, buf_out, seqnum);
236 }
237
238 if (do_encrypt) {
239 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
240 if (!NT_STATUS_IS_OK(status)) {
241 DEBUG(0, ("send_smb: SMB encryption failed "
242 "on outgoing packet! Error %s\n",
243 nt_errstr(status) ));
244 ret = -1;
245 goto out;
246 }
247 }
248
249 len = smb_len_large(buf_out) + 4;
250
251 ret = write_data(xconn->transport.sock, buf_out, len);
252 if (ret <= 0) {
253 int saved_errno = errno;
254 /*
255 * Try and give an error message saying what
256 * client failed.
257 */
258 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
259 (int)getpid(), (int)len,
260 smbXsrv_connection_dbg(xconn),
261 (int)ret, strerror(saved_errno)));
262 errno = saved_errno;
263
264 srv_free_enc_buffer(xconn, buf_out);
265 goto out;
266 }
267
268 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
269 srv_free_enc_buffer(xconn, buf_out);
270out:
271 SMB_PERFCOUNT_END(pcd);
272
273 smbd_unlock_socket(xconn);
274 return (ret > 0);
275}
276
277/*******************************************************************
278 Setup the word count and byte count for a smb message.
279********************************************************************/
280
281int srv_set_message(char *buf,
282 int num_words,
283 int num_bytes,
284 bool zero)
285{
286 if (zero && (num_words || num_bytes)) {
287 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
288 }
289 SCVAL(buf,smb_wct,num_words);
290 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
291 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
292 return (smb_size + num_words*2 + num_bytes);
293}
294
295static bool valid_smb_header(const uint8_t *inbuf)
296{
297 if (is_encrypted_packet(inbuf)) {
298 return true;
299 }
300 /*
301 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
302 * but it just looks weird to call strncmp for this one.
303 */
304 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
305}
306
307/* Socket functions for smbd packet processing. */
308
309static bool valid_packet_size(size_t len)
310{
311 /*
312 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
313 * of header. Don't print the error if this fits.... JRA.
314 */
315
316 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
317 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
318 (unsigned long)len));
319 return false;
320 }
321 return true;
322}
323
324static NTSTATUS read_packet_remainder(int fd, char *buffer,
325 unsigned int timeout, ssize_t len)
326{
327 NTSTATUS status;
328
329 if (len <= 0) {
330 return NT_STATUS_OK;
331 }
332
333 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
334 if (!NT_STATUS_IS_OK(status)) {
335 char addr[INET6_ADDRSTRLEN];
336 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
337 "error = %s.\n",
338 get_peer_addr(fd, addr, sizeof(addr)),
339 nt_errstr(status)));
340 }
341 return status;
342}
343
344/****************************************************************************
345 Attempt a zerocopy writeX read. We know here that len > smb_size-4
346****************************************************************************/
347
348/*
349 * Unfortunately, earlier versions of smbclient/libsmbclient
350 * don't send this "standard" writeX header. I've fixed this
351 * for 3.2 but we'll use the old method with earlier versions.
352 * Windows and CIFSFS at least use this standard size. Not
353 * sure about MacOSX.
354 */
355
356#define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
357 (2*14) + /* word count (including bcc) */ \
358 1 /* pad byte */)
359
360static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
361 const char lenbuf[4],
362 struct smbXsrv_connection *xconn,
363 int sock,
364 char **buffer,
365 unsigned int timeout,
366 size_t *p_unread,
367 size_t *len_ret)
368{
369 /* Size of a WRITEX call (+4 byte len). */
370 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
371 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
372 ssize_t toread;
373 NTSTATUS status;
374
375 memcpy(writeX_header, lenbuf, 4);
376
377 status = read_fd_with_timeout(
378 sock, writeX_header + 4,
379 STANDARD_WRITE_AND_X_HEADER_SIZE,
380 STANDARD_WRITE_AND_X_HEADER_SIZE,
381 timeout, NULL);
382
383 if (!NT_STATUS_IS_OK(status)) {
384 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
385 "error = %s.\n",
386 smbXsrv_connection_dbg(xconn),
387 nt_errstr(status)));
388 return status;
389 }
390
391 /*
392 * Ok - now try and see if this is a possible
393 * valid writeX call.
394 */
395
396 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
397 /*
398 * If the data offset is beyond what
399 * we've read, drain the extra bytes.
400 */
401 uint16_t doff = SVAL(writeX_header,smb_vwv11);
402 ssize_t newlen;
403
404 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
405 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
406 if (drain_socket(sock, drain) != drain) {
407 smb_panic("receive_smb_raw_talloc_partial_read:"
408 " failed to drain pending bytes");
409 }
410 } else {
411 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
412 }
413
414 /* Spoof down the length and null out the bcc. */
415 set_message_bcc(writeX_header, 0);
416 newlen = smb_len(writeX_header);
417
418 /* Copy the header we've written. */
419
420 *buffer = (char *)talloc_memdup(mem_ctx,
421 writeX_header,
422 sizeof(writeX_header));
423
424 if (*buffer == NULL) {
425 DEBUG(0, ("Could not allocate inbuf of length %d\n",
426 (int)sizeof(writeX_header)));
427 return NT_STATUS_NO_MEMORY;
428 }
429
430 /* Work out the remaining bytes. */
431 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
432 *len_ret = newlen + 4;
433 return NT_STATUS_OK;
434 }
435
436 if (!valid_packet_size(len)) {
437 return NT_STATUS_INVALID_PARAMETER;
438 }
439
440 /*
441 * Not a valid writeX call. Just do the standard
442 * talloc and return.
443 */
444
445 *buffer = talloc_array(mem_ctx, char, len+4);
446
447 if (*buffer == NULL) {
448 DEBUG(0, ("Could not allocate inbuf of length %d\n",
449 (int)len+4));
450 return NT_STATUS_NO_MEMORY;
451 }
452
453 /* Copy in what we already read. */
454 memcpy(*buffer,
455 writeX_header,
456 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
457 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
458
459 if(toread > 0) {
460 status = read_packet_remainder(
461 sock,
462 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
463 timeout, toread);
464
465 if (!NT_STATUS_IS_OK(status)) {
466 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
467 nt_errstr(status)));
468 return status;
469 }
470 }
471
472 *len_ret = len + 4;
473 return NT_STATUS_OK;
474}
475
476static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
477 struct smbXsrv_connection *xconn,
478 int sock,
479 char **buffer, unsigned int timeout,
480 size_t *p_unread, size_t *plen)
481{
482 char lenbuf[4];
483 size_t len;
484 int min_recv_size = lp_min_receive_file_size();
485 NTSTATUS status;
486
487 *p_unread = 0;
488
489 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
490 &len);
491 if (!NT_STATUS_IS_OK(status)) {
492 return status;
493 }
494
495 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
496 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
497 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
498 !srv_is_signing_active(xconn) &&
499 xconn->smb1.echo_handler.trusted_fde == NULL) {
500
501 return receive_smb_raw_talloc_partial_read(
502 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
503 p_unread, plen);
504 }
505
506 if (!valid_packet_size(len)) {
507 return NT_STATUS_INVALID_PARAMETER;
508 }
509
510 /*
511 * The +4 here can't wrap, we've checked the length above already.
512 */
513
514 *buffer = talloc_array(mem_ctx, char, len+4);
515
516 if (*buffer == NULL) {
517 DEBUG(0, ("Could not allocate inbuf of length %d\n",
518 (int)len+4));
519 return NT_STATUS_NO_MEMORY;
520 }
521
522 memcpy(*buffer, lenbuf, sizeof(lenbuf));
523
524 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
525 if (!NT_STATUS_IS_OK(status)) {
526 return status;
527 }
528
529 *plen = len + 4;
530 return NT_STATUS_OK;
531}
532
533static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
534 struct smbXsrv_connection *xconn,
535 int sock,
536 char **buffer, unsigned int timeout,
537 size_t *p_unread, bool *p_encrypted,
538 size_t *p_len,
539 uint32_t *seqnum,
540 bool trusted_channel)
541{
542 size_t len = 0;
543 NTSTATUS status;
544
545 *p_encrypted = false;
546
547 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
548 p_unread, &len);
549 if (!NT_STATUS_IS_OK(status)) {
550 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
551 ("receive_smb_raw_talloc failed for client %s "
552 "read error = %s.\n",
553 smbXsrv_connection_dbg(xconn),
554 nt_errstr(status)) );
555 return status;
556 }
557
558 if (is_encrypted_packet((uint8_t *)*buffer)) {
559 status = srv_decrypt_buffer(xconn, *buffer);
560 if (!NT_STATUS_IS_OK(status)) {
561 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
562 "incoming packet! Error %s\n",
563 nt_errstr(status) ));
564 return status;
565 }
566 *p_encrypted = true;
567 }
568
569 /* Check the incoming SMB signature. */
570 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
571 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
572 "incoming packet!\n"));
573 return NT_STATUS_INVALID_NETWORK_RESPONSE;
574 }
575
576 *p_len = len;
577 return NT_STATUS_OK;
578}
579
580/*
581 * Initialize a struct smb_request from an inbuf
582 */
583
584static bool init_smb_request(struct smb_request *req,
585 struct smbd_server_connection *sconn,
586 struct smbXsrv_connection *xconn,
587 const uint8_t *inbuf,
588 size_t unread_bytes, bool encrypted,
589 uint32_t seqnum)
590{
591 struct smbXsrv_tcon *tcon;
592 NTSTATUS status;
593 NTTIME now;
594 size_t req_size = smb_len(inbuf) + 4;
595
596 /* Ensure we have at least smb_size bytes. */
597 if (req_size < smb_size) {
598 DEBUG(0,("init_smb_request: invalid request size %u\n",
599 (unsigned int)req_size ));
600 return false;
601 }
602
603 req->request_time = timeval_current();
604 now = timeval_to_nttime(&req->request_time);
605
606 req->cmd = CVAL(inbuf, smb_com);
607 req->flags2 = SVAL(inbuf, smb_flg2);
608 req->smbpid = SVAL(inbuf, smb_pid);
609 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
610 req->seqnum = seqnum;
611 req->vuid = SVAL(inbuf, smb_uid);
612 req->tid = SVAL(inbuf, smb_tid);
613 req->wct = CVAL(inbuf, smb_wct);
614 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
615 req->buflen = smb_buflen(inbuf);
616 req->buf = (const uint8_t *)smb_buf_const(inbuf);
617 req->unread_bytes = unread_bytes;
618 req->encrypted = encrypted;
619 req->sconn = sconn;
620 req->xconn = xconn;
621 req->conn = NULL;
622 if (xconn != NULL) {
623 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
624 if (NT_STATUS_IS_OK(status)) {
625 req->conn = tcon->compat;
626 }
627 }
628 req->chain_fsp = NULL;
629 req->smb2req = NULL;
630 req->priv_paths = NULL;
631 req->chain = NULL;
632 req->posix_pathnames = lp_posix_pathnames();
633 smb_init_perfcount_data(&req->pcd);
634
635 /* Ensure we have at least wct words and 2 bytes of bcc. */
636 if (smb_size + req->wct*2 > req_size) {
637 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
638 (unsigned int)req->wct,
639 (unsigned int)req_size));
640 return false;
641 }
642 /* Ensure bcc is correct. */
643 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
644 DEBUG(0,("init_smb_request: invalid bcc number %u "
645 "(wct = %u, size %u)\n",
646 (unsigned int)req->buflen,
647 (unsigned int)req->wct,
648 (unsigned int)req_size));
649 return false;
650 }
651
652 req->outbuf = NULL;
653 return true;
654}
655
656static void process_smb(struct smbXsrv_connection *xconn,
657 uint8_t *inbuf, size_t nread, size_t unread_bytes,
658 uint32_t seqnum, bool encrypted,
659 struct smb_perfcount_data *deferred_pcd);
660
661static void smbd_deferred_open_timer(struct tevent_context *ev,
662 struct tevent_timer *te,
663 struct timeval _tval,
664 void *private_data)
665{
666 struct pending_message_list *msg = talloc_get_type(private_data,
667 struct pending_message_list);
668 struct smbd_server_connection *sconn = msg->sconn;
669 struct smbXsrv_connection *xconn = msg->xconn;
670 TALLOC_CTX *mem_ctx = talloc_tos();
671 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
672 uint8_t *inbuf;
673
674 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
675 msg->buf.length);
676 if (inbuf == NULL) {
677 exit_server("smbd_deferred_open_timer: talloc failed\n");
678 return;
679 }
680
681 /* We leave this message on the queue so the open code can
682 know this is a retry. */
683 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
684 (unsigned long long)mid ));
685
686 /* Mark the message as processed so this is not
687 * re-processed in error. */
688 msg->processed = true;
689
690 process_smb(xconn, inbuf,
691 msg->buf.length, 0,
692 msg->seqnum, msg->encrypted, &msg->pcd);
693
694 /* If it's still there and was processed, remove it. */
695 msg = get_deferred_open_message_smb(sconn, mid);
696 if (msg && msg->processed) {
697 remove_deferred_open_message_smb(xconn, mid);
698 }
699}
700
701/****************************************************************************
702 Function to push a message onto the tail of a linked list of smb messages ready
703 for processing.
704****************************************************************************/
705
706static bool push_queued_message(struct smb_request *req,
707 struct timeval request_time,
708 struct timeval end_time,
709 struct deferred_open_record *open_rec)
710{
711 int msg_len = smb_len(req->inbuf) + 4;
712 struct pending_message_list *msg;
713
714 msg = talloc_zero(NULL, struct pending_message_list);
715
716 if(msg == NULL) {
717 DEBUG(0,("push_message: malloc fail (1)\n"));
718 return False;
719 }
720 msg->sconn = req->sconn;
721 msg->xconn = req->xconn;
722
723 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
724 if(msg->buf.data == NULL) {
725 DEBUG(0,("push_message: malloc fail (2)\n"));
726 TALLOC_FREE(msg);
727 return False;
728 }
729
730 msg->request_time = request_time;
731 msg->seqnum = req->seqnum;
732 msg->encrypted = req->encrypted;
733 msg->processed = false;
734 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
735
736 if (open_rec) {
737 msg->open_rec = talloc_move(msg, &open_rec);
738 }
739
740#if 0
741 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
742 msg,
743 end_time,
744 smbd_deferred_open_timer,
745 msg);
746 if (!msg->te) {
747 DEBUG(0,("push_message: event_add_timed failed\n"));
748 TALLOC_FREE(msg);
749 return false;
750 }
751#endif
752
753 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
754
755 DEBUG(10,("push_message: pushed message length %u on "
756 "deferred_open_queue\n", (unsigned int)msg_len));
757
758 return True;
759}
760
761/****************************************************************************
762 Function to delete a sharing violation open message by mid.
763****************************************************************************/
764
765void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
766 uint64_t mid)
767{
768 struct smbd_server_connection *sconn = xconn->client->sconn;
769 struct pending_message_list *pml;
770
771 if (sconn->using_smb2) {
772 remove_deferred_open_message_smb2(xconn, mid);
773 return;
774 }
775
776 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
777 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
778 DEBUG(10,("remove_deferred_open_message_smb: "
779 "deleting mid %llu len %u\n",
780 (unsigned long long)mid,
781 (unsigned int)pml->buf.length ));
782 DLIST_REMOVE(sconn->deferred_open_queue, pml);
783 TALLOC_FREE(pml);
784 return;
785 }
786 }
787}
788
789/****************************************************************************
790 Move a sharing violation open retry message to the front of the list and
791 schedule it for immediate processing.
792****************************************************************************/
793
794bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
795 uint64_t mid)
796{
797 struct smbd_server_connection *sconn = xconn->client->sconn;
798 struct pending_message_list *pml;
799 int i = 0;
800
801 if (sconn->using_smb2) {
802 return schedule_deferred_open_message_smb2(xconn, mid);
803 }
804
805 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
806 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
807
808 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
809 "msg_mid = %llu\n",
810 i++,
811 (unsigned long long)msg_mid ));
812
813 if (mid == msg_mid) {
814 struct tevent_timer *te;
815
816 if (pml->processed) {
817 /* A processed message should not be
818 * rescheduled. */
819 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
820 "message mid %llu was already processed\n",
821 (unsigned long long)msg_mid ));
822 continue;
823 }
824
825 DEBUG(10,("schedule_deferred_open_message_smb: "
826 "scheduling mid %llu\n",
827 (unsigned long long)mid ));
828
829 te = tevent_add_timer(pml->sconn->ev_ctx,
830 pml,
831 timeval_zero(),
832 smbd_deferred_open_timer,
833 pml);
834 if (!te) {
835 DEBUG(10,("schedule_deferred_open_message_smb: "
836 "event_add_timed() failed, "
837 "skipping mid %llu\n",
838 (unsigned long long)msg_mid ));
839 }
840
841 TALLOC_FREE(pml->te);
842 pml->te = te;
843 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
844 return true;
845 }
846 }
847
848 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
849 "find message mid %llu\n",
850 (unsigned long long)mid ));
851
852 return false;
853}
854
855/****************************************************************************
856 Return true if this mid is on the deferred queue and was not yet processed.
857****************************************************************************/
858
859bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
860{
861 struct smbd_server_connection *sconn = xconn->client->sconn;
862 struct pending_message_list *pml;
863
864 if (sconn->using_smb2) {
865 return open_was_deferred_smb2(xconn, mid);
866 }
867
868 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
869 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
870 return True;
871 }
872 }
873 return False;
874}
875
876/****************************************************************************
877 Return the message queued by this mid.
878****************************************************************************/
879
880static struct pending_message_list *get_deferred_open_message_smb(
881 struct smbd_server_connection *sconn, uint64_t mid)
882{
883 struct pending_message_list *pml;
884
885 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
886 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
887 return pml;
888 }
889 }
890 return NULL;
891}
892
893/****************************************************************************
894 Get the state data queued by this mid.
895****************************************************************************/
896
897bool get_deferred_open_message_state(struct smb_request *smbreq,
898 struct timeval *p_request_time,
899 struct deferred_open_record **open_rec)
900{
901 struct pending_message_list *pml;
902
903 if (smbreq->sconn->using_smb2) {
904 return get_deferred_open_message_state_smb2(smbreq->smb2req,
905 p_request_time,
906 open_rec);
907 }
908
909 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
910 if (!pml) {
911 return false;
912 }
913 if (p_request_time) {
914 *p_request_time = pml->request_time;
915 }
916 if (open_rec != NULL) {
917 *open_rec = pml->open_rec;
918 }
919 return true;
920}
921
922/****************************************************************************
923 Function to push a deferred open smb message onto a linked list of local smb
924 messages ready for processing.
925****************************************************************************/
926
927bool push_deferred_open_message_smb(struct smb_request *req,
928 struct timeval request_time,
929 struct timeval timeout,
930 struct file_id id,
931 struct deferred_open_record *open_rec)
932{
933 struct timeval end_time;
934
935 if (req->smb2req) {
936 return push_deferred_open_message_smb2(req->smb2req,
937 request_time,
938 timeout,
939 id,
940 open_rec);
941 }
942
943 if (req->unread_bytes) {
944 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
945 "unread_bytes = %u\n",
946 (unsigned int)req->unread_bytes ));
947 smb_panic("push_deferred_open_message_smb: "
948 "logic error unread_bytes != 0" );
949 }
950
951 end_time = timeval_sum(&request_time, &timeout);
952
953 DEBUG(10,("push_deferred_open_message_smb: pushing message "
954 "len %u mid %llu timeout time [%u.%06u]\n",
955 (unsigned int) smb_len(req->inbuf)+4,
956 (unsigned long long)req->mid,
957 (unsigned int)end_time.tv_sec,
958 (unsigned int)end_time.tv_usec));
959
960 return push_queued_message(req, request_time, end_time, open_rec);
961}
962
963static void smbd_sig_term_handler(struct tevent_context *ev,
964 struct tevent_signal *se,
965 int signum,
966 int count,
967 void *siginfo,
968 void *private_data)
969{
970 exit_server_cleanly("termination signal");
971}
972
973void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
974{
975 struct tevent_signal *se;
976
977 se = tevent_add_signal(sconn->ev_ctx,
978 sconn,
979 SIGTERM, 0,
980 smbd_sig_term_handler,
981 sconn);
982 if (!se) {
983 exit_server("failed to setup SIGTERM handler");
984 }
985}
986
987static void smbd_sig_hup_handler(struct tevent_context *ev,
988 struct tevent_signal *se,
989 int signum,
990 int count,
991 void *siginfo,
992 void *private_data)
993{
994 struct smbd_server_connection *sconn =
995 talloc_get_type_abort(private_data,
996 struct smbd_server_connection);
997
998 change_to_root_user();
999 DEBUG(1,("Reloading services after SIGHUP\n"));
1000 reload_services(sconn, conn_snum_used, false);
1001}
1002
1003void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1004{
1005 struct tevent_signal *se;
1006
1007 se = tevent_add_signal(sconn->ev_ctx,
1008 sconn,
1009 SIGHUP, 0,
1010 smbd_sig_hup_handler,
1011 sconn);
1012 if (!se) {
1013 exit_server("failed to setup SIGHUP handler");
1014 }
1015}
1016
1017static void smbd_conf_updated(struct messaging_context *msg,
1018 void *private_data,
1019 uint32_t msg_type,
1020 struct server_id server_id,
1021 DATA_BLOB *data)
1022{
1023 struct smbd_server_connection *sconn =
1024 talloc_get_type_abort(private_data,
1025 struct smbd_server_connection);
1026
1027 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1028 "updated. Reloading.\n"));
1029 change_to_root_user();
1030 reload_services(sconn, conn_snum_used, false);
1031}
1032
1033/*
1034 * Only allow 5 outstanding trans requests. We're allocating memory, so
1035 * prevent a DoS.
1036 */
1037
1038NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1039{
1040 int count = 0;
1041 for (; list != NULL; list = list->next) {
1042
1043 if (list->mid == mid) {
1044 return NT_STATUS_INVALID_PARAMETER;
1045 }
1046
1047 count += 1;
1048 }
1049 if (count > 5) {
1050 return NT_STATUS_INSUFFICIENT_RESOURCES;
1051 }
1052
1053 return NT_STATUS_OK;
1054}
1055
1056/*
1057These flags determine some of the permissions required to do an operation
1058
1059Note that I don't set NEED_WRITE on some write operations because they
1060are used by some brain-dead clients when printing, and I don't want to
1061force write permissions on print services.
1062*/
1063#define AS_USER (1<<0)
1064#define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1065#define TIME_INIT (1<<2)
1066#define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1067#define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1068#define DO_CHDIR (1<<6)
1069
1070/*
1071 define a list of possible SMB messages and their corresponding
1072 functions. Any message that has a NULL function is unimplemented -
1073 please feel free to contribute implementations!
1074*/
1075static const struct smb_message_struct {
1076 const char *name;
1077 void (*fn)(struct smb_request *req);
1078 int flags;
1079} smb_messages[256] = {
1080
1081/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1082/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1083/* 0x02 */ { "SMBopen",reply_open,AS_USER },
1084/* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1085/* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1086/* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1087/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1088/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1089/* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1090/* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1091/* 0x0a */ { "SMBread",reply_read,AS_USER},
1092/* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1093/* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1094/* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1095/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1096/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1097/* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1098/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1099/* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1100/* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1101/* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1102/* 0x15 */ { NULL, NULL, 0 },
1103/* 0x16 */ { NULL, NULL, 0 },
1104/* 0x17 */ { NULL, NULL, 0 },
1105/* 0x18 */ { NULL, NULL, 0 },
1106/* 0x19 */ { NULL, NULL, 0 },
1107/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1108/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1109/* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1110/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1111/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1112/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1113/* 0x20 */ { "SMBwritec", NULL,0},
1114/* 0x21 */ { NULL, NULL, 0 },
1115/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1116/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1117/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1118/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1119/* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1120/* 0x27 */ { "SMBioctl",reply_ioctl,0},
1121/* 0x28 */ { "SMBioctls", NULL,AS_USER},
1122/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1123/* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1124/* 0x2b */ { "SMBecho",reply_echo,0},
1125/* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1126/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1127/* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1128/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1129/* 0x30 */ { NULL, NULL, 0 },
1130/* 0x31 */ { NULL, NULL, 0 },
1131/* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1132/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1133/* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1134/* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1135/* 0x36 */ { NULL, NULL, 0 },
1136/* 0x37 */ { NULL, NULL, 0 },
1137/* 0x38 */ { NULL, NULL, 0 },
1138/* 0x39 */ { NULL, NULL, 0 },
1139/* 0x3a */ { NULL, NULL, 0 },
1140/* 0x3b */ { NULL, NULL, 0 },
1141/* 0x3c */ { NULL, NULL, 0 },
1142/* 0x3d */ { NULL, NULL, 0 },
1143/* 0x3e */ { NULL, NULL, 0 },
1144/* 0x3f */ { NULL, NULL, 0 },
1145/* 0x40 */ { NULL, NULL, 0 },
1146/* 0x41 */ { NULL, NULL, 0 },
1147/* 0x42 */ { NULL, NULL, 0 },
1148/* 0x43 */ { NULL, NULL, 0 },
1149/* 0x44 */ { NULL, NULL, 0 },
1150/* 0x45 */ { NULL, NULL, 0 },
1151/* 0x46 */ { NULL, NULL, 0 },
1152/* 0x47 */ { NULL, NULL, 0 },
1153/* 0x48 */ { NULL, NULL, 0 },
1154/* 0x49 */ { NULL, NULL, 0 },
1155/* 0x4a */ { NULL, NULL, 0 },
1156/* 0x4b */ { NULL, NULL, 0 },
1157/* 0x4c */ { NULL, NULL, 0 },
1158/* 0x4d */ { NULL, NULL, 0 },
1159/* 0x4e */ { NULL, NULL, 0 },
1160/* 0x4f */ { NULL, NULL, 0 },
1161/* 0x50 */ { NULL, NULL, 0 },
1162/* 0x51 */ { NULL, NULL, 0 },
1163/* 0x52 */ { NULL, NULL, 0 },
1164/* 0x53 */ { NULL, NULL, 0 },
1165/* 0x54 */ { NULL, NULL, 0 },
1166/* 0x55 */ { NULL, NULL, 0 },
1167/* 0x56 */ { NULL, NULL, 0 },
1168/* 0x57 */ { NULL, NULL, 0 },
1169/* 0x58 */ { NULL, NULL, 0 },
1170/* 0x59 */ { NULL, NULL, 0 },
1171/* 0x5a */ { NULL, NULL, 0 },
1172/* 0x5b */ { NULL, NULL, 0 },
1173/* 0x5c */ { NULL, NULL, 0 },
1174/* 0x5d */ { NULL, NULL, 0 },
1175/* 0x5e */ { NULL, NULL, 0 },
1176/* 0x5f */ { NULL, NULL, 0 },
1177/* 0x60 */ { NULL, NULL, 0 },
1178/* 0x61 */ { NULL, NULL, 0 },
1179/* 0x62 */ { NULL, NULL, 0 },
1180/* 0x63 */ { NULL, NULL, 0 },
1181/* 0x64 */ { NULL, NULL, 0 },
1182/* 0x65 */ { NULL, NULL, 0 },
1183/* 0x66 */ { NULL, NULL, 0 },
1184/* 0x67 */ { NULL, NULL, 0 },
1185/* 0x68 */ { NULL, NULL, 0 },
1186/* 0x69 */ { NULL, NULL, 0 },
1187/* 0x6a */ { NULL, NULL, 0 },
1188/* 0x6b */ { NULL, NULL, 0 },
1189/* 0x6c */ { NULL, NULL, 0 },
1190/* 0x6d */ { NULL, NULL, 0 },
1191/* 0x6e */ { NULL, NULL, 0 },
1192/* 0x6f */ { NULL, NULL, 0 },
1193/* 0x70 */ { "SMBtcon",reply_tcon,0},
1194/* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1195/* 0x72 */ { "SMBnegprot",reply_negprot,0},
1196/* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1197/* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1198/* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1199/* 0x76 */ { NULL, NULL, 0 },
1200/* 0x77 */ { NULL, NULL, 0 },
1201/* 0x78 */ { NULL, NULL, 0 },
1202/* 0x79 */ { NULL, NULL, 0 },
1203/* 0x7a */ { NULL, NULL, 0 },
1204/* 0x7b */ { NULL, NULL, 0 },
1205/* 0x7c */ { NULL, NULL, 0 },
1206/* 0x7d */ { NULL, NULL, 0 },
1207/* 0x7e */ { NULL, NULL, 0 },
1208/* 0x7f */ { NULL, NULL, 0 },
1209/* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1210/* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1211/* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1212/* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1213/* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1214/* 0x85 */ { NULL, NULL, 0 },
1215/* 0x86 */ { NULL, NULL, 0 },
1216/* 0x87 */ { NULL, NULL, 0 },
1217/* 0x88 */ { NULL, NULL, 0 },
1218/* 0x89 */ { NULL, NULL, 0 },
1219/* 0x8a */ { NULL, NULL, 0 },
1220/* 0x8b */ { NULL, NULL, 0 },
1221/* 0x8c */ { NULL, NULL, 0 },
1222/* 0x8d */ { NULL, NULL, 0 },
1223/* 0x8e */ { NULL, NULL, 0 },
1224/* 0x8f */ { NULL, NULL, 0 },
1225/* 0x90 */ { NULL, NULL, 0 },
1226/* 0x91 */ { NULL, NULL, 0 },
1227/* 0x92 */ { NULL, NULL, 0 },
1228/* 0x93 */ { NULL, NULL, 0 },
1229/* 0x94 */ { NULL, NULL, 0 },
1230/* 0x95 */ { NULL, NULL, 0 },
1231/* 0x96 */ { NULL, NULL, 0 },
1232/* 0x97 */ { NULL, NULL, 0 },
1233/* 0x98 */ { NULL, NULL, 0 },
1234/* 0x99 */ { NULL, NULL, 0 },
1235/* 0x9a */ { NULL, NULL, 0 },
1236/* 0x9b */ { NULL, NULL, 0 },
1237/* 0x9c */ { NULL, NULL, 0 },
1238/* 0x9d */ { NULL, NULL, 0 },
1239/* 0x9e */ { NULL, NULL, 0 },
1240/* 0x9f */ { NULL, NULL, 0 },
1241/* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1242/* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1243/* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1244/* 0xa3 */ { NULL, NULL, 0 },
1245/* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1246/* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1247/* 0xa6 */ { NULL, NULL, 0 },
1248/* 0xa7 */ { NULL, NULL, 0 },
1249/* 0xa8 */ { NULL, NULL, 0 },
1250/* 0xa9 */ { NULL, NULL, 0 },
1251/* 0xaa */ { NULL, NULL, 0 },
1252/* 0xab */ { NULL, NULL, 0 },
1253/* 0xac */ { NULL, NULL, 0 },
1254/* 0xad */ { NULL, NULL, 0 },
1255/* 0xae */ { NULL, NULL, 0 },
1256/* 0xaf */ { NULL, NULL, 0 },
1257/* 0xb0 */ { NULL, NULL, 0 },
1258/* 0xb1 */ { NULL, NULL, 0 },
1259/* 0xb2 */ { NULL, NULL, 0 },
1260/* 0xb3 */ { NULL, NULL, 0 },
1261/* 0xb4 */ { NULL, NULL, 0 },
1262/* 0xb5 */ { NULL, NULL, 0 },
1263/* 0xb6 */ { NULL, NULL, 0 },
1264/* 0xb7 */ { NULL, NULL, 0 },
1265/* 0xb8 */ { NULL, NULL, 0 },
1266/* 0xb9 */ { NULL, NULL, 0 },
1267/* 0xba */ { NULL, NULL, 0 },
1268/* 0xbb */ { NULL, NULL, 0 },
1269/* 0xbc */ { NULL, NULL, 0 },
1270/* 0xbd */ { NULL, NULL, 0 },
1271/* 0xbe */ { NULL, NULL, 0 },
1272/* 0xbf */ { NULL, NULL, 0 },
1273/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1274/* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1275/* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1276/* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1277/* 0xc4 */ { NULL, NULL, 0 },
1278/* 0xc5 */ { NULL, NULL, 0 },
1279/* 0xc6 */ { NULL, NULL, 0 },
1280/* 0xc7 */ { NULL, NULL, 0 },
1281/* 0xc8 */ { NULL, NULL, 0 },
1282/* 0xc9 */ { NULL, NULL, 0 },
1283/* 0xca */ { NULL, NULL, 0 },
1284/* 0xcb */ { NULL, NULL, 0 },
1285/* 0xcc */ { NULL, NULL, 0 },
1286/* 0xcd */ { NULL, NULL, 0 },
1287/* 0xce */ { NULL, NULL, 0 },
1288/* 0xcf */ { NULL, NULL, 0 },
1289/* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1290/* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1291/* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1292/* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1293/* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1294/* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1295/* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1296/* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1297/* 0xd8 */ { NULL, NULL, 0 },
1298/* 0xd9 */ { NULL, NULL, 0 },
1299/* 0xda */ { NULL, NULL, 0 },
1300/* 0xdb */ { NULL, NULL, 0 },
1301/* 0xdc */ { NULL, NULL, 0 },
1302/* 0xdd */ { NULL, NULL, 0 },
1303/* 0xde */ { NULL, NULL, 0 },
1304/* 0xdf */ { NULL, NULL, 0 },
1305/* 0xe0 */ { NULL, NULL, 0 },
1306/* 0xe1 */ { NULL, NULL, 0 },
1307/* 0xe2 */ { NULL, NULL, 0 },
1308/* 0xe3 */ { NULL, NULL, 0 },
1309/* 0xe4 */ { NULL, NULL, 0 },
1310/* 0xe5 */ { NULL, NULL, 0 },
1311/* 0xe6 */ { NULL, NULL, 0 },
1312/* 0xe7 */ { NULL, NULL, 0 },
1313/* 0xe8 */ { NULL, NULL, 0 },
1314/* 0xe9 */ { NULL, NULL, 0 },
1315/* 0xea */ { NULL, NULL, 0 },
1316/* 0xeb */ { NULL, NULL, 0 },
1317/* 0xec */ { NULL, NULL, 0 },
1318/* 0xed */ { NULL, NULL, 0 },
1319/* 0xee */ { NULL, NULL, 0 },
1320/* 0xef */ { NULL, NULL, 0 },
1321/* 0xf0 */ { NULL, NULL, 0 },
1322/* 0xf1 */ { NULL, NULL, 0 },
1323/* 0xf2 */ { NULL, NULL, 0 },
1324/* 0xf3 */ { NULL, NULL, 0 },
1325/* 0xf4 */ { NULL, NULL, 0 },
1326/* 0xf5 */ { NULL, NULL, 0 },
1327/* 0xf6 */ { NULL, NULL, 0 },
1328/* 0xf7 */ { NULL, NULL, 0 },
1329/* 0xf8 */ { NULL, NULL, 0 },
1330/* 0xf9 */ { NULL, NULL, 0 },
1331/* 0xfa */ { NULL, NULL, 0 },
1332/* 0xfb */ { NULL, NULL, 0 },
1333/* 0xfc */ { NULL, NULL, 0 },
1334/* 0xfd */ { NULL, NULL, 0 },
1335/* 0xfe */ { NULL, NULL, 0 },
1336/* 0xff */ { NULL, NULL, 0 }
1337
1338};
1339
1340/*******************************************************************
1341 allocate and initialize a reply packet
1342********************************************************************/
1343
1344static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1345 const uint8_t *inbuf, char **outbuf,
1346 uint8_t num_words, uint32_t num_bytes)
1347{
1348 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1349
1350 /*
1351 * Protect against integer wrap.
1352 * The SMB layer reply can be up to 0xFFFFFF bytes.
1353 */
1354 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1355 char *msg;
1356 if (asprintf(&msg, "num_bytes too large: %u",
1357 (unsigned)num_bytes) == -1) {
1358 msg = discard_const_p(char, "num_bytes too large");
1359 }
1360 smb_panic(msg);
1361 }
1362
1363 /*
1364 * Here we include the NBT header for now.
1365 */
1366 *outbuf = talloc_array(mem_ctx, char,
1367 NBT_HDR_SIZE + smb_len);
1368 if (*outbuf == NULL) {
1369 return false;
1370 }
1371
1372 construct_reply_common(req->cmd, inbuf, *outbuf);
1373 srv_set_message(*outbuf, num_words, num_bytes, false);
1374 /*
1375 * Zero out the word area, the caller has to take care of the bcc area
1376 * himself
1377 */
1378 if (num_words != 0) {
1379 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1380 }
1381
1382 return true;
1383}
1384
1385void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1386{
1387 char *outbuf;
1388 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1389 num_bytes)) {
1390 smb_panic("could not allocate output buffer\n");
1391 }
1392 req->outbuf = (uint8_t *)outbuf;
1393}
1394
1395
1396/*******************************************************************
1397 Dump a packet to a file.
1398********************************************************************/
1399
1400static void smb_dump(const char *name, int type, const char *data)
1401{
1402 size_t len;
1403 int fd, i;
1404 char *fname = NULL;
1405 if (DEBUGLEVEL < 50) {
1406 return;
1407 }
1408
1409 len = smb_len_tcp(data)+4;
1410 for (i=1;i<100;i++) {
1411 fname = talloc_asprintf(talloc_tos(),
1412 "/tmp/%s.%d.%s",
1413 name,
1414 i,
1415 type ? "req" : "resp");
1416 if (fname == NULL) {
1417 return;
1418 }
1419 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1420 if (fd != -1 || errno != EEXIST) break;
1421 TALLOC_FREE(fname);
1422 }
1423 if (fd != -1) {
1424 ssize_t ret = write(fd, data, len);
1425 if (ret != len)
1426 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1427 close(fd);
1428 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1429 }
1430 TALLOC_FREE(fname);
1431}
1432
1433static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1434 struct smb_request *req,
1435 uint8_t type,
1436 bool *update_session_globalp,
1437 bool *update_tcon_globalp)
1438{
1439 connection_struct *conn = req->conn;
1440 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1441 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1442 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1443 bool update_session = false;
1444 bool update_tcon = false;
1445
1446 if (req->encrypted) {
1447 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1448 }
1449
1450 if (srv_is_signing_active(req->xconn)) {
1451 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1452 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1453 /*
1454 * echo can be unsigned. Sesssion setup except final
1455 * session setup response too
1456 */
1457 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1458 }
1459
1460 update_session |= smbXsrv_set_crypto_flag(
1461 &session->global->encryption_flags, encrypt_flag);
1462 update_session |= smbXsrv_set_crypto_flag(
1463 &session->global->signing_flags, sign_flag);
1464
1465 if (tcon) {
1466 update_tcon |= smbXsrv_set_crypto_flag(
1467 &tcon->global->encryption_flags, encrypt_flag);
1468 update_tcon |= smbXsrv_set_crypto_flag(
1469 &tcon->global->signing_flags, sign_flag);
1470 }
1471
1472 if (update_session) {
1473 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1474 }
1475
1476 *update_session_globalp = update_session;
1477 *update_tcon_globalp = update_tcon;
1478 return;
1479}
1480
1481/****************************************************************************
1482 Prepare everything for calling the actual request function, and potentially
1483 call the request function via the "new" interface.
1484
1485 Return False if the "legacy" function needs to be called, everything is
1486 prepared.
1487
1488 Return True if we're done.
1489
1490 I know this API sucks, but it is the one with the least code change I could
1491 find.
1492****************************************************************************/
1493
1494static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1495{
1496 int flags;
1497 uint64_t session_tag;
1498 connection_struct *conn = NULL;
1499 struct smbXsrv_connection *xconn = req->xconn;
1500 NTTIME now = timeval_to_nttime(&req->request_time);
1501 struct smbXsrv_session *session = NULL;
1502 NTSTATUS status;
1503
1504 errno = 0;
1505
1506 if (!xconn->smb1.negprot.done) {
1507 switch (type) {
1508 /*
1509 * Without a negprot the request must
1510 * either be a negprot, or one of the
1511 * evil old SMB mailslot messaging types.
1512 */
1513 case SMBnegprot:
1514 case SMBsendstrt:
1515 case SMBsendend:
1516 case SMBsendtxt:
1517 break;
1518 default:
1519 exit_server_cleanly("The first request "
1520 "should be a negprot");
1521 }
1522 }
1523
1524 if (smb_messages[type].fn == NULL) {
1525 DEBUG(0,("Unknown message type %d!\n",type));
1526 smb_dump("Unknown", 1, (const char *)req->inbuf);
1527 reply_unknown_new(req, type);
1528 return NULL;
1529 }
1530
1531 flags = smb_messages[type].flags;
1532
1533 /* In share mode security we must ignore the vuid. */
1534 session_tag = req->vuid;
1535 conn = req->conn;
1536
1537 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1538 (int)getpid(), (unsigned long)conn));
1539
1540 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1541
1542 /* Ensure this value is replaced in the incoming packet. */
1543 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1544
1545 /*
1546 * Ensure the correct username is in current_user_info. This is a
1547 * really ugly bugfix for problems with multiple session_setup_and_X's
1548 * being done and allowing %U and %G substitutions to work correctly.
1549 * There is a reason this code is done here, don't move it unless you
1550 * know what you're doing... :-).
1551 * JRA.
1552 */
1553
1554 /*
1555 * lookup an existing session
1556 *
1557 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1558 * here, the main check is still in change_to_user()
1559 */
1560 status = smb1srv_session_lookup(xconn,
1561 session_tag,
1562 now,
1563 &session);
1564 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1565 switch (type) {
1566 case SMBsesssetupX:
1567 status = NT_STATUS_OK;
1568 break;
1569 default:
1570 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1571 (unsigned long long)session_tag,
1572 (unsigned long long)req->mid));
1573 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1574 return conn;
1575 }
1576 }
1577
1578 if (session_tag != xconn->client->last_session_id) {
1579 struct user_struct *vuser = NULL;
1580
1581 xconn->client->last_session_id = session_tag;
1582 if (session) {
1583 vuser = session->compat;
1584 }
1585 if (vuser) {
1586 set_current_user_info(
1587 vuser->session_info->unix_info->sanitized_username,
1588 vuser->session_info->unix_info->unix_name,
1589 vuser->session_info->info->domain_name);
1590 }
1591 }
1592
1593 /* Does this call need to be run as the connected user? */
1594 if (flags & AS_USER) {
1595
1596 /* Does this call need a valid tree connection? */
1597 if (!conn) {
1598 /*
1599 * Amazingly, the error code depends on the command
1600 * (from Samba4).
1601 */
1602 if (type == SMBntcreateX) {
1603 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1604 } else {
1605 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1606 }
1607 return NULL;
1608 }
1609
1610 if (!change_to_user(conn,session_tag)) {
1611 DEBUG(0, ("Error: Could not change to user. Removing "
1612 "deferred open, mid=%llu.\n",
1613 (unsigned long long)req->mid));
1614 reply_force_doserror(req, ERRSRV, ERRbaduid);
1615 return conn;
1616 }
1617
1618 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1619
1620 /* Does it need write permission? */
1621 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1622 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1623 return conn;
1624 }
1625
1626 /* IPC services are limited */
1627 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1628 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1629 return conn;
1630 }
1631 } else {
1632 /* This call needs to be run as root */
1633 change_to_root_user();
1634 }
1635
1636 /* load service specific parameters */
1637 if (conn) {
1638 if (req->encrypted) {
1639 conn->encrypted_tid = true;
1640 /* encrypted required from now on. */
1641 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1642 } else if (ENCRYPTION_REQUIRED(conn)) {
1643 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1644 DEBUG(1,("service[%s] requires encryption"
1645 "%s ACCESS_DENIED. mid=%llu\n",
1646 lp_servicename(talloc_tos(), SNUM(conn)),
1647 smb_fn_name(type),
1648 (unsigned long long)req->mid));
1649 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1650 return conn;
1651 }
1652 }
1653
1654 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1655 (flags & (AS_USER|DO_CHDIR)
1656 ?True:False))) {
1657 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1658 return conn;
1659 }
1660 conn->num_smb_operations++;
1661 }
1662
1663 /*
1664 * Does this protocol need to be run as guest? (Only archane
1665 * messenger service requests have this...)
1666 */
1667 if (flags & AS_GUEST) {
1668 char *raddr;
1669 bool ok;
1670
1671 if (!change_to_guest()) {
1672 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1673 return conn;
1674 }
1675
1676 raddr = tsocket_address_inet_addr_string(xconn->remote_address,
1677 talloc_tos());
1678 if (raddr == NULL) {
1679 reply_nterror(req, NT_STATUS_NO_MEMORY);
1680 return conn;
1681 }
1682
1683 /*
1684 * Haven't we checked this in smbd_process already???
1685 */
1686
1687 ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
1688 xconn->remote_hostname, raddr);
1689 TALLOC_FREE(raddr);
1690
1691 if (!ok) {
1692 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1693 return conn;
1694 }
1695 }
1696
1697 /*
1698 * Update encryption and signing state tracking flags that are
1699 * used by smbstatus to display signing and encryption status.
1700 */
1701 if (session != NULL) {
1702 bool update_session_global = false;
1703 bool update_tcon_global = false;
1704
1705 smb1srv_update_crypto_flags(session, req, type,
1706 &update_session_global,
1707 &update_tcon_global);
1708
1709 if (update_session_global) {
1710 status = smbXsrv_session_update(session);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1713 return conn;
1714 }
1715 }
1716
1717 if (update_tcon_global) {
1718 status = smbXsrv_tcon_update(req->conn->tcon);
1719 if (!NT_STATUS_IS_OK(status)) {
1720 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1721 return conn;
1722 }
1723 }
1724 }
1725
1726 smb_messages[type].fn(req);
1727 return req->conn;
1728}
1729
1730/****************************************************************************
1731 Construct a reply to the incoming packet.
1732****************************************************************************/
1733
1734static void construct_reply(struct smbXsrv_connection *xconn,
1735 char *inbuf, int size, size_t unread_bytes,
1736 uint32_t seqnum, bool encrypted,
1737 struct smb_perfcount_data *deferred_pcd)
1738{
1739 struct smbd_server_connection *sconn = xconn->client->sconn;
1740 struct smb_request *req;
1741
1742 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1743 smb_panic("could not allocate smb_request");
1744 }
1745
1746 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1747 encrypted, seqnum)) {
1748 exit_server_cleanly("Invalid SMB request");
1749 }
1750
1751 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1752
1753 /* we popped this message off the queue - keep original perf data */
1754 if (deferred_pcd)
1755 req->pcd = *deferred_pcd;
1756 else {
1757 SMB_PERFCOUNT_START(&req->pcd);
1758 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1759 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1760 }
1761
1762 req->conn = switch_message(req->cmd, req);
1763
1764 if (req->outbuf == NULL) {
1765 /*
1766 * Request has suspended itself, will come
1767 * back here.
1768 */
1769 return;
1770 }
1771 if (CVAL(req->outbuf,0) == 0) {
1772 show_msg((char *)req->outbuf);
1773 }
1774 smb_request_done(req);
1775}
1776
1777static void construct_reply_chain(struct smbXsrv_connection *xconn,
1778 char *inbuf, int size, uint32_t seqnum,
1779 bool encrypted,
1780 struct smb_perfcount_data *deferred_pcd)
1781{
1782 struct smb_request **reqs = NULL;
1783 struct smb_request *req;
1784 unsigned num_reqs;
1785 bool ok;
1786
1787 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, xconn, encrypted,
1788 seqnum, &reqs, &num_reqs);
1789 if (!ok) {
1790 char errbuf[smb_size];
1791 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1792 __LINE__, __FILE__);
1793 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1794 NULL)) {
1795 exit_server_cleanly("construct_reply_chain: "
1796 "srv_send_smb failed.");
1797 }
1798 return;
1799 }
1800
1801 req = reqs[0];
1802 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1803
1804 req->conn = switch_message(req->cmd, req);
1805
1806 if (req->outbuf == NULL) {
1807 /*
1808 * Request has suspended itself, will come
1809 * back here.
1810 */
1811 return;
1812 }
1813 smb_request_done(req);
1814}
1815
1816/*
1817 * To be called from an async SMB handler that is potentially chained
1818 * when it is finished for shipping.
1819 */
1820
1821void smb_request_done(struct smb_request *req)
1822{
1823 struct smb_request **reqs = NULL;
1824 struct smb_request *first_req;
1825 size_t i, num_reqs, next_index;
1826 NTSTATUS status;
1827
1828 if (req->chain == NULL) {
1829 first_req = req;
1830 goto shipit;
1831 }
1832
1833 reqs = req->chain;
1834 num_reqs = talloc_array_length(reqs);
1835
1836 for (i=0; i<num_reqs; i++) {
1837 if (reqs[i] == req) {
1838 break;
1839 }
1840 }
1841 if (i == num_reqs) {
1842 /*
1843 * Invalid chain, should not happen
1844 */
1845 status = NT_STATUS_INTERNAL_ERROR;
1846 goto error;
1847 }
1848 next_index = i+1;
1849
1850 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1851 struct smb_request *next = reqs[next_index];
1852 struct smbXsrv_tcon *tcon;
1853 NTTIME now = timeval_to_nttime(&req->request_time);
1854
1855 next->vuid = SVAL(req->outbuf, smb_uid);
1856 next->tid = SVAL(req->outbuf, smb_tid);
1857 status = smb1srv_tcon_lookup(req->xconn, req->tid,
1858 now, &tcon);
1859 if (NT_STATUS_IS_OK(status)) {
1860 req->conn = tcon->compat;
1861 } else {
1862 req->conn = NULL;
1863 }
1864 next->chain_fsp = req->chain_fsp;
1865 next->inbuf = req->inbuf;
1866
1867 req = next;
1868 req->conn = switch_message(req->cmd, req);
1869
1870 if (req->outbuf == NULL) {
1871 /*
1872 * Request has suspended itself, will come
1873 * back here.
1874 */
1875 return;
1876 }
1877 next_index += 1;
1878 }
1879
1880 first_req = reqs[0];
1881
1882 for (i=1; i<next_index; i++) {
1883 bool ok;
1884
1885 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1886 if (!ok) {
1887 status = NT_STATUS_INTERNAL_ERROR;
1888 goto error;
1889 }
1890 }
1891
1892 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1893 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1894
1895 /*
1896 * This scary statement intends to set the
1897 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1898 * to the value last_req->outbuf carries
1899 */
1900 SSVAL(first_req->outbuf, smb_flg2,
1901 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1902 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1903
1904 /*
1905 * Transfer the error codes from the subrequest to the main one
1906 */
1907 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1908 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1909
1910 _smb_setlen_large(
1911 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1912
1913shipit:
1914 if (!srv_send_smb(first_req->xconn,
1915 (char *)first_req->outbuf,
1916 true, first_req->seqnum+1,
1917 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1918 &first_req->pcd)) {
1919 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1920 "failed.");
1921 }
1922 TALLOC_FREE(req); /* non-chained case */
1923 TALLOC_FREE(reqs); /* chained case */
1924 return;
1925
1926error:
1927 {
1928 char errbuf[smb_size];
1929 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1930 if (!srv_send_smb(req->xconn, errbuf, true,
1931 req->seqnum+1, req->encrypted,
1932 NULL)) {
1933 exit_server_cleanly("construct_reply_chain: "
1934 "srv_send_smb failed.");
1935 }
1936 }
1937 TALLOC_FREE(req); /* non-chained case */
1938 TALLOC_FREE(reqs); /* chained case */
1939}
1940
1941/****************************************************************************
1942 Process an smb from the client
1943****************************************************************************/
1944static void process_smb(struct smbXsrv_connection *xconn,
1945 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1946 uint32_t seqnum, bool encrypted,
1947 struct smb_perfcount_data *deferred_pcd)
1948{
1949 struct smbd_server_connection *sconn = xconn->client->sconn;
1950 int msg_type = CVAL(inbuf,0);
1951
1952 DO_PROFILE_INC(request);
1953
1954 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1955 smb_len(inbuf) ) );
1956 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1957 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1958
1959 if (msg_type != NBSSmessage) {
1960 /*
1961 * NetBIOS session request, keepalive, etc.
1962 */
1963 reply_special(xconn, (char *)inbuf, nread);
1964 goto done;
1965 }
1966
1967 if (sconn->using_smb2) {
1968 /* At this point we're not really using smb2,
1969 * we make the decision here.. */
1970 if (smbd_is_smb2_header(inbuf, nread)) {
1971 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1972 size_t pdulen = nread - NBT_HDR_SIZE;
1973 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1974 return;
1975 } else if (nread >= smb_size && valid_smb_header(inbuf)
1976 && CVAL(inbuf, smb_com) != 0x72) {
1977 /* This is a non-negprot SMB1 packet.
1978 Disable SMB2 from now on. */
1979 sconn->using_smb2 = false;
1980 }
1981 }
1982
1983 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1984 * so subtract 4 from it. */
1985 if ((nread < (smb_size - 4)) || !valid_smb_header(inbuf)) {
1986 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1987 smb_len(inbuf)));
1988
1989 /* special magic for immediate exit */
1990 if ((nread == 9) &&
1991 (IVAL(inbuf, 4) == 0x74697865) &&
1992 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1993 uint8_t exitcode = CVAL(inbuf, 8);
1994 DEBUG(1, ("Exiting immediately with code %d\n",
1995 (int)exitcode));
1996 exit(exitcode);
1997 }
1998
1999 exit_server_cleanly("Non-SMB packet");
2000 }
2001
2002 show_msg((char *)inbuf);
2003
2004 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
2005 construct_reply_chain(xconn, (char *)inbuf, nread,
2006 seqnum, encrypted, deferred_pcd);
2007 } else {
2008 construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
2009 seqnum, encrypted, deferred_pcd);
2010 }
2011
2012 sconn->trans_num++;
2013
2014done:
2015 sconn->num_requests++;
2016
2017 /* The timeout_processing function isn't run nearly
2018 often enough to implement 'max log size' without
2019 overrunning the size of the file by many megabytes.
2020 This is especially true if we are running at debug
2021 level 10. Checking every 50 SMBs is a nice
2022 tradeoff of performance vs log file size overrun. */
2023
2024 if ((sconn->num_requests % 50) == 0 &&
2025 need_to_check_log_size()) {
2026 change_to_root_user();
2027 check_log_size();
2028 }
2029}
2030
2031/****************************************************************************
2032 Return a string containing the function name of a SMB command.
2033****************************************************************************/
2034
2035const char *smb_fn_name(int type)
2036{
2037 const char *unknown_name = "SMBunknown";
2038
2039 if (smb_messages[type].name == NULL)
2040 return(unknown_name);
2041
2042 return(smb_messages[type].name);
2043}
2044
2045/****************************************************************************
2046 Helper functions for contruct_reply.
2047****************************************************************************/
2048
2049void add_to_common_flags2(uint32_t v)
2050{
2051 common_flags2 |= v;
2052}
2053
2054void remove_from_common_flags2(uint32_t v)
2055{
2056 common_flags2 &= ~v;
2057}
2058
2059static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2060 char *outbuf)
2061{
2062 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2063 uint16_t out_flags2 = common_flags2;
2064
2065 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
2066 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
2067 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
2068
2069 srv_set_message(outbuf,0,0,false);
2070
2071 SCVAL(outbuf, smb_com, cmd);
2072 SIVAL(outbuf,smb_rcls,0);
2073 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
2074 SSVAL(outbuf,smb_flg2, out_flags2);
2075 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
2076 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
2077
2078 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2079 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2080 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2081 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2082}
2083
2084void construct_reply_common_req(struct smb_request *req, char *outbuf)
2085{
2086 construct_reply_common(req->cmd, req->inbuf, outbuf);
2087}
2088
2089/**
2090 * @brief Find the smb_cmd offset of the last command pushed
2091 * @param[in] buf The buffer we're building up
2092 * @retval Where can we put our next andx cmd?
2093 *
2094 * While chaining requests, the "next" request we're looking at needs to put
2095 * its SMB_Command before the data the previous request already built up added
2096 * to the chain. Find the offset to the place where we have to put our cmd.
2097 */
2098
2099static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2100{
2101 uint8_t cmd;
2102 size_t ofs;
2103
2104 cmd = CVAL(buf, smb_com);
2105
2106 if (!is_andx_req(cmd)) {
2107 return false;
2108 }
2109
2110 ofs = smb_vwv0;
2111
2112 while (CVAL(buf, ofs) != 0xff) {
2113
2114 if (!is_andx_req(CVAL(buf, ofs))) {
2115 return false;
2116 }
2117
2118 /*
2119 * ofs is from start of smb header, so add the 4 length
2120 * bytes. The next cmd is right after the wct field.
2121 */
2122 ofs = SVAL(buf, ofs+2) + 4 + 1;
2123
2124 if (ofs+4 >= talloc_get_size(buf)) {
2125 return false;
2126 }
2127 }
2128
2129 *pofs = ofs;
2130 return true;
2131}
2132
2133/**
2134 * @brief Do the smb chaining at a buffer level
2135 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2136 * @param[in] andx_buf Buffer to be appended
2137 */
2138
2139static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2140{
2141 uint8_t smb_command = CVAL(andx_buf, smb_com);
2142 uint8_t wct = CVAL(andx_buf, smb_wct);
2143 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2144 uint32_t num_bytes = smb_buflen(andx_buf);
2145 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2146
2147 uint8_t *outbuf;
2148 size_t old_size, new_size;
2149 size_t ofs;
2150 size_t chain_padding = 0;
2151 size_t andx_cmd_ofs;
2152
2153
2154 old_size = talloc_get_size(*poutbuf);
2155
2156 if ((old_size % 4) != 0) {
2157 /*
2158 * Align the wct field of subsequent requests to a 4-byte
2159 * boundary
2160 */
2161 chain_padding = 4 - (old_size % 4);
2162 }
2163
2164 /*
2165 * After the old request comes the new wct field (1 byte), the vwv's
2166 * and the num_bytes field.
2167 */
2168
2169 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2170 new_size += num_bytes;
2171
2172 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2173 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2174 (unsigned)new_size));
2175 return false;
2176 }
2177
2178 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2179 if (outbuf == NULL) {
2180 DEBUG(0, ("talloc failed\n"));
2181 return false;
2182 }
2183 *poutbuf = outbuf;
2184
2185 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2186 DEBUG(1, ("invalid command chain\n"));
2187 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2188 return false;
2189 }
2190
2191 if (chain_padding != 0) {
2192 memset(outbuf + old_size, 0, chain_padding);
2193 old_size += chain_padding;
2194 }
2195
2196 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2197 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2198
2199 ofs = old_size;
2200
2201 /*
2202 * Push the chained request:
2203 *
2204 * wct field
2205 */
2206
2207 SCVAL(outbuf, ofs, wct);
2208 ofs += 1;
2209
2210 /*
2211 * vwv array
2212 */
2213
2214 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2215
2216 /*
2217 * HACK ALERT
2218 *
2219 * Read&X has an offset into its data buffer at
2220 * vwv[6]. reply_read_andx has no idea anymore that it's
2221 * running from within a chain, so we have to fix up the
2222 * offset here.
2223 *
2224 * Although it looks disgusting at this place, I want to keep
2225 * it here. The alternative would be to push knowledge about
2226 * the andx chain down into read&x again.
2227 */
2228
2229 if (smb_command == SMBreadX) {
2230 uint8_t *bytes_addr;
2231
2232 if (wct < 7) {
2233 /*
2234 * Invalid read&x response
2235 */
2236 return false;
2237 }
2238
2239 bytes_addr = outbuf + ofs /* vwv start */
2240 + sizeof(uint16_t) * wct /* vwv array */
2241 + sizeof(uint16_t) /* bcc */
2242 + 1; /* padding byte */
2243
2244 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2245 bytes_addr - outbuf - 4);
2246 }
2247
2248 ofs += sizeof(uint16_t) * wct;
2249
2250 /*
2251 * bcc (byte count)
2252 */
2253
2254 SSVAL(outbuf, ofs, num_bytes);
2255 ofs += sizeof(uint16_t);
2256
2257 /*
2258 * The bytes field
2259 */
2260
2261 memcpy(outbuf + ofs, bytes, num_bytes);
2262
2263 return true;
2264}
2265
2266bool smb1_is_chain(const uint8_t *buf)
2267{
2268 uint8_t cmd, wct, andx_cmd;
2269
2270 cmd = CVAL(buf, smb_com);
2271 if (!is_andx_req(cmd)) {
2272 return false;
2273 }
2274 wct = CVAL(buf, smb_wct);
2275 if (wct < 2) {
2276 return false;
2277 }
2278 andx_cmd = CVAL(buf, smb_vwv);
2279 return (andx_cmd != 0xFF);
2280}
2281
2282bool smb1_walk_chain(const uint8_t *buf,
2283 bool (*fn)(uint8_t cmd,
2284 uint8_t wct, const uint16_t *vwv,
2285 uint16_t num_bytes, const uint8_t *bytes,
2286 void *private_data),
2287 void *private_data)
2288{
2289 size_t smblen = smb_len(buf);
2290 const char *smb_buf = smb_base(buf);
2291 uint8_t cmd, chain_cmd;
2292 uint8_t wct;
2293 const uint16_t *vwv;
2294 uint16_t num_bytes;
2295 const uint8_t *bytes;
2296
2297 cmd = CVAL(buf, smb_com);
2298 wct = CVAL(buf, smb_wct);
2299 vwv = (const uint16_t *)(buf + smb_vwv);
2300 num_bytes = smb_buflen(buf);
2301 bytes = (const uint8_t *)smb_buf_const(buf);
2302
2303 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2304 return false;
2305 }
2306
2307 if (!is_andx_req(cmd)) {
2308 return true;
2309 }
2310 if (wct < 2) {
2311 return false;
2312 }
2313
2314 chain_cmd = CVAL(vwv, 0);
2315
2316 while (chain_cmd != 0xff) {
2317 uint32_t chain_offset; /* uint32_t to avoid overflow */
2318 size_t length_needed;
2319 ptrdiff_t vwv_offset;
2320
2321 chain_offset = SVAL(vwv+1, 0);
2322
2323 /*
2324 * Check if the client tries to fool us. The chain
2325 * offset needs to point beyond the current request in
2326 * the chain, it needs to strictly grow. Otherwise we
2327 * might be tricked into an endless loop always
2328 * processing the same request over and over again. We
2329 * used to assume that vwv and the byte buffer array
2330 * in a chain are always attached, but OS/2 the
2331 * Write&X/Read&X chain puts the Read&X vwv array
2332 * right behind the Write&X vwv chain. The Write&X bcc
2333 * array is put behind the Read&X vwv array. So now we
2334 * check whether the chain offset points strictly
2335 * behind the previous vwv array. req->buf points
2336 * right after the vwv array of the previous
2337 * request. See
2338 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2339 * more information.
2340 */
2341
2342 vwv_offset = ((const char *)vwv - smb_buf);
2343 if (chain_offset <= vwv_offset) {
2344 return false;
2345 }
2346
2347 /*
2348 * Next check: Make sure the chain offset does not
2349 * point beyond the overall smb request length.
2350 */
2351
2352 length_needed = chain_offset+1; /* wct */
2353 if (length_needed > smblen) {
2354 return false;
2355 }
2356
2357 /*
2358 * Now comes the pointer magic. Goal here is to set up
2359 * vwv and buf correctly again. The chain offset (the
2360 * former vwv[1]) points at the new wct field.
2361 */
2362
2363 wct = CVAL(smb_buf, chain_offset);
2364
2365 if (is_andx_req(chain_cmd) && (wct < 2)) {
2366 return false;
2367 }
2368
2369 /*
2370 * Next consistency check: Make the new vwv array fits
2371 * in the overall smb request.
2372 */
2373
2374 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2375 if (length_needed > smblen) {
2376 return false;
2377 }
2378 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2379
2380 /*
2381 * Now grab the new byte buffer....
2382 */
2383
2384 num_bytes = SVAL(vwv+wct, 0);
2385
2386 /*
2387 * .. and check that it fits.
2388 */
2389
2390 length_needed += num_bytes;
2391 if (length_needed > smblen) {
2392 return false;
2393 }
2394 bytes = (const uint8_t *)(vwv+wct+1);
2395
2396 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2397 return false;
2398 }
2399
2400 if (!is_andx_req(chain_cmd)) {
2401 return true;
2402 }
2403 chain_cmd = CVAL(vwv, 0);
2404 }
2405 return true;
2406}
2407
2408static bool smb1_chain_length_cb(uint8_t cmd,
2409 uint8_t wct, const uint16_t *vwv,
2410 uint16_t num_bytes, const uint8_t *bytes,
2411 void *private_data)
2412{
2413 unsigned *count = (unsigned *)private_data;
2414 *count += 1;
2415 return true;
2416}
2417
2418unsigned smb1_chain_length(const uint8_t *buf)
2419{
2420 unsigned count = 0;
2421
2422 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2423 return 0;
2424 }
2425 return count;
2426}
2427
2428struct smb1_parse_chain_state {
2429 TALLOC_CTX *mem_ctx;
2430 const uint8_t *buf;
2431 struct smbd_server_connection *sconn;
2432 struct smbXsrv_connection *xconn;
2433 bool encrypted;
2434 uint32_t seqnum;
2435
2436 struct smb_request **reqs;
2437 unsigned num_reqs;
2438};
2439
2440static bool smb1_parse_chain_cb(uint8_t cmd,
2441 uint8_t wct, const uint16_t *vwv,
2442 uint16_t num_bytes, const uint8_t *bytes,
2443 void *private_data)
2444{
2445 struct smb1_parse_chain_state *state =
2446 (struct smb1_parse_chain_state *)private_data;
2447 struct smb_request **reqs;
2448 struct smb_request *req;
2449 bool ok;
2450
2451 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2452 struct smb_request *, state->num_reqs+1);
2453 if (reqs == NULL) {
2454 return false;
2455 }
2456 state->reqs = reqs;
2457
2458 req = talloc(reqs, struct smb_request);
2459 if (req == NULL) {
2460 return false;
2461 }
2462
2463 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2464 state->encrypted, state->seqnum);
2465 if (!ok) {
2466 return false;
2467 }
2468 req->cmd = cmd;
2469 req->wct = wct;
2470 req->vwv = vwv;
2471 req->buflen = num_bytes;
2472 req->buf = bytes;
2473
2474 reqs[state->num_reqs] = req;
2475 state->num_reqs += 1;
2476 return true;
2477}
2478
2479bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2480 struct smbXsrv_connection *xconn,
2481 bool encrypted, uint32_t seqnum,
2482 struct smb_request ***reqs, unsigned *num_reqs)
2483{
2484 struct smbd_server_connection *sconn = NULL;
2485 struct smb1_parse_chain_state state;
2486 unsigned i;
2487
2488 if (xconn != NULL) {
2489 sconn = xconn->client->sconn;
2490 }
2491
2492 state.mem_ctx = mem_ctx;
2493 state.buf = buf;
2494 state.sconn = sconn;
2495 state.xconn = xconn;
2496 state.encrypted = encrypted;
2497 state.seqnum = seqnum;
2498 state.reqs = NULL;
2499 state.num_reqs = 0;
2500
2501 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2502 TALLOC_FREE(state.reqs);
2503 return false;
2504 }
2505 for (i=0; i<state.num_reqs; i++) {
2506 state.reqs[i]->chain = state.reqs;
2507 }
2508 *reqs = state.reqs;
2509 *num_reqs = state.num_reqs;
2510 return true;
2511}
2512
2513/****************************************************************************
2514 Check if services need reloading.
2515****************************************************************************/
2516
2517static void check_reload(struct smbd_server_connection *sconn, time_t t)
2518{
2519
2520 if (last_smb_conf_reload_time == 0) {
2521 last_smb_conf_reload_time = t;
2522 }
2523
2524 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2525 reload_services(sconn, conn_snum_used, true);
2526 last_smb_conf_reload_time = t;
2527 }
2528}
2529
2530static bool fd_is_readable(int fd)
2531{
2532 int ret, revents;
2533
2534 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2535
2536 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2537
2538}
2539
2540static void smbd_server_connection_write_handler(
2541 struct smbXsrv_connection *xconn)
2542{
2543 /* TODO: make write nonblocking */
2544}
2545
2546static void smbd_server_connection_read_handler(
2547 struct smbXsrv_connection *xconn, int fd)
2548{
2549 uint8_t *inbuf = NULL;
2550 size_t inbuf_len = 0;
2551 size_t unread_bytes = 0;
2552 bool encrypted = false;
2553 TALLOC_CTX *mem_ctx = talloc_tos();
2554 NTSTATUS status;
2555 uint32_t seqnum;
2556
2557 bool async_echo = lp_async_smb_echo_handler();
2558 bool from_client = false;
2559
2560 if (async_echo) {
2561 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2562 /*
2563 * This is the super-ugly hack to prefer the packets
2564 * forwarded by the echo handler over the ones by the
2565 * client directly
2566 */
2567 fd = xconn->smb1.echo_handler.trusted_fd;
2568 }
2569 }
2570
2571 from_client = (xconn->transport.sock == fd);
2572
2573 if (async_echo && from_client) {
2574 smbd_lock_socket(xconn);
2575
2576 if (!fd_is_readable(fd)) {
2577 DEBUG(10,("the echo listener was faster\n"));
2578 smbd_unlock_socket(xconn);
2579 return;
2580 }
2581 }
2582
2583 /* TODO: make this completely nonblocking */
2584 status = receive_smb_talloc(mem_ctx, xconn, fd,
2585 (char **)(void *)&inbuf,
2586 0, /* timeout */
2587 &unread_bytes,
2588 &encrypted,
2589 &inbuf_len, &seqnum,
2590 !from_client /* trusted channel */);
2591
2592 if (async_echo && from_client) {
2593 smbd_unlock_socket(xconn);
2594 }
2595
2596 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2597 goto process;
2598 }
2599 if (NT_STATUS_IS_ERR(status)) {
2600 exit_server_cleanly("failed to receive smb request");
2601 }
2602 if (!NT_STATUS_IS_OK(status)) {
2603 return;
2604 }
2605
2606process:
2607 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2608 seqnum, encrypted, NULL);
2609}
2610
2611static void smbd_server_connection_handler(struct tevent_context *ev,
2612 struct tevent_fd *fde,
2613 uint16_t flags,
2614 void *private_data)
2615{
2616 struct smbXsrv_connection *xconn =
2617 talloc_get_type_abort(private_data,
2618 struct smbXsrv_connection);
2619
2620 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2621 /*
2622 * we're not supposed to do any io
2623 */
2624 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2625 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2626 return;
2627 }
2628
2629 if (flags & TEVENT_FD_WRITE) {
2630 smbd_server_connection_write_handler(xconn);
2631 return;
2632 }
2633 if (flags & TEVENT_FD_READ) {
2634 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2635 return;
2636 }
2637}
2638
2639static void smbd_server_echo_handler(struct tevent_context *ev,
2640 struct tevent_fd *fde,
2641 uint16_t flags,
2642 void *private_data)
2643{
2644 struct smbXsrv_connection *xconn =
2645 talloc_get_type_abort(private_data,
2646 struct smbXsrv_connection);
2647
2648 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2649 /*
2650 * we're not supposed to do any io
2651 */
2652 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2653 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2654 return;
2655 }
2656
2657 if (flags & TEVENT_FD_WRITE) {
2658 smbd_server_connection_write_handler(xconn);
2659 return;
2660 }
2661 if (flags & TEVENT_FD_READ) {
2662 smbd_server_connection_read_handler(
2663 xconn, xconn->smb1.echo_handler.trusted_fd);
2664 return;
2665 }
2666}
2667
2668struct smbd_release_ip_state {
2669 struct smbXsrv_connection *xconn;
2670 struct tevent_immediate *im;
2671 char addr[INET6_ADDRSTRLEN];
2672};
2673
2674static void smbd_release_ip_immediate(struct tevent_context *ctx,
2675 struct tevent_immediate *im,
2676 void *private_data)
2677{
2678 struct smbd_release_ip_state *state =
2679 talloc_get_type_abort(private_data,
2680 struct smbd_release_ip_state);
2681 struct smbXsrv_connection *xconn = state->xconn;
2682
2683 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2684 /*
2685 * smbd_server_connection_terminate() already triggered ?
2686 */
2687 return;
2688 }
2689
2690 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2691}
2692
2693/****************************************************************************
2694received when we should release a specific IP
2695****************************************************************************/
2696static int release_ip(uint32_t src_vnn, uint32_t dst_vnn,
2697 uint64_t dst_srvid,
2698 const uint8_t *msg, size_t msglen,
2699 void *private_data)
2700{
2701 struct smbd_release_ip_state *state =
2702 talloc_get_type_abort(private_data,
2703 struct smbd_release_ip_state);
2704 struct smbXsrv_connection *xconn = state->xconn;
2705 const char *ip;
2706 const char *addr = state->addr;
2707 const char *p = addr;
2708
2709 if (msglen == 0) {
2710 return 0;
2711 }
2712 if (msg[msglen-1] != '\0') {
2713 return 0;
2714 }
2715
2716 ip = (const char *)msg;
2717
2718 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2719 /* avoid recursion */
2720 return 0;
2721 }
2722
2723 if (strncmp("::ffff:", addr, 7) == 0) {
2724 p = addr + 7;
2725 }
2726
2727 DEBUG(10, ("Got release IP message for %s, "
2728 "our address is %s\n", ip, p));
2729
2730 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2731 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2732 ip));
2733 /*
2734 * With SMB2 we should do a clean disconnect,
2735 * the previous_session_id in the session setup
2736 * will cleanup the old session, tcons and opens.
2737 *
2738 * A clean disconnect is needed in order to support
2739 * durable handles.
2740 *
2741 * Note: typically this is never triggered
2742 * as we got a TCP RST (triggered by ctdb event scripts)
2743 * before we get CTDB_SRVID_RELEASE_IP.
2744 *
2745 * We used to call _exit(1) here, but as this was mostly never
2746 * triggered and has implication on our process model,
2747 * we can just use smbd_server_connection_terminate()
2748 * (also for SMB1).
2749 *
2750 * We don't call smbd_server_connection_terminate() directly
2751 * as we might be called from within ctdbd_migrate(),
2752 * we need to defer our action to the next event loop
2753 */
2754 tevent_schedule_immediate(state->im, xconn->ev_ctx,
2755 smbd_release_ip_immediate, state);
2756
2757 /*
2758 * Make sure we don't get any io on the connection.
2759 */
2760 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2761 return EADDRNOTAVAIL;
2762 }
2763
2764 return 0;
2765}
2766
2767static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2768 struct sockaddr_storage *srv,
2769 struct sockaddr_storage *clnt)
2770{
2771 struct smbd_release_ip_state *state;
2772 struct ctdbd_connection *cconn;
2773 int ret;
2774
2775 cconn = messaging_ctdbd_connection();
2776 if (cconn == NULL) {
2777 return NT_STATUS_NO_MEMORY;
2778 }
2779
2780 state = talloc_zero(xconn, struct smbd_release_ip_state);
2781 if (state == NULL) {
2782 return NT_STATUS_NO_MEMORY;
2783 }
2784 state->xconn = xconn;
2785 state->im = tevent_create_immediate(state);
2786 if (state->im == NULL) {
2787 return NT_STATUS_NO_MEMORY;
2788 }
2789 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2790 return NT_STATUS_NO_MEMORY;
2791 }
2792
2793 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2794 if (ret != 0) {
2795 return map_nt_error_from_unix(ret);
2796 }
2797 return NT_STATUS_OK;
2798}
2799
2800static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2801 void *private_data, uint32_t msg_type,
2802 struct server_id server_id, DATA_BLOB *data)
2803{
2804 struct smbd_server_connection *sconn = talloc_get_type_abort(
2805 private_data, struct smbd_server_connection);
2806 const char *ip = (char *) data->data;
2807 char *client_ip;
2808
2809 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2810
2811 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2812 talloc_tos());
2813 if (client_ip == NULL) {
2814 return;
2815 }
2816
2817 if (strequal(ip, client_ip)) {
2818 DBG_WARNING("Got kill client message for %s - "
2819 "exiting immediately\n", ip);
2820 exit_server_cleanly("Forced disconnect for client");
2821 }
2822
2823 TALLOC_FREE(client_ip);
2824}
2825
2826/*
2827 * Send keepalive packets to our client
2828 */
2829static bool keepalive_fn(const struct timeval *now, void *private_data)
2830{
2831 struct smbd_server_connection *sconn = talloc_get_type_abort(
2832 private_data, struct smbd_server_connection);
2833 struct smbXsrv_connection *xconn = NULL;
2834 bool ret;
2835
2836 if (sconn->using_smb2) {
2837 /* Don't do keepalives on an SMB2 connection. */
2838 return false;
2839 }
2840
2841 /*
2842 * With SMB1 we only have 1 connection
2843 */
2844 xconn = sconn->client->connections;
2845 smbd_lock_socket(xconn);
2846 ret = send_keepalive(xconn->transport.sock);
2847 smbd_unlock_socket(xconn);
2848
2849 if (!ret) {
2850 int saved_errno = errno;
2851 /*
2852 * Try and give an error message saying what
2853 * client failed.
2854 */
2855 DEBUG(0, ("send_keepalive failed for client %s. "
2856 "Error %s - exiting\n",
2857 smbXsrv_connection_dbg(xconn),
2858 strerror(saved_errno)));
2859 errno = saved_errno;
2860 return False;
2861 }
2862 return True;
2863}
2864
2865/*
2866 * Do the recurring check if we're idle
2867 */
2868static bool deadtime_fn(const struct timeval *now, void *private_data)
2869{
2870 struct smbd_server_connection *sconn =
2871 (struct smbd_server_connection *)private_data;
2872
2873 if ((conn_num_open(sconn) == 0)
2874 || (conn_idle_all(sconn, now->tv_sec))) {
2875 DEBUG( 2, ( "Closing idle connection\n" ) );
2876 messaging_send(sconn->msg_ctx,
2877 messaging_server_id(sconn->msg_ctx),
2878 MSG_SHUTDOWN, &data_blob_null);
2879 return False;
2880 }
2881
2882 return True;
2883}
2884
2885/*
2886 * Do the recurring log file and smb.conf reload checks.
2887 */
2888
2889static bool housekeeping_fn(const struct timeval *now, void *private_data)
2890{
2891 struct smbd_server_connection *sconn = talloc_get_type_abort(
2892 private_data, struct smbd_server_connection);
2893
2894 DEBUG(5, ("housekeeping\n"));
2895
2896 change_to_root_user();
2897
2898 /* update printer queue caches if necessary */
2899 update_monitored_printq_cache(sconn->msg_ctx);
2900
2901 /* check if we need to reload services */
2902 check_reload(sconn, time_mono(NULL));
2903
2904 /*
2905 * Force a log file check.
2906 */
2907 force_check_log_size();
2908 check_log_size();
2909 return true;
2910}
2911
2912/*
2913 * Read an smb packet in the echo handler child, giving the parent
2914 * smbd one second to react once the socket becomes readable.
2915 */
2916
2917struct smbd_echo_read_state {
2918 struct tevent_context *ev;
2919 struct smbXsrv_connection *xconn;
2920
2921 char *buf;
2922 size_t buflen;
2923 uint32_t seqnum;
2924};
2925
2926static void smbd_echo_read_readable(struct tevent_req *subreq);
2927static void smbd_echo_read_waited(struct tevent_req *subreq);
2928
2929static struct tevent_req *smbd_echo_read_send(
2930 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2931 struct smbXsrv_connection *xconn)
2932{
2933 struct tevent_req *req, *subreq;
2934 struct smbd_echo_read_state *state;
2935
2936 req = tevent_req_create(mem_ctx, &state,
2937 struct smbd_echo_read_state);
2938 if (req == NULL) {
2939 return NULL;
2940 }
2941 state->ev = ev;
2942 state->xconn = xconn;
2943
2944 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2945 if (tevent_req_nomem(subreq, req)) {
2946 return tevent_req_post(req, ev);
2947 }
2948 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2949 return req;
2950}
2951
2952static void smbd_echo_read_readable(struct tevent_req *subreq)
2953{
2954 struct tevent_req *req = tevent_req_callback_data(
2955 subreq, struct tevent_req);
2956 struct smbd_echo_read_state *state = tevent_req_data(
2957 req, struct smbd_echo_read_state);
2958 bool ok;
2959 int err;
2960
2961 ok = wait_for_read_recv(subreq, &err);
2962 TALLOC_FREE(subreq);
2963 if (!ok) {
2964 tevent_req_nterror(req, map_nt_error_from_unix(err));
2965 return;
2966 }
2967
2968 /*
2969 * Give the parent smbd one second to step in
2970 */
2971
2972 subreq = tevent_wakeup_send(
2973 state, state->ev, timeval_current_ofs(1, 0));
2974 if (tevent_req_nomem(subreq, req)) {
2975 return;
2976 }
2977 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2978}
2979
2980static void smbd_echo_read_waited(struct tevent_req *subreq)
2981{
2982 struct tevent_req *req = tevent_req_callback_data(
2983 subreq, struct tevent_req);
2984 struct smbd_echo_read_state *state = tevent_req_data(
2985 req, struct smbd_echo_read_state);
2986 struct smbXsrv_connection *xconn = state->xconn;
2987 bool ok;
2988 NTSTATUS status;
2989 size_t unread = 0;
2990 bool encrypted;
2991
2992 ok = tevent_wakeup_recv(subreq);
2993 TALLOC_FREE(subreq);
2994 if (!ok) {
2995 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2996 return;
2997 }
2998
2999 ok = smbd_lock_socket_internal(xconn);
3000 if (!ok) {
3001 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3002 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3003 return;
3004 }
3005
3006 if (!fd_is_readable(xconn->transport.sock)) {
3007 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3008 (int)getpid()));
3009
3010 ok = smbd_unlock_socket_internal(xconn);
3011 if (!ok) {
3012 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3013 DEBUG(1, ("%s: failed to unlock socket\n",
3014 __location__));
3015 return;
3016 }
3017
3018 subreq = wait_for_read_send(state, state->ev,
3019 xconn->transport.sock, false);
3020 if (tevent_req_nomem(subreq, req)) {
3021 return;
3022 }
3023 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3024 return;
3025 }
3026
3027 status = receive_smb_talloc(state, xconn,
3028 xconn->transport.sock,
3029 &state->buf,
3030 0 /* timeout */,
3031 &unread,
3032 &encrypted,
3033 &state->buflen,
3034 &state->seqnum,
3035 false /* trusted_channel*/);
3036
3037 if (tevent_req_nterror(req, status)) {
3038 tevent_req_nterror(req, status);
3039 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3040 (int)getpid(), nt_errstr(status)));
3041 return;
3042 }
3043
3044 ok = smbd_unlock_socket_internal(xconn);
3045 if (!ok) {
3046 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3047 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3048 return;
3049 }
3050 tevent_req_done(req);
3051}
3052
3053static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3054 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3055{
3056 struct smbd_echo_read_state *state = tevent_req_data(
3057 req, struct smbd_echo_read_state);
3058 NTSTATUS status;
3059
3060 if (tevent_req_is_nterror(req, &status)) {
3061 return status;
3062 }
3063 *pbuf = talloc_move(mem_ctx, &state->buf);
3064 *pbuflen = state->buflen;
3065 *pseqnum = state->seqnum;
3066 return NT_STATUS_OK;
3067}
3068
3069struct smbd_echo_state {
3070 struct tevent_context *ev;
3071 struct iovec *pending;
3072 struct smbd_server_connection *sconn;
3073 struct smbXsrv_connection *xconn;
3074 int parent_pipe;
3075
3076 struct tevent_fd *parent_fde;
3077
3078 struct tevent_req *write_req;
3079};
3080
3081static void smbd_echo_writer_done(struct tevent_req *req);
3082
3083static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3084{
3085 int num_pending;
3086
3087 if (state->write_req != NULL) {
3088 return;
3089 }
3090
3091 num_pending = talloc_array_length(state->pending);
3092 if (num_pending == 0) {
3093 return;
3094 }
3095
3096 state->write_req = writev_send(state, state->ev, NULL,
3097 state->parent_pipe, false,
3098 state->pending, num_pending);
3099 if (state->write_req == NULL) {
3100 DEBUG(1, ("writev_send failed\n"));
3101 exit(1);
3102 }
3103
3104 talloc_steal(state->write_req, state->pending);
3105 state->pending = NULL;
3106
3107 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3108 state);
3109}
3110
3111static void smbd_echo_writer_done(struct tevent_req *req)
3112{
3113 struct smbd_echo_state *state = tevent_req_callback_data(
3114 req, struct smbd_echo_state);
3115 ssize_t written;
3116 int err;
3117
3118 written = writev_recv(req, &err);
3119 TALLOC_FREE(req);
3120 state->write_req = NULL;
3121 if (written == -1) {
3122 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3123 exit(1);
3124 }
3125 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3126 smbd_echo_activate_writer(state);
3127}
3128
3129static bool smbd_echo_reply(struct smbd_echo_state *state,
3130 uint8_t *inbuf, size_t inbuf_len,
3131 uint32_t seqnum)
3132{
3133 struct smb_request req;
3134 uint16_t num_replies;
3135 char *outbuf;
3136 bool ok;
3137
3138 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3139 DEBUG(10, ("Got netbios keepalive\n"));
3140 /*
3141 * Just swallow it
3142 */
3143 return true;
3144 }
3145
3146 if (inbuf_len < smb_size) {
3147 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3148 return false;
3149 }
3150 if (!valid_smb_header(inbuf)) {
3151 DEBUG(10, ("Got invalid SMB header\n"));
3152 return false;
3153 }
3154
3155 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3156 seqnum)) {
3157 return false;
3158 }
3159 req.inbuf = inbuf;
3160
3161 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3162 smb_messages[req.cmd].name
3163 ? smb_messages[req.cmd].name : "unknown"));
3164
3165 if (req.cmd != SMBecho) {
3166 return false;
3167 }
3168 if (req.wct < 1) {
3169 return false;
3170 }
3171
3172 num_replies = SVAL(req.vwv+0, 0);
3173 if (num_replies != 1) {
3174 /* Not a Windows "Hey, you're still there?" request */
3175 return false;
3176 }
3177
3178 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3179 1, req.buflen)) {
3180 DEBUG(10, ("create_outbuf failed\n"));
3181 return false;
3182 }
3183 req.outbuf = (uint8_t *)outbuf;
3184
3185 SSVAL(req.outbuf, smb_vwv0, num_replies);
3186
3187 if (req.buflen > 0) {
3188 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3189 }
3190
3191 ok = srv_send_smb(req.xconn,
3192 (char *)outbuf,
3193 true, seqnum+1,
3194 false, &req.pcd);
3195 TALLOC_FREE(outbuf);
3196 if (!ok) {
3197 exit(1);
3198 }
3199
3200 return true;
3201}
3202
3203static void smbd_echo_exit(struct tevent_context *ev,
3204 struct tevent_fd *fde, uint16_t flags,
3205 void *private_data)
3206{
3207 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3208 exit(0);
3209}
3210
3211static void smbd_echo_got_packet(struct tevent_req *req);
3212
3213static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3214 int parent_pipe)
3215{
3216 struct smbd_echo_state *state;
3217 struct tevent_req *read_req;
3218
3219 state = talloc_zero(xconn, struct smbd_echo_state);
3220 if (state == NULL) {
3221 DEBUG(1, ("talloc failed\n"));
3222 return;
3223 }
3224 state->xconn = xconn;
3225 state->parent_pipe = parent_pipe;
3226 state->ev = samba_tevent_context_init(state);
3227 if (state->ev == NULL) {
3228 DEBUG(1, ("samba_tevent_context_init failed\n"));
3229 TALLOC_FREE(state);
3230 return;
3231 }
3232 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3233 TEVENT_FD_READ, smbd_echo_exit,
3234 state);
3235 if (state->parent_fde == NULL) {
3236 DEBUG(1, ("tevent_add_fd failed\n"));
3237 TALLOC_FREE(state);
3238 return;
3239 }
3240
3241 read_req = smbd_echo_read_send(state, state->ev, xconn);
3242 if (read_req == NULL) {
3243 DEBUG(1, ("smbd_echo_read_send failed\n"));
3244 TALLOC_FREE(state);
3245 return;
3246 }
3247 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3248
3249 while (true) {
3250 if (tevent_loop_once(state->ev) == -1) {
3251 DEBUG(1, ("tevent_loop_once failed: %s\n",
3252 strerror(errno)));
3253 break;
3254 }
3255 }
3256 TALLOC_FREE(state);
3257}
3258
3259static void smbd_echo_got_packet(struct tevent_req *req)
3260{
3261 struct smbd_echo_state *state = tevent_req_callback_data(
3262 req, struct smbd_echo_state);
3263 NTSTATUS status;
3264 char *buf = NULL;
3265 size_t buflen = 0;
3266 uint32_t seqnum = 0;
3267 bool reply;
3268
3269 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3270 TALLOC_FREE(req);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3273 nt_errstr(status)));
3274 exit(1);
3275 }
3276
3277 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3278 if (!reply) {
3279 size_t num_pending;
3280 struct iovec *tmp;
3281 struct iovec *iov;
3282
3283 num_pending = talloc_array_length(state->pending);
3284 tmp = talloc_realloc(state, state->pending, struct iovec,
3285 num_pending+1);
3286 if (tmp == NULL) {
3287 DEBUG(1, ("talloc_realloc failed\n"));
3288 exit(1);
3289 }
3290 state->pending = tmp;
3291
3292 if (buflen >= smb_size) {
3293 /*
3294 * place the seqnum in the packet so that the main process
3295 * can reply with signing
3296 */
3297 SIVAL(buf, smb_ss_field, seqnum);
3298 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3299 }
3300
3301 iov = &state->pending[num_pending];
3302 iov->iov_base = talloc_move(state->pending, &buf);
3303 iov->iov_len = buflen;
3304
3305 DEBUG(10,("echo_handler[%d]: forward to main\n",
3306 (int)getpid()));
3307 smbd_echo_activate_writer(state);
3308 }
3309
3310 req = smbd_echo_read_send(state, state->ev, state->xconn);
3311 if (req == NULL) {
3312 DEBUG(1, ("smbd_echo_read_send failed\n"));
3313 exit(1);
3314 }
3315 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3316}
3317
3318
3319/*
3320 * Handle SMBecho requests in a forked child process
3321 */
3322bool fork_echo_handler(struct smbXsrv_connection *xconn)
3323{
3324 int listener_pipe[2];
3325 int res;
3326 pid_t child;
3327 bool use_mutex = false;
3328
3329 res = pipe(listener_pipe);
3330 if (res == -1) {
3331 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3332 return false;
3333 }
3334
3335#ifdef HAVE_ROBUST_MUTEXES
3336 use_mutex = tdb_runtime_check_for_robust_mutexes();
3337
3338 if (use_mutex) {
3339 pthread_mutexattr_t a;
3340
3341 xconn->smb1.echo_handler.socket_mutex =
3342 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3343 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3344 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3345 strerror(errno)));
3346 goto fail;
3347 }
3348
3349 res = pthread_mutexattr_init(&a);
3350 if (res != 0) {
3351 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3352 strerror(res)));
3353 goto fail;
3354 }
3355 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3356 if (res != 0) {
3357 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3358 strerror(res)));
3359 pthread_mutexattr_destroy(&a);
3360 goto fail;
3361 }
3362 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3363 if (res != 0) {
3364 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3365 strerror(res)));
3366 pthread_mutexattr_destroy(&a);
3367 goto fail;
3368 }
3369 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3370 if (res != 0) {
3371 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3372 "%s\n", strerror(res)));
3373 pthread_mutexattr_destroy(&a);
3374 goto fail;
3375 }
3376 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3377 &a);
3378 pthread_mutexattr_destroy(&a);
3379 if (res != 0) {
3380 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3381 strerror(res)));
3382 goto fail;
3383 }
3384 }
3385#endif
3386
3387 if (!use_mutex) {
3388 xconn->smb1.echo_handler.socket_lock_fd =
3389 create_unlink_tmp(lp_lock_directory());
3390 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3391 DEBUG(1, ("Could not create lock fd: %s\n",
3392 strerror(errno)));
3393 goto fail;
3394 }
3395 }
3396
3397 child = fork();
3398 if (child == 0) {
3399 NTSTATUS status;
3400
3401 close(listener_pipe[0]);
3402 set_blocking(listener_pipe[1], false);
3403
3404 status = smbd_reinit_after_fork(xconn->msg_ctx, xconn->ev_ctx,
3405 true, "smbd-echo");
3406 if (!NT_STATUS_IS_OK(status)) {
3407 DEBUG(1, ("reinit_after_fork failed: %s\n",
3408 nt_errstr(status)));
3409 exit(1);
3410 }
3411 smbd_echo_loop(xconn, listener_pipe[1]);
3412 exit(0);
3413 }
3414 close(listener_pipe[1]);
3415 listener_pipe[1] = -1;
3416 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3417
3418 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3419
3420 /*
3421 * Without smb signing this is the same as the normal smbd
3422 * listener. This needs to change once signing comes in.
3423 */
3424 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
3425 xconn,
3426 xconn->smb1.echo_handler.trusted_fd,
3427 TEVENT_FD_READ,
3428 smbd_server_echo_handler,
3429 xconn);
3430 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3431 DEBUG(1, ("event_add_fd failed\n"));
3432 goto fail;
3433 }
3434
3435 return true;
3436
3437fail:
3438 if (listener_pipe[0] != -1) {
3439 close(listener_pipe[0]);
3440 }
3441 if (listener_pipe[1] != -1) {
3442 close(listener_pipe[1]);
3443 }
3444 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3445 close(xconn->smb1.echo_handler.socket_lock_fd);
3446 }
3447#ifdef HAVE_ROBUST_MUTEXES
3448 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3449 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3450 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3451 }
3452#endif
3453 smbd_echo_init(xconn);
3454
3455 return false;
3456}
3457
3458static bool uid_in_use(const struct user_struct *user, uid_t uid)
3459{
3460 while (user) {
3461 if (user->session_info &&
3462 (user->session_info->unix_token->uid == uid)) {
3463 return true;
3464 }
3465 user = user->next;
3466 }
3467 return false;
3468}
3469
3470static bool gid_in_use(const struct user_struct *user, gid_t gid)
3471{
3472 while (user) {
3473 if (user->session_info != NULL) {
3474 int i;
3475 struct security_unix_token *utok;
3476
3477 utok = user->session_info->unix_token;
3478 if (utok->gid == gid) {
3479 return true;
3480 }
3481 for(i=0; i<utok->ngroups; i++) {
3482 if (utok->groups[i] == gid) {
3483 return true;
3484 }
3485 }
3486 }
3487 user = user->next;
3488 }
3489 return false;
3490}
3491
3492static bool sid_in_use(const struct user_struct *user,
3493 const struct dom_sid *psid)
3494{
3495 while (user) {
3496 struct security_token *tok;
3497
3498 if (user->session_info == NULL) {
3499 continue;
3500 }
3501 tok = user->session_info->security_token;
3502 if (tok == NULL) {
3503 /*
3504 * Not sure session_info->security_token can
3505 * ever be NULL. This check might be not
3506 * necessary.
3507 */
3508 continue;
3509 }
3510 if (security_token_has_sid(tok, psid)) {
3511 return true;
3512 }
3513 user = user->next;
3514 }
3515 return false;
3516}
3517
3518static bool id_in_use(const struct user_struct *user,
3519 const struct id_cache_ref *id)
3520{
3521 switch(id->type) {
3522 case UID:
3523 return uid_in_use(user, id->id.uid);
3524 case GID:
3525 return gid_in_use(user, id->id.gid);
3526 case SID:
3527 return sid_in_use(user, &id->id.sid);
3528 default:
3529 break;
3530 }
3531 return false;
3532}
3533
3534static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3535 void *private_data,
3536 uint32_t msg_type,
3537 struct server_id server_id,
3538 DATA_BLOB* data)
3539{
3540 const char *msg = (data && data->data)
3541 ? (const char *)data->data : "<NULL>";
3542 struct id_cache_ref id;
3543 struct smbd_server_connection *sconn =
3544 talloc_get_type_abort(private_data,
3545 struct smbd_server_connection);
3546
3547 if (!id_cache_ref_parse(msg, &id)) {
3548 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3549 return;
3550 }
3551
3552 if (id_in_use(sconn->users, &id)) {
3553 exit_server_cleanly(msg);
3554 }
3555 id_cache_delete_from_cache(&id);
3556}
3557
3558NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3559 enum protocol_types protocol)
3560{
3561 NTSTATUS status;
3562
3563 conn->protocol = protocol;
3564
3565 if (conn->client->session_table != NULL) {
3566 return NT_STATUS_OK;
3567 }
3568
3569 if (protocol >= PROTOCOL_SMB2_02) {
3570 status = smb2srv_session_table_init(conn);
3571 if (!NT_STATUS_IS_OK(status)) {
3572 conn->protocol = PROTOCOL_NONE;
3573 return status;
3574 }
3575
3576 status = smb2srv_open_table_init(conn);
3577 if (!NT_STATUS_IS_OK(status)) {
3578 conn->protocol = PROTOCOL_NONE;
3579 return status;
3580 }
3581 } else {
3582 status = smb1srv_session_table_init(conn);
3583 if (!NT_STATUS_IS_OK(status)) {
3584 conn->protocol = PROTOCOL_NONE;
3585 return status;
3586 }
3587
3588 status = smb1srv_tcon_table_init(conn);
3589 if (!NT_STATUS_IS_OK(status)) {
3590 conn->protocol = PROTOCOL_NONE;
3591 return status;
3592 }
3593
3594 status = smb1srv_open_table_init(conn);
3595 if (!NT_STATUS_IS_OK(status)) {
3596 conn->protocol = PROTOCOL_NONE;
3597 return status;
3598 }
3599 }
3600
3601 set_Protocol(protocol);
3602 return NT_STATUS_OK;
3603}
3604
3605struct smbd_tevent_trace_state {
3606 struct tevent_context *ev;
3607 TALLOC_CTX *frame;
3608 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3609};
3610
3611static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3612 void *private_data)
3613{
3614 struct smbd_tevent_trace_state *state =
3615 (struct smbd_tevent_trace_state *)private_data;
3616
3617 switch (point) {
3618 case TEVENT_TRACE_BEFORE_WAIT:
3619 if (!smbprofile_dump_pending()) {
3620 /*
3621 * If there's no dump pending
3622 * we don't want to schedule a new 1 sec timer.
3623 *
3624 * Instead we want to sleep as long as nothing happens.
3625 */
3626 smbprofile_dump_setup(NULL);
3627 }
3628 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3629 break;
3630 case TEVENT_TRACE_AFTER_WAIT:
3631 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3632 if (!smbprofile_dump_pending()) {
3633 /*
3634 * We need to flush our state after sleeping
3635 * (hopefully a long time).
3636 */
3637 smbprofile_dump();
3638 /*
3639 * future profiling events should trigger timers
3640 * on our main event context.
3641 */
3642 smbprofile_dump_setup(state->ev);
3643 }
3644 break;
3645 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3646 TALLOC_FREE(state->frame);
3647 state->frame = talloc_stackframe_pool(8192);
3648 break;
3649 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3650 TALLOC_FREE(state->frame);
3651 break;
3652 }
3653
3654 errno = 0;
3655}
3656
3657/**
3658 * Create a debug string for the connection
3659 *
3660 * This is allocated to talloc_tos() or a string constant
3661 * in certain corner cases. The returned string should
3662 * hence not be free'd directly but only via the talloc stack.
3663 */
3664const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3665{
3666 const char *ret;
3667
3668 /*
3669 * TODO: this can be improved later
3670 * maybe including the client guid or more
3671 */
3672 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3673 if (ret == NULL) {
3674 return "<tsocket_address_string() failed>";
3675 }
3676
3677 return ret;
3678}
3679
3680NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3681 struct smbXsrv_connection **_xconn)
3682{
3683 TALLOC_CTX *frame = talloc_stackframe();
3684 struct smbXsrv_connection *xconn;
3685 struct sockaddr_storage ss_srv;
3686 void *sp_srv = (void *)&ss_srv;
3687 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3688 struct sockaddr_storage ss_clnt;
3689 void *sp_clnt = (void *)&ss_clnt;
3690 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3691 socklen_t sa_socklen;
3692 struct tsocket_address *local_address = NULL;
3693 struct tsocket_address *remote_address = NULL;
3694 const char *remaddr = NULL;
3695 char *p;
3696 const char *rhost = NULL;
3697 int ret;
3698 int tmp;
3699
3700 *_xconn = NULL;
3701
3702 DO_PROFILE_INC(connect);
3703
3704 xconn = talloc_zero(client, struct smbXsrv_connection);
3705 if (xconn == NULL) {
3706 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3707 TALLOC_FREE(frame);
3708 return NT_STATUS_NO_MEMORY;
3709 }
3710 talloc_steal(frame, xconn);
3711
3712 xconn->ev_ctx = client->ev_ctx;
3713 xconn->msg_ctx = client->msg_ctx;
3714 xconn->transport.sock = sock_fd;
3715 smbd_echo_init(xconn);
3716 xconn->protocol = PROTOCOL_NONE;
3717
3718 /* Ensure child is set to blocking mode */
3719 set_blocking(sock_fd,True);
3720
3721 set_socket_options(sock_fd, "SO_KEEPALIVE");
3722 set_socket_options(sock_fd, lp_socket_options());
3723
3724 sa_socklen = sizeof(ss_clnt);
3725 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3726 if (ret != 0) {
3727 int saved_errno = errno;
3728 int level = (errno == ENOTCONN)?2:0;
3729 DEBUG(level,("getpeername() failed - %s\n",
3730 strerror(saved_errno)));
3731 TALLOC_FREE(frame);
3732 return map_nt_error_from_unix_common(saved_errno);
3733 }
3734 ret = tsocket_address_bsd_from_sockaddr(xconn,
3735 sa_clnt, sa_socklen,
3736 &remote_address);
3737 if (ret != 0) {
3738 int saved_errno = errno;
3739 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3740 __location__, strerror(saved_errno)));
3741 TALLOC_FREE(frame);
3742 return map_nt_error_from_unix_common(saved_errno);
3743 }
3744
3745 sa_socklen = sizeof(ss_srv);
3746 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3747 if (ret != 0) {
3748 int saved_errno = errno;
3749 int level = (errno == ENOTCONN)?2:0;
3750 DEBUG(level,("getsockname() failed - %s\n",
3751 strerror(saved_errno)));
3752 TALLOC_FREE(frame);
3753 return map_nt_error_from_unix_common(saved_errno);
3754 }
3755 ret = tsocket_address_bsd_from_sockaddr(xconn,
3756 sa_srv, sa_socklen,
3757 &local_address);
3758 if (ret != 0) {
3759 int saved_errno = errno;
3760 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3761 __location__, strerror(saved_errno)));
3762 TALLOC_FREE(frame);
3763 return map_nt_error_from_unix_common(saved_errno);
3764 }
3765
3766 if (tsocket_address_is_inet(remote_address, "ip")) {
3767 remaddr = tsocket_address_inet_addr_string(remote_address,
3768 talloc_tos());
3769 if (remaddr == NULL) {
3770 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3771 __location__, strerror(errno)));
3772 TALLOC_FREE(frame);
3773 return NT_STATUS_NO_MEMORY;
3774 }
3775 } else {
3776 remaddr = "0.0.0.0";
3777 }
3778
3779 /*
3780 * Before the first packet, check the global hosts allow/ hosts deny
3781 * parameters before doing any parsing of packets passed to us by the
3782 * client. This prevents attacks on our parsing code from hosts not in
3783 * the hosts allow list.
3784 */
3785
3786 ret = get_remote_hostname(remote_address,
3787 &p, talloc_tos());
3788 if (ret < 0) {
3789 int saved_errno = errno;
3790 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3791 __location__, strerror(saved_errno)));
3792 TALLOC_FREE(frame);
3793 return map_nt_error_from_unix_common(saved_errno);
3794 }
3795 rhost = p;
3796 if (strequal(rhost, "UNKNOWN")) {
3797 rhost = remaddr;
3798 }
3799
3800 xconn->local_address = local_address;
3801 xconn->remote_address = remote_address;
3802 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3803 if (xconn->remote_hostname == NULL) {
3804 return NT_STATUS_NO_MEMORY;
3805 }
3806
3807 if (!srv_init_signing(xconn)) {
3808 DEBUG(0, ("Failed to init smb_signing\n"));
3809 TALLOC_FREE(frame);
3810 return NT_STATUS_INTERNAL_ERROR;
3811 }
3812
3813 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3814 xconn->remote_hostname,
3815 remaddr)) {
3816 DEBUG( 1, ("Connection denied from %s to %s\n",
3817 tsocket_address_string(remote_address, talloc_tos()),
3818 tsocket_address_string(local_address, talloc_tos())));
3819
3820 /*
3821 * We return a valid xconn
3822 * so that the caller can return an error message
3823 * to the client
3824 */
3825 client->connections = xconn;
3826 xconn->client = client;
3827 talloc_steal(client, xconn);
3828
3829 *_xconn = xconn;
3830 TALLOC_FREE(frame);
3831 return NT_STATUS_NETWORK_ACCESS_DENIED;
3832 }
3833
3834 DEBUG(10, ("Connection allowed from %s to %s\n",
3835 tsocket_address_string(remote_address, talloc_tos()),
3836 tsocket_address_string(local_address, talloc_tos())));
3837
3838 if (lp_clustering()) {
3839 /*
3840 * We need to tell ctdb about our client's TCP
3841 * connection, so that for failover ctdbd can send
3842 * tickle acks, triggering a reconnection by the
3843 * client.
3844 */
3845 NTSTATUS status;
3846
3847 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3848 if (!NT_STATUS_IS_OK(status)) {
3849 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3850 nt_errstr(status)));
3851 }
3852 }
3853
3854 tmp = lp_max_xmit();
3855 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3856 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3857
3858 xconn->smb1.negprot.max_recv = tmp;
3859
3860 xconn->smb1.sessions.done_sesssetup = false;
3861 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3862
3863 xconn->transport.fde = tevent_add_fd(client->ev_ctx,
3864 xconn,
3865 sock_fd,
3866 TEVENT_FD_READ,
3867 smbd_server_connection_handler,
3868 xconn);
3869 if (!xconn->transport.fde) {
3870 TALLOC_FREE(frame);
3871 return NT_STATUS_NO_MEMORY;
3872 }
3873
3874 /* for now we only have one connection */
3875 DLIST_ADD_END(client->connections, xconn);
3876 xconn->client = client;
3877 talloc_steal(client, xconn);
3878
3879 *_xconn = xconn;
3880 TALLOC_FREE(frame);
3881 return NT_STATUS_OK;
3882}
3883
3884/****************************************************************************
3885 Process commands from the client
3886****************************************************************************/
3887
3888void smbd_process(struct tevent_context *ev_ctx,
3889 struct messaging_context *msg_ctx,
3890 int sock_fd,
3891 bool interactive)
3892{
3893 struct smbd_tevent_trace_state trace_state = {
3894 .ev = ev_ctx,
3895 .frame = talloc_stackframe(),
3896 };
3897 struct smbXsrv_client *client = NULL;
3898 struct smbd_server_connection *sconn = NULL;
3899 struct smbXsrv_connection *xconn = NULL;
3900 const char *locaddr = NULL;
3901 const char *remaddr = NULL;
3902 int ret;
3903 NTSTATUS status;
3904 struct timeval tv = timeval_current();
3905 NTTIME now = timeval_to_nttime(&tv);
3906
3907 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3908 if (!NT_STATUS_IS_OK(status)) {
3909 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3910 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3911 }
3912
3913 /*
3914 * TODO: remove this...:-)
3915 */
3916 global_smbXsrv_client = client;
3917
3918 sconn = talloc_zero(client, struct smbd_server_connection);
3919 if (sconn == NULL) {
3920 exit_server("failed to create smbd_server_connection");
3921 }
3922
3923 client->sconn = sconn;
3924 sconn->client = client;
3925
3926 sconn->ev_ctx = ev_ctx;
3927 sconn->msg_ctx = msg_ctx;
3928
3929 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3930 /*
3931 * We're not making the decision here,
3932 * we're just allowing the client
3933 * to decide between SMB1 and SMB2
3934 * with the first negprot
3935 * packet.
3936 */
3937 sconn->using_smb2 = true;
3938 }
3939
3940 if (!interactive) {
3941 smbd_setup_sig_term_handler(sconn);
3942 smbd_setup_sig_hup_handler(sconn);
3943
3944 if (!serverid_register(messaging_server_id(msg_ctx),
3945 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3946 |FLAG_MSG_DBWRAP
3947 |FLAG_MSG_PRINT_GENERAL)) {
3948 exit_server_cleanly("Could not register myself in "
3949 "serverid.tdb");
3950 }
3951 }
3952
3953 status = smbd_add_connection(client, sock_fd, &xconn);
3954 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3955 /*
3956 * send a negative session response "not listening on calling
3957 * name"
3958 */
3959 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3960 (void)srv_send_smb(xconn,(char *)buf, false,
3961 0, false, NULL);
3962 exit_server_cleanly("connection denied");
3963 } else if (!NT_STATUS_IS_OK(status)) {
3964 exit_server_cleanly(nt_errstr(status));
3965 }
3966
3967 sconn->local_address =
3968 tsocket_address_copy(xconn->local_address, sconn);
3969 if (sconn->local_address == NULL) {
3970 exit_server_cleanly("tsocket_address_copy() failed");
3971 }
3972 sconn->remote_address =
3973 tsocket_address_copy(xconn->remote_address, sconn);
3974 if (sconn->remote_address == NULL) {
3975 exit_server_cleanly("tsocket_address_copy() failed");
3976 }
3977 sconn->remote_hostname =
3978 talloc_strdup(sconn, xconn->remote_hostname);
3979 if (sconn->remote_hostname == NULL) {
3980 exit_server_cleanly("tsocket_strdup() failed");
3981 }
3982
3983 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3984 locaddr = tsocket_address_inet_addr_string(
3985 sconn->local_address,
3986 talloc_tos());
3987 if (locaddr == NULL) {
3988 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3989 __location__, strerror(errno)));
3990 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3991 }
3992 } else {
3993 locaddr = "0.0.0.0";
3994 }
3995
3996 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
3997 remaddr = tsocket_address_inet_addr_string(
3998 sconn->remote_address,
3999 talloc_tos());
4000 if (remaddr == NULL) {
4001 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4002 __location__, strerror(errno)));
4003 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4004 }
4005 } else {
4006 remaddr = "0.0.0.0";
4007 }
4008
4009 /* this is needed so that we get decent entries
4010 in smbstatus for port 445 connects */
4011 set_remote_machine_name(remaddr, false);
4012 reload_services(sconn, conn_snum_used, true);
4013 sub_set_socket_ids(remaddr,
4014 sconn->remote_hostname,
4015 locaddr);
4016
4017 if (lp_preload_modules()) {
4018 smb_load_modules(lp_preload_modules());
4019 }
4020
4021 smb_perfcount_init();
4022
4023 if (!init_account_policy()) {
4024 exit_server("Could not open account policy tdb.\n");
4025 }
4026
4027 if (*lp_root_directory(talloc_tos())) {
4028 if (chroot(lp_root_directory(talloc_tos())) != 0) {
4029 DEBUG(0,("Failed to change root to %s\n",
4030 lp_root_directory(talloc_tos())));
4031 exit_server("Failed to chroot()");
4032 }
4033 if (chdir("/") == -1) {
4034 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
4035 exit_server("Failed to chroot()");
4036 }
4037 DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
4038 }
4039
4040 if (!file_init(sconn)) {
4041 exit_server("file_init() failed");
4042 }
4043
4044 /* Setup oplocks */
4045 if (!init_oplocks(sconn))
4046 exit_server("Failed to init oplocks");
4047
4048 /* register our message handlers */
4049 messaging_register(sconn->msg_ctx, sconn,
4050 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4051 messaging_register(sconn->msg_ctx, sconn,
4052 MSG_SMB_CLOSE_FILE, msg_close_file);
4053 messaging_register(sconn->msg_ctx, sconn,
4054 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4055
4056 id_cache_register_msgs(sconn->msg_ctx);
4057 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4058 messaging_register(sconn->msg_ctx, sconn,
4059 ID_CACHE_KILL, smbd_id_cache_kill);
4060
4061 messaging_deregister(sconn->msg_ctx,
4062 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4063 messaging_register(sconn->msg_ctx, sconn,
4064 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4065
4066 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4067 NULL);
4068 messaging_register(sconn->msg_ctx, sconn,
4069 MSG_SMB_KILL_CLIENT_IP,
4070 msg_kill_client_ip);
4071
4072 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4073
4074 /*
4075 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4076 * MSGs to all child processes
4077 */
4078 messaging_deregister(sconn->msg_ctx,
4079 MSG_DEBUG, NULL);
4080 messaging_register(sconn->msg_ctx, NULL,
4081 MSG_DEBUG, debug_message);
4082
4083 if ((lp_keepalive() != 0)
4084 && !(event_add_idle(ev_ctx, NULL,
4085 timeval_set(lp_keepalive(), 0),
4086 "keepalive", keepalive_fn,
4087 sconn))) {
4088 DEBUG(0, ("Could not add keepalive event\n"));
4089 exit(1);
4090 }
4091
4092 if (!(event_add_idle(ev_ctx, NULL,
4093 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4094 "deadtime", deadtime_fn, sconn))) {
4095 DEBUG(0, ("Could not add deadtime event\n"));
4096 exit(1);
4097 }
4098
4099 if (!(event_add_idle(ev_ctx, NULL,
4100 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4101 "housekeeping", housekeeping_fn, sconn))) {
4102 DEBUG(0, ("Could not add housekeeping event\n"));
4103 exit(1);
4104 }
4105
4106 smbprofile_dump_setup(ev_ctx);
4107
4108 if (!init_dptrs(sconn)) {
4109 exit_server("init_dptrs() failed");
4110 }
4111
4112 TALLOC_FREE(trace_state.frame);
4113
4114 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4115 &trace_state);
4116
4117 ret = tevent_loop_wait(ev_ctx);
4118 if (ret != 0) {
4119 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4120 " exiting\n", ret, strerror(errno)));
4121 }
4122
4123 TALLOC_FREE(trace_state.frame);
4124
4125 exit_server_cleanly(NULL);
4126}
4127
4128bool req_is_in_chain(const struct smb_request *req)
4129{
4130 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4131 /*
4132 * We're right now handling a subsequent request, so we must
4133 * be in a chain
4134 */
4135 return true;
4136 }
4137
4138 if (!is_andx_req(req->cmd)) {
4139 return false;
4140 }
4141
4142 if (req->wct < 2) {
4143 /*
4144 * Okay, an illegal request, but definitely not chained :-)
4145 */
4146 return false;
4147 }
4148
4149 return (CVAL(req->vwv+0, 0) != 0xFF);
4150}
Note: See TracBrowser for help on using the repository browser.