smbd: Return "blocker_pid" from do_lock()
[Samba.git] / source3 / smbd / process.c
blob177cb3cc5056b325da87d80c1d8893f237fa912d
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
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.
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.
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/>.
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 "lib/messages_ctdb.h"
36 #include "smbprofile.h"
37 #include "rpc_server/spoolss/srv_spoolss_nt.h"
38 #include "libsmb/libsmb.h"
39 #include "../lib/util/tevent_ntstatus.h"
40 #include "../libcli/security/dom_sid.h"
41 #include "../libcli/security/security_token.h"
42 #include "lib/id_cache.h"
43 #include "lib/util/sys_rw_data.h"
44 #include "system/threads.h"
45 #include "lib/pthreadpool/pthreadpool_tevent.h"
46 #include "util_event.h"
47 #include "libcli/smb/smbXcli_base.h"
49 /* Internal message queue for deferred opens. */
50 struct pending_message_list {
51 struct pending_message_list *next, *prev;
52 struct timeval request_time; /* When was this first issued? */
53 struct smbd_server_connection *sconn;
54 struct smbXsrv_connection *xconn;
55 struct tevent_timer *te;
56 struct smb_perfcount_data pcd;
57 uint32_t seqnum;
58 bool encrypted;
59 bool processed;
60 DATA_BLOB buf;
61 struct deferred_open_record *open_rec;
64 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
65 char *outbuf);
66 static struct pending_message_list *get_deferred_open_message_smb(
67 struct smbd_server_connection *sconn, uint64_t mid);
68 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
70 static void smbd_echo_init(struct smbXsrv_connection *xconn)
72 xconn->smb1.echo_handler.trusted_fd = -1;
73 xconn->smb1.echo_handler.socket_lock_fd = -1;
74 #ifdef HAVE_ROBUST_MUTEXES
75 xconn->smb1.echo_handler.socket_mutex = NULL;
76 #endif
79 static bool smbd_echo_active(struct smbXsrv_connection *xconn)
81 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
82 return true;
85 #ifdef HAVE_ROBUST_MUTEXES
86 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
87 return true;
89 #endif
91 return false;
94 static bool smbd_lock_socket_internal(struct smbXsrv_connection *xconn)
96 if (!smbd_echo_active(xconn)) {
97 return true;
100 xconn->smb1.echo_handler.ref_count++;
102 if (xconn->smb1.echo_handler.ref_count > 1) {
103 return true;
106 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
108 #ifdef HAVE_ROBUST_MUTEXES
109 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
110 int ret = EINTR;
112 while (ret == EINTR) {
113 ret = pthread_mutex_lock(
114 xconn->smb1.echo_handler.socket_mutex);
115 if (ret == 0) {
116 break;
119 if (ret != 0) {
120 DEBUG(1, ("pthread_mutex_lock failed: %s\n",
121 strerror(ret)));
122 return false;
125 #endif
127 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
128 bool ok;
130 do {
131 ok = fcntl_lock(
132 xconn->smb1.echo_handler.socket_lock_fd,
133 F_SETLKW, 0, 0, F_WRLCK);
134 } while (!ok && (errno == EINTR));
136 if (!ok) {
137 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
138 return false;
142 DEBUG(10,("pid[%d] got socket lock\n", (int)getpid()));
144 return true;
147 void smbd_lock_socket(struct smbXsrv_connection *xconn)
149 if (!smbd_lock_socket_internal(xconn)) {
150 exit_server_cleanly("failed to lock socket");
154 static bool smbd_unlock_socket_internal(struct smbXsrv_connection *xconn)
156 if (!smbd_echo_active(xconn)) {
157 return true;
160 xconn->smb1.echo_handler.ref_count--;
162 if (xconn->smb1.echo_handler.ref_count > 0) {
163 return true;
166 #ifdef HAVE_ROBUST_MUTEXES
167 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
168 int ret;
169 ret = pthread_mutex_unlock(
170 xconn->smb1.echo_handler.socket_mutex);
171 if (ret != 0) {
172 DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
173 strerror(ret)));
174 return false;
177 #endif
179 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
180 bool ok;
182 do {
183 ok = fcntl_lock(
184 xconn->smb1.echo_handler.socket_lock_fd,
185 F_SETLKW, 0, 0, F_UNLCK);
186 } while (!ok && (errno == EINTR));
188 if (!ok) {
189 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
190 return false;
194 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
196 return true;
199 void smbd_unlock_socket(struct smbXsrv_connection *xconn)
201 if (!smbd_unlock_socket_internal(xconn)) {
202 exit_server_cleanly("failed to unlock socket");
206 /* Accessor function for smb_read_error for smbd functions. */
208 /****************************************************************************
209 Send an smb to a fd.
210 ****************************************************************************/
212 bool srv_send_smb(struct smbXsrv_connection *xconn, char *buffer,
213 bool do_signing, uint32_t seqnum,
214 bool do_encrypt,
215 struct smb_perfcount_data *pcd)
217 size_t len = 0;
218 ssize_t ret;
219 char *buf_out = buffer;
221 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
223 * we're not supposed to do any io
225 return true;
228 smbd_lock_socket(xconn);
230 if (do_signing) {
231 NTSTATUS status;
233 /* Sign the outgoing packet if required. */
234 status = srv_calculate_sign_mac(xconn, buf_out, seqnum);
235 if (!NT_STATUS_IS_OK(status)) {
236 DBG_ERR("Failed to calculate signing mac: %s\n",
237 nt_errstr(status));
238 return false;
242 if (do_encrypt) {
243 NTSTATUS status = srv_encrypt_buffer(xconn, buffer, &buf_out);
244 if (!NT_STATUS_IS_OK(status)) {
245 DEBUG(0, ("send_smb: SMB encryption failed "
246 "on outgoing packet! Error %s\n",
247 nt_errstr(status) ));
248 ret = -1;
249 goto out;
253 len = smb_len_large(buf_out) + 4;
255 ret = write_data(xconn->transport.sock, buf_out, len);
256 if (ret <= 0) {
257 int saved_errno = errno;
259 * Try and give an error message saying what
260 * client failed.
262 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
263 (int)getpid(), (int)len,
264 smbXsrv_connection_dbg(xconn),
265 (int)ret, strerror(saved_errno)));
266 errno = saved_errno;
268 srv_free_enc_buffer(xconn, buf_out);
269 goto out;
272 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
273 srv_free_enc_buffer(xconn, buf_out);
274 out:
275 SMB_PERFCOUNT_END(pcd);
277 smbd_unlock_socket(xconn);
278 return (ret > 0);
281 /*******************************************************************
282 Setup the word count and byte count for a smb message.
283 ********************************************************************/
285 size_t srv_set_message(char *buf,
286 size_t num_words,
287 size_t num_bytes,
288 bool zero)
290 if (zero && (num_words || num_bytes)) {
291 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
293 SCVAL(buf,smb_wct,num_words);
294 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
295 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
296 return (smb_size + num_words*2 + num_bytes);
299 static bool valid_smb_header(const uint8_t *inbuf)
301 if (is_encrypted_packet(inbuf)) {
302 return true;
305 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
306 * but it just looks weird to call strncmp for this one.
308 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
311 /* Socket functions for smbd packet processing. */
313 static bool valid_packet_size(size_t len)
316 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
317 * of header. Don't print the error if this fits.... JRA.
320 if (len > (LARGE_WRITEX_BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
321 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
322 (unsigned long)len));
323 return false;
325 return true;
328 static NTSTATUS read_packet_remainder(int fd, char *buffer,
329 unsigned int timeout, ssize_t len)
331 NTSTATUS status;
333 if (len <= 0) {
334 return NT_STATUS_OK;
337 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
338 if (!NT_STATUS_IS_OK(status)) {
339 char addr[INET6_ADDRSTRLEN];
340 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
341 "error = %s.\n",
342 get_peer_addr(fd, addr, sizeof(addr)),
343 nt_errstr(status)));
345 return status;
348 /****************************************************************************
349 Attempt a zerocopy writeX read. We know here that len > smb_size-4
350 ****************************************************************************/
353 * Unfortunately, earlier versions of smbclient/libsmbclient
354 * don't send this "standard" writeX header. I've fixed this
355 * for 3.2 but we'll use the old method with earlier versions.
356 * Windows and CIFSFS at least use this standard size. Not
357 * sure about MacOSX.
360 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
361 (2*14) + /* word count (including bcc) */ \
362 1 /* pad byte */)
364 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
365 const char lenbuf[4],
366 struct smbXsrv_connection *xconn,
367 int sock,
368 char **buffer,
369 unsigned int timeout,
370 size_t *p_unread,
371 size_t *len_ret)
373 /* Size of a WRITEX call (+4 byte len). */
374 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
375 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
376 ssize_t toread;
377 NTSTATUS status;
379 memcpy(writeX_header, lenbuf, 4);
381 status = read_fd_with_timeout(
382 sock, writeX_header + 4,
383 STANDARD_WRITE_AND_X_HEADER_SIZE,
384 STANDARD_WRITE_AND_X_HEADER_SIZE,
385 timeout, NULL);
387 if (!NT_STATUS_IS_OK(status)) {
388 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
389 "error = %s.\n",
390 smbXsrv_connection_dbg(xconn),
391 nt_errstr(status)));
392 return status;
396 * Ok - now try and see if this is a possible
397 * valid writeX call.
400 if (is_valid_writeX_buffer(xconn, (uint8_t *)writeX_header)) {
402 * If the data offset is beyond what
403 * we've read, drain the extra bytes.
405 uint16_t doff = SVAL(writeX_header,smb_vwv11);
406 ssize_t newlen;
408 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
409 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
410 if (drain_socket(sock, drain) != drain) {
411 smb_panic("receive_smb_raw_talloc_partial_read:"
412 " failed to drain pending bytes");
414 } else {
415 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
418 /* Spoof down the length and null out the bcc. */
419 set_message_bcc(writeX_header, 0);
420 newlen = smb_len(writeX_header);
422 /* Copy the header we've written. */
424 *buffer = (char *)talloc_memdup(mem_ctx,
425 writeX_header,
426 sizeof(writeX_header));
428 if (*buffer == NULL) {
429 DEBUG(0, ("Could not allocate inbuf of length %d\n",
430 (int)sizeof(writeX_header)));
431 return NT_STATUS_NO_MEMORY;
434 /* Work out the remaining bytes. */
435 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
436 *len_ret = newlen + 4;
437 return NT_STATUS_OK;
440 if (!valid_packet_size(len)) {
441 return NT_STATUS_INVALID_PARAMETER;
445 * Not a valid writeX call. Just do the standard
446 * talloc and return.
449 *buffer = talloc_array(mem_ctx, char, len+4);
451 if (*buffer == NULL) {
452 DEBUG(0, ("Could not allocate inbuf of length %d\n",
453 (int)len+4));
454 return NT_STATUS_NO_MEMORY;
457 /* Copy in what we already read. */
458 memcpy(*buffer,
459 writeX_header,
460 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
461 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
463 if(toread > 0) {
464 status = read_packet_remainder(
465 sock,
466 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
467 timeout, toread);
469 if (!NT_STATUS_IS_OK(status)) {
470 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
471 nt_errstr(status)));
472 return status;
476 *len_ret = len + 4;
477 return NT_STATUS_OK;
480 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
481 struct smbXsrv_connection *xconn,
482 int sock,
483 char **buffer, unsigned int timeout,
484 size_t *p_unread, size_t *plen)
486 char lenbuf[4];
487 size_t len;
488 int min_recv_size = lp_min_receive_file_size();
489 NTSTATUS status;
491 *p_unread = 0;
493 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
494 &len);
495 if (!NT_STATUS_IS_OK(status)) {
496 return status;
499 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
500 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
501 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
502 !srv_is_signing_active(xconn) &&
503 xconn->smb1.echo_handler.trusted_fde == NULL) {
505 return receive_smb_raw_talloc_partial_read(
506 mem_ctx, lenbuf, xconn, sock, buffer, timeout,
507 p_unread, plen);
510 if (!valid_packet_size(len)) {
511 return NT_STATUS_INVALID_PARAMETER;
515 * The +4 here can't wrap, we've checked the length above already.
518 *buffer = talloc_array(mem_ctx, char, len+4);
520 if (*buffer == NULL) {
521 DEBUG(0, ("Could not allocate inbuf of length %d\n",
522 (int)len+4));
523 return NT_STATUS_NO_MEMORY;
526 memcpy(*buffer, lenbuf, sizeof(lenbuf));
528 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
529 if (!NT_STATUS_IS_OK(status)) {
530 return status;
533 *plen = len + 4;
534 return NT_STATUS_OK;
537 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
538 struct smbXsrv_connection *xconn,
539 int sock,
540 char **buffer, unsigned int timeout,
541 size_t *p_unread, bool *p_encrypted,
542 size_t *p_len,
543 uint32_t *seqnum,
544 bool trusted_channel)
546 size_t len = 0;
547 NTSTATUS status;
549 *p_encrypted = false;
551 status = receive_smb_raw_talloc(mem_ctx, xconn, sock, buffer, timeout,
552 p_unread, &len);
553 if (!NT_STATUS_IS_OK(status)) {
554 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
555 ("receive_smb_raw_talloc failed for client %s "
556 "read error = %s.\n",
557 smbXsrv_connection_dbg(xconn),
558 nt_errstr(status)) );
559 return status;
562 if (is_encrypted_packet((uint8_t *)*buffer)) {
563 status = srv_decrypt_buffer(xconn, *buffer);
564 if (!NT_STATUS_IS_OK(status)) {
565 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
566 "incoming packet! Error %s\n",
567 nt_errstr(status) ));
568 return status;
570 *p_encrypted = true;
573 /* Check the incoming SMB signature. */
574 if (!srv_check_sign_mac(xconn, *buffer, seqnum, trusted_channel)) {
575 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
576 "incoming packet!\n"));
577 return NT_STATUS_INVALID_NETWORK_RESPONSE;
580 *p_len = len;
581 return NT_STATUS_OK;
585 * Initialize a struct smb_request from an inbuf
588 static bool init_smb_request(struct smb_request *req,
589 struct smbd_server_connection *sconn,
590 struct smbXsrv_connection *xconn,
591 const uint8_t *inbuf,
592 size_t unread_bytes, bool encrypted,
593 uint32_t seqnum)
595 struct smbXsrv_tcon *tcon;
596 NTSTATUS status;
597 NTTIME now;
598 size_t req_size = smb_len(inbuf) + 4;
600 /* Ensure we have at least smb_size bytes. */
601 if (req_size < smb_size) {
602 DEBUG(0,("init_smb_request: invalid request size %u\n",
603 (unsigned int)req_size ));
604 return false;
607 req->request_time = timeval_current();
608 now = timeval_to_nttime(&req->request_time);
610 req->cmd = CVAL(inbuf, smb_com);
611 req->flags2 = SVAL(inbuf, smb_flg2);
612 req->smbpid = SVAL(inbuf, smb_pid);
613 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
614 req->seqnum = seqnum;
615 req->vuid = SVAL(inbuf, smb_uid);
616 req->tid = SVAL(inbuf, smb_tid);
617 req->wct = CVAL(inbuf, smb_wct);
618 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
619 req->buflen = smb_buflen(inbuf);
620 req->buf = (const uint8_t *)smb_buf_const(inbuf);
621 req->unread_bytes = unread_bytes;
622 req->encrypted = encrypted;
623 req->sconn = sconn;
624 req->xconn = xconn;
625 req->conn = NULL;
626 if (xconn != NULL) {
627 status = smb1srv_tcon_lookup(xconn, req->tid, now, &tcon);
628 if (NT_STATUS_IS_OK(status)) {
629 req->conn = tcon->compat;
632 req->chain_fsp = NULL;
633 req->smb2req = NULL;
634 req->priv_paths = NULL;
635 req->chain = NULL;
636 req->posix_pathnames = lp_posix_pathnames();
637 smb_init_perfcount_data(&req->pcd);
639 /* Ensure we have at least wct words and 2 bytes of bcc. */
640 if (smb_size + req->wct*2 > req_size) {
641 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
642 (unsigned int)req->wct,
643 (unsigned int)req_size));
644 return false;
646 /* Ensure bcc is correct. */
647 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
648 DEBUG(0,("init_smb_request: invalid bcc number %u "
649 "(wct = %u, size %u)\n",
650 (unsigned int)req->buflen,
651 (unsigned int)req->wct,
652 (unsigned int)req_size));
653 return false;
656 req->outbuf = NULL;
657 return true;
660 static void process_smb(struct smbXsrv_connection *xconn,
661 uint8_t *inbuf, size_t nread, size_t unread_bytes,
662 uint32_t seqnum, bool encrypted,
663 struct smb_perfcount_data *deferred_pcd);
665 static void smbd_deferred_open_timer(struct tevent_context *ev,
666 struct tevent_timer *te,
667 struct timeval _tval,
668 void *private_data)
670 struct pending_message_list *msg = talloc_get_type(private_data,
671 struct pending_message_list);
672 struct smbd_server_connection *sconn = msg->sconn;
673 struct smbXsrv_connection *xconn = msg->xconn;
674 TALLOC_CTX *mem_ctx = talloc_tos();
675 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
676 uint8_t *inbuf;
678 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
679 msg->buf.length);
680 if (inbuf == NULL) {
681 exit_server("smbd_deferred_open_timer: talloc failed\n");
682 return;
685 /* We leave this message on the queue so the open code can
686 know this is a retry. */
687 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
688 (unsigned long long)mid ));
690 /* Mark the message as processed so this is not
691 * re-processed in error. */
692 msg->processed = true;
694 process_smb(xconn, inbuf,
695 msg->buf.length, 0,
696 msg->seqnum, msg->encrypted, &msg->pcd);
698 /* If it's still there and was processed, remove it. */
699 msg = get_deferred_open_message_smb(sconn, mid);
700 if (msg && msg->processed) {
701 remove_deferred_open_message_smb(xconn, mid);
705 /****************************************************************************
706 Function to push a message onto the tail of a linked list of smb messages ready
707 for processing.
708 ****************************************************************************/
710 static bool push_queued_message(struct smb_request *req,
711 struct timeval request_time,
712 struct timeval end_time,
713 struct deferred_open_record *open_rec)
715 int msg_len = smb_len(req->inbuf) + 4;
716 struct pending_message_list *msg;
718 msg = talloc_zero(NULL, struct pending_message_list);
720 if(msg == NULL) {
721 DEBUG(0,("push_message: malloc fail (1)\n"));
722 return False;
724 msg->sconn = req->sconn;
725 msg->xconn = req->xconn;
727 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
728 if(msg->buf.data == NULL) {
729 DEBUG(0,("push_message: malloc fail (2)\n"));
730 TALLOC_FREE(msg);
731 return False;
734 msg->request_time = request_time;
735 msg->seqnum = req->seqnum;
736 msg->encrypted = req->encrypted;
737 msg->processed = false;
738 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
740 if (open_rec) {
741 msg->open_rec = talloc_move(msg, &open_rec);
744 #if 0
745 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
746 msg,
747 end_time,
748 smbd_deferred_open_timer,
749 msg);
750 if (!msg->te) {
751 DEBUG(0,("push_message: event_add_timed failed\n"));
752 TALLOC_FREE(msg);
753 return false;
755 #endif
757 DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
759 DEBUG(10,("push_message: pushed message length %u on "
760 "deferred_open_queue\n", (unsigned int)msg_len));
762 return True;
765 /****************************************************************************
766 Function to delete a sharing violation open message by mid.
767 ****************************************************************************/
769 void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
770 uint64_t mid)
772 struct smbd_server_connection *sconn = xconn->client->sconn;
773 struct pending_message_list *pml;
775 if (sconn->using_smb2) {
776 remove_deferred_open_message_smb2(xconn, mid);
777 return;
780 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
781 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
782 DEBUG(10,("remove_deferred_open_message_smb: "
783 "deleting mid %llu len %u\n",
784 (unsigned long long)mid,
785 (unsigned int)pml->buf.length ));
786 DLIST_REMOVE(sconn->deferred_open_queue, pml);
787 TALLOC_FREE(pml);
788 return;
793 /****************************************************************************
794 Move a sharing violation open retry message to the front of the list and
795 schedule it for immediate processing.
796 ****************************************************************************/
798 bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
799 uint64_t mid)
801 struct smbd_server_connection *sconn = xconn->client->sconn;
802 struct pending_message_list *pml;
803 int i = 0;
805 if (sconn->using_smb2) {
806 return schedule_deferred_open_message_smb2(xconn, mid);
809 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
810 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
812 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
813 "msg_mid = %llu\n",
814 i++,
815 (unsigned long long)msg_mid ));
817 if (mid == msg_mid) {
818 struct tevent_timer *te;
820 if (pml->processed) {
821 /* A processed message should not be
822 * rescheduled. */
823 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
824 "message mid %llu was already processed\n",
825 (unsigned long long)msg_mid ));
826 continue;
829 DEBUG(10,("schedule_deferred_open_message_smb: "
830 "scheduling mid %llu\n",
831 (unsigned long long)mid ));
834 * smbd_deferred_open_timer() calls
835 * process_smb() to redispatch the request
836 * including the required impersonation.
838 * So we can just use the raw tevent_context.
840 te = tevent_add_timer(xconn->client->raw_ev_ctx,
841 pml,
842 timeval_zero(),
843 smbd_deferred_open_timer,
844 pml);
845 if (!te) {
846 DEBUG(10,("schedule_deferred_open_message_smb: "
847 "event_add_timed() failed, "
848 "skipping mid %llu\n",
849 (unsigned long long)msg_mid ));
852 TALLOC_FREE(pml->te);
853 pml->te = te;
854 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
855 return true;
859 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
860 "find message mid %llu\n",
861 (unsigned long long)mid ));
863 return false;
866 /****************************************************************************
867 Return true if this mid is on the deferred queue and was not yet processed.
868 ****************************************************************************/
870 bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
872 struct smbd_server_connection *sconn = xconn->client->sconn;
873 struct pending_message_list *pml;
875 if (sconn->using_smb2) {
876 return open_was_deferred_smb2(xconn, mid);
879 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
880 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
881 return True;
884 return False;
887 /****************************************************************************
888 Return the message queued by this mid.
889 ****************************************************************************/
891 static struct pending_message_list *get_deferred_open_message_smb(
892 struct smbd_server_connection *sconn, uint64_t mid)
894 struct pending_message_list *pml;
896 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
897 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
898 return pml;
901 return NULL;
904 /****************************************************************************
905 Get the state data queued by this mid.
906 ****************************************************************************/
908 bool get_deferred_open_message_state(struct smb_request *smbreq,
909 struct timeval *p_request_time,
910 struct deferred_open_record **open_rec)
912 struct pending_message_list *pml;
914 if (smbreq->sconn->using_smb2) {
915 return get_deferred_open_message_state_smb2(smbreq->smb2req,
916 p_request_time,
917 open_rec);
920 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
921 if (!pml) {
922 return false;
924 if (p_request_time) {
925 *p_request_time = pml->request_time;
927 if (open_rec != NULL) {
928 *open_rec = pml->open_rec;
930 return true;
933 /****************************************************************************
934 Function to push a deferred open smb message onto a linked list of local smb
935 messages ready for processing.
936 ****************************************************************************/
938 bool push_deferred_open_message_smb(struct smb_request *req,
939 struct timeval request_time,
940 struct timeval timeout,
941 struct file_id id,
942 struct deferred_open_record *open_rec)
944 struct timeval end_time;
946 if (req->smb2req) {
947 return push_deferred_open_message_smb2(req->smb2req,
948 request_time,
949 timeout,
951 open_rec);
954 if (req->unread_bytes) {
955 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
956 "unread_bytes = %u\n",
957 (unsigned int)req->unread_bytes ));
958 smb_panic("push_deferred_open_message_smb: "
959 "logic error unread_bytes != 0" );
962 end_time = timeval_sum(&request_time, &timeout);
964 DEBUG(10,("push_deferred_open_message_smb: pushing message "
965 "len %u mid %llu timeout time [%u.%06u]\n",
966 (unsigned int) smb_len(req->inbuf)+4,
967 (unsigned long long)req->mid,
968 (unsigned int)end_time.tv_sec,
969 (unsigned int)end_time.tv_usec));
971 return push_queued_message(req, request_time, end_time, open_rec);
974 static void smbd_sig_term_handler(struct tevent_context *ev,
975 struct tevent_signal *se,
976 int signum,
977 int count,
978 void *siginfo,
979 void *private_data)
981 exit_server_cleanly("termination signal");
984 static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
986 struct tevent_signal *se;
988 se = tevent_add_signal(sconn->ev_ctx,
989 sconn,
990 SIGTERM, 0,
991 smbd_sig_term_handler,
992 sconn);
993 if (!se) {
994 exit_server("failed to setup SIGTERM handler");
998 static void smbd_sig_hup_handler(struct tevent_context *ev,
999 struct tevent_signal *se,
1000 int signum,
1001 int count,
1002 void *siginfo,
1003 void *private_data)
1005 struct smbd_server_connection *sconn =
1006 talloc_get_type_abort(private_data,
1007 struct smbd_server_connection);
1009 change_to_root_user();
1010 DEBUG(1,("Reloading services after SIGHUP\n"));
1011 reload_services(sconn, conn_snum_used, false);
1014 static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
1016 struct tevent_signal *se;
1018 se = tevent_add_signal(sconn->ev_ctx,
1019 sconn,
1020 SIGHUP, 0,
1021 smbd_sig_hup_handler,
1022 sconn);
1023 if (!se) {
1024 exit_server("failed to setup SIGHUP handler");
1028 static void smbd_conf_updated(struct messaging_context *msg,
1029 void *private_data,
1030 uint32_t msg_type,
1031 struct server_id server_id,
1032 DATA_BLOB *data)
1034 struct smbd_server_connection *sconn =
1035 talloc_get_type_abort(private_data,
1036 struct smbd_server_connection);
1038 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
1039 "updated. Reloading.\n"));
1040 change_to_root_user();
1041 reload_services(sconn, conn_snum_used, false);
1045 * Only allow 5 outstanding trans requests. We're allocating memory, so
1046 * prevent a DoS.
1049 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1051 int count = 0;
1052 for (; list != NULL; list = list->next) {
1054 if (list->mid == mid) {
1055 return NT_STATUS_INVALID_PARAMETER;
1058 count += 1;
1060 if (count > 5) {
1061 return NT_STATUS_INSUFFICIENT_RESOURCES;
1064 return NT_STATUS_OK;
1068 These flags determine some of the permissions required to do an operation
1070 Note that I don't set NEED_WRITE on some write operations because they
1071 are used by some brain-dead clients when printing, and I don't want to
1072 force write permissions on print services.
1074 #define AS_USER (1<<0)
1075 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1076 #define TIME_INIT (1<<2)
1077 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1078 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1079 #define DO_CHDIR (1<<6)
1082 define a list of possible SMB messages and their corresponding
1083 functions. Any message that has a NULL function is unimplemented -
1084 please feel free to contribute implementations!
1086 static const struct smb_message_struct {
1087 const char *name;
1088 void (*fn)(struct smb_request *req);
1089 int flags;
1090 } smb_messages[256] = {
1092 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1093 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1094 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1095 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1096 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1097 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1098 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1099 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1100 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1101 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1102 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1103 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1104 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1105 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1106 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1107 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1108 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1109 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1110 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1111 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1112 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1113 /* 0x15 */ { NULL, NULL, 0 },
1114 /* 0x16 */ { NULL, NULL, 0 },
1115 /* 0x17 */ { NULL, NULL, 0 },
1116 /* 0x18 */ { NULL, NULL, 0 },
1117 /* 0x19 */ { NULL, NULL, 0 },
1118 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1119 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1120 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1121 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1122 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1123 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1124 /* 0x20 */ { "SMBwritec", NULL,0},
1125 /* 0x21 */ { NULL, NULL, 0 },
1126 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1127 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1128 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1129 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1130 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1131 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1132 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1133 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1134 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1135 /* 0x2b */ { "SMBecho",reply_echo,0},
1136 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1137 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1138 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1139 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1140 /* 0x30 */ { NULL, NULL, 0 },
1141 /* 0x31 */ { NULL, NULL, 0 },
1142 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1143 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1144 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1145 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1146 /* 0x36 */ { NULL, NULL, 0 },
1147 /* 0x37 */ { NULL, NULL, 0 },
1148 /* 0x38 */ { NULL, NULL, 0 },
1149 /* 0x39 */ { NULL, NULL, 0 },
1150 /* 0x3a */ { NULL, NULL, 0 },
1151 /* 0x3b */ { NULL, NULL, 0 },
1152 /* 0x3c */ { NULL, NULL, 0 },
1153 /* 0x3d */ { NULL, NULL, 0 },
1154 /* 0x3e */ { NULL, NULL, 0 },
1155 /* 0x3f */ { NULL, NULL, 0 },
1156 /* 0x40 */ { NULL, NULL, 0 },
1157 /* 0x41 */ { NULL, NULL, 0 },
1158 /* 0x42 */ { NULL, NULL, 0 },
1159 /* 0x43 */ { NULL, NULL, 0 },
1160 /* 0x44 */ { NULL, NULL, 0 },
1161 /* 0x45 */ { NULL, NULL, 0 },
1162 /* 0x46 */ { NULL, NULL, 0 },
1163 /* 0x47 */ { NULL, NULL, 0 },
1164 /* 0x48 */ { NULL, NULL, 0 },
1165 /* 0x49 */ { NULL, NULL, 0 },
1166 /* 0x4a */ { NULL, NULL, 0 },
1167 /* 0x4b */ { NULL, NULL, 0 },
1168 /* 0x4c */ { NULL, NULL, 0 },
1169 /* 0x4d */ { NULL, NULL, 0 },
1170 /* 0x4e */ { NULL, NULL, 0 },
1171 /* 0x4f */ { NULL, NULL, 0 },
1172 /* 0x50 */ { NULL, NULL, 0 },
1173 /* 0x51 */ { NULL, NULL, 0 },
1174 /* 0x52 */ { NULL, NULL, 0 },
1175 /* 0x53 */ { NULL, NULL, 0 },
1176 /* 0x54 */ { NULL, NULL, 0 },
1177 /* 0x55 */ { NULL, NULL, 0 },
1178 /* 0x56 */ { NULL, NULL, 0 },
1179 /* 0x57 */ { NULL, NULL, 0 },
1180 /* 0x58 */ { NULL, NULL, 0 },
1181 /* 0x59 */ { NULL, NULL, 0 },
1182 /* 0x5a */ { NULL, NULL, 0 },
1183 /* 0x5b */ { NULL, NULL, 0 },
1184 /* 0x5c */ { NULL, NULL, 0 },
1185 /* 0x5d */ { NULL, NULL, 0 },
1186 /* 0x5e */ { NULL, NULL, 0 },
1187 /* 0x5f */ { NULL, NULL, 0 },
1188 /* 0x60 */ { NULL, NULL, 0 },
1189 /* 0x61 */ { NULL, NULL, 0 },
1190 /* 0x62 */ { NULL, NULL, 0 },
1191 /* 0x63 */ { NULL, NULL, 0 },
1192 /* 0x64 */ { NULL, NULL, 0 },
1193 /* 0x65 */ { NULL, NULL, 0 },
1194 /* 0x66 */ { NULL, NULL, 0 },
1195 /* 0x67 */ { NULL, NULL, 0 },
1196 /* 0x68 */ { NULL, NULL, 0 },
1197 /* 0x69 */ { NULL, NULL, 0 },
1198 /* 0x6a */ { NULL, NULL, 0 },
1199 /* 0x6b */ { NULL, NULL, 0 },
1200 /* 0x6c */ { NULL, NULL, 0 },
1201 /* 0x6d */ { NULL, NULL, 0 },
1202 /* 0x6e */ { NULL, NULL, 0 },
1203 /* 0x6f */ { NULL, NULL, 0 },
1204 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1205 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1206 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1207 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1208 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1209 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1210 /* 0x76 */ { NULL, NULL, 0 },
1211 /* 0x77 */ { NULL, NULL, 0 },
1212 /* 0x78 */ { NULL, NULL, 0 },
1213 /* 0x79 */ { NULL, NULL, 0 },
1214 /* 0x7a */ { NULL, NULL, 0 },
1215 /* 0x7b */ { NULL, NULL, 0 },
1216 /* 0x7c */ { NULL, NULL, 0 },
1217 /* 0x7d */ { NULL, NULL, 0 },
1218 /* 0x7e */ { NULL, NULL, 0 },
1219 /* 0x7f */ { NULL, NULL, 0 },
1220 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1221 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1222 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1223 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1224 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1225 /* 0x85 */ { NULL, NULL, 0 },
1226 /* 0x86 */ { NULL, NULL, 0 },
1227 /* 0x87 */ { NULL, NULL, 0 },
1228 /* 0x88 */ { NULL, NULL, 0 },
1229 /* 0x89 */ { NULL, NULL, 0 },
1230 /* 0x8a */ { NULL, NULL, 0 },
1231 /* 0x8b */ { NULL, NULL, 0 },
1232 /* 0x8c */ { NULL, NULL, 0 },
1233 /* 0x8d */ { NULL, NULL, 0 },
1234 /* 0x8e */ { NULL, NULL, 0 },
1235 /* 0x8f */ { NULL, NULL, 0 },
1236 /* 0x90 */ { NULL, NULL, 0 },
1237 /* 0x91 */ { NULL, NULL, 0 },
1238 /* 0x92 */ { NULL, NULL, 0 },
1239 /* 0x93 */ { NULL, NULL, 0 },
1240 /* 0x94 */ { NULL, NULL, 0 },
1241 /* 0x95 */ { NULL, NULL, 0 },
1242 /* 0x96 */ { NULL, NULL, 0 },
1243 /* 0x97 */ { NULL, NULL, 0 },
1244 /* 0x98 */ { NULL, NULL, 0 },
1245 /* 0x99 */ { NULL, NULL, 0 },
1246 /* 0x9a */ { NULL, NULL, 0 },
1247 /* 0x9b */ { NULL, NULL, 0 },
1248 /* 0x9c */ { NULL, NULL, 0 },
1249 /* 0x9d */ { NULL, NULL, 0 },
1250 /* 0x9e */ { NULL, NULL, 0 },
1251 /* 0x9f */ { NULL, NULL, 0 },
1252 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1253 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1254 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1255 /* 0xa3 */ { NULL, NULL, 0 },
1256 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1257 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1258 /* 0xa6 */ { NULL, NULL, 0 },
1259 /* 0xa7 */ { NULL, NULL, 0 },
1260 /* 0xa8 */ { NULL, NULL, 0 },
1261 /* 0xa9 */ { NULL, NULL, 0 },
1262 /* 0xaa */ { NULL, NULL, 0 },
1263 /* 0xab */ { NULL, NULL, 0 },
1264 /* 0xac */ { NULL, NULL, 0 },
1265 /* 0xad */ { NULL, NULL, 0 },
1266 /* 0xae */ { NULL, NULL, 0 },
1267 /* 0xaf */ { NULL, NULL, 0 },
1268 /* 0xb0 */ { NULL, NULL, 0 },
1269 /* 0xb1 */ { NULL, NULL, 0 },
1270 /* 0xb2 */ { NULL, NULL, 0 },
1271 /* 0xb3 */ { NULL, NULL, 0 },
1272 /* 0xb4 */ { NULL, NULL, 0 },
1273 /* 0xb5 */ { NULL, NULL, 0 },
1274 /* 0xb6 */ { NULL, NULL, 0 },
1275 /* 0xb7 */ { NULL, NULL, 0 },
1276 /* 0xb8 */ { NULL, NULL, 0 },
1277 /* 0xb9 */ { NULL, NULL, 0 },
1278 /* 0xba */ { NULL, NULL, 0 },
1279 /* 0xbb */ { NULL, NULL, 0 },
1280 /* 0xbc */ { NULL, NULL, 0 },
1281 /* 0xbd */ { NULL, NULL, 0 },
1282 /* 0xbe */ { NULL, NULL, 0 },
1283 /* 0xbf */ { NULL, NULL, 0 },
1284 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1285 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1286 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1287 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1288 /* 0xc4 */ { NULL, NULL, 0 },
1289 /* 0xc5 */ { NULL, NULL, 0 },
1290 /* 0xc6 */ { NULL, NULL, 0 },
1291 /* 0xc7 */ { NULL, NULL, 0 },
1292 /* 0xc8 */ { NULL, NULL, 0 },
1293 /* 0xc9 */ { NULL, NULL, 0 },
1294 /* 0xca */ { NULL, NULL, 0 },
1295 /* 0xcb */ { NULL, NULL, 0 },
1296 /* 0xcc */ { NULL, NULL, 0 },
1297 /* 0xcd */ { NULL, NULL, 0 },
1298 /* 0xce */ { NULL, NULL, 0 },
1299 /* 0xcf */ { NULL, NULL, 0 },
1300 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1301 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1302 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1303 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1304 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1305 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1306 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1307 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1308 /* 0xd8 */ { NULL, NULL, 0 },
1309 /* 0xd9 */ { NULL, NULL, 0 },
1310 /* 0xda */ { NULL, NULL, 0 },
1311 /* 0xdb */ { NULL, NULL, 0 },
1312 /* 0xdc */ { NULL, NULL, 0 },
1313 /* 0xdd */ { NULL, NULL, 0 },
1314 /* 0xde */ { NULL, NULL, 0 },
1315 /* 0xdf */ { NULL, NULL, 0 },
1316 /* 0xe0 */ { NULL, NULL, 0 },
1317 /* 0xe1 */ { NULL, NULL, 0 },
1318 /* 0xe2 */ { NULL, NULL, 0 },
1319 /* 0xe3 */ { NULL, NULL, 0 },
1320 /* 0xe4 */ { NULL, NULL, 0 },
1321 /* 0xe5 */ { NULL, NULL, 0 },
1322 /* 0xe6 */ { NULL, NULL, 0 },
1323 /* 0xe7 */ { NULL, NULL, 0 },
1324 /* 0xe8 */ { NULL, NULL, 0 },
1325 /* 0xe9 */ { NULL, NULL, 0 },
1326 /* 0xea */ { NULL, NULL, 0 },
1327 /* 0xeb */ { NULL, NULL, 0 },
1328 /* 0xec */ { NULL, NULL, 0 },
1329 /* 0xed */ { NULL, NULL, 0 },
1330 /* 0xee */ { NULL, NULL, 0 },
1331 /* 0xef */ { NULL, NULL, 0 },
1332 /* 0xf0 */ { NULL, NULL, 0 },
1333 /* 0xf1 */ { NULL, NULL, 0 },
1334 /* 0xf2 */ { NULL, NULL, 0 },
1335 /* 0xf3 */ { NULL, NULL, 0 },
1336 /* 0xf4 */ { NULL, NULL, 0 },
1337 /* 0xf5 */ { NULL, NULL, 0 },
1338 /* 0xf6 */ { NULL, NULL, 0 },
1339 /* 0xf7 */ { NULL, NULL, 0 },
1340 /* 0xf8 */ { NULL, NULL, 0 },
1341 /* 0xf9 */ { NULL, NULL, 0 },
1342 /* 0xfa */ { NULL, NULL, 0 },
1343 /* 0xfb */ { NULL, NULL, 0 },
1344 /* 0xfc */ { NULL, NULL, 0 },
1345 /* 0xfd */ { NULL, NULL, 0 },
1346 /* 0xfe */ { NULL, NULL, 0 },
1347 /* 0xff */ { NULL, NULL, 0 }
1351 /*******************************************************************
1352 allocate and initialize a reply packet
1353 ********************************************************************/
1355 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1356 const uint8_t *inbuf, char **outbuf,
1357 uint8_t num_words, uint32_t num_bytes)
1359 size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
1362 * Protect against integer wrap.
1363 * The SMB layer reply can be up to 0xFFFFFF bytes.
1365 if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) {
1366 char *msg;
1367 if (asprintf(&msg, "num_bytes too large: %u",
1368 (unsigned)num_bytes) == -1) {
1369 msg = discard_const_p(char, "num_bytes too large");
1371 smb_panic(msg);
1375 * Here we include the NBT header for now.
1377 *outbuf = talloc_array(mem_ctx, char,
1378 NBT_HDR_SIZE + smb_len);
1379 if (*outbuf == NULL) {
1380 return false;
1383 construct_reply_common(req->cmd, inbuf, *outbuf);
1384 srv_set_message(*outbuf, num_words, num_bytes, false);
1386 * Zero out the word area, the caller has to take care of the bcc area
1387 * himself
1389 if (num_words != 0) {
1390 memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words));
1393 return true;
1396 void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes)
1398 char *outbuf;
1399 if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
1400 num_bytes)) {
1401 smb_panic("could not allocate output buffer\n");
1403 req->outbuf = (uint8_t *)outbuf;
1407 /*******************************************************************
1408 Dump a packet to a file.
1409 ********************************************************************/
1411 static void smb_dump(const char *name, int type, const char *data)
1413 size_t len;
1414 int fd, i;
1415 char *fname = NULL;
1416 if (DEBUGLEVEL < 50) {
1417 return;
1420 len = smb_len_tcp(data)+4;
1421 for (i=1;i<100;i++) {
1422 fname = talloc_asprintf(talloc_tos(),
1423 "/tmp/%s.%d.%s",
1424 name,
1426 type ? "req" : "resp");
1427 if (fname == NULL) {
1428 return;
1430 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1431 if (fd != -1 || errno != EEXIST) break;
1432 TALLOC_FREE(fname);
1434 if (fd != -1) {
1435 ssize_t ret = write(fd, data, len);
1436 if (ret != len)
1437 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1438 close(fd);
1439 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1441 TALLOC_FREE(fname);
1444 static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
1445 struct smb_request *req,
1446 uint8_t type,
1447 bool *update_session_globalp,
1448 bool *update_tcon_globalp)
1450 connection_struct *conn = req->conn;
1451 struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
1452 uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
1453 uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1454 bool update_session = false;
1455 bool update_tcon = false;
1457 if (req->encrypted) {
1458 encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
1461 if (srv_is_signing_active(req->xconn)) {
1462 sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
1463 } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
1465 * echo can be unsigned. Sesssion setup except final
1466 * session setup response too
1468 sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
1471 update_session |= smbXsrv_set_crypto_flag(
1472 &session->global->encryption_flags, encrypt_flag);
1473 update_session |= smbXsrv_set_crypto_flag(
1474 &session->global->signing_flags, sign_flag);
1476 if (tcon) {
1477 update_tcon |= smbXsrv_set_crypto_flag(
1478 &tcon->global->encryption_flags, encrypt_flag);
1479 update_tcon |= smbXsrv_set_crypto_flag(
1480 &tcon->global->signing_flags, sign_flag);
1483 if (update_session) {
1484 session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
1487 *update_session_globalp = update_session;
1488 *update_tcon_globalp = update_tcon;
1489 return;
1492 /****************************************************************************
1493 Prepare everything for calling the actual request function, and potentially
1494 call the request function via the "new" interface.
1496 Return False if the "legacy" function needs to be called, everything is
1497 prepared.
1499 Return True if we're done.
1501 I know this API sucks, but it is the one with the least code change I could
1502 find.
1503 ****************************************************************************/
1505 static connection_struct *switch_message(uint8_t type, struct smb_request *req)
1507 int flags;
1508 uint64_t session_tag;
1509 connection_struct *conn = NULL;
1510 struct smbXsrv_connection *xconn = req->xconn;
1511 NTTIME now = timeval_to_nttime(&req->request_time);
1512 struct smbXsrv_session *session = NULL;
1513 NTSTATUS status;
1515 errno = 0;
1517 if (!xconn->smb1.negprot.done) {
1518 switch (type) {
1520 * Without a negprot the request must
1521 * either be a negprot, or one of the
1522 * evil old SMB mailslot messaging types.
1524 case SMBnegprot:
1525 case SMBsendstrt:
1526 case SMBsendend:
1527 case SMBsendtxt:
1528 break;
1529 default:
1530 exit_server_cleanly("The first request "
1531 "should be a negprot");
1535 if (smb_messages[type].fn == NULL) {
1536 DEBUG(0,("Unknown message type %d!\n",type));
1537 smb_dump("Unknown", 1, (const char *)req->inbuf);
1538 reply_unknown_new(req, type);
1539 return NULL;
1542 flags = smb_messages[type].flags;
1544 /* In share mode security we must ignore the vuid. */
1545 session_tag = req->vuid;
1546 conn = req->conn;
1548 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1549 (int)getpid(), (unsigned long)conn));
1551 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1553 /* Ensure this value is replaced in the incoming packet. */
1554 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1557 * Ensure the correct username is in current_user_info. This is a
1558 * really ugly bugfix for problems with multiple session_setup_and_X's
1559 * being done and allowing %U and %G substitutions to work correctly.
1560 * There is a reason this code is done here, don't move it unless you
1561 * know what you're doing... :-).
1562 * JRA.
1566 * lookup an existing session
1568 * Note: for now we only check for NT_STATUS_NETWORK_SESSION_EXPIRED
1569 * here, the main check is still in change_to_user()
1571 status = smb1srv_session_lookup(xconn,
1572 session_tag,
1573 now,
1574 &session);
1575 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
1576 switch (type) {
1577 case SMBsesssetupX:
1578 status = NT_STATUS_OK;
1579 break;
1580 default:
1581 DEBUG(1,("Error: session %llu is expired, mid=%llu.\n",
1582 (unsigned long long)session_tag,
1583 (unsigned long long)req->mid));
1584 reply_nterror(req, NT_STATUS_NETWORK_SESSION_EXPIRED);
1585 return conn;
1589 if (session != NULL && !(flags & AS_USER)) {
1590 struct user_struct *vuser = session->compat;
1593 * change_to_user() implies set_current_user_info()
1594 * and chdir_connect_service().
1596 * So we only call set_current_user_info if
1597 * we don't have AS_USER specified.
1599 if (vuser) {
1600 set_current_user_info(
1601 vuser->session_info->unix_info->sanitized_username,
1602 vuser->session_info->unix_info->unix_name,
1603 vuser->session_info->info->domain_name);
1607 /* Does this call need to be run as the connected user? */
1608 if (flags & AS_USER) {
1610 /* Does this call need a valid tree connection? */
1611 if (!conn) {
1613 * Amazingly, the error code depends on the command
1614 * (from Samba4).
1616 if (type == SMBntcreateX) {
1617 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1618 } else {
1619 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1621 return NULL;
1624 set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
1627 * change_to_user() implies set_current_user_info()
1628 * and chdir_connect_service().
1630 if (!change_to_user(conn,session_tag)) {
1631 DEBUG(0, ("Error: Could not change to user. Removing "
1632 "deferred open, mid=%llu.\n",
1633 (unsigned long long)req->mid));
1634 reply_force_doserror(req, ERRSRV, ERRbaduid);
1635 return conn;
1638 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1640 /* Does it need write permission? */
1641 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1642 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1643 return conn;
1646 /* IPC services are limited */
1647 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1648 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1649 return conn;
1651 } else if (flags & AS_GUEST) {
1653 * Does this protocol need to be run as guest? (Only archane
1654 * messenger service requests have this...)
1656 if (!change_to_guest()) {
1657 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1658 return conn;
1660 } else {
1661 /* This call needs to be run as root */
1662 change_to_root_user();
1665 /* load service specific parameters */
1666 if (conn) {
1667 if (req->encrypted) {
1668 conn->encrypted_tid = true;
1669 /* encrypted required from now on. */
1670 conn->encrypt_level = SMB_SIGNING_REQUIRED;
1671 } else if (ENCRYPTION_REQUIRED(conn)) {
1672 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1673 DEBUG(1,("service[%s] requires encryption"
1674 "%s ACCESS_DENIED. mid=%llu\n",
1675 lp_servicename(talloc_tos(), SNUM(conn)),
1676 smb_fn_name(type),
1677 (unsigned long long)req->mid));
1678 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1679 return conn;
1683 if (flags & DO_CHDIR) {
1684 bool ok;
1686 ok = chdir_current_service(conn);
1687 if (!ok) {
1688 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1689 return conn;
1692 conn->num_smb_operations++;
1696 * Update encryption and signing state tracking flags that are
1697 * used by smbstatus to display signing and encryption status.
1699 if (session != NULL) {
1700 bool update_session_global = false;
1701 bool update_tcon_global = false;
1703 smb1srv_update_crypto_flags(session, req, type,
1704 &update_session_global,
1705 &update_tcon_global);
1707 if (update_session_global) {
1708 status = smbXsrv_session_update(session);
1709 if (!NT_STATUS_IS_OK(status)) {
1710 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1711 return conn;
1715 if (update_tcon_global) {
1716 status = smbXsrv_tcon_update(req->conn->tcon);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1719 return conn;
1724 smb_messages[type].fn(req);
1725 return req->conn;
1728 /****************************************************************************
1729 Construct a reply to the incoming packet.
1730 ****************************************************************************/
1732 static void construct_reply(struct smbXsrv_connection *xconn,
1733 char *inbuf, int size, size_t unread_bytes,
1734 uint32_t seqnum, bool encrypted,
1735 struct smb_perfcount_data *deferred_pcd)
1737 struct smbd_server_connection *sconn = xconn->client->sconn;
1738 struct smb_request *req;
1740 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1741 smb_panic("could not allocate smb_request");
1744 if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
1745 encrypted, seqnum)) {
1746 exit_server_cleanly("Invalid SMB request");
1749 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1751 /* we popped this message off the queue - keep original perf data */
1752 if (deferred_pcd)
1753 req->pcd = *deferred_pcd;
1754 else {
1755 SMB_PERFCOUNT_START(&req->pcd);
1756 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1757 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1760 req->conn = switch_message(req->cmd, req);
1762 if (req->outbuf == NULL) {
1764 * Request has suspended itself, will come
1765 * back here.
1767 return;
1769 if (CVAL(req->outbuf,0) == 0) {
1770 show_msg((char *)req->outbuf);
1772 smb_request_done(req);
1775 static void construct_reply_chain(struct smbXsrv_connection *xconn,
1776 char *inbuf, int size, uint32_t seqnum,
1777 bool encrypted,
1778 struct smb_perfcount_data *deferred_pcd)
1780 struct smb_request **reqs = NULL;
1781 struct smb_request *req;
1782 unsigned num_reqs;
1783 bool ok;
1785 ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
1786 seqnum, &reqs, &num_reqs);
1787 if (!ok) {
1788 char errbuf[smb_size];
1789 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1790 __LINE__, __FILE__);
1791 if (!srv_send_smb(xconn, errbuf, true, seqnum, encrypted,
1792 NULL)) {
1793 exit_server_cleanly("construct_reply_chain: "
1794 "srv_send_smb failed.");
1796 return;
1799 req = reqs[0];
1800 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1802 req->conn = switch_message(req->cmd, req);
1804 if (req->outbuf == NULL) {
1806 * Request has suspended itself, will come
1807 * back here.
1809 return;
1811 smb_request_done(req);
1815 * To be called from an async SMB handler that is potentially chained
1816 * when it is finished for shipping.
1819 void smb_request_done(struct smb_request *req)
1821 struct smb_request **reqs = NULL;
1822 struct smb_request *first_req;
1823 size_t i, num_reqs, next_index;
1824 NTSTATUS status;
1826 if (req->chain == NULL) {
1827 first_req = req;
1828 goto shipit;
1831 reqs = req->chain;
1832 num_reqs = talloc_array_length(reqs);
1834 for (i=0; i<num_reqs; i++) {
1835 if (reqs[i] == req) {
1836 break;
1839 if (i == num_reqs) {
1841 * Invalid chain, should not happen
1843 status = NT_STATUS_INTERNAL_ERROR;
1844 goto error;
1846 next_index = i+1;
1848 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1849 struct smb_request *next = reqs[next_index];
1850 struct smbXsrv_tcon *tcon;
1851 NTTIME now = timeval_to_nttime(&req->request_time);
1853 next->vuid = SVAL(req->outbuf, smb_uid);
1854 next->tid = SVAL(req->outbuf, smb_tid);
1855 status = smb1srv_tcon_lookup(req->xconn, next->tid,
1856 now, &tcon);
1858 if (NT_STATUS_IS_OK(status)) {
1859 next->conn = tcon->compat;
1860 } else {
1861 next->conn = NULL;
1863 next->chain_fsp = req->chain_fsp;
1864 next->inbuf = req->inbuf;
1866 req = next;
1867 req->conn = switch_message(req->cmd, req);
1869 if (req->outbuf == NULL) {
1871 * Request has suspended itself, will come
1872 * back here.
1874 return;
1876 next_index += 1;
1879 first_req = reqs[0];
1881 for (i=1; i<next_index; i++) {
1882 bool ok;
1884 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1885 if (!ok) {
1886 status = NT_STATUS_INTERNAL_ERROR;
1887 goto error;
1891 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1892 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1895 * This scary statement intends to set the
1896 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1897 * to the value last_req->outbuf carries
1899 SSVAL(first_req->outbuf, smb_flg2,
1900 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1901 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1904 * Transfer the error codes from the subrequest to the main one
1906 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1907 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1909 _smb_setlen_large(
1910 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1912 shipit:
1913 if (!srv_send_smb(first_req->xconn,
1914 (char *)first_req->outbuf,
1915 true, first_req->seqnum+1,
1916 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1917 &first_req->pcd)) {
1918 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1919 "failed.");
1921 TALLOC_FREE(req); /* non-chained case */
1922 TALLOC_FREE(reqs); /* chained case */
1923 return;
1925 error:
1927 char errbuf[smb_size];
1928 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1929 if (!srv_send_smb(req->xconn, errbuf, true,
1930 req->seqnum+1, req->encrypted,
1931 NULL)) {
1932 exit_server_cleanly("construct_reply_chain: "
1933 "srv_send_smb failed.");
1936 TALLOC_FREE(req); /* non-chained case */
1937 TALLOC_FREE(reqs); /* chained case */
1940 /****************************************************************************
1941 Process an smb from the client
1942 ****************************************************************************/
1943 static void process_smb(struct smbXsrv_connection *xconn,
1944 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1945 uint32_t seqnum, bool encrypted,
1946 struct smb_perfcount_data *deferred_pcd)
1948 struct smbd_server_connection *sconn = xconn->client->sconn;
1949 int msg_type = CVAL(inbuf,0);
1951 DO_PROFILE_INC(request);
1953 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1954 smb_len(inbuf) ) );
1955 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1956 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1958 if (msg_type != NBSSmessage) {
1960 * NetBIOS session request, keepalive, etc.
1962 reply_special(xconn, (char *)inbuf, nread);
1963 goto done;
1966 if (sconn->using_smb2) {
1967 /* At this point we're not really using smb2,
1968 * we make the decision here.. */
1969 if (smbd_is_smb2_header(inbuf, nread)) {
1970 const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
1971 size_t pdulen = nread - NBT_HDR_SIZE;
1972 smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
1973 return;
1975 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;
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)));
1989 /* special magic for immediate exit */
1990 if ((nread == 9) &&
1991 (IVAL(inbuf, 4) == SMB_SUICIDE_PACKET) &&
1992 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1993 uint8_t exitcode = CVAL(inbuf, 8);
1994 DBG_WARNING("SUICIDE: Exiting immediately with code %d\n",
1995 (int)exitcode);
1996 exit(exitcode);
1999 exit_server_cleanly("Non-SMB packet");
2002 show_msg((char *)inbuf);
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);
2012 sconn->trans_num++;
2014 done:
2015 sconn->num_requests++;
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. */
2024 if ((sconn->num_requests % 50) == 0 &&
2025 need_to_check_log_size()) {
2026 change_to_root_user();
2027 check_log_size();
2031 /****************************************************************************
2032 Return a string containing the function name of a SMB command.
2033 ****************************************************************************/
2035 const char *smb_fn_name(int type)
2037 const char *unknown_name = "SMBunknown";
2039 if (smb_messages[type].name == NULL)
2040 return(unknown_name);
2042 return(smb_messages[type].name);
2045 /****************************************************************************
2046 Helper functions for contruct_reply.
2047 ****************************************************************************/
2049 void add_to_common_flags2(uint32_t v)
2051 common_flags2 |= v;
2054 void remove_from_common_flags2(uint32_t v)
2056 common_flags2 &= ~v;
2059 static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
2060 char *outbuf)
2062 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
2063 uint16_t out_flags2 = common_flags2;
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;
2069 srv_set_message(outbuf,0,0,false);
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);
2078 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
2079 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
2080 SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
2081 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
2082 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
2085 void construct_reply_common_req(struct smb_request *req, char *outbuf)
2087 construct_reply_common(req->cmd, req->inbuf, outbuf);
2091 * @brief Find the smb_cmd offset of the last command pushed
2092 * @param[in] buf The buffer we're building up
2093 * @retval Where can we put our next andx cmd?
2095 * While chaining requests, the "next" request we're looking at needs to put
2096 * its SMB_Command before the data the previous request already built up added
2097 * to the chain. Find the offset to the place where we have to put our cmd.
2100 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
2102 uint8_t cmd;
2103 size_t ofs;
2105 cmd = CVAL(buf, smb_com);
2107 if (!smb1cli_is_andx_req(cmd)) {
2108 return false;
2111 ofs = smb_vwv0;
2113 while (CVAL(buf, ofs) != 0xff) {
2115 if (!smb1cli_is_andx_req(CVAL(buf, ofs))) {
2116 return false;
2120 * ofs is from start of smb header, so add the 4 length
2121 * bytes. The next cmd is right after the wct field.
2123 ofs = SVAL(buf, ofs+2) + 4 + 1;
2125 if (ofs+4 >= talloc_get_size(buf)) {
2126 return false;
2130 *pofs = ofs;
2131 return true;
2135 * @brief Do the smb chaining at a buffer level
2136 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
2137 * @param[in] andx_buf Buffer to be appended
2140 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
2142 uint8_t smb_command = CVAL(andx_buf, smb_com);
2143 uint8_t wct = CVAL(andx_buf, smb_wct);
2144 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
2145 uint32_t num_bytes = smb_buflen(andx_buf);
2146 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
2148 uint8_t *outbuf;
2149 size_t old_size, new_size;
2150 size_t ofs;
2151 size_t chain_padding = 0;
2152 size_t andx_cmd_ofs;
2155 old_size = talloc_get_size(*poutbuf);
2157 if ((old_size % 4) != 0) {
2159 * Align the wct field of subsequent requests to a 4-byte
2160 * boundary
2162 chain_padding = 4 - (old_size % 4);
2166 * After the old request comes the new wct field (1 byte), the vwv's
2167 * and the num_bytes field.
2170 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
2171 new_size += num_bytes;
2173 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
2174 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
2175 (unsigned)new_size));
2176 return false;
2179 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
2180 if (outbuf == NULL) {
2181 DEBUG(0, ("talloc failed\n"));
2182 return false;
2184 *poutbuf = outbuf;
2186 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
2187 DEBUG(1, ("invalid command chain\n"));
2188 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
2189 return false;
2192 if (chain_padding != 0) {
2193 memset(outbuf + old_size, 0, chain_padding);
2194 old_size += chain_padding;
2197 SCVAL(outbuf, andx_cmd_ofs, smb_command);
2198 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
2200 ofs = old_size;
2203 * Push the chained request:
2205 * wct field
2208 SCVAL(outbuf, ofs, wct);
2209 ofs += 1;
2212 * vwv array
2215 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2218 * HACK ALERT
2220 * Read&X has an offset into its data buffer at
2221 * vwv[6]. reply_read_andx has no idea anymore that it's
2222 * running from within a chain, so we have to fix up the
2223 * offset here.
2225 * Although it looks disgusting at this place, I want to keep
2226 * it here. The alternative would be to push knowledge about
2227 * the andx chain down into read&x again.
2230 if (smb_command == SMBreadX) {
2231 uint8_t *bytes_addr;
2233 if (wct < 7) {
2235 * Invalid read&x response
2237 return false;
2240 bytes_addr = outbuf + ofs /* vwv start */
2241 + sizeof(uint16_t) * wct /* vwv array */
2242 + sizeof(uint16_t) /* bcc */
2243 + 1; /* padding byte */
2245 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2246 bytes_addr - outbuf - 4);
2249 ofs += sizeof(uint16_t) * wct;
2252 * bcc (byte count)
2255 SSVAL(outbuf, ofs, num_bytes);
2256 ofs += sizeof(uint16_t);
2259 * The bytes field
2262 memcpy(outbuf + ofs, bytes, num_bytes);
2264 return true;
2267 bool smb1_is_chain(const uint8_t *buf)
2269 uint8_t cmd, wct, andx_cmd;
2271 cmd = CVAL(buf, smb_com);
2272 if (!smb1cli_is_andx_req(cmd)) {
2273 return false;
2275 wct = CVAL(buf, smb_wct);
2276 if (wct < 2) {
2277 return false;
2279 andx_cmd = CVAL(buf, smb_vwv);
2280 return (andx_cmd != 0xFF);
2283 bool smb1_walk_chain(const uint8_t *buf,
2284 bool (*fn)(uint8_t cmd,
2285 uint8_t wct, const uint16_t *vwv,
2286 uint16_t num_bytes, const uint8_t *bytes,
2287 void *private_data),
2288 void *private_data)
2290 size_t smblen = smb_len(buf);
2291 const char *smb_buf = smb_base(buf);
2292 uint8_t cmd, chain_cmd;
2293 uint8_t wct;
2294 const uint16_t *vwv;
2295 uint16_t num_bytes;
2296 const uint8_t *bytes;
2298 cmd = CVAL(buf, smb_com);
2299 wct = CVAL(buf, smb_wct);
2300 vwv = (const uint16_t *)(buf + smb_vwv);
2301 num_bytes = smb_buflen(buf);
2302 bytes = (const uint8_t *)smb_buf_const(buf);
2304 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2305 return false;
2308 if (!smb1cli_is_andx_req(cmd)) {
2309 return true;
2311 if (wct < 2) {
2312 return false;
2315 chain_cmd = CVAL(vwv, 0);
2317 while (chain_cmd != 0xff) {
2318 uint32_t chain_offset; /* uint32_t to avoid overflow */
2319 size_t length_needed;
2320 ptrdiff_t vwv_offset;
2322 chain_offset = SVAL(vwv+1, 0);
2325 * Check if the client tries to fool us. The chain
2326 * offset needs to point beyond the current request in
2327 * the chain, it needs to strictly grow. Otherwise we
2328 * might be tricked into an endless loop always
2329 * processing the same request over and over again. We
2330 * used to assume that vwv and the byte buffer array
2331 * in a chain are always attached, but OS/2 the
2332 * Write&X/Read&X chain puts the Read&X vwv array
2333 * right behind the Write&X vwv chain. The Write&X bcc
2334 * array is put behind the Read&X vwv array. So now we
2335 * check whether the chain offset points strictly
2336 * behind the previous vwv array. req->buf points
2337 * right after the vwv array of the previous
2338 * request. See
2339 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2340 * more information.
2343 vwv_offset = ((const char *)vwv - smb_buf);
2344 if (chain_offset <= vwv_offset) {
2345 return false;
2349 * Next check: Make sure the chain offset does not
2350 * point beyond the overall smb request length.
2353 length_needed = chain_offset+1; /* wct */
2354 if (length_needed > smblen) {
2355 return false;
2359 * Now comes the pointer magic. Goal here is to set up
2360 * vwv and buf correctly again. The chain offset (the
2361 * former vwv[1]) points at the new wct field.
2364 wct = CVAL(smb_buf, chain_offset);
2366 if (smb1cli_is_andx_req(chain_cmd) && (wct < 2)) {
2367 return false;
2371 * Next consistency check: Make the new vwv array fits
2372 * in the overall smb request.
2375 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2376 if (length_needed > smblen) {
2377 return false;
2379 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2382 * Now grab the new byte buffer....
2385 num_bytes = SVAL(vwv+wct, 0);
2388 * .. and check that it fits.
2391 length_needed += num_bytes;
2392 if (length_needed > smblen) {
2393 return false;
2395 bytes = (const uint8_t *)(vwv+wct+1);
2397 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2398 return false;
2401 if (!smb1cli_is_andx_req(chain_cmd)) {
2402 return true;
2404 chain_cmd = CVAL(vwv, 0);
2406 return true;
2409 static bool smb1_chain_length_cb(uint8_t cmd,
2410 uint8_t wct, const uint16_t *vwv,
2411 uint16_t num_bytes, const uint8_t *bytes,
2412 void *private_data)
2414 unsigned *count = (unsigned *)private_data;
2415 *count += 1;
2416 return true;
2419 unsigned smb1_chain_length(const uint8_t *buf)
2421 unsigned count = 0;
2423 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2424 return 0;
2426 return count;
2429 struct smb1_parse_chain_state {
2430 TALLOC_CTX *mem_ctx;
2431 const uint8_t *buf;
2432 struct smbd_server_connection *sconn;
2433 struct smbXsrv_connection *xconn;
2434 bool encrypted;
2435 uint32_t seqnum;
2437 struct smb_request **reqs;
2438 unsigned num_reqs;
2441 static bool smb1_parse_chain_cb(uint8_t cmd,
2442 uint8_t wct, const uint16_t *vwv,
2443 uint16_t num_bytes, const uint8_t *bytes,
2444 void *private_data)
2446 struct smb1_parse_chain_state *state =
2447 (struct smb1_parse_chain_state *)private_data;
2448 struct smb_request **reqs;
2449 struct smb_request *req;
2450 bool ok;
2452 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2453 struct smb_request *, state->num_reqs+1);
2454 if (reqs == NULL) {
2455 return false;
2457 state->reqs = reqs;
2459 req = talloc(reqs, struct smb_request);
2460 if (req == NULL) {
2461 return false;
2464 ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
2465 state->encrypted, state->seqnum);
2466 if (!ok) {
2467 return false;
2469 req->cmd = cmd;
2470 req->wct = wct;
2471 req->vwv = vwv;
2472 req->buflen = num_bytes;
2473 req->buf = bytes;
2475 reqs[state->num_reqs] = req;
2476 state->num_reqs += 1;
2477 return true;
2480 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2481 struct smbXsrv_connection *xconn,
2482 bool encrypted, uint32_t seqnum,
2483 struct smb_request ***reqs, unsigned *num_reqs)
2485 struct smbd_server_connection *sconn = NULL;
2486 struct smb1_parse_chain_state state;
2487 unsigned i;
2489 if (xconn != NULL) {
2490 sconn = xconn->client->sconn;
2493 state.mem_ctx = mem_ctx;
2494 state.buf = buf;
2495 state.sconn = sconn;
2496 state.xconn = xconn;
2497 state.encrypted = encrypted;
2498 state.seqnum = seqnum;
2499 state.reqs = NULL;
2500 state.num_reqs = 0;
2502 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2503 TALLOC_FREE(state.reqs);
2504 return false;
2506 for (i=0; i<state.num_reqs; i++) {
2507 state.reqs[i]->chain = state.reqs;
2509 *reqs = state.reqs;
2510 *num_reqs = state.num_reqs;
2511 return true;
2514 /****************************************************************************
2515 Check if services need reloading.
2516 ****************************************************************************/
2518 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2521 if (last_smb_conf_reload_time == 0) {
2522 last_smb_conf_reload_time = t;
2525 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2526 reload_services(sconn, conn_snum_used, true);
2527 last_smb_conf_reload_time = t;
2531 static bool fd_is_readable(int fd)
2533 int ret, revents;
2535 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2537 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2541 static void smbd_server_connection_write_handler(
2542 struct smbXsrv_connection *xconn)
2544 /* TODO: make write nonblocking */
2547 static void smbd_server_connection_read_handler(
2548 struct smbXsrv_connection *xconn, int fd)
2550 uint8_t *inbuf = NULL;
2551 size_t inbuf_len = 0;
2552 size_t unread_bytes = 0;
2553 bool encrypted = false;
2554 TALLOC_CTX *mem_ctx = talloc_tos();
2555 NTSTATUS status;
2556 uint32_t seqnum;
2558 bool async_echo = lp_async_smb_echo_handler();
2559 bool from_client = false;
2561 if (async_echo) {
2562 if (fd_is_readable(xconn->smb1.echo_handler.trusted_fd)) {
2564 * This is the super-ugly hack to prefer the packets
2565 * forwarded by the echo handler over the ones by the
2566 * client directly
2568 fd = xconn->smb1.echo_handler.trusted_fd;
2572 from_client = (xconn->transport.sock == fd);
2574 if (async_echo && from_client) {
2575 smbd_lock_socket(xconn);
2577 if (!fd_is_readable(fd)) {
2578 DEBUG(10,("the echo listener was faster\n"));
2579 smbd_unlock_socket(xconn);
2580 return;
2584 /* TODO: make this completely nonblocking */
2585 status = receive_smb_talloc(mem_ctx, xconn, fd,
2586 (char **)(void *)&inbuf,
2587 0, /* timeout */
2588 &unread_bytes,
2589 &encrypted,
2590 &inbuf_len, &seqnum,
2591 !from_client /* trusted channel */);
2593 if (async_echo && from_client) {
2594 smbd_unlock_socket(xconn);
2597 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2598 goto process;
2600 if (NT_STATUS_IS_ERR(status)) {
2601 exit_server_cleanly("failed to receive smb request");
2603 if (!NT_STATUS_IS_OK(status)) {
2604 return;
2607 process:
2608 process_smb(xconn, inbuf, inbuf_len, unread_bytes,
2609 seqnum, encrypted, NULL);
2612 static void smbd_server_connection_handler(struct tevent_context *ev,
2613 struct tevent_fd *fde,
2614 uint16_t flags,
2615 void *private_data)
2617 struct smbXsrv_connection *xconn =
2618 talloc_get_type_abort(private_data,
2619 struct smbXsrv_connection);
2621 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2623 * we're not supposed to do any io
2625 TEVENT_FD_NOT_READABLE(xconn->transport.fde);
2626 TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
2627 return;
2630 if (flags & TEVENT_FD_WRITE) {
2631 smbd_server_connection_write_handler(xconn);
2632 return;
2634 if (flags & TEVENT_FD_READ) {
2635 smbd_server_connection_read_handler(xconn, xconn->transport.sock);
2636 return;
2640 static void smbd_server_echo_handler(struct tevent_context *ev,
2641 struct tevent_fd *fde,
2642 uint16_t flags,
2643 void *private_data)
2645 struct smbXsrv_connection *xconn =
2646 talloc_get_type_abort(private_data,
2647 struct smbXsrv_connection);
2649 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2651 * we're not supposed to do any io
2653 TEVENT_FD_NOT_READABLE(xconn->smb1.echo_handler.trusted_fde);
2654 TEVENT_FD_NOT_WRITEABLE(xconn->smb1.echo_handler.trusted_fde);
2655 return;
2658 if (flags & TEVENT_FD_WRITE) {
2659 smbd_server_connection_write_handler(xconn);
2660 return;
2662 if (flags & TEVENT_FD_READ) {
2663 smbd_server_connection_read_handler(
2664 xconn, xconn->smb1.echo_handler.trusted_fd);
2665 return;
2669 struct smbd_release_ip_state {
2670 struct smbXsrv_connection *xconn;
2671 struct tevent_immediate *im;
2672 char addr[INET6_ADDRSTRLEN];
2675 static void smbd_release_ip_immediate(struct tevent_context *ctx,
2676 struct tevent_immediate *im,
2677 void *private_data)
2679 struct smbd_release_ip_state *state =
2680 talloc_get_type_abort(private_data,
2681 struct smbd_release_ip_state);
2682 struct smbXsrv_connection *xconn = state->xconn;
2684 if (!NT_STATUS_EQUAL(xconn->transport.status, NT_STATUS_ADDRESS_CLOSED)) {
2686 * smbd_server_connection_terminate() already triggered ?
2688 return;
2691 smbd_server_connection_terminate(xconn, "CTDB_SRVID_RELEASE_IP");
2694 /****************************************************************************
2695 received when we should release a specific IP
2696 ****************************************************************************/
2697 static int release_ip(struct tevent_context *ev,
2698 uint32_t src_vnn, uint32_t dst_vnn,
2699 uint64_t dst_srvid,
2700 const uint8_t *msg, size_t msglen,
2701 void *private_data)
2703 struct smbd_release_ip_state *state =
2704 talloc_get_type_abort(private_data,
2705 struct smbd_release_ip_state);
2706 struct smbXsrv_connection *xconn = state->xconn;
2707 const char *ip;
2708 const char *addr = state->addr;
2709 const char *p = addr;
2711 if (msglen == 0) {
2712 return 0;
2714 if (msg[msglen-1] != '\0') {
2715 return 0;
2718 ip = (const char *)msg;
2720 if (!NT_STATUS_IS_OK(xconn->transport.status)) {
2721 /* avoid recursion */
2722 return 0;
2725 if (strncmp("::ffff:", addr, 7) == 0) {
2726 p = addr + 7;
2729 DEBUG(10, ("Got release IP message for %s, "
2730 "our address is %s\n", ip, p));
2732 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2733 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2734 ip));
2736 * With SMB2 we should do a clean disconnect,
2737 * the previous_session_id in the session setup
2738 * will cleanup the old session, tcons and opens.
2740 * A clean disconnect is needed in order to support
2741 * durable handles.
2743 * Note: typically this is never triggered
2744 * as we got a TCP RST (triggered by ctdb event scripts)
2745 * before we get CTDB_SRVID_RELEASE_IP.
2747 * We used to call _exit(1) here, but as this was mostly never
2748 * triggered and has implication on our process model,
2749 * we can just use smbd_server_connection_terminate()
2750 * (also for SMB1).
2752 * We don't call smbd_server_connection_terminate() directly
2753 * as we might be called from within ctdbd_migrate(),
2754 * we need to defer our action to the next event loop
2756 tevent_schedule_immediate(state->im,
2757 xconn->client->raw_ev_ctx,
2758 smbd_release_ip_immediate,
2759 state);
2762 * Make sure we don't get any io on the connection.
2764 xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
2765 return EADDRNOTAVAIL;
2768 return 0;
2771 static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
2772 struct sockaddr_storage *srv,
2773 struct sockaddr_storage *clnt)
2775 struct smbd_release_ip_state *state;
2776 struct ctdbd_connection *cconn;
2777 int ret;
2779 cconn = messaging_ctdb_connection();
2780 if (cconn == NULL) {
2781 return NT_STATUS_NO_MEMORY;
2784 state = talloc_zero(xconn, struct smbd_release_ip_state);
2785 if (state == NULL) {
2786 return NT_STATUS_NO_MEMORY;
2788 state->xconn = xconn;
2789 state->im = tevent_create_immediate(state);
2790 if (state->im == NULL) {
2791 return NT_STATUS_NO_MEMORY;
2793 if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
2794 return NT_STATUS_NO_MEMORY;
2797 ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
2798 if (ret != 0) {
2799 return map_nt_error_from_unix(ret);
2801 return NT_STATUS_OK;
2804 static void msg_kill_client_ip(struct messaging_context *msg_ctx,
2805 void *private_data, uint32_t msg_type,
2806 struct server_id server_id, DATA_BLOB *data)
2808 struct smbd_server_connection *sconn = talloc_get_type_abort(
2809 private_data, struct smbd_server_connection);
2810 const char *ip = (char *) data->data;
2811 char *client_ip;
2813 DBG_DEBUG("Got kill request for client IP %s\n", ip);
2815 client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
2816 talloc_tos());
2817 if (client_ip == NULL) {
2818 return;
2821 if (strequal(ip, client_ip)) {
2822 DBG_WARNING("Got kill client message for %s - "
2823 "exiting immediately\n", ip);
2824 exit_server_cleanly("Forced disconnect for client");
2827 TALLOC_FREE(client_ip);
2831 * Send keepalive packets to our client
2833 static bool keepalive_fn(const struct timeval *now, void *private_data)
2835 struct smbd_server_connection *sconn = talloc_get_type_abort(
2836 private_data, struct smbd_server_connection);
2837 struct smbXsrv_connection *xconn = NULL;
2838 bool ret;
2840 if (sconn->using_smb2) {
2841 /* Don't do keepalives on an SMB2 connection. */
2842 return false;
2846 * With SMB1 we only have 1 connection
2848 xconn = sconn->client->connections;
2849 smbd_lock_socket(xconn);
2850 ret = send_keepalive(xconn->transport.sock);
2851 smbd_unlock_socket(xconn);
2853 if (!ret) {
2854 int saved_errno = errno;
2856 * Try and give an error message saying what
2857 * client failed.
2859 DEBUG(0, ("send_keepalive failed for client %s. "
2860 "Error %s - exiting\n",
2861 smbXsrv_connection_dbg(xconn),
2862 strerror(saved_errno)));
2863 errno = saved_errno;
2864 return False;
2866 return True;
2870 * Do the recurring check if we're idle
2872 static bool deadtime_fn(const struct timeval *now, void *private_data)
2874 struct smbd_server_connection *sconn =
2875 (struct smbd_server_connection *)private_data;
2877 if ((conn_num_open(sconn) == 0)
2878 || (conn_idle_all(sconn, now->tv_sec))) {
2879 DEBUG( 2, ( "Closing idle connection\n" ) );
2880 messaging_send(sconn->msg_ctx,
2881 messaging_server_id(sconn->msg_ctx),
2882 MSG_SHUTDOWN, &data_blob_null);
2883 return False;
2886 return True;
2890 * Do the recurring log file and smb.conf reload checks.
2893 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2895 struct smbd_server_connection *sconn = talloc_get_type_abort(
2896 private_data, struct smbd_server_connection);
2898 DEBUG(5, ("housekeeping\n"));
2900 change_to_root_user();
2902 /* update printer queue caches if necessary */
2903 update_monitored_printq_cache(sconn->msg_ctx);
2905 /* check if we need to reload services */
2906 check_reload(sconn, time_mono(NULL));
2909 * Force a log file check.
2911 force_check_log_size();
2912 check_log_size();
2913 return true;
2917 * Read an smb packet in the echo handler child, giving the parent
2918 * smbd one second to react once the socket becomes readable.
2921 struct smbd_echo_read_state {
2922 struct tevent_context *ev;
2923 struct smbXsrv_connection *xconn;
2925 char *buf;
2926 size_t buflen;
2927 uint32_t seqnum;
2930 static void smbd_echo_read_readable(struct tevent_req *subreq);
2931 static void smbd_echo_read_waited(struct tevent_req *subreq);
2933 static struct tevent_req *smbd_echo_read_send(
2934 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2935 struct smbXsrv_connection *xconn)
2937 struct tevent_req *req, *subreq;
2938 struct smbd_echo_read_state *state;
2940 req = tevent_req_create(mem_ctx, &state,
2941 struct smbd_echo_read_state);
2942 if (req == NULL) {
2943 return NULL;
2945 state->ev = ev;
2946 state->xconn = xconn;
2948 subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
2949 if (tevent_req_nomem(subreq, req)) {
2950 return tevent_req_post(req, ev);
2952 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2953 return req;
2956 static void smbd_echo_read_readable(struct tevent_req *subreq)
2958 struct tevent_req *req = tevent_req_callback_data(
2959 subreq, struct tevent_req);
2960 struct smbd_echo_read_state *state = tevent_req_data(
2961 req, struct smbd_echo_read_state);
2962 bool ok;
2963 int err;
2965 ok = wait_for_read_recv(subreq, &err);
2966 TALLOC_FREE(subreq);
2967 if (!ok) {
2968 tevent_req_nterror(req, map_nt_error_from_unix(err));
2969 return;
2973 * Give the parent smbd one second to step in
2976 subreq = tevent_wakeup_send(
2977 state, state->ev, timeval_current_ofs(1, 0));
2978 if (tevent_req_nomem(subreq, req)) {
2979 return;
2981 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2984 static void smbd_echo_read_waited(struct tevent_req *subreq)
2986 struct tevent_req *req = tevent_req_callback_data(
2987 subreq, struct tevent_req);
2988 struct smbd_echo_read_state *state = tevent_req_data(
2989 req, struct smbd_echo_read_state);
2990 struct smbXsrv_connection *xconn = state->xconn;
2991 bool ok;
2992 NTSTATUS status;
2993 size_t unread = 0;
2994 bool encrypted;
2996 ok = tevent_wakeup_recv(subreq);
2997 TALLOC_FREE(subreq);
2998 if (!ok) {
2999 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3000 return;
3003 ok = smbd_lock_socket_internal(xconn);
3004 if (!ok) {
3005 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3006 DEBUG(0, ("%s: failed to lock socket\n", __location__));
3007 return;
3010 if (!fd_is_readable(xconn->transport.sock)) {
3011 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
3012 (int)getpid()));
3014 ok = smbd_unlock_socket_internal(xconn);
3015 if (!ok) {
3016 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3017 DEBUG(1, ("%s: failed to unlock socket\n",
3018 __location__));
3019 return;
3022 subreq = wait_for_read_send(state, state->ev,
3023 xconn->transport.sock, false);
3024 if (tevent_req_nomem(subreq, req)) {
3025 return;
3027 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
3028 return;
3031 status = receive_smb_talloc(state, xconn,
3032 xconn->transport.sock,
3033 &state->buf,
3034 0 /* timeout */,
3035 &unread,
3036 &encrypted,
3037 &state->buflen,
3038 &state->seqnum,
3039 false /* trusted_channel*/);
3041 if (tevent_req_nterror(req, status)) {
3042 tevent_req_nterror(req, status);
3043 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
3044 (int)getpid(), nt_errstr(status)));
3045 return;
3048 ok = smbd_unlock_socket_internal(xconn);
3049 if (!ok) {
3050 tevent_req_nterror(req, map_nt_error_from_unix(errno));
3051 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
3052 return;
3054 tevent_req_done(req);
3057 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
3058 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
3060 struct smbd_echo_read_state *state = tevent_req_data(
3061 req, struct smbd_echo_read_state);
3062 NTSTATUS status;
3064 if (tevent_req_is_nterror(req, &status)) {
3065 return status;
3067 *pbuf = talloc_move(mem_ctx, &state->buf);
3068 *pbuflen = state->buflen;
3069 *pseqnum = state->seqnum;
3070 return NT_STATUS_OK;
3073 struct smbd_echo_state {
3074 struct tevent_context *ev;
3075 struct iovec *pending;
3076 struct smbd_server_connection *sconn;
3077 struct smbXsrv_connection *xconn;
3078 int parent_pipe;
3080 struct tevent_fd *parent_fde;
3082 struct tevent_req *write_req;
3085 static void smbd_echo_writer_done(struct tevent_req *req);
3087 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
3089 int num_pending;
3091 if (state->write_req != NULL) {
3092 return;
3095 num_pending = talloc_array_length(state->pending);
3096 if (num_pending == 0) {
3097 return;
3100 state->write_req = writev_send(state, state->ev, NULL,
3101 state->parent_pipe, false,
3102 state->pending, num_pending);
3103 if (state->write_req == NULL) {
3104 DEBUG(1, ("writev_send failed\n"));
3105 exit(1);
3108 talloc_steal(state->write_req, state->pending);
3109 state->pending = NULL;
3111 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
3112 state);
3115 static void smbd_echo_writer_done(struct tevent_req *req)
3117 struct smbd_echo_state *state = tevent_req_callback_data(
3118 req, struct smbd_echo_state);
3119 ssize_t written;
3120 int err;
3122 written = writev_recv(req, &err);
3123 TALLOC_FREE(req);
3124 state->write_req = NULL;
3125 if (written == -1) {
3126 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
3127 exit(1);
3129 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
3130 smbd_echo_activate_writer(state);
3133 static bool smbd_echo_reply(struct smbd_echo_state *state,
3134 uint8_t *inbuf, size_t inbuf_len,
3135 uint32_t seqnum)
3137 struct smb_request req;
3138 uint16_t num_replies;
3139 char *outbuf;
3140 bool ok;
3142 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
3143 DEBUG(10, ("Got netbios keepalive\n"));
3145 * Just swallow it
3147 return true;
3150 if (inbuf_len < smb_size) {
3151 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
3152 return false;
3154 if (!valid_smb_header(inbuf)) {
3155 DEBUG(10, ("Got invalid SMB header\n"));
3156 return false;
3159 if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
3160 seqnum)) {
3161 return false;
3163 req.inbuf = inbuf;
3165 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
3166 smb_messages[req.cmd].name
3167 ? smb_messages[req.cmd].name : "unknown"));
3169 if (req.cmd != SMBecho) {
3170 return false;
3172 if (req.wct < 1) {
3173 return false;
3176 num_replies = SVAL(req.vwv+0, 0);
3177 if (num_replies != 1) {
3178 /* Not a Windows "Hey, you're still there?" request */
3179 return false;
3182 if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
3183 1, req.buflen)) {
3184 DEBUG(10, ("create_outbuf failed\n"));
3185 return false;
3187 req.outbuf = (uint8_t *)outbuf;
3189 SSVAL(req.outbuf, smb_vwv0, num_replies);
3191 if (req.buflen > 0) {
3192 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
3195 ok = srv_send_smb(req.xconn,
3196 (char *)outbuf,
3197 true, seqnum+1,
3198 false, &req.pcd);
3199 TALLOC_FREE(outbuf);
3200 if (!ok) {
3201 exit(1);
3204 return true;
3207 static void smbd_echo_exit(struct tevent_context *ev,
3208 struct tevent_fd *fde, uint16_t flags,
3209 void *private_data)
3211 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
3212 exit(0);
3215 static void smbd_echo_got_packet(struct tevent_req *req);
3217 static void smbd_echo_loop(struct smbXsrv_connection *xconn,
3218 int parent_pipe)
3220 struct smbd_echo_state *state;
3221 struct tevent_req *read_req;
3223 state = talloc_zero(xconn, struct smbd_echo_state);
3224 if (state == NULL) {
3225 DEBUG(1, ("talloc failed\n"));
3226 return;
3228 state->xconn = xconn;
3229 state->parent_pipe = parent_pipe;
3230 state->ev = samba_tevent_context_init(state);
3231 if (state->ev == NULL) {
3232 DEBUG(1, ("samba_tevent_context_init failed\n"));
3233 TALLOC_FREE(state);
3234 return;
3236 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
3237 TEVENT_FD_READ, smbd_echo_exit,
3238 state);
3239 if (state->parent_fde == NULL) {
3240 DEBUG(1, ("tevent_add_fd failed\n"));
3241 TALLOC_FREE(state);
3242 return;
3245 read_req = smbd_echo_read_send(state, state->ev, xconn);
3246 if (read_req == NULL) {
3247 DEBUG(1, ("smbd_echo_read_send failed\n"));
3248 TALLOC_FREE(state);
3249 return;
3251 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
3253 while (true) {
3254 if (tevent_loop_once(state->ev) == -1) {
3255 DEBUG(1, ("tevent_loop_once failed: %s\n",
3256 strerror(errno)));
3257 break;
3260 TALLOC_FREE(state);
3263 static void smbd_echo_got_packet(struct tevent_req *req)
3265 struct smbd_echo_state *state = tevent_req_callback_data(
3266 req, struct smbd_echo_state);
3267 NTSTATUS status;
3268 char *buf = NULL;
3269 size_t buflen = 0;
3270 uint32_t seqnum = 0;
3271 bool reply;
3273 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
3274 TALLOC_FREE(req);
3275 if (!NT_STATUS_IS_OK(status)) {
3276 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
3277 nt_errstr(status)));
3278 exit(1);
3281 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
3282 if (!reply) {
3283 size_t num_pending;
3284 struct iovec *tmp;
3285 struct iovec *iov;
3287 num_pending = talloc_array_length(state->pending);
3288 tmp = talloc_realloc(state, state->pending, struct iovec,
3289 num_pending+1);
3290 if (tmp == NULL) {
3291 DEBUG(1, ("talloc_realloc failed\n"));
3292 exit(1);
3294 state->pending = tmp;
3296 if (buflen >= smb_size) {
3298 * place the seqnum in the packet so that the main process
3299 * can reply with signing
3301 SIVAL(buf, smb_ss_field, seqnum);
3302 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
3305 iov = &state->pending[num_pending];
3306 iov->iov_base = talloc_move(state->pending, &buf);
3307 iov->iov_len = buflen;
3309 DEBUG(10,("echo_handler[%d]: forward to main\n",
3310 (int)getpid()));
3311 smbd_echo_activate_writer(state);
3314 req = smbd_echo_read_send(state, state->ev, state->xconn);
3315 if (req == NULL) {
3316 DEBUG(1, ("smbd_echo_read_send failed\n"));
3317 exit(1);
3319 tevent_req_set_callback(req, smbd_echo_got_packet, state);
3324 * Handle SMBecho requests in a forked child process
3326 bool fork_echo_handler(struct smbXsrv_connection *xconn)
3328 int listener_pipe[2];
3329 int res;
3330 pid_t child;
3331 bool use_mutex = false;
3333 res = pipe(listener_pipe);
3334 if (res == -1) {
3335 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
3336 return false;
3339 #ifdef HAVE_ROBUST_MUTEXES
3340 use_mutex = tdb_runtime_check_for_robust_mutexes();
3342 if (use_mutex) {
3343 pthread_mutexattr_t a;
3345 xconn->smb1.echo_handler.socket_mutex =
3346 anonymous_shared_allocate(sizeof(pthread_mutex_t));
3347 if (xconn->smb1.echo_handler.socket_mutex == NULL) {
3348 DEBUG(1, ("Could not create mutex shared memory: %s\n",
3349 strerror(errno)));
3350 goto fail;
3353 res = pthread_mutexattr_init(&a);
3354 if (res != 0) {
3355 DEBUG(1, ("pthread_mutexattr_init failed: %s\n",
3356 strerror(res)));
3357 goto fail;
3359 res = pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK);
3360 if (res != 0) {
3361 DEBUG(1, ("pthread_mutexattr_settype failed: %s\n",
3362 strerror(res)));
3363 pthread_mutexattr_destroy(&a);
3364 goto fail;
3366 res = pthread_mutexattr_setpshared(&a, PTHREAD_PROCESS_SHARED);
3367 if (res != 0) {
3368 DEBUG(1, ("pthread_mutexattr_setpshared failed: %s\n",
3369 strerror(res)));
3370 pthread_mutexattr_destroy(&a);
3371 goto fail;
3373 res = pthread_mutexattr_setrobust(&a, PTHREAD_MUTEX_ROBUST);
3374 if (res != 0) {
3375 DEBUG(1, ("pthread_mutexattr_setrobust failed: "
3376 "%s\n", strerror(res)));
3377 pthread_mutexattr_destroy(&a);
3378 goto fail;
3380 res = pthread_mutex_init(xconn->smb1.echo_handler.socket_mutex,
3381 &a);
3382 pthread_mutexattr_destroy(&a);
3383 if (res != 0) {
3384 DEBUG(1, ("pthread_mutex_init failed: %s\n",
3385 strerror(res)));
3386 goto fail;
3389 #endif
3391 if (!use_mutex) {
3392 xconn->smb1.echo_handler.socket_lock_fd =
3393 create_unlink_tmp(lp_lock_directory());
3394 if (xconn->smb1.echo_handler.socket_lock_fd == -1) {
3395 DEBUG(1, ("Could not create lock fd: %s\n",
3396 strerror(errno)));
3397 goto fail;
3401 child = fork();
3402 if (child == 0) {
3403 NTSTATUS status;
3405 close(listener_pipe[0]);
3406 set_blocking(listener_pipe[1], false);
3408 status = smbd_reinit_after_fork(xconn->client->msg_ctx,
3409 xconn->client->raw_ev_ctx,
3410 true,
3411 "smbd-echo");
3412 if (!NT_STATUS_IS_OK(status)) {
3413 DEBUG(1, ("reinit_after_fork failed: %s\n",
3414 nt_errstr(status)));
3415 exit(1);
3417 initialize_password_db(true, xconn->client->raw_ev_ctx);
3418 smbd_echo_loop(xconn, listener_pipe[1]);
3419 exit(0);
3421 close(listener_pipe[1]);
3422 listener_pipe[1] = -1;
3423 xconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
3425 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), (int)child));
3428 * Without smb signing this is the same as the normal smbd
3429 * listener. This needs to change once signing comes in.
3431 xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(
3432 xconn->client->raw_ev_ctx,
3433 xconn,
3434 xconn->smb1.echo_handler.trusted_fd,
3435 TEVENT_FD_READ,
3436 smbd_server_echo_handler,
3437 xconn);
3438 if (xconn->smb1.echo_handler.trusted_fde == NULL) {
3439 DEBUG(1, ("event_add_fd failed\n"));
3440 goto fail;
3443 return true;
3445 fail:
3446 if (listener_pipe[0] != -1) {
3447 close(listener_pipe[0]);
3449 if (listener_pipe[1] != -1) {
3450 close(listener_pipe[1]);
3452 if (xconn->smb1.echo_handler.socket_lock_fd != -1) {
3453 close(xconn->smb1.echo_handler.socket_lock_fd);
3455 #ifdef HAVE_ROBUST_MUTEXES
3456 if (xconn->smb1.echo_handler.socket_mutex != NULL) {
3457 pthread_mutex_destroy(xconn->smb1.echo_handler.socket_mutex);
3458 anonymous_shared_free(xconn->smb1.echo_handler.socket_mutex);
3460 #endif
3461 smbd_echo_init(xconn);
3463 return false;
3466 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3468 while (user) {
3469 if (user->session_info &&
3470 (user->session_info->unix_token->uid == uid)) {
3471 return true;
3473 user = user->next;
3475 return false;
3478 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3480 while (user) {
3481 if (user->session_info != NULL) {
3482 int i;
3483 struct security_unix_token *utok;
3485 utok = user->session_info->unix_token;
3486 if (utok->gid == gid) {
3487 return true;
3489 for(i=0; i<utok->ngroups; i++) {
3490 if (utok->groups[i] == gid) {
3491 return true;
3495 user = user->next;
3497 return false;
3500 static bool sid_in_use(const struct user_struct *user,
3501 const struct dom_sid *psid)
3503 while (user) {
3504 struct security_token *tok;
3506 if (user->session_info == NULL) {
3507 continue;
3509 tok = user->session_info->security_token;
3510 if (tok == NULL) {
3512 * Not sure session_info->security_token can
3513 * ever be NULL. This check might be not
3514 * necessary.
3516 continue;
3518 if (security_token_has_sid(tok, psid)) {
3519 return true;
3521 user = user->next;
3523 return false;
3526 static bool id_in_use(const struct user_struct *user,
3527 const struct id_cache_ref *id)
3529 switch(id->type) {
3530 case UID:
3531 return uid_in_use(user, id->id.uid);
3532 case GID:
3533 return gid_in_use(user, id->id.gid);
3534 case SID:
3535 return sid_in_use(user, &id->id.sid);
3536 default:
3537 break;
3539 return false;
3542 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3543 void *private_data,
3544 uint32_t msg_type,
3545 struct server_id server_id,
3546 DATA_BLOB* data)
3548 const char *msg = (data && data->data)
3549 ? (const char *)data->data : "<NULL>";
3550 struct id_cache_ref id;
3551 struct smbd_server_connection *sconn =
3552 talloc_get_type_abort(private_data,
3553 struct smbd_server_connection);
3555 if (!id_cache_ref_parse(msg, &id)) {
3556 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3557 return;
3560 if (id_in_use(sconn->users, &id)) {
3561 exit_server_cleanly(msg);
3563 id_cache_delete_from_cache(&id);
3566 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3567 enum protocol_types protocol)
3569 NTSTATUS status;
3571 conn->protocol = protocol;
3573 if (conn->client->session_table != NULL) {
3574 return NT_STATUS_OK;
3577 if (protocol >= PROTOCOL_SMB2_02) {
3578 status = smb2srv_session_table_init(conn);
3579 if (!NT_STATUS_IS_OK(status)) {
3580 conn->protocol = PROTOCOL_NONE;
3581 return status;
3584 status = smb2srv_open_table_init(conn);
3585 if (!NT_STATUS_IS_OK(status)) {
3586 conn->protocol = PROTOCOL_NONE;
3587 return status;
3589 } else {
3590 status = smb1srv_session_table_init(conn);
3591 if (!NT_STATUS_IS_OK(status)) {
3592 conn->protocol = PROTOCOL_NONE;
3593 return status;
3596 status = smb1srv_tcon_table_init(conn);
3597 if (!NT_STATUS_IS_OK(status)) {
3598 conn->protocol = PROTOCOL_NONE;
3599 return status;
3602 status = smb1srv_open_table_init(conn);
3603 if (!NT_STATUS_IS_OK(status)) {
3604 conn->protocol = PROTOCOL_NONE;
3605 return status;
3609 set_Protocol(protocol);
3610 return NT_STATUS_OK;
3613 struct smbd_tevent_trace_state {
3614 struct tevent_context *ev;
3615 TALLOC_CTX *frame;
3616 SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
3619 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3620 void *private_data)
3622 struct smbd_tevent_trace_state *state =
3623 (struct smbd_tevent_trace_state *)private_data;
3625 switch (point) {
3626 case TEVENT_TRACE_BEFORE_WAIT:
3627 if (!smbprofile_dump_pending()) {
3629 * If there's no dump pending
3630 * we don't want to schedule a new 1 sec timer.
3632 * Instead we want to sleep as long as nothing happens.
3634 smbprofile_dump_setup(NULL);
3636 SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
3637 break;
3638 case TEVENT_TRACE_AFTER_WAIT:
3639 SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
3640 if (!smbprofile_dump_pending()) {
3642 * We need to flush our state after sleeping
3643 * (hopefully a long time).
3645 smbprofile_dump();
3647 * future profiling events should trigger timers
3648 * on our main event context.
3650 smbprofile_dump_setup(state->ev);
3652 break;
3653 case TEVENT_TRACE_BEFORE_LOOP_ONCE:
3654 TALLOC_FREE(state->frame);
3655 state->frame = talloc_stackframe_pool(8192);
3656 break;
3657 case TEVENT_TRACE_AFTER_LOOP_ONCE:
3658 TALLOC_FREE(state->frame);
3659 break;
3662 errno = 0;
3666 * Create a debug string for the connection
3668 * This is allocated to talloc_tos() or a string constant
3669 * in certain corner cases. The returned string should
3670 * hence not be free'd directly but only via the talloc stack.
3672 const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn)
3674 const char *ret;
3677 * TODO: this can be improved later
3678 * maybe including the client guid or more
3680 ret = tsocket_address_string(xconn->remote_address, talloc_tos());
3681 if (ret == NULL) {
3682 return "<tsocket_address_string() failed>";
3685 return ret;
3688 NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
3689 struct smbXsrv_connection **_xconn)
3691 TALLOC_CTX *frame = talloc_stackframe();
3692 struct smbXsrv_connection *xconn;
3693 struct sockaddr_storage ss_srv;
3694 void *sp_srv = (void *)&ss_srv;
3695 struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
3696 struct sockaddr_storage ss_clnt;
3697 void *sp_clnt = (void *)&ss_clnt;
3698 struct sockaddr *sa_clnt = (struct sockaddr *)sp_clnt;
3699 socklen_t sa_socklen;
3700 struct tsocket_address *local_address = NULL;
3701 struct tsocket_address *remote_address = NULL;
3702 const char *remaddr = NULL;
3703 char *p;
3704 const char *rhost = NULL;
3705 int ret;
3706 int tmp;
3708 *_xconn = NULL;
3710 DO_PROFILE_INC(connect);
3712 xconn = talloc_zero(client, struct smbXsrv_connection);
3713 if (xconn == NULL) {
3714 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3715 TALLOC_FREE(frame);
3716 return NT_STATUS_NO_MEMORY;
3718 talloc_steal(frame, xconn);
3720 xconn->transport.sock = sock_fd;
3721 smbd_echo_init(xconn);
3722 xconn->protocol = PROTOCOL_NONE;
3724 /* Ensure child is set to blocking mode */
3725 set_blocking(sock_fd,True);
3727 set_socket_options(sock_fd, "SO_KEEPALIVE");
3728 set_socket_options(sock_fd, lp_socket_options());
3730 sa_socklen = sizeof(ss_clnt);
3731 ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
3732 if (ret != 0) {
3733 int saved_errno = errno;
3734 int level = (errno == ENOTCONN)?2:0;
3735 DEBUG(level,("getpeername() failed - %s\n",
3736 strerror(saved_errno)));
3737 TALLOC_FREE(frame);
3738 return map_nt_error_from_unix_common(saved_errno);
3740 ret = tsocket_address_bsd_from_sockaddr(xconn,
3741 sa_clnt, sa_socklen,
3742 &remote_address);
3743 if (ret != 0) {
3744 int saved_errno = errno;
3745 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3746 __location__, strerror(saved_errno)));
3747 TALLOC_FREE(frame);
3748 return map_nt_error_from_unix_common(saved_errno);
3751 sa_socklen = sizeof(ss_srv);
3752 ret = getsockname(sock_fd, sa_srv, &sa_socklen);
3753 if (ret != 0) {
3754 int saved_errno = errno;
3755 int level = (errno == ENOTCONN)?2:0;
3756 DEBUG(level,("getsockname() failed - %s\n",
3757 strerror(saved_errno)));
3758 TALLOC_FREE(frame);
3759 return map_nt_error_from_unix_common(saved_errno);
3761 ret = tsocket_address_bsd_from_sockaddr(xconn,
3762 sa_srv, sa_socklen,
3763 &local_address);
3764 if (ret != 0) {
3765 int saved_errno = errno;
3766 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3767 __location__, strerror(saved_errno)));
3768 TALLOC_FREE(frame);
3769 return map_nt_error_from_unix_common(saved_errno);
3772 if (tsocket_address_is_inet(remote_address, "ip")) {
3773 remaddr = tsocket_address_inet_addr_string(remote_address,
3774 talloc_tos());
3775 if (remaddr == NULL) {
3776 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3777 __location__, strerror(errno)));
3778 TALLOC_FREE(frame);
3779 return NT_STATUS_NO_MEMORY;
3781 } else {
3782 remaddr = "0.0.0.0";
3786 * Before the first packet, check the global hosts allow/ hosts deny
3787 * parameters before doing any parsing of packets passed to us by the
3788 * client. This prevents attacks on our parsing code from hosts not in
3789 * the hosts allow list.
3792 ret = get_remote_hostname(remote_address,
3793 &p, talloc_tos());
3794 if (ret < 0) {
3795 int saved_errno = errno;
3796 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3797 __location__, strerror(saved_errno)));
3798 TALLOC_FREE(frame);
3799 return map_nt_error_from_unix_common(saved_errno);
3801 rhost = p;
3802 if (strequal(rhost, "UNKNOWN")) {
3803 rhost = remaddr;
3806 xconn->local_address = local_address;
3807 xconn->remote_address = remote_address;
3808 xconn->remote_hostname = talloc_strdup(xconn, rhost);
3809 if (xconn->remote_hostname == NULL) {
3810 return NT_STATUS_NO_MEMORY;
3813 if (!srv_init_signing(xconn)) {
3814 DEBUG(0, ("Failed to init smb_signing\n"));
3815 TALLOC_FREE(frame);
3816 return NT_STATUS_INTERNAL_ERROR;
3819 if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
3820 xconn->remote_hostname,
3821 remaddr)) {
3822 DEBUG( 1, ("Connection denied from %s to %s\n",
3823 tsocket_address_string(remote_address, talloc_tos()),
3824 tsocket_address_string(local_address, talloc_tos())));
3827 * We return a valid xconn
3828 * so that the caller can return an error message
3829 * to the client
3831 client->connections = xconn;
3832 xconn->client = client;
3833 talloc_steal(client, xconn);
3835 *_xconn = xconn;
3836 TALLOC_FREE(frame);
3837 return NT_STATUS_NETWORK_ACCESS_DENIED;
3840 DEBUG(10, ("Connection allowed from %s to %s\n",
3841 tsocket_address_string(remote_address, talloc_tos()),
3842 tsocket_address_string(local_address, talloc_tos())));
3844 if (lp_clustering()) {
3846 * We need to tell ctdb about our client's TCP
3847 * connection, so that for failover ctdbd can send
3848 * tickle acks, triggering a reconnection by the
3849 * client.
3851 NTSTATUS status;
3853 status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
3854 if (!NT_STATUS_IS_OK(status)) {
3855 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3856 nt_errstr(status)));
3860 tmp = lp_max_xmit();
3861 tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
3862 tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
3864 xconn->smb1.negprot.max_recv = tmp;
3866 xconn->smb1.sessions.done_sesssetup = false;
3867 xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
3869 xconn->transport.fde = tevent_add_fd(client->raw_ev_ctx,
3870 xconn,
3871 sock_fd,
3872 TEVENT_FD_READ,
3873 smbd_server_connection_handler,
3874 xconn);
3875 if (!xconn->transport.fde) {
3876 TALLOC_FREE(frame);
3877 return NT_STATUS_NO_MEMORY;
3880 /* for now we only have one connection */
3881 DLIST_ADD_END(client->connections, xconn);
3882 xconn->client = client;
3883 talloc_steal(client, xconn);
3885 *_xconn = xconn;
3886 TALLOC_FREE(frame);
3887 return NT_STATUS_OK;
3890 /****************************************************************************
3891 Process commands from the client
3892 ****************************************************************************/
3894 void smbd_process(struct tevent_context *ev_ctx,
3895 struct messaging_context *msg_ctx,
3896 int sock_fd,
3897 bool interactive)
3899 struct smbd_tevent_trace_state trace_state = {
3900 .ev = ev_ctx,
3901 .frame = talloc_stackframe(),
3903 struct smbXsrv_client *client = NULL;
3904 struct smbd_server_connection *sconn = NULL;
3905 struct smbXsrv_connection *xconn = NULL;
3906 const char *locaddr = NULL;
3907 const char *remaddr = NULL;
3908 int ret;
3909 NTSTATUS status;
3910 struct timeval tv = timeval_current();
3911 NTTIME now = timeval_to_nttime(&tv);
3912 char *chroot_dir = NULL;
3913 int rc;
3915 status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
3916 if (!NT_STATUS_IS_OK(status)) {
3917 DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
3918 exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
3922 * TODO: remove this...:-)
3924 global_smbXsrv_client = client;
3926 sconn = talloc_zero(client, struct smbd_server_connection);
3927 if (sconn == NULL) {
3928 exit_server("failed to create smbd_server_connection");
3931 client->sconn = sconn;
3932 sconn->client = client;
3934 sconn->ev_ctx = ev_ctx;
3935 sconn->msg_ctx = msg_ctx;
3937 ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
3938 &sconn->pool);
3939 if (ret != 0) {
3940 exit_server("pthreadpool_tevent_init() failed.");
3943 if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
3945 * We're not making the decision here,
3946 * we're just allowing the client
3947 * to decide between SMB1 and SMB2
3948 * with the first negprot
3949 * packet.
3951 sconn->using_smb2 = true;
3954 if (!interactive) {
3955 smbd_setup_sig_term_handler(sconn);
3956 smbd_setup_sig_hup_handler(sconn);
3959 status = smbd_add_connection(client, sock_fd, &xconn);
3960 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3962 * send a negative session response "not listening on calling
3963 * name"
3965 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3966 (void)srv_send_smb(xconn,(char *)buf, false,
3967 0, false, NULL);
3968 exit_server_cleanly("connection denied");
3969 } else if (!NT_STATUS_IS_OK(status)) {
3970 exit_server_cleanly(nt_errstr(status));
3973 sconn->local_address =
3974 tsocket_address_copy(xconn->local_address, sconn);
3975 if (sconn->local_address == NULL) {
3976 exit_server_cleanly("tsocket_address_copy() failed");
3978 sconn->remote_address =
3979 tsocket_address_copy(xconn->remote_address, sconn);
3980 if (sconn->remote_address == NULL) {
3981 exit_server_cleanly("tsocket_address_copy() failed");
3983 sconn->remote_hostname =
3984 talloc_strdup(sconn, xconn->remote_hostname);
3985 if (sconn->remote_hostname == NULL) {
3986 exit_server_cleanly("tsocket_strdup() failed");
3989 if (tsocket_address_is_inet(sconn->local_address, "ip")) {
3990 locaddr = tsocket_address_inet_addr_string(
3991 sconn->local_address,
3992 talloc_tos());
3993 if (locaddr == NULL) {
3994 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3995 __location__, strerror(errno)));
3996 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3998 } else {
3999 locaddr = "0.0.0.0";
4002 if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
4003 remaddr = tsocket_address_inet_addr_string(
4004 sconn->remote_address,
4005 talloc_tos());
4006 if (remaddr == NULL) {
4007 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
4008 __location__, strerror(errno)));
4009 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
4011 } else {
4012 remaddr = "0.0.0.0";
4015 /* this is needed so that we get decent entries
4016 in smbstatus for port 445 connects */
4017 set_remote_machine_name(remaddr, false);
4018 reload_services(sconn, conn_snum_used, true);
4019 sub_set_socket_ids(remaddr,
4020 sconn->remote_hostname,
4021 locaddr);
4023 if (lp_preload_modules()) {
4024 smb_load_all_modules_absoute_path(lp_preload_modules());
4027 smb_perfcount_init();
4029 if (!init_account_policy()) {
4030 exit_server("Could not open account policy tdb.\n");
4033 chroot_dir = lp_root_directory(talloc_tos());
4034 if (chroot_dir[0] != '\0') {
4035 rc = chdir(chroot_dir);
4036 if (rc != 0) {
4037 DBG_ERR("Failed to chdir to %s\n", chroot_dir);
4038 exit_server("Failed to chdir()");
4041 rc = chroot(chroot_dir);
4042 if (rc != 0) {
4043 DBG_ERR("Failed to change root to %s\n", chroot_dir);
4044 exit_server("Failed to chroot()");
4046 DBG_WARNING("Changed root to %s\n", chroot_dir);
4048 TALLOC_FREE(chroot_dir);
4051 if (!file_init(sconn)) {
4052 exit_server("file_init() failed");
4055 /* Setup oplocks */
4056 if (!init_oplocks(sconn))
4057 exit_server("Failed to init oplocks");
4059 /* register our message handlers */
4060 messaging_register(sconn->msg_ctx, sconn,
4061 MSG_SMB_FORCE_TDIS, msg_force_tdis);
4062 messaging_register(sconn->msg_ctx, sconn,
4063 MSG_SMB_CLOSE_FILE, msg_close_file);
4064 messaging_register(sconn->msg_ctx, sconn,
4065 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
4067 id_cache_register_msgs(sconn->msg_ctx);
4068 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
4069 messaging_register(sconn->msg_ctx, sconn,
4070 ID_CACHE_KILL, smbd_id_cache_kill);
4072 messaging_deregister(sconn->msg_ctx,
4073 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
4074 messaging_register(sconn->msg_ctx, sconn,
4075 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
4077 messaging_deregister(sconn->msg_ctx, MSG_SMB_KILL_CLIENT_IP,
4078 NULL);
4079 messaging_register(sconn->msg_ctx, sconn,
4080 MSG_SMB_KILL_CLIENT_IP,
4081 msg_kill_client_ip);
4083 messaging_deregister(sconn->msg_ctx, MSG_SMB_TELL_NUM_CHILDREN, NULL);
4086 * Use the default MSG_DEBUG handler to avoid rebroadcasting
4087 * MSGs to all child processes
4089 messaging_deregister(sconn->msg_ctx,
4090 MSG_DEBUG, NULL);
4091 messaging_register(sconn->msg_ctx, NULL,
4092 MSG_DEBUG, debug_message);
4094 if ((lp_keepalive() != 0)
4095 && !(event_add_idle(ev_ctx, NULL,
4096 timeval_set(lp_keepalive(), 0),
4097 "keepalive", keepalive_fn,
4098 sconn))) {
4099 DEBUG(0, ("Could not add keepalive event\n"));
4100 exit(1);
4103 if (!(event_add_idle(ev_ctx, NULL,
4104 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
4105 "deadtime", deadtime_fn, sconn))) {
4106 DEBUG(0, ("Could not add deadtime event\n"));
4107 exit(1);
4110 if (!(event_add_idle(ev_ctx, NULL,
4111 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
4112 "housekeeping", housekeeping_fn, sconn))) {
4113 DEBUG(0, ("Could not add housekeeping event\n"));
4114 exit(1);
4117 smbprofile_dump_setup(ev_ctx);
4119 if (!init_dptrs(sconn)) {
4120 exit_server("init_dptrs() failed");
4123 TALLOC_FREE(trace_state.frame);
4125 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
4126 &trace_state);
4128 ret = tevent_loop_wait(ev_ctx);
4129 if (ret != 0) {
4130 DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
4131 " exiting\n", ret, strerror(errno)));
4134 TALLOC_FREE(trace_state.frame);
4136 exit_server_cleanly(NULL);
4139 bool req_is_in_chain(const struct smb_request *req)
4141 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
4143 * We're right now handling a subsequent request, so we must
4144 * be in a chain
4146 return true;
4149 if (!smb1cli_is_andx_req(req->cmd)) {
4150 return false;
4153 if (req->wct < 2) {
4155 * Okay, an illegal request, but definitely not chained :-)
4157 return false;
4160 return (CVAL(req->vwv+0, 0) != 0xFF);