s3:smb2_sesssetup: make use of the smbXsrv_session infrastructure
[Samba/wip.git] / source3 / smbd / process.c
blobe25fbc77c16150d18aae5004f86bc0ceccb16bc3
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 "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "serverid.h"
44 extern bool global_machine_password_needs_changing;
46 /* Internal message queue for deferred opens. */
47 struct pending_message_list {
48 struct pending_message_list *next, *prev;
49 struct timeval request_time; /* When was this first issued? */
50 struct smbd_server_connection *sconn;
51 struct timed_event *te;
52 struct smb_perfcount_data pcd;
53 uint32_t seqnum;
54 bool encrypted;
55 bool processed;
56 DATA_BLOB buf;
57 DATA_BLOB private_data;
60 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 char *outbuf);
62 static struct pending_message_list *get_deferred_open_message_smb(
63 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
66 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
68 bool ok;
70 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
71 return true;
74 sconn->smb1.echo_handler.ref_count++;
76 if (sconn->smb1.echo_handler.ref_count > 1) {
77 return true;
80 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
82 do {
83 ok = fcntl_lock(
84 sconn->smb1.echo_handler.socket_lock_fd,
85 F_SETLKW, 0, 0, F_WRLCK);
86 } while (!ok && (errno == EINTR));
88 if (!ok) {
89 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
90 return false;
93 DEBUG(10,("pid[%d] got for socket lock\n", (int)getpid()));
95 return true;
98 void smbd_lock_socket(struct smbd_server_connection *sconn)
100 if (!smbd_lock_socket_internal(sconn)) {
101 exit_server_cleanly("failed to lock socket");
105 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
107 bool ok;
109 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
110 return true;
113 sconn->smb1.echo_handler.ref_count--;
115 if (sconn->smb1.echo_handler.ref_count > 0) {
116 return true;
119 do {
120 ok = fcntl_lock(
121 sconn->smb1.echo_handler.socket_lock_fd,
122 F_SETLKW, 0, 0, F_UNLCK);
123 } while (!ok && (errno == EINTR));
125 if (!ok) {
126 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
127 return false;
130 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
132 return true;
135 void smbd_unlock_socket(struct smbd_server_connection *sconn)
137 if (!smbd_unlock_socket_internal(sconn)) {
138 exit_server_cleanly("failed to unlock socket");
142 /* Accessor function for smb_read_error for smbd functions. */
144 /****************************************************************************
145 Send an smb to a fd.
146 ****************************************************************************/
148 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
149 bool do_signing, uint32_t seqnum,
150 bool do_encrypt,
151 struct smb_perfcount_data *pcd)
153 size_t len = 0;
154 size_t nwritten=0;
155 ssize_t ret;
156 char *buf_out = buffer;
158 smbd_lock_socket(sconn);
160 if (do_signing) {
161 /* Sign the outgoing packet if required. */
162 srv_calculate_sign_mac(sconn, buf_out, seqnum);
165 if (do_encrypt) {
166 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
167 if (!NT_STATUS_IS_OK(status)) {
168 DEBUG(0, ("send_smb: SMB encryption failed "
169 "on outgoing packet! Error %s\n",
170 nt_errstr(status) ));
171 goto out;
175 len = smb_len(buf_out) + 4;
177 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
178 if (ret <= 0) {
180 char addr[INET6_ADDRSTRLEN];
182 * Try and give an error message saying what
183 * client failed.
185 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
186 (int)getpid(), (int)len,
187 get_peer_addr(sconn->sock, addr, sizeof(addr)),
188 (int)ret, strerror(errno) ));
190 srv_free_enc_buffer(sconn, buf_out);
191 goto out;
194 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
195 srv_free_enc_buffer(sconn, buf_out);
196 out:
197 SMB_PERFCOUNT_END(pcd);
199 smbd_unlock_socket(sconn);
200 return true;
203 /*******************************************************************
204 Setup the word count and byte count for a smb message.
205 ********************************************************************/
207 int srv_set_message(char *buf,
208 int num_words,
209 int num_bytes,
210 bool zero)
212 if (zero && (num_words || num_bytes)) {
213 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
215 SCVAL(buf,smb_wct,num_words);
216 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
217 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
218 return (smb_size + num_words*2 + num_bytes);
221 static bool valid_smb_header(struct smbd_server_connection *sconn,
222 const uint8_t *inbuf)
224 if (is_encrypted_packet(sconn, inbuf)) {
225 return true;
228 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
229 * but it just looks weird to call strncmp for this one.
231 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
234 /* Socket functions for smbd packet processing. */
236 static bool valid_packet_size(size_t len)
239 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
240 * of header. Don't print the error if this fits.... JRA.
243 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
244 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
245 (unsigned long)len));
246 return false;
248 return true;
251 static NTSTATUS read_packet_remainder(int fd, char *buffer,
252 unsigned int timeout, ssize_t len)
254 NTSTATUS status;
256 if (len <= 0) {
257 return NT_STATUS_OK;
260 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
261 if (!NT_STATUS_IS_OK(status)) {
262 char addr[INET6_ADDRSTRLEN];
263 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
264 "error = %s.\n",
265 get_peer_addr(fd, addr, sizeof(addr)),
266 nt_errstr(status)));
268 return status;
271 /****************************************************************************
272 Attempt a zerocopy writeX read. We know here that len > smb_size-4
273 ****************************************************************************/
276 * Unfortunately, earlier versions of smbclient/libsmbclient
277 * don't send this "standard" writeX header. I've fixed this
278 * for 3.2 but we'll use the old method with earlier versions.
279 * Windows and CIFSFS at least use this standard size. Not
280 * sure about MacOSX.
283 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
284 (2*14) + /* word count (including bcc) */ \
285 1 /* pad byte */)
287 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
288 const char lenbuf[4],
289 struct smbd_server_connection *sconn,
290 int sock,
291 char **buffer,
292 unsigned int timeout,
293 size_t *p_unread,
294 size_t *len_ret)
296 /* Size of a WRITEX call (+4 byte len). */
297 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
298 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
299 ssize_t toread;
300 NTSTATUS status;
302 memcpy(writeX_header, lenbuf, 4);
304 status = read_fd_with_timeout(
305 sock, writeX_header + 4,
306 STANDARD_WRITE_AND_X_HEADER_SIZE,
307 STANDARD_WRITE_AND_X_HEADER_SIZE,
308 timeout, NULL);
310 if (!NT_STATUS_IS_OK(status)) {
311 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
312 "error = %s.\n",
313 tsocket_address_string(sconn->remote_address,
314 talloc_tos()),
315 nt_errstr(status)));
316 return status;
320 * Ok - now try and see if this is a possible
321 * valid writeX call.
324 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
326 * If the data offset is beyond what
327 * we've read, drain the extra bytes.
329 uint16_t doff = SVAL(writeX_header,smb_vwv11);
330 ssize_t newlen;
332 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
333 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
334 if (drain_socket(sock, drain) != drain) {
335 smb_panic("receive_smb_raw_talloc_partial_read:"
336 " failed to drain pending bytes");
338 } else {
339 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
342 /* Spoof down the length and null out the bcc. */
343 set_message_bcc(writeX_header, 0);
344 newlen = smb_len(writeX_header);
346 /* Copy the header we've written. */
348 *buffer = (char *)talloc_memdup(mem_ctx,
349 writeX_header,
350 sizeof(writeX_header));
352 if (*buffer == NULL) {
353 DEBUG(0, ("Could not allocate inbuf of length %d\n",
354 (int)sizeof(writeX_header)));
355 return NT_STATUS_NO_MEMORY;
358 /* Work out the remaining bytes. */
359 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
360 *len_ret = newlen + 4;
361 return NT_STATUS_OK;
364 if (!valid_packet_size(len)) {
365 return NT_STATUS_INVALID_PARAMETER;
369 * Not a valid writeX call. Just do the standard
370 * talloc and return.
373 *buffer = talloc_array(mem_ctx, char, len+4);
375 if (*buffer == NULL) {
376 DEBUG(0, ("Could not allocate inbuf of length %d\n",
377 (int)len+4));
378 return NT_STATUS_NO_MEMORY;
381 /* Copy in what we already read. */
382 memcpy(*buffer,
383 writeX_header,
384 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
385 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
387 if(toread > 0) {
388 status = read_packet_remainder(
389 sock,
390 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
391 timeout, toread);
393 if (!NT_STATUS_IS_OK(status)) {
394 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
395 nt_errstr(status)));
396 return status;
400 *len_ret = len + 4;
401 return NT_STATUS_OK;
404 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
405 struct smbd_server_connection *sconn,
406 int sock,
407 char **buffer, unsigned int timeout,
408 size_t *p_unread, size_t *plen)
410 char lenbuf[4];
411 size_t len;
412 int min_recv_size = lp_min_receive_file_size();
413 NTSTATUS status;
415 *p_unread = 0;
417 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
418 &len);
419 if (!NT_STATUS_IS_OK(status)) {
420 return status;
423 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
424 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
425 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
426 !srv_is_signing_active(sconn) &&
427 sconn->smb1.echo_handler.trusted_fde == NULL) {
429 return receive_smb_raw_talloc_partial_read(
430 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
431 p_unread, plen);
434 if (!valid_packet_size(len)) {
435 return NT_STATUS_INVALID_PARAMETER;
439 * The +4 here can't wrap, we've checked the length above already.
442 *buffer = talloc_array(mem_ctx, char, len+4);
444 if (*buffer == NULL) {
445 DEBUG(0, ("Could not allocate inbuf of length %d\n",
446 (int)len+4));
447 return NT_STATUS_NO_MEMORY;
450 memcpy(*buffer, lenbuf, sizeof(lenbuf));
452 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
453 if (!NT_STATUS_IS_OK(status)) {
454 return status;
457 *plen = len + 4;
458 return NT_STATUS_OK;
461 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
462 struct smbd_server_connection *sconn,
463 int sock,
464 char **buffer, unsigned int timeout,
465 size_t *p_unread, bool *p_encrypted,
466 size_t *p_len,
467 uint32_t *seqnum,
468 bool trusted_channel)
470 size_t len = 0;
471 NTSTATUS status;
473 *p_encrypted = false;
475 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
476 p_unread, &len);
477 if (!NT_STATUS_IS_OK(status)) {
478 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
479 ("receive_smb_raw_talloc failed for client %s "
480 "read error = %s.\n",
481 tsocket_address_string(sconn->remote_address,
482 talloc_tos()),
483 nt_errstr(status)) );
484 return status;
487 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
488 status = srv_decrypt_buffer(sconn, *buffer);
489 if (!NT_STATUS_IS_OK(status)) {
490 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
491 "incoming packet! Error %s\n",
492 nt_errstr(status) ));
493 return status;
495 *p_encrypted = true;
498 /* Check the incoming SMB signature. */
499 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
500 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
501 "incoming packet!\n"));
502 return NT_STATUS_INVALID_NETWORK_RESPONSE;
505 *p_len = len;
506 return NT_STATUS_OK;
510 * Initialize a struct smb_request from an inbuf
513 static bool init_smb_request(struct smb_request *req,
514 struct smbd_server_connection *sconn,
515 const uint8 *inbuf,
516 size_t unread_bytes, bool encrypted,
517 uint32_t seqnum)
519 size_t req_size = smb_len(inbuf) + 4;
521 /* Ensure we have at least smb_size bytes. */
522 if (req_size < smb_size) {
523 DEBUG(0,("init_smb_request: invalid request size %u\n",
524 (unsigned int)req_size ));
525 return false;
528 req->request_time = timeval_current();
530 req->cmd = CVAL(inbuf, smb_com);
531 req->flags2 = SVAL(inbuf, smb_flg2);
532 req->smbpid = SVAL(inbuf, smb_pid);
533 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
534 req->seqnum = seqnum;
535 req->vuid = SVAL(inbuf, smb_uid);
536 req->tid = SVAL(inbuf, smb_tid);
537 req->wct = CVAL(inbuf, smb_wct);
538 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
539 req->buflen = smb_buflen(inbuf);
540 req->buf = (const uint8_t *)smb_buf_const(inbuf);
541 req->unread_bytes = unread_bytes;
542 req->encrypted = encrypted;
543 req->sconn = sconn;
544 req->conn = conn_find(sconn,req->tid);
545 req->chain_fsp = NULL;
546 req->smb2req = NULL;
547 req->priv_paths = NULL;
548 req->chain = NULL;
549 smb_init_perfcount_data(&req->pcd);
551 /* Ensure we have at least wct words and 2 bytes of bcc. */
552 if (smb_size + req->wct*2 > req_size) {
553 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
554 (unsigned int)req->wct,
555 (unsigned int)req_size));
556 return false;
558 /* Ensure bcc is correct. */
559 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
560 DEBUG(0,("init_smb_request: invalid bcc number %u "
561 "(wct = %u, size %u)\n",
562 (unsigned int)req->buflen,
563 (unsigned int)req->wct,
564 (unsigned int)req_size));
565 return false;
568 req->outbuf = NULL;
569 return true;
572 static void process_smb(struct smbd_server_connection *conn,
573 uint8_t *inbuf, size_t nread, size_t unread_bytes,
574 uint32_t seqnum, bool encrypted,
575 struct smb_perfcount_data *deferred_pcd);
577 static void smbd_deferred_open_timer(struct event_context *ev,
578 struct timed_event *te,
579 struct timeval _tval,
580 void *private_data)
582 struct pending_message_list *msg = talloc_get_type(private_data,
583 struct pending_message_list);
584 struct smbd_server_connection *sconn = msg->sconn;
585 TALLOC_CTX *mem_ctx = talloc_tos();
586 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
587 uint8_t *inbuf;
589 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
590 msg->buf.length);
591 if (inbuf == NULL) {
592 exit_server("smbd_deferred_open_timer: talloc failed\n");
593 return;
596 /* We leave this message on the queue so the open code can
597 know this is a retry. */
598 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
599 (unsigned long long)mid ));
601 /* Mark the message as processed so this is not
602 * re-processed in error. */
603 msg->processed = true;
605 process_smb(sconn, inbuf,
606 msg->buf.length, 0,
607 msg->seqnum, msg->encrypted, &msg->pcd);
609 /* If it's still there and was processed, remove it. */
610 msg = get_deferred_open_message_smb(sconn, mid);
611 if (msg && msg->processed) {
612 remove_deferred_open_message_smb(sconn, mid);
616 /****************************************************************************
617 Function to push a message onto the tail of a linked list of smb messages ready
618 for processing.
619 ****************************************************************************/
621 static bool push_queued_message(struct smb_request *req,
622 struct timeval request_time,
623 struct timeval end_time,
624 char *private_data, size_t private_len)
626 int msg_len = smb_len(req->inbuf) + 4;
627 struct pending_message_list *msg;
629 msg = talloc_zero(NULL, struct pending_message_list);
631 if(msg == NULL) {
632 DEBUG(0,("push_message: malloc fail (1)\n"));
633 return False;
635 msg->sconn = req->sconn;
637 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
638 if(msg->buf.data == NULL) {
639 DEBUG(0,("push_message: malloc fail (2)\n"));
640 TALLOC_FREE(msg);
641 return False;
644 msg->request_time = request_time;
645 msg->seqnum = req->seqnum;
646 msg->encrypted = req->encrypted;
647 msg->processed = false;
648 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
650 if (private_data) {
651 msg->private_data = data_blob_talloc(msg, private_data,
652 private_len);
653 if (msg->private_data.data == NULL) {
654 DEBUG(0,("push_message: malloc fail (3)\n"));
655 TALLOC_FREE(msg);
656 return False;
660 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
661 msg,
662 end_time,
663 smbd_deferred_open_timer,
664 msg);
665 if (!msg->te) {
666 DEBUG(0,("push_message: event_add_timed failed\n"));
667 TALLOC_FREE(msg);
668 return false;
671 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
672 struct pending_message_list *);
674 DEBUG(10,("push_message: pushed message length %u on "
675 "deferred_open_queue\n", (unsigned int)msg_len));
677 return True;
680 /****************************************************************************
681 Function to delete a sharing violation open message by mid.
682 ****************************************************************************/
684 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
685 uint64_t mid)
687 struct pending_message_list *pml;
689 if (sconn->using_smb2) {
690 remove_deferred_open_message_smb2(sconn, mid);
691 return;
694 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
695 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
696 DEBUG(10,("remove_deferred_open_message_smb: "
697 "deleting mid %llu len %u\n",
698 (unsigned long long)mid,
699 (unsigned int)pml->buf.length ));
700 DLIST_REMOVE(sconn->deferred_open_queue, pml);
701 TALLOC_FREE(pml);
702 return;
707 /****************************************************************************
708 Move a sharing violation open retry message to the front of the list and
709 schedule it for immediate processing.
710 ****************************************************************************/
712 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
713 uint64_t mid)
715 struct pending_message_list *pml;
716 int i = 0;
718 if (sconn->using_smb2) {
719 schedule_deferred_open_message_smb2(sconn, mid);
720 return;
723 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
724 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
726 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
727 "msg_mid = %llu\n",
728 i++,
729 (unsigned long long)msg_mid ));
731 if (mid == msg_mid) {
732 struct timed_event *te;
734 if (pml->processed) {
735 /* A processed message should not be
736 * rescheduled. */
737 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
738 "message mid %llu was already processed\n",
739 (unsigned long long)msg_mid ));
740 continue;
743 DEBUG(10,("schedule_deferred_open_message_smb: "
744 "scheduling mid %llu\n",
745 (unsigned long long)mid ));
747 te = tevent_add_timer(pml->sconn->ev_ctx,
748 pml,
749 timeval_zero(),
750 smbd_deferred_open_timer,
751 pml);
752 if (!te) {
753 DEBUG(10,("schedule_deferred_open_message_smb: "
754 "event_add_timed() failed, "
755 "skipping mid %llu\n",
756 (unsigned long long)msg_mid ));
759 TALLOC_FREE(pml->te);
760 pml->te = te;
761 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
762 return;
766 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
767 "find message mid %llu\n",
768 (unsigned long long)mid ));
771 /****************************************************************************
772 Return true if this mid is on the deferred queue and was not yet processed.
773 ****************************************************************************/
775 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
777 struct pending_message_list *pml;
779 if (sconn->using_smb2) {
780 return open_was_deferred_smb2(sconn, mid);
783 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
784 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
785 return True;
788 return False;
791 /****************************************************************************
792 Return the message queued by this mid.
793 ****************************************************************************/
795 static struct pending_message_list *get_deferred_open_message_smb(
796 struct smbd_server_connection *sconn, uint64_t mid)
798 struct pending_message_list *pml;
800 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
801 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
802 return pml;
805 return NULL;
808 /****************************************************************************
809 Get the state data queued by this mid.
810 ****************************************************************************/
812 bool get_deferred_open_message_state(struct smb_request *smbreq,
813 struct timeval *p_request_time,
814 void **pp_state)
816 struct pending_message_list *pml;
818 if (smbreq->sconn->using_smb2) {
819 return get_deferred_open_message_state_smb2(smbreq->smb2req,
820 p_request_time,
821 pp_state);
824 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
825 if (!pml) {
826 return false;
828 if (p_request_time) {
829 *p_request_time = pml->request_time;
831 if (pp_state) {
832 *pp_state = (void *)pml->private_data.data;
834 return true;
837 /****************************************************************************
838 Function to push a deferred open smb message onto a linked list of local smb
839 messages ready for processing.
840 ****************************************************************************/
842 bool push_deferred_open_message_smb(struct smb_request *req,
843 struct timeval request_time,
844 struct timeval timeout,
845 struct file_id id,
846 char *private_data, size_t priv_len)
848 struct timeval end_time;
850 if (req->smb2req) {
851 return push_deferred_open_message_smb2(req->smb2req,
852 request_time,
853 timeout,
855 private_data,
856 priv_len);
859 if (req->unread_bytes) {
860 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
861 "unread_bytes = %u\n",
862 (unsigned int)req->unread_bytes ));
863 smb_panic("push_deferred_open_message_smb: "
864 "logic error unread_bytes != 0" );
867 end_time = timeval_sum(&request_time, &timeout);
869 DEBUG(10,("push_deferred_open_message_smb: pushing message "
870 "len %u mid %llu timeout time [%u.%06u]\n",
871 (unsigned int) smb_len(req->inbuf)+4,
872 (unsigned long long)req->mid,
873 (unsigned int)end_time.tv_sec,
874 (unsigned int)end_time.tv_usec));
876 return push_queued_message(req, request_time, end_time,
877 private_data, priv_len);
880 static void smbd_sig_term_handler(struct tevent_context *ev,
881 struct tevent_signal *se,
882 int signum,
883 int count,
884 void *siginfo,
885 void *private_data)
887 exit_server_cleanly("termination signal");
890 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
892 struct tevent_signal *se;
894 se = tevent_add_signal(sconn->ev_ctx,
895 sconn,
896 SIGTERM, 0,
897 smbd_sig_term_handler,
898 sconn);
899 if (!se) {
900 exit_server("failed to setup SIGTERM handler");
904 static void smbd_sig_hup_handler(struct tevent_context *ev,
905 struct tevent_signal *se,
906 int signum,
907 int count,
908 void *siginfo,
909 void *private_data)
911 struct smbd_server_connection *sconn =
912 talloc_get_type_abort(private_data,
913 struct smbd_server_connection);
915 change_to_root_user();
916 DEBUG(1,("Reloading services after SIGHUP\n"));
917 reload_services(sconn, conn_snum_used, false);
920 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
922 struct tevent_signal *se;
924 se = tevent_add_signal(sconn->ev_ctx,
925 sconn,
926 SIGHUP, 0,
927 smbd_sig_hup_handler,
928 sconn);
929 if (!se) {
930 exit_server("failed to setup SIGHUP handler");
934 static void smbd_conf_updated(struct messaging_context *msg,
935 void *private_data,
936 uint32_t msg_type,
937 struct server_id server_id,
938 DATA_BLOB *data)
940 struct smbd_server_connection *sconn =
941 talloc_get_type_abort(private_data,
942 struct smbd_server_connection);
944 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
945 "updated. Reloading.\n"));
946 change_to_root_user();
947 reload_services(sconn, conn_snum_used, false);
951 * Only allow 5 outstanding trans requests. We're allocating memory, so
952 * prevent a DoS.
955 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
957 int count = 0;
958 for (; list != NULL; list = list->next) {
960 if (list->mid == mid) {
961 return NT_STATUS_INVALID_PARAMETER;
964 count += 1;
966 if (count > 5) {
967 return NT_STATUS_INSUFFICIENT_RESOURCES;
970 return NT_STATUS_OK;
974 These flags determine some of the permissions required to do an operation
976 Note that I don't set NEED_WRITE on some write operations because they
977 are used by some brain-dead clients when printing, and I don't want to
978 force write permissions on print services.
980 #define AS_USER (1<<0)
981 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
982 #define TIME_INIT (1<<2)
983 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
984 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
985 #define DO_CHDIR (1<<6)
988 define a list of possible SMB messages and their corresponding
989 functions. Any message that has a NULL function is unimplemented -
990 please feel free to contribute implementations!
992 static const struct smb_message_struct {
993 const char *name;
994 void (*fn)(struct smb_request *req);
995 int flags;
996 } smb_messages[256] = {
998 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
999 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1000 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1001 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1002 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1003 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1004 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1005 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1006 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1007 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1008 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1009 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1010 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1011 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1012 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1013 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1014 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1015 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1016 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1017 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1018 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1019 /* 0x15 */ { NULL, NULL, 0 },
1020 /* 0x16 */ { NULL, NULL, 0 },
1021 /* 0x17 */ { NULL, NULL, 0 },
1022 /* 0x18 */ { NULL, NULL, 0 },
1023 /* 0x19 */ { NULL, NULL, 0 },
1024 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1025 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1026 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1027 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1028 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1029 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1030 /* 0x20 */ { "SMBwritec", NULL,0},
1031 /* 0x21 */ { NULL, NULL, 0 },
1032 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1033 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1034 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1035 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1036 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1037 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1038 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1039 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1040 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1041 /* 0x2b */ { "SMBecho",reply_echo,0},
1042 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1043 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1044 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1045 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1046 /* 0x30 */ { NULL, NULL, 0 },
1047 /* 0x31 */ { NULL, NULL, 0 },
1048 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1049 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1050 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1051 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1052 /* 0x36 */ { NULL, NULL, 0 },
1053 /* 0x37 */ { NULL, NULL, 0 },
1054 /* 0x38 */ { NULL, NULL, 0 },
1055 /* 0x39 */ { NULL, NULL, 0 },
1056 /* 0x3a */ { NULL, NULL, 0 },
1057 /* 0x3b */ { NULL, NULL, 0 },
1058 /* 0x3c */ { NULL, NULL, 0 },
1059 /* 0x3d */ { NULL, NULL, 0 },
1060 /* 0x3e */ { NULL, NULL, 0 },
1061 /* 0x3f */ { NULL, NULL, 0 },
1062 /* 0x40 */ { NULL, NULL, 0 },
1063 /* 0x41 */ { NULL, NULL, 0 },
1064 /* 0x42 */ { NULL, NULL, 0 },
1065 /* 0x43 */ { NULL, NULL, 0 },
1066 /* 0x44 */ { NULL, NULL, 0 },
1067 /* 0x45 */ { NULL, NULL, 0 },
1068 /* 0x46 */ { NULL, NULL, 0 },
1069 /* 0x47 */ { NULL, NULL, 0 },
1070 /* 0x48 */ { NULL, NULL, 0 },
1071 /* 0x49 */ { NULL, NULL, 0 },
1072 /* 0x4a */ { NULL, NULL, 0 },
1073 /* 0x4b */ { NULL, NULL, 0 },
1074 /* 0x4c */ { NULL, NULL, 0 },
1075 /* 0x4d */ { NULL, NULL, 0 },
1076 /* 0x4e */ { NULL, NULL, 0 },
1077 /* 0x4f */ { NULL, NULL, 0 },
1078 /* 0x50 */ { NULL, NULL, 0 },
1079 /* 0x51 */ { NULL, NULL, 0 },
1080 /* 0x52 */ { NULL, NULL, 0 },
1081 /* 0x53 */ { NULL, NULL, 0 },
1082 /* 0x54 */ { NULL, NULL, 0 },
1083 /* 0x55 */ { NULL, NULL, 0 },
1084 /* 0x56 */ { NULL, NULL, 0 },
1085 /* 0x57 */ { NULL, NULL, 0 },
1086 /* 0x58 */ { NULL, NULL, 0 },
1087 /* 0x59 */ { NULL, NULL, 0 },
1088 /* 0x5a */ { NULL, NULL, 0 },
1089 /* 0x5b */ { NULL, NULL, 0 },
1090 /* 0x5c */ { NULL, NULL, 0 },
1091 /* 0x5d */ { NULL, NULL, 0 },
1092 /* 0x5e */ { NULL, NULL, 0 },
1093 /* 0x5f */ { NULL, NULL, 0 },
1094 /* 0x60 */ { NULL, NULL, 0 },
1095 /* 0x61 */ { NULL, NULL, 0 },
1096 /* 0x62 */ { NULL, NULL, 0 },
1097 /* 0x63 */ { NULL, NULL, 0 },
1098 /* 0x64 */ { NULL, NULL, 0 },
1099 /* 0x65 */ { NULL, NULL, 0 },
1100 /* 0x66 */ { NULL, NULL, 0 },
1101 /* 0x67 */ { NULL, NULL, 0 },
1102 /* 0x68 */ { NULL, NULL, 0 },
1103 /* 0x69 */ { NULL, NULL, 0 },
1104 /* 0x6a */ { NULL, NULL, 0 },
1105 /* 0x6b */ { NULL, NULL, 0 },
1106 /* 0x6c */ { NULL, NULL, 0 },
1107 /* 0x6d */ { NULL, NULL, 0 },
1108 /* 0x6e */ { NULL, NULL, 0 },
1109 /* 0x6f */ { NULL, NULL, 0 },
1110 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1111 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1112 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1113 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1114 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1115 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1116 /* 0x76 */ { NULL, NULL, 0 },
1117 /* 0x77 */ { NULL, NULL, 0 },
1118 /* 0x78 */ { NULL, NULL, 0 },
1119 /* 0x79 */ { NULL, NULL, 0 },
1120 /* 0x7a */ { NULL, NULL, 0 },
1121 /* 0x7b */ { NULL, NULL, 0 },
1122 /* 0x7c */ { NULL, NULL, 0 },
1123 /* 0x7d */ { NULL, NULL, 0 },
1124 /* 0x7e */ { NULL, NULL, 0 },
1125 /* 0x7f */ { NULL, NULL, 0 },
1126 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1127 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1128 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1129 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1130 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1131 /* 0x85 */ { NULL, NULL, 0 },
1132 /* 0x86 */ { NULL, NULL, 0 },
1133 /* 0x87 */ { NULL, NULL, 0 },
1134 /* 0x88 */ { NULL, NULL, 0 },
1135 /* 0x89 */ { NULL, NULL, 0 },
1136 /* 0x8a */ { NULL, NULL, 0 },
1137 /* 0x8b */ { NULL, NULL, 0 },
1138 /* 0x8c */ { NULL, NULL, 0 },
1139 /* 0x8d */ { NULL, NULL, 0 },
1140 /* 0x8e */ { NULL, NULL, 0 },
1141 /* 0x8f */ { NULL, NULL, 0 },
1142 /* 0x90 */ { NULL, NULL, 0 },
1143 /* 0x91 */ { NULL, NULL, 0 },
1144 /* 0x92 */ { NULL, NULL, 0 },
1145 /* 0x93 */ { NULL, NULL, 0 },
1146 /* 0x94 */ { NULL, NULL, 0 },
1147 /* 0x95 */ { NULL, NULL, 0 },
1148 /* 0x96 */ { NULL, NULL, 0 },
1149 /* 0x97 */ { NULL, NULL, 0 },
1150 /* 0x98 */ { NULL, NULL, 0 },
1151 /* 0x99 */ { NULL, NULL, 0 },
1152 /* 0x9a */ { NULL, NULL, 0 },
1153 /* 0x9b */ { NULL, NULL, 0 },
1154 /* 0x9c */ { NULL, NULL, 0 },
1155 /* 0x9d */ { NULL, NULL, 0 },
1156 /* 0x9e */ { NULL, NULL, 0 },
1157 /* 0x9f */ { NULL, NULL, 0 },
1158 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1159 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1160 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1161 /* 0xa3 */ { NULL, NULL, 0 },
1162 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1163 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1164 /* 0xa6 */ { NULL, NULL, 0 },
1165 /* 0xa7 */ { NULL, NULL, 0 },
1166 /* 0xa8 */ { NULL, NULL, 0 },
1167 /* 0xa9 */ { NULL, NULL, 0 },
1168 /* 0xaa */ { NULL, NULL, 0 },
1169 /* 0xab */ { NULL, NULL, 0 },
1170 /* 0xac */ { NULL, NULL, 0 },
1171 /* 0xad */ { NULL, NULL, 0 },
1172 /* 0xae */ { NULL, NULL, 0 },
1173 /* 0xaf */ { NULL, NULL, 0 },
1174 /* 0xb0 */ { NULL, NULL, 0 },
1175 /* 0xb1 */ { NULL, NULL, 0 },
1176 /* 0xb2 */ { NULL, NULL, 0 },
1177 /* 0xb3 */ { NULL, NULL, 0 },
1178 /* 0xb4 */ { NULL, NULL, 0 },
1179 /* 0xb5 */ { NULL, NULL, 0 },
1180 /* 0xb6 */ { NULL, NULL, 0 },
1181 /* 0xb7 */ { NULL, NULL, 0 },
1182 /* 0xb8 */ { NULL, NULL, 0 },
1183 /* 0xb9 */ { NULL, NULL, 0 },
1184 /* 0xba */ { NULL, NULL, 0 },
1185 /* 0xbb */ { NULL, NULL, 0 },
1186 /* 0xbc */ { NULL, NULL, 0 },
1187 /* 0xbd */ { NULL, NULL, 0 },
1188 /* 0xbe */ { NULL, NULL, 0 },
1189 /* 0xbf */ { NULL, NULL, 0 },
1190 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1191 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1192 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1193 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1194 /* 0xc4 */ { NULL, NULL, 0 },
1195 /* 0xc5 */ { NULL, NULL, 0 },
1196 /* 0xc6 */ { NULL, NULL, 0 },
1197 /* 0xc7 */ { NULL, NULL, 0 },
1198 /* 0xc8 */ { NULL, NULL, 0 },
1199 /* 0xc9 */ { NULL, NULL, 0 },
1200 /* 0xca */ { NULL, NULL, 0 },
1201 /* 0xcb */ { NULL, NULL, 0 },
1202 /* 0xcc */ { NULL, NULL, 0 },
1203 /* 0xcd */ { NULL, NULL, 0 },
1204 /* 0xce */ { NULL, NULL, 0 },
1205 /* 0xcf */ { NULL, NULL, 0 },
1206 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1207 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1208 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1209 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1210 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1211 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1212 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1213 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1214 /* 0xd8 */ { NULL, NULL, 0 },
1215 /* 0xd9 */ { NULL, NULL, 0 },
1216 /* 0xda */ { NULL, NULL, 0 },
1217 /* 0xdb */ { NULL, NULL, 0 },
1218 /* 0xdc */ { NULL, NULL, 0 },
1219 /* 0xdd */ { NULL, NULL, 0 },
1220 /* 0xde */ { NULL, NULL, 0 },
1221 /* 0xdf */ { NULL, NULL, 0 },
1222 /* 0xe0 */ { NULL, NULL, 0 },
1223 /* 0xe1 */ { NULL, NULL, 0 },
1224 /* 0xe2 */ { NULL, NULL, 0 },
1225 /* 0xe3 */ { NULL, NULL, 0 },
1226 /* 0xe4 */ { NULL, NULL, 0 },
1227 /* 0xe5 */ { NULL, NULL, 0 },
1228 /* 0xe6 */ { NULL, NULL, 0 },
1229 /* 0xe7 */ { NULL, NULL, 0 },
1230 /* 0xe8 */ { NULL, NULL, 0 },
1231 /* 0xe9 */ { NULL, NULL, 0 },
1232 /* 0xea */ { NULL, NULL, 0 },
1233 /* 0xeb */ { NULL, NULL, 0 },
1234 /* 0xec */ { NULL, NULL, 0 },
1235 /* 0xed */ { NULL, NULL, 0 },
1236 /* 0xee */ { NULL, NULL, 0 },
1237 /* 0xef */ { NULL, NULL, 0 },
1238 /* 0xf0 */ { NULL, NULL, 0 },
1239 /* 0xf1 */ { NULL, NULL, 0 },
1240 /* 0xf2 */ { NULL, NULL, 0 },
1241 /* 0xf3 */ { NULL, NULL, 0 },
1242 /* 0xf4 */ { NULL, NULL, 0 },
1243 /* 0xf5 */ { NULL, NULL, 0 },
1244 /* 0xf6 */ { NULL, NULL, 0 },
1245 /* 0xf7 */ { NULL, NULL, 0 },
1246 /* 0xf8 */ { NULL, NULL, 0 },
1247 /* 0xf9 */ { NULL, NULL, 0 },
1248 /* 0xfa */ { NULL, NULL, 0 },
1249 /* 0xfb */ { NULL, NULL, 0 },
1250 /* 0xfc */ { NULL, NULL, 0 },
1251 /* 0xfd */ { NULL, NULL, 0 },
1252 /* 0xfe */ { NULL, NULL, 0 },
1253 /* 0xff */ { NULL, NULL, 0 }
1257 /*******************************************************************
1258 allocate and initialize a reply packet
1259 ********************************************************************/
1261 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1262 const char *inbuf, char **outbuf, uint8_t num_words,
1263 uint32_t num_bytes)
1266 * Protect against integer wrap
1268 if ((num_bytes > 0xffffff)
1269 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1270 char *msg;
1271 if (asprintf(&msg, "num_bytes too large: %u",
1272 (unsigned)num_bytes) == -1) {
1273 msg = discard_const_p(char, "num_bytes too large");
1275 smb_panic(msg);
1278 *outbuf = talloc_array(mem_ctx, char,
1279 smb_size + num_words*2 + num_bytes);
1280 if (*outbuf == NULL) {
1281 return false;
1284 construct_reply_common(req, inbuf, *outbuf);
1285 srv_set_message(*outbuf, num_words, num_bytes, false);
1287 * Zero out the word area, the caller has to take care of the bcc area
1288 * himself
1290 if (num_words != 0) {
1291 memset(*outbuf + smb_vwv0, 0, num_words*2);
1294 return true;
1297 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1299 char *outbuf;
1300 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1301 num_bytes)) {
1302 smb_panic("could not allocate output buffer\n");
1304 req->outbuf = (uint8_t *)outbuf;
1308 /*******************************************************************
1309 Dump a packet to a file.
1310 ********************************************************************/
1312 static void smb_dump(const char *name, int type, const char *data)
1314 size_t len;
1315 int fd, i;
1316 char *fname = NULL;
1317 if (DEBUGLEVEL < 50) {
1318 return;
1321 len = smb_len_tcp(data)+4;
1322 for (i=1;i<100;i++) {
1323 fname = talloc_asprintf(talloc_tos(),
1324 "/tmp/%s.%d.%s",
1325 name,
1327 type ? "req" : "resp");
1328 if (fname == NULL) {
1329 return;
1331 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1332 if (fd != -1 || errno != EEXIST) break;
1333 TALLOC_FREE(fname);
1335 if (fd != -1) {
1336 ssize_t ret = write(fd, data, len);
1337 if (ret != len)
1338 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1339 close(fd);
1340 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1342 TALLOC_FREE(fname);
1345 /****************************************************************************
1346 Prepare everything for calling the actual request function, and potentially
1347 call the request function via the "new" interface.
1349 Return False if the "legacy" function needs to be called, everything is
1350 prepared.
1352 Return True if we're done.
1354 I know this API sucks, but it is the one with the least code change I could
1355 find.
1356 ****************************************************************************/
1358 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1360 int flags;
1361 uint64_t session_tag;
1362 connection_struct *conn = NULL;
1363 struct smbd_server_connection *sconn = req->sconn;
1365 errno = 0;
1367 if (smb_messages[type].fn == NULL) {
1368 DEBUG(0,("Unknown message type %d!\n",type));
1369 smb_dump("Unknown", 1, (const char *)req->inbuf);
1370 reply_unknown_new(req, type);
1371 return NULL;
1374 flags = smb_messages[type].flags;
1376 /* In share mode security we must ignore the vuid. */
1377 session_tag = req->vuid;
1378 conn = req->conn;
1380 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1381 (int)getpid(), (unsigned long)conn));
1383 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1385 /* Ensure this value is replaced in the incoming packet. */
1386 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1389 * Ensure the correct username is in current_user_info. This is a
1390 * really ugly bugfix for problems with multiple session_setup_and_X's
1391 * being done and allowing %U and %G substitutions to work correctly.
1392 * There is a reason this code is done here, don't move it unless you
1393 * know what you're doing... :-).
1394 * JRA.
1397 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1398 struct user_struct *vuser = NULL;
1400 sconn->smb1.sessions.last_session_tag = session_tag;
1401 if(session_tag != UID_FIELD_INVALID) {
1402 vuser = get_valid_user_struct(sconn, session_tag);
1403 if (vuser) {
1404 set_current_user_info(
1405 vuser->session_info->unix_info->sanitized_username,
1406 vuser->session_info->unix_info->unix_name,
1407 vuser->session_info->info->domain_name);
1412 /* Does this call need to be run as the connected user? */
1413 if (flags & AS_USER) {
1415 /* Does this call need a valid tree connection? */
1416 if (!conn) {
1418 * Amazingly, the error code depends on the command
1419 * (from Samba4).
1421 if (type == SMBntcreateX) {
1422 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1423 } else {
1424 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1426 return NULL;
1429 if (!change_to_user(conn,session_tag)) {
1430 DEBUG(0, ("Error: Could not change to user. Removing "
1431 "deferred open, mid=%llu.\n",
1432 (unsigned long long)req->mid));
1433 reply_force_doserror(req, ERRSRV, ERRbaduid);
1434 return conn;
1437 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1439 /* Does it need write permission? */
1440 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1441 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1442 return conn;
1445 /* IPC services are limited */
1446 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1447 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1448 return conn;
1450 } else {
1451 /* This call needs to be run as root */
1452 change_to_root_user();
1455 /* load service specific parameters */
1456 if (conn) {
1457 if (req->encrypted) {
1458 conn->encrypted_tid = true;
1459 /* encrypted required from now on. */
1460 conn->encrypt_level = Required;
1461 } else if (ENCRYPTION_REQUIRED(conn)) {
1462 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1463 exit_server_cleanly("encryption required "
1464 "on connection");
1465 return conn;
1469 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1470 (flags & (AS_USER|DO_CHDIR)
1471 ?True:False))) {
1472 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1473 return conn;
1475 conn->num_smb_operations++;
1479 * Does this protocol need to be run as guest? (Only archane
1480 * messenger service requests have this...)
1482 if (flags & AS_GUEST) {
1483 char *raddr;
1484 bool ok;
1486 if (!change_to_guest()) {
1487 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1488 return conn;
1491 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1492 talloc_tos());
1493 if (raddr == NULL) {
1494 reply_nterror(req, NT_STATUS_NO_MEMORY);
1495 return conn;
1499 * Haven't we checked this in smbd_process already???
1502 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1503 sconn->remote_hostname, raddr);
1504 TALLOC_FREE(raddr);
1506 if (!ok) {
1507 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1508 return conn;
1512 smb_messages[type].fn(req);
1513 return req->conn;
1516 /****************************************************************************
1517 Construct a reply to the incoming packet.
1518 ****************************************************************************/
1520 static void construct_reply(struct smbd_server_connection *sconn,
1521 char *inbuf, int size, size_t unread_bytes,
1522 uint32_t seqnum, bool encrypted,
1523 struct smb_perfcount_data *deferred_pcd)
1525 connection_struct *conn;
1526 struct smb_request *req;
1528 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1529 smb_panic("could not allocate smb_request");
1532 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1533 encrypted, seqnum)) {
1534 exit_server_cleanly("Invalid SMB request");
1537 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1539 /* we popped this message off the queue - keep original perf data */
1540 if (deferred_pcd)
1541 req->pcd = *deferred_pcd;
1542 else {
1543 SMB_PERFCOUNT_START(&req->pcd);
1544 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1545 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1548 conn = switch_message(req->cmd, req);
1550 if (req->outbuf == NULL) {
1551 return;
1554 if (CVAL(req->outbuf,0) == 0) {
1555 show_msg((char *)req->outbuf);
1558 if (!srv_send_smb(req->sconn,
1559 (char *)req->outbuf,
1560 true, req->seqnum+1,
1561 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1562 &req->pcd)) {
1563 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1566 TALLOC_FREE(req);
1568 return;
1571 static void construct_reply_chain(struct smbd_server_connection *sconn,
1572 char *inbuf, int size, uint32_t seqnum,
1573 bool encrypted,
1574 struct smb_perfcount_data *deferred_pcd)
1576 struct smb_request **reqs = NULL;
1577 struct smb_request *req;
1578 unsigned num_reqs;
1579 bool ok;
1581 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1582 seqnum, &reqs, &num_reqs);
1583 if (!ok) {
1584 char errbuf[smb_size];
1585 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1586 __LINE__, __FILE__);
1587 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1588 NULL)) {
1589 exit_server_cleanly("construct_reply_chain: "
1590 "srv_send_smb failed.");
1592 return;
1595 req = reqs[0];
1596 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1598 req->conn = switch_message(req->cmd, req);
1600 if (req->outbuf == NULL) {
1602 * Request has suspended itself, will come
1603 * back here.
1605 return;
1607 smb_request_done(req);
1611 * To be called from an async SMB handler that is potentially chained
1612 * when it is finished for shipping.
1615 void smb_request_done(struct smb_request *req)
1617 struct smb_request **reqs = NULL;
1618 struct smb_request *first_req;
1619 size_t i, num_reqs, next_index;
1620 NTSTATUS status;
1622 if (req->chain == NULL) {
1623 first_req = req;
1624 goto shipit;
1627 reqs = req->chain;
1628 num_reqs = talloc_array_length(reqs);
1630 for (i=0; i<num_reqs; i++) {
1631 if (reqs[i] == req) {
1632 break;
1635 if (i == num_reqs) {
1637 * Invalid chain, should not happen
1639 status = NT_STATUS_INTERNAL_ERROR;
1640 goto error;
1642 next_index = i+1;
1644 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1645 struct smb_request *next = reqs[next_index];
1647 next->vuid = SVAL(req->outbuf, smb_uid);
1648 next->tid = SVAL(req->outbuf, smb_tid);
1649 next->conn = conn_find(req->sconn, req->tid);
1650 next->chain_fsp = req->chain_fsp;
1651 next->inbuf = (uint8_t *)req->inbuf;
1653 req = next;
1654 req->conn = switch_message(req->cmd, req);
1656 if (req->outbuf == NULL) {
1658 * Request has suspended itself, will come
1659 * back here.
1661 return;
1663 next_index += 1;
1666 first_req = reqs[0];
1668 for (i=1; i<next_index; i++) {
1669 bool ok;
1671 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1672 if (!ok) {
1673 status = NT_STATUS_INTERNAL_ERROR;
1674 goto error;
1678 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1679 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1682 * This scary statement intends to set the
1683 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1684 * to the value last_req->outbuf carries
1686 SSVAL(first_req->outbuf, smb_flg2,
1687 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1688 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1691 * Transfer the error codes from the subrequest to the main one
1693 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1694 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1696 _smb_setlen_large(
1697 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1699 shipit:
1700 if (!srv_send_smb(first_req->sconn,
1701 (char *)first_req->outbuf,
1702 true, first_req->seqnum+1,
1703 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1704 &first_req->pcd)) {
1705 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1706 "failed.");
1708 TALLOC_FREE(req); /* non-chained case */
1709 TALLOC_FREE(reqs); /* chained case */
1710 return;
1712 error:
1714 char errbuf[smb_size];
1715 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1716 if (!srv_send_smb(req->sconn, errbuf, true,
1717 req->seqnum+1, req->encrypted,
1718 NULL)) {
1719 exit_server_cleanly("construct_reply_chain: "
1720 "srv_send_smb failed.");
1723 TALLOC_FREE(req); /* non-chained case */
1724 TALLOC_FREE(reqs); /* chained case */
1727 /****************************************************************************
1728 Process an smb from the client
1729 ****************************************************************************/
1730 static void process_smb(struct smbd_server_connection *sconn,
1731 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1732 uint32_t seqnum, bool encrypted,
1733 struct smb_perfcount_data *deferred_pcd)
1735 int msg_type = CVAL(inbuf,0);
1737 DO_PROFILE_INC(smb_count);
1739 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1740 smb_len(inbuf) ) );
1741 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1742 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1744 if (msg_type != NBSSmessage) {
1746 * NetBIOS session request, keepalive, etc.
1748 reply_special(sconn, (char *)inbuf, nread);
1749 goto done;
1752 if (sconn->using_smb2) {
1753 /* At this point we're not really using smb2,
1754 * we make the decision here.. */
1755 if (smbd_is_smb2_header(inbuf, nread)) {
1756 smbd_smb2_first_negprot(sconn, inbuf, nread);
1757 return;
1758 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1759 && CVAL(inbuf, smb_com) != 0x72) {
1760 /* This is a non-negprot SMB1 packet.
1761 Disable SMB2 from now on. */
1762 sconn->using_smb2 = false;
1766 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1767 * so subtract 4 from it. */
1768 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1769 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1770 smb_len(inbuf)));
1772 /* special magic for immediate exit */
1773 if ((nread == 9) &&
1774 (IVAL(inbuf, 4) == 0x74697865) &&
1775 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1776 uint8_t exitcode = CVAL(inbuf, 8);
1777 DEBUG(1, ("Exiting immediately with code %d\n",
1778 (int)exitcode));
1779 exit(exitcode);
1782 exit_server_cleanly("Non-SMB packet");
1785 show_msg((char *)inbuf);
1787 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1788 construct_reply_chain(sconn, (char *)inbuf, nread,
1789 seqnum, encrypted, deferred_pcd);
1790 } else {
1791 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1792 seqnum, encrypted, deferred_pcd);
1795 sconn->trans_num++;
1797 done:
1798 sconn->num_requests++;
1800 /* The timeout_processing function isn't run nearly
1801 often enough to implement 'max log size' without
1802 overrunning the size of the file by many megabytes.
1803 This is especially true if we are running at debug
1804 level 10. Checking every 50 SMBs is a nice
1805 tradeoff of performance vs log file size overrun. */
1807 if ((sconn->num_requests % 50) == 0 &&
1808 need_to_check_log_size()) {
1809 change_to_root_user();
1810 check_log_size();
1814 /****************************************************************************
1815 Return a string containing the function name of a SMB command.
1816 ****************************************************************************/
1818 const char *smb_fn_name(int type)
1820 const char *unknown_name = "SMBunknown";
1822 if (smb_messages[type].name == NULL)
1823 return(unknown_name);
1825 return(smb_messages[type].name);
1828 /****************************************************************************
1829 Helper functions for contruct_reply.
1830 ****************************************************************************/
1832 void add_to_common_flags2(uint32 v)
1834 common_flags2 |= v;
1837 void remove_from_common_flags2(uint32 v)
1839 common_flags2 &= ~v;
1842 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1843 char *outbuf)
1845 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1846 uint16_t out_flags2 = common_flags2;
1848 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1849 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1850 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1852 srv_set_message(outbuf,0,0,false);
1854 SCVAL(outbuf, smb_com, req->cmd);
1855 SIVAL(outbuf,smb_rcls,0);
1856 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1857 SSVAL(outbuf,smb_flg2, out_flags2);
1858 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1859 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1861 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1862 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1863 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1864 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1867 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1869 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1873 * @brief Find the smb_cmd offset of the last command pushed
1874 * @param[in] buf The buffer we're building up
1875 * @retval Where can we put our next andx cmd?
1877 * While chaining requests, the "next" request we're looking at needs to put
1878 * its SMB_Command before the data the previous request already built up added
1879 * to the chain. Find the offset to the place where we have to put our cmd.
1882 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1884 uint8_t cmd;
1885 size_t ofs;
1887 cmd = CVAL(buf, smb_com);
1889 if (!is_andx_req(cmd)) {
1890 return false;
1893 ofs = smb_vwv0;
1895 while (CVAL(buf, ofs) != 0xff) {
1897 if (!is_andx_req(CVAL(buf, ofs))) {
1898 return false;
1902 * ofs is from start of smb header, so add the 4 length
1903 * bytes. The next cmd is right after the wct field.
1905 ofs = SVAL(buf, ofs+2) + 4 + 1;
1907 if (ofs+4 >= talloc_get_size(buf)) {
1908 return false;
1912 *pofs = ofs;
1913 return true;
1917 * @brief Do the smb chaining at a buffer level
1918 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1919 * @param[in] andx_buf Buffer to be appended
1922 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1924 uint8_t smb_command = CVAL(andx_buf, smb_com);
1925 uint8_t wct = CVAL(andx_buf, smb_wct);
1926 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1927 uint32_t num_bytes = smb_buflen(andx_buf);
1928 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1930 uint8_t *outbuf;
1931 size_t old_size, new_size;
1932 size_t ofs;
1933 size_t chain_padding = 0;
1934 size_t andx_cmd_ofs;
1937 old_size = talloc_get_size(*poutbuf);
1939 if ((old_size % 4) != 0) {
1941 * Align the wct field of subsequent requests to a 4-byte
1942 * boundary
1944 chain_padding = 4 - (old_size % 4);
1948 * After the old request comes the new wct field (1 byte), the vwv's
1949 * and the num_bytes field.
1952 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1953 new_size += num_bytes;
1955 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1956 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1957 (unsigned)new_size));
1958 return false;
1961 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1962 if (outbuf == NULL) {
1963 DEBUG(0, ("talloc failed\n"));
1964 return false;
1966 *poutbuf = outbuf;
1968 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1969 DEBUG(1, ("invalid command chain\n"));
1970 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
1971 return false;
1974 if (chain_padding != 0) {
1975 memset(outbuf + old_size, 0, chain_padding);
1976 old_size += chain_padding;
1979 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1980 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1982 ofs = old_size;
1985 * Push the chained request:
1987 * wct field
1990 SCVAL(outbuf, ofs, wct);
1991 ofs += 1;
1994 * vwv array
1997 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
2000 * HACK ALERT
2002 * Read&X has an offset into its data buffer at
2003 * vwv[6]. reply_read_andx has no idea anymore that it's
2004 * running from within a chain, so we have to fix up the
2005 * offset here.
2007 * Although it looks disgusting at this place, I want to keep
2008 * it here. The alternative would be to push knowledge about
2009 * the andx chain down into read&x again.
2012 if (smb_command == SMBreadX) {
2013 uint8_t *bytes_addr;
2015 if (wct < 7) {
2017 * Invalid read&x response
2019 return false;
2022 bytes_addr = outbuf + ofs /* vwv start */
2023 + sizeof(uint16_t) * wct /* vwv array */
2024 + sizeof(uint16_t); /* bcc */
2026 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2027 bytes_addr - outbuf - 4);
2030 ofs += sizeof(uint16_t) * wct;
2033 * bcc (byte count)
2036 SSVAL(outbuf, ofs, num_bytes);
2037 ofs += sizeof(uint16_t);
2040 * The bytes field
2043 memcpy(outbuf + ofs, bytes, num_bytes);
2045 return true;
2048 bool smb1_is_chain(const uint8_t *buf)
2050 uint8_t cmd, wct, andx_cmd;
2052 cmd = CVAL(buf, smb_com);
2053 if (!is_andx_req(cmd)) {
2054 return false;
2056 wct = CVAL(buf, smb_wct);
2057 if (wct < 2) {
2058 return false;
2060 andx_cmd = CVAL(buf, smb_vwv);
2061 return (andx_cmd != 0xFF);
2064 bool smb1_walk_chain(const uint8_t *buf,
2065 bool (*fn)(uint8_t cmd,
2066 uint8_t wct, const uint16_t *vwv,
2067 uint16_t num_bytes, const uint8_t *bytes,
2068 void *private_data),
2069 void *private_data)
2071 size_t smblen = smb_len(buf);
2072 const char *smb_buf = smb_base(buf);
2073 uint8_t cmd, chain_cmd;
2074 uint8_t wct;
2075 const uint16_t *vwv;
2076 uint16_t num_bytes;
2077 const uint8_t *bytes;
2079 cmd = CVAL(buf, smb_com);
2080 wct = CVAL(buf, smb_wct);
2081 vwv = (const uint16_t *)(buf + smb_vwv);
2082 num_bytes = smb_buflen(buf);
2083 bytes = (uint8_t *)smb_buf_const(buf);
2085 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2086 return false;
2089 if (!is_andx_req(cmd)) {
2090 return true;
2092 if (wct < 2) {
2093 return false;
2096 chain_cmd = CVAL(vwv, 0);
2098 while (chain_cmd != 0xff) {
2099 uint32_t chain_offset; /* uint32_t to avoid overflow */
2100 size_t length_needed;
2101 ptrdiff_t vwv_offset;
2103 chain_offset = SVAL(vwv+1, 0);
2106 * Check if the client tries to fool us. The chain
2107 * offset needs to point beyond the current request in
2108 * the chain, it needs to strictly grow. Otherwise we
2109 * might be tricked into an endless loop always
2110 * processing the same request over and over again. We
2111 * used to assume that vwv and the byte buffer array
2112 * in a chain are always attached, but OS/2 the
2113 * Write&X/Read&X chain puts the Read&X vwv array
2114 * right behind the Write&X vwv chain. The Write&X bcc
2115 * array is put behind the Read&X vwv array. So now we
2116 * check whether the chain offset points strictly
2117 * behind the previous vwv array. req->buf points
2118 * right after the vwv array of the previous
2119 * request. See
2120 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2121 * more information.
2124 vwv_offset = ((const char *)vwv - smb_buf);
2125 if (chain_offset <= vwv_offset) {
2126 return false;
2130 * Next check: Make sure the chain offset does not
2131 * point beyond the overall smb request length.
2134 length_needed = chain_offset+1; /* wct */
2135 if (length_needed > smblen) {
2136 return false;
2140 * Now comes the pointer magic. Goal here is to set up
2141 * vwv and buf correctly again. The chain offset (the
2142 * former vwv[1]) points at the new wct field.
2145 wct = CVAL(smb_buf, chain_offset);
2147 if (is_andx_req(chain_cmd) && (wct < 2)) {
2148 return false;
2152 * Next consistency check: Make the new vwv array fits
2153 * in the overall smb request.
2156 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2157 if (length_needed > smblen) {
2158 return false;
2160 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2163 * Now grab the new byte buffer....
2166 num_bytes = SVAL(vwv+wct, 0);
2169 * .. and check that it fits.
2172 length_needed += num_bytes;
2173 if (length_needed > smblen) {
2174 return false;
2176 bytes = (const uint8_t *)(vwv+wct+1);
2178 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2179 return false;
2182 if (!is_andx_req(chain_cmd)) {
2183 return true;
2185 chain_cmd = CVAL(vwv, 0);
2187 return true;
2190 static bool smb1_chain_length_cb(uint8_t cmd,
2191 uint8_t wct, const uint16_t *vwv,
2192 uint16_t num_bytes, const uint8_t *bytes,
2193 void *private_data)
2195 unsigned *count = (unsigned *)private_data;
2196 *count += 1;
2197 return true;
2200 unsigned smb1_chain_length(const uint8_t *buf)
2202 unsigned count = 0;
2204 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2205 return 0;
2207 return count;
2210 struct smb1_parse_chain_state {
2211 TALLOC_CTX *mem_ctx;
2212 const uint8_t *buf;
2213 struct smbd_server_connection *sconn;
2214 bool encrypted;
2215 uint32_t seqnum;
2217 struct smb_request **reqs;
2218 unsigned num_reqs;
2221 static bool smb1_parse_chain_cb(uint8_t cmd,
2222 uint8_t wct, const uint16_t *vwv,
2223 uint16_t num_bytes, const uint8_t *bytes,
2224 void *private_data)
2226 struct smb1_parse_chain_state *state =
2227 (struct smb1_parse_chain_state *)private_data;
2228 struct smb_request **reqs;
2229 struct smb_request *req;
2230 bool ok;
2232 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2233 struct smb_request *, state->num_reqs+1);
2234 if (reqs == NULL) {
2235 return false;
2237 state->reqs = reqs;
2239 req = talloc(reqs, struct smb_request);
2240 if (req == NULL) {
2241 return false;
2244 ok = init_smb_request(req, state->sconn, state->buf, 0,
2245 state->encrypted, state->seqnum);
2246 if (!ok) {
2247 return false;
2249 req->cmd = cmd;
2250 req->wct = wct;
2251 req->vwv = vwv;
2252 req->buflen = num_bytes;
2253 req->buf = bytes;
2255 reqs[state->num_reqs] = req;
2256 state->num_reqs += 1;
2257 return true;
2260 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2261 struct smbd_server_connection *sconn,
2262 bool encrypted, uint32_t seqnum,
2263 struct smb_request ***reqs, unsigned *num_reqs)
2265 struct smb1_parse_chain_state state;
2266 unsigned i;
2268 state.mem_ctx = mem_ctx;
2269 state.buf = buf;
2270 state.sconn = sconn;
2271 state.encrypted = encrypted;
2272 state.seqnum = seqnum;
2273 state.reqs = NULL;
2274 state.num_reqs = 0;
2276 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2277 TALLOC_FREE(state.reqs);
2278 return false;
2280 for (i=0; i<state.num_reqs; i++) {
2281 state.reqs[i]->chain = state.reqs;
2283 *reqs = state.reqs;
2284 *num_reqs = state.num_reqs;
2285 return true;
2288 /****************************************************************************
2289 Check if services need reloading.
2290 ****************************************************************************/
2292 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2295 if (last_smb_conf_reload_time == 0) {
2296 last_smb_conf_reload_time = t;
2299 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2300 reload_services(sconn, conn_snum_used, true);
2301 last_smb_conf_reload_time = t;
2305 static bool fd_is_readable(int fd)
2307 int ret, revents;
2309 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2311 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2315 static void smbd_server_connection_write_handler(
2316 struct smbd_server_connection *sconn)
2318 /* TODO: make write nonblocking */
2321 static void smbd_server_connection_read_handler(
2322 struct smbd_server_connection *sconn, int fd)
2324 uint8_t *inbuf = NULL;
2325 size_t inbuf_len = 0;
2326 size_t unread_bytes = 0;
2327 bool encrypted = false;
2328 TALLOC_CTX *mem_ctx = talloc_tos();
2329 NTSTATUS status;
2330 uint32_t seqnum;
2332 bool from_client;
2334 if (lp_async_smb_echo_handler()
2335 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2337 * This is the super-ugly hack to prefer the packets
2338 * forwarded by the echo handler over the ones by the
2339 * client directly
2341 fd = sconn->smb1.echo_handler.trusted_fd;
2344 from_client = (sconn->sock == fd);
2346 if (from_client) {
2347 smbd_lock_socket(sconn);
2349 if (!fd_is_readable(fd)) {
2350 DEBUG(10,("the echo listener was faster\n"));
2351 smbd_unlock_socket(sconn);
2352 return;
2356 /* TODO: make this completely nonblocking */
2357 status = receive_smb_talloc(mem_ctx, sconn, fd,
2358 (char **)(void *)&inbuf,
2359 0, /* timeout */
2360 &unread_bytes,
2361 &encrypted,
2362 &inbuf_len, &seqnum,
2363 false /* trusted channel */);
2365 if (from_client) {
2366 smbd_unlock_socket(sconn);
2369 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2370 goto process;
2372 if (NT_STATUS_IS_ERR(status)) {
2373 exit_server_cleanly("failed to receive smb request");
2375 if (!NT_STATUS_IS_OK(status)) {
2376 return;
2379 process:
2380 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2381 seqnum, encrypted, NULL);
2384 static void smbd_server_connection_handler(struct event_context *ev,
2385 struct fd_event *fde,
2386 uint16_t flags,
2387 void *private_data)
2389 struct smbd_server_connection *conn = talloc_get_type(private_data,
2390 struct smbd_server_connection);
2392 if (flags & EVENT_FD_WRITE) {
2393 smbd_server_connection_write_handler(conn);
2394 return;
2396 if (flags & EVENT_FD_READ) {
2397 smbd_server_connection_read_handler(conn, conn->sock);
2398 return;
2402 static void smbd_server_echo_handler(struct event_context *ev,
2403 struct fd_event *fde,
2404 uint16_t flags,
2405 void *private_data)
2407 struct smbd_server_connection *conn = talloc_get_type(private_data,
2408 struct smbd_server_connection);
2410 if (flags & EVENT_FD_WRITE) {
2411 smbd_server_connection_write_handler(conn);
2412 return;
2414 if (flags & EVENT_FD_READ) {
2415 smbd_server_connection_read_handler(
2416 conn, conn->smb1.echo_handler.trusted_fd);
2417 return;
2421 #ifdef CLUSTER_SUPPORT
2422 /****************************************************************************
2423 received when we should release a specific IP
2424 ****************************************************************************/
2425 static void release_ip(const char *ip, void *priv)
2427 const char *addr = (const char *)priv;
2428 const char *p = addr;
2430 if (strncmp("::ffff:", addr, 7) == 0) {
2431 p = addr + 7;
2434 DEBUG(10, ("Got release IP message for %s, "
2435 "our address is %s\n", ip, p));
2437 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2438 /* we can't afford to do a clean exit - that involves
2439 database writes, which would potentially mean we
2440 are still running after the failover has finished -
2441 we have to get rid of this process ID straight
2442 away */
2443 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2444 ip));
2445 /* note we must exit with non-zero status so the unclean handler gets
2446 called in the parent, so that the brl database is tickled */
2447 _exit(1);
2451 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2452 struct sockaddr_storage *client)
2454 socklen_t length;
2455 length = sizeof(*server);
2456 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2457 return -1;
2459 length = sizeof(*client);
2460 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2461 return -1;
2463 return 0;
2465 #endif
2468 * Send keepalive packets to our client
2470 static bool keepalive_fn(const struct timeval *now, void *private_data)
2472 struct smbd_server_connection *sconn = talloc_get_type_abort(
2473 private_data, struct smbd_server_connection);
2474 bool ret;
2476 if (sconn->using_smb2) {
2477 /* Don't do keepalives on an SMB2 connection. */
2478 return false;
2481 smbd_lock_socket(sconn);
2482 ret = send_keepalive(sconn->sock);
2483 smbd_unlock_socket(sconn);
2485 if (!ret) {
2486 char addr[INET6_ADDRSTRLEN];
2488 * Try and give an error message saying what
2489 * client failed.
2491 DEBUG(0, ("send_keepalive failed for client %s. "
2492 "Error %s - exiting\n",
2493 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2494 strerror(errno)));
2495 return False;
2497 return True;
2501 * Do the recurring check if we're idle
2503 static bool deadtime_fn(const struct timeval *now, void *private_data)
2505 struct smbd_server_connection *sconn =
2506 (struct smbd_server_connection *)private_data;
2508 if ((conn_num_open(sconn) == 0)
2509 || (conn_idle_all(sconn, now->tv_sec))) {
2510 DEBUG( 2, ( "Closing idle connection\n" ) );
2511 messaging_send(sconn->msg_ctx,
2512 messaging_server_id(sconn->msg_ctx),
2513 MSG_SHUTDOWN, &data_blob_null);
2514 return False;
2517 return True;
2521 * Do the recurring log file and smb.conf reload checks.
2524 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2526 struct smbd_server_connection *sconn = talloc_get_type_abort(
2527 private_data, struct smbd_server_connection);
2529 DEBUG(5, ("housekeeping\n"));
2531 change_to_root_user();
2533 /* update printer queue caches if necessary */
2534 update_monitored_printq_cache(sconn->msg_ctx);
2536 /* check if we need to reload services */
2537 check_reload(sconn, time_mono(NULL));
2539 /* Change machine password if neccessary. */
2540 attempt_machine_password_change();
2543 * Force a log file check.
2545 force_check_log_size();
2546 check_log_size();
2547 return true;
2551 * Read an smb packet in the echo handler child, giving the parent
2552 * smbd one second to react once the socket becomes readable.
2555 struct smbd_echo_read_state {
2556 struct tevent_context *ev;
2557 struct smbd_server_connection *sconn;
2559 char *buf;
2560 size_t buflen;
2561 uint32_t seqnum;
2564 static void smbd_echo_read_readable(struct tevent_req *subreq);
2565 static void smbd_echo_read_waited(struct tevent_req *subreq);
2567 static struct tevent_req *smbd_echo_read_send(
2568 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2569 struct smbd_server_connection *sconn)
2571 struct tevent_req *req, *subreq;
2572 struct smbd_echo_read_state *state;
2574 req = tevent_req_create(mem_ctx, &state,
2575 struct smbd_echo_read_state);
2576 if (req == NULL) {
2577 return NULL;
2579 state->ev = ev;
2580 state->sconn = sconn;
2582 subreq = wait_for_read_send(state, ev, sconn->sock);
2583 if (tevent_req_nomem(subreq, req)) {
2584 return tevent_req_post(req, ev);
2586 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2587 return req;
2590 static void smbd_echo_read_readable(struct tevent_req *subreq)
2592 struct tevent_req *req = tevent_req_callback_data(
2593 subreq, struct tevent_req);
2594 struct smbd_echo_read_state *state = tevent_req_data(
2595 req, struct smbd_echo_read_state);
2596 bool ok;
2597 int err;
2599 ok = wait_for_read_recv(subreq, &err);
2600 TALLOC_FREE(subreq);
2601 if (!ok) {
2602 tevent_req_nterror(req, map_nt_error_from_unix(err));
2603 return;
2607 * Give the parent smbd one second to step in
2610 subreq = tevent_wakeup_send(
2611 state, state->ev, timeval_current_ofs(1, 0));
2612 if (tevent_req_nomem(subreq, req)) {
2613 return;
2615 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2618 static void smbd_echo_read_waited(struct tevent_req *subreq)
2620 struct tevent_req *req = tevent_req_callback_data(
2621 subreq, struct tevent_req);
2622 struct smbd_echo_read_state *state = tevent_req_data(
2623 req, struct smbd_echo_read_state);
2624 struct smbd_server_connection *sconn = state->sconn;
2625 bool ok;
2626 NTSTATUS status;
2627 size_t unread = 0;
2628 bool encrypted;
2630 ok = tevent_wakeup_recv(subreq);
2631 TALLOC_FREE(subreq);
2632 if (!ok) {
2633 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2634 return;
2637 ok = smbd_lock_socket_internal(sconn);
2638 if (!ok) {
2639 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2640 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2641 return;
2644 if (!fd_is_readable(sconn->sock)) {
2645 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2646 (int)getpid()));
2648 ok = smbd_unlock_socket_internal(sconn);
2649 if (!ok) {
2650 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2651 DEBUG(1, ("%s: failed to unlock socket\n",
2652 __location__));
2653 return;
2656 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2657 if (tevent_req_nomem(subreq, req)) {
2658 return;
2660 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2661 return;
2664 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2665 0 /* timeout */,
2666 &unread,
2667 &encrypted,
2668 &state->buflen,
2669 &state->seqnum,
2670 false /* trusted_channel*/);
2672 if (tevent_req_nterror(req, status)) {
2673 tevent_req_nterror(req, status);
2674 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2675 (int)getpid(), nt_errstr(status)));
2676 return;
2679 ok = smbd_unlock_socket_internal(sconn);
2680 if (!ok) {
2681 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2682 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2683 return;
2685 tevent_req_done(req);
2688 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2689 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2691 struct smbd_echo_read_state *state = tevent_req_data(
2692 req, struct smbd_echo_read_state);
2693 NTSTATUS status;
2695 if (tevent_req_is_nterror(req, &status)) {
2696 return status;
2698 *pbuf = talloc_move(mem_ctx, &state->buf);
2699 *pbuflen = state->buflen;
2700 *pseqnum = state->seqnum;
2701 return NT_STATUS_OK;
2704 struct smbd_echo_state {
2705 struct tevent_context *ev;
2706 struct iovec *pending;
2707 struct smbd_server_connection *sconn;
2708 int parent_pipe;
2710 struct tevent_fd *parent_fde;
2712 struct tevent_req *write_req;
2715 static void smbd_echo_writer_done(struct tevent_req *req);
2717 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2719 int num_pending;
2721 if (state->write_req != NULL) {
2722 return;
2725 num_pending = talloc_array_length(state->pending);
2726 if (num_pending == 0) {
2727 return;
2730 state->write_req = writev_send(state, state->ev, NULL,
2731 state->parent_pipe, false,
2732 state->pending, num_pending);
2733 if (state->write_req == NULL) {
2734 DEBUG(1, ("writev_send failed\n"));
2735 exit(1);
2738 talloc_steal(state->write_req, state->pending);
2739 state->pending = NULL;
2741 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2742 state);
2745 static void smbd_echo_writer_done(struct tevent_req *req)
2747 struct smbd_echo_state *state = tevent_req_callback_data(
2748 req, struct smbd_echo_state);
2749 ssize_t written;
2750 int err;
2752 written = writev_recv(req, &err);
2753 TALLOC_FREE(req);
2754 state->write_req = NULL;
2755 if (written == -1) {
2756 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2757 exit(1);
2759 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2760 smbd_echo_activate_writer(state);
2763 static bool smbd_echo_reply(struct smbd_echo_state *state,
2764 uint8_t *inbuf, size_t inbuf_len,
2765 uint32_t seqnum)
2767 struct smb_request req;
2768 uint16_t num_replies;
2769 char *outbuf;
2770 bool ok;
2772 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2773 DEBUG(10, ("Got netbios keepalive\n"));
2775 * Just swallow it
2777 return true;
2780 if (inbuf_len < smb_size) {
2781 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2782 return false;
2784 if (!valid_smb_header(state->sconn, inbuf)) {
2785 DEBUG(10, ("Got invalid SMB header\n"));
2786 return false;
2789 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2790 seqnum)) {
2791 return false;
2793 req.inbuf = inbuf;
2795 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2796 smb_messages[req.cmd].name
2797 ? smb_messages[req.cmd].name : "unknown"));
2799 if (req.cmd != SMBecho) {
2800 return false;
2802 if (req.wct < 1) {
2803 return false;
2806 num_replies = SVAL(req.vwv+0, 0);
2807 if (num_replies != 1) {
2808 /* Not a Windows "Hey, you're still there?" request */
2809 return false;
2812 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2813 1, req.buflen)) {
2814 DEBUG(10, ("create_outbuf failed\n"));
2815 return false;
2817 req.outbuf = (uint8_t *)outbuf;
2819 SSVAL(req.outbuf, smb_vwv0, num_replies);
2821 if (req.buflen > 0) {
2822 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2825 ok = srv_send_smb(req.sconn,
2826 (char *)outbuf,
2827 true, seqnum+1,
2828 false, &req.pcd);
2829 TALLOC_FREE(outbuf);
2830 if (!ok) {
2831 exit(1);
2834 return true;
2837 static void smbd_echo_exit(struct tevent_context *ev,
2838 struct tevent_fd *fde, uint16_t flags,
2839 void *private_data)
2841 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2842 exit(0);
2845 static void smbd_echo_got_packet(struct tevent_req *req);
2847 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2848 int parent_pipe)
2850 struct smbd_echo_state *state;
2851 struct tevent_req *read_req;
2853 state = talloc_zero(sconn, struct smbd_echo_state);
2854 if (state == NULL) {
2855 DEBUG(1, ("talloc failed\n"));
2856 return;
2858 state->sconn = sconn;
2859 state->parent_pipe = parent_pipe;
2860 state->ev = s3_tevent_context_init(state);
2861 if (state->ev == NULL) {
2862 DEBUG(1, ("tevent_context_init failed\n"));
2863 TALLOC_FREE(state);
2864 return;
2866 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2867 TEVENT_FD_READ, smbd_echo_exit,
2868 state);
2869 if (state->parent_fde == NULL) {
2870 DEBUG(1, ("tevent_add_fd failed\n"));
2871 TALLOC_FREE(state);
2872 return;
2875 read_req = smbd_echo_read_send(state, state->ev, sconn);
2876 if (read_req == NULL) {
2877 DEBUG(1, ("smbd_echo_read_send failed\n"));
2878 TALLOC_FREE(state);
2879 return;
2881 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2883 while (true) {
2884 if (tevent_loop_once(state->ev) == -1) {
2885 DEBUG(1, ("tevent_loop_once failed: %s\n",
2886 strerror(errno)));
2887 break;
2890 TALLOC_FREE(state);
2893 static void smbd_echo_got_packet(struct tevent_req *req)
2895 struct smbd_echo_state *state = tevent_req_callback_data(
2896 req, struct smbd_echo_state);
2897 NTSTATUS status;
2898 char *buf = NULL;
2899 size_t buflen = 0;
2900 uint32_t seqnum = 0;
2901 bool reply;
2903 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2904 TALLOC_FREE(req);
2905 if (!NT_STATUS_IS_OK(status)) {
2906 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2907 nt_errstr(status)));
2908 exit(1);
2911 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2912 if (!reply) {
2913 size_t num_pending;
2914 struct iovec *tmp;
2915 struct iovec *iov;
2917 num_pending = talloc_array_length(state->pending);
2918 tmp = talloc_realloc(state, state->pending, struct iovec,
2919 num_pending+1);
2920 if (tmp == NULL) {
2921 DEBUG(1, ("talloc_realloc failed\n"));
2922 exit(1);
2924 state->pending = tmp;
2926 if (buflen >= smb_size) {
2928 * place the seqnum in the packet so that the main process
2929 * can reply with signing
2931 SIVAL(buf, smb_ss_field, seqnum);
2932 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2935 iov = &state->pending[num_pending];
2936 iov->iov_base = buf;
2937 iov->iov_len = buflen;
2939 DEBUG(10,("echo_handler[%d]: forward to main\n",
2940 (int)getpid()));
2941 smbd_echo_activate_writer(state);
2944 req = smbd_echo_read_send(state, state->ev, state->sconn);
2945 if (req == NULL) {
2946 DEBUG(1, ("smbd_echo_read_send failed\n"));
2947 exit(1);
2949 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2954 * Handle SMBecho requests in a forked child process
2956 bool fork_echo_handler(struct smbd_server_connection *sconn)
2958 int listener_pipe[2];
2959 int res;
2960 pid_t child;
2962 res = pipe(listener_pipe);
2963 if (res == -1) {
2964 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2965 return false;
2967 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2968 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2969 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2970 goto fail;
2973 child = fork();
2974 if (child == 0) {
2975 NTSTATUS status;
2977 close(listener_pipe[0]);
2978 set_blocking(listener_pipe[1], false);
2980 status = reinit_after_fork(sconn->msg_ctx,
2981 sconn->ev_ctx,
2982 false);
2983 if (!NT_STATUS_IS_OK(status)) {
2984 DEBUG(1, ("reinit_after_fork failed: %s\n",
2985 nt_errstr(status)));
2986 exit(1);
2988 smbd_echo_loop(sconn, listener_pipe[1]);
2989 exit(0);
2991 close(listener_pipe[1]);
2992 listener_pipe[1] = -1;
2993 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2995 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child));
2998 * Without smb signing this is the same as the normal smbd
2999 * listener. This needs to change once signing comes in.
3001 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
3002 sconn,
3003 sconn->smb1.echo_handler.trusted_fd,
3004 TEVENT_FD_READ,
3005 smbd_server_echo_handler,
3006 sconn);
3007 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3008 DEBUG(1, ("event_add_fd failed\n"));
3009 goto fail;
3012 return true;
3014 fail:
3015 if (listener_pipe[0] != -1) {
3016 close(listener_pipe[0]);
3018 if (listener_pipe[1] != -1) {
3019 close(listener_pipe[1]);
3021 sconn->smb1.echo_handler.trusted_fd = -1;
3022 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3023 close(sconn->smb1.echo_handler.socket_lock_fd);
3025 sconn->smb1.echo_handler.trusted_fd = -1;
3026 sconn->smb1.echo_handler.socket_lock_fd = -1;
3027 return false;
3030 #if CLUSTER_SUPPORT
3032 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
3033 struct sockaddr_storage *srv,
3034 struct sockaddr_storage *clnt)
3036 struct ctdbd_connection *cconn;
3037 char tmp_addr[INET6_ADDRSTRLEN];
3038 char *addr;
3040 cconn = messaging_ctdbd_connection();
3041 if (cconn == NULL) {
3042 return NT_STATUS_NO_MEMORY;
3045 if (client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr)) == NULL) {
3046 return NT_STATUS_NO_MEMORY;
3048 addr = talloc_strdup(cconn, tmp_addr);
3049 if (addr == NULL) {
3050 return NT_STATUS_NO_MEMORY;
3052 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
3055 #endif
3057 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3059 while (user) {
3060 if (user->session_info &&
3061 (user->session_info->unix_token->uid == uid)) {
3062 return true;
3064 user = user->next;
3066 return false;
3069 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3071 while (user) {
3072 if (user->session_info != NULL) {
3073 int i;
3074 struct security_unix_token *utok;
3076 utok = user->session_info->unix_token;
3077 if (utok->gid == gid) {
3078 return true;
3080 for(i=0; i<utok->ngroups; i++) {
3081 if (utok->groups[i] == gid) {
3082 return true;
3086 user = user->next;
3088 return false;
3091 static bool sid_in_use(const struct user_struct *user,
3092 const struct dom_sid *psid)
3094 while (user) {
3095 struct security_token *tok;
3097 if (user->session_info == NULL) {
3098 continue;
3100 tok = user->session_info->security_token;
3101 if (tok == NULL) {
3103 * Not sure session_info->security_token can
3104 * ever be NULL. This check might be not
3105 * necessary.
3107 continue;
3109 if (security_token_has_sid(tok, psid)) {
3110 return true;
3112 user = user->next;
3114 return false;
3117 static bool id_in_use(const struct user_struct *user,
3118 const struct id_cache_ref *id)
3120 switch(id->type) {
3121 case UID:
3122 return uid_in_use(user, id->id.uid);
3123 case GID:
3124 return gid_in_use(user, id->id.gid);
3125 case SID:
3126 return sid_in_use(user, &id->id.sid);
3127 default:
3128 break;
3130 return false;
3133 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3134 void *private_data,
3135 uint32_t msg_type,
3136 struct server_id server_id,
3137 DATA_BLOB* data)
3139 const char *msg = (data && data->data)
3140 ? (const char *)data->data : "<NULL>";
3141 struct id_cache_ref id;
3142 struct smbd_server_connection *sconn =
3143 talloc_get_type_abort(private_data,
3144 struct smbd_server_connection);
3146 if (!id_cache_ref_parse(msg, &id)) {
3147 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3148 return;
3151 if (id_in_use(sconn->users, &id)) {
3152 exit_server_cleanly(msg);
3154 id_cache_delete_from_cache(&id);
3157 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3158 enum protocol_types protocol)
3160 NTSTATUS status;
3162 set_Protocol(protocol);
3163 conn->protocol = protocol;
3165 if (protocol >= PROTOCOL_SMB2_02) {
3166 status = smb2srv_session_table_init(conn);
3167 if (!NT_STATUS_IS_OK(status)) {
3168 return status;
3172 return NT_STATUS_OK;
3175 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3176 void *private_data)
3178 struct smbXsrv_connection *conn =
3179 talloc_get_type_abort(private_data,
3180 struct smbXsrv_connection);
3182 switch (point) {
3183 case TEVENT_TRACE_BEFORE_WAIT:
3185 * This just removes compiler warning
3186 * without profile support
3188 conn->smbd_idle_profstamp = 0;
3189 START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3190 break;
3191 case TEVENT_TRACE_AFTER_WAIT:
3192 END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
3193 break;
3197 /****************************************************************************
3198 Process commands from the client
3199 ****************************************************************************/
3201 void smbd_process(struct tevent_context *ev_ctx,
3202 struct messaging_context *msg_ctx,
3203 int sock_fd,
3204 bool interactive)
3206 TALLOC_CTX *frame = talloc_stackframe();
3207 struct smbXsrv_connection *conn;
3208 struct smbd_server_connection *sconn;
3209 struct sockaddr_storage ss;
3210 struct sockaddr *sa = NULL;
3211 socklen_t sa_socklen;
3212 struct tsocket_address *local_address = NULL;
3213 struct tsocket_address *remote_address = NULL;
3214 const char *locaddr = NULL;
3215 const char *remaddr = NULL;
3216 char *rhost;
3217 int ret;
3219 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3220 if (conn == NULL) {
3221 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3222 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3225 conn->ev_ctx = ev_ctx;
3226 conn->msg_ctx = msg_ctx;
3228 sconn = talloc_zero(conn, struct smbd_server_connection);
3229 if (!sconn) {
3230 exit_server("failed to create smbd_server_connection");
3233 conn->sconn = sconn;
3234 sconn->conn = conn;
3237 * TODO: remove this...:-)
3239 global_smbXsrv_connection = conn;
3241 sconn->ev_ctx = ev_ctx;
3242 sconn->msg_ctx = msg_ctx;
3243 sconn->sock = sock_fd;
3244 sconn->smb1.echo_handler.trusted_fd = -1;
3245 sconn->smb1.echo_handler.socket_lock_fd = -1;
3247 if (!interactive) {
3248 smbd_setup_sig_term_handler(sconn);
3249 smbd_setup_sig_hup_handler(sconn);
3251 if (!serverid_register(messaging_server_id(msg_ctx),
3252 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3253 |FLAG_MSG_DBWRAP
3254 |FLAG_MSG_PRINT_GENERAL)) {
3255 exit_server_cleanly("Could not register myself in "
3256 "serverid.tdb");
3260 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3262 * We're not making the decision here,
3263 * we're just allowing the client
3264 * to decide between SMB1 and SMB2
3265 * with the first negprot
3266 * packet.
3268 sconn->using_smb2 = true;
3271 /* Ensure child is set to blocking mode */
3272 set_blocking(sconn->sock,True);
3274 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3275 set_socket_options(sconn->sock, lp_socket_options());
3277 sa = (struct sockaddr *)(void *)&ss;
3278 sa_socklen = sizeof(ss);
3279 ret = getpeername(sconn->sock, sa, &sa_socklen);
3280 if (ret != 0) {
3281 int level = (errno == ENOTCONN)?2:0;
3282 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3283 exit_server_cleanly("getpeername() failed.\n");
3285 ret = tsocket_address_bsd_from_sockaddr(sconn,
3286 sa, sa_socklen,
3287 &remote_address);
3288 if (ret != 0) {
3289 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3290 __location__, strerror(errno)));
3291 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3294 sa = (struct sockaddr *)(void *)&ss;
3295 sa_socklen = sizeof(ss);
3296 ret = getsockname(sconn->sock, sa, &sa_socklen);
3297 if (ret != 0) {
3298 int level = (errno == ENOTCONN)?2:0;
3299 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3300 exit_server_cleanly("getsockname() failed.\n");
3302 ret = tsocket_address_bsd_from_sockaddr(sconn,
3303 sa, sa_socklen,
3304 &local_address);
3305 if (ret != 0) {
3306 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3307 __location__, strerror(errno)));
3308 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3311 sconn->local_address = local_address;
3312 sconn->remote_address = remote_address;
3314 if (tsocket_address_is_inet(local_address, "ip")) {
3315 locaddr = tsocket_address_inet_addr_string(
3316 sconn->local_address,
3317 talloc_tos());
3318 if (locaddr == NULL) {
3319 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3320 __location__, strerror(errno)));
3321 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3323 } else {
3324 locaddr = "0.0.0.0";
3327 if (tsocket_address_is_inet(remote_address, "ip")) {
3328 remaddr = tsocket_address_inet_addr_string(
3329 sconn->remote_address,
3330 talloc_tos());
3331 if (remaddr == NULL) {
3332 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3333 __location__, strerror(errno)));
3334 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3336 } else {
3337 remaddr = "0.0.0.0";
3340 /* this is needed so that we get decent entries
3341 in smbstatus for port 445 connects */
3342 set_remote_machine_name(remaddr, false);
3343 reload_services(sconn, conn_snum_used, true);
3346 * Before the first packet, check the global hosts allow/ hosts deny
3347 * parameters before doing any parsing of packets passed to us by the
3348 * client. This prevents attacks on our parsing code from hosts not in
3349 * the hosts allow list.
3352 ret = get_remote_hostname(remote_address,
3353 &rhost,
3354 talloc_tos());
3355 if (ret < 0) {
3356 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3357 __location__, strerror(errno)));
3358 exit_server_cleanly("get_remote_hostname failed.\n");
3360 if (strequal(rhost, "UNKNOWN")) {
3361 rhost = talloc_strdup(talloc_tos(), remaddr);
3363 sconn->remote_hostname = talloc_move(sconn, &rhost);
3365 sub_set_socket_ids(remaddr,
3366 sconn->remote_hostname,
3367 locaddr);
3369 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3370 sconn->remote_hostname,
3371 remaddr)) {
3373 * send a negative session response "not listening on calling
3374 * name"
3376 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3377 DEBUG( 1, ("Connection denied from %s to %s\n",
3378 tsocket_address_string(remote_address, talloc_tos()),
3379 tsocket_address_string(local_address, talloc_tos())));
3380 (void)srv_send_smb(sconn,(char *)buf, false,
3381 0, false, NULL);
3382 exit_server_cleanly("connection denied");
3385 DEBUG(10, ("Connection allowed from %s to %s\n",
3386 tsocket_address_string(remote_address, talloc_tos()),
3387 tsocket_address_string(local_address, talloc_tos())));
3389 if (lp_preload_modules()) {
3390 smb_load_modules(lp_preload_modules());
3393 smb_perfcount_init();
3395 if (!init_account_policy()) {
3396 exit_server("Could not open account policy tdb.\n");
3399 if (*lp_rootdir()) {
3400 if (chroot(lp_rootdir()) != 0) {
3401 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3402 exit_server("Failed to chroot()");
3404 if (chdir("/") == -1) {
3405 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3406 exit_server("Failed to chroot()");
3408 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3411 if (!srv_init_signing(sconn)) {
3412 exit_server("Failed to init smb_signing");
3415 if (!file_init(sconn)) {
3416 exit_server("file_init() failed");
3419 /* Setup oplocks */
3420 if (!init_oplocks(sconn))
3421 exit_server("Failed to init oplocks");
3423 /* register our message handlers */
3424 messaging_register(sconn->msg_ctx, sconn,
3425 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3426 messaging_register(sconn->msg_ctx, sconn,
3427 MSG_SMB_CLOSE_FILE, msg_close_file);
3428 messaging_register(sconn->msg_ctx, sconn,
3429 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3431 id_cache_register_msgs(sconn->msg_ctx);
3432 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3433 messaging_register(sconn->msg_ctx, sconn,
3434 ID_CACHE_KILL, smbd_id_cache_kill);
3436 messaging_deregister(sconn->msg_ctx,
3437 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3438 messaging_register(sconn->msg_ctx, sconn,
3439 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3442 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3443 * MSGs to all child processes
3445 messaging_deregister(sconn->msg_ctx,
3446 MSG_DEBUG, NULL);
3447 messaging_register(sconn->msg_ctx, NULL,
3448 MSG_DEBUG, debug_message);
3450 if ((lp_keepalive() != 0)
3451 && !(event_add_idle(ev_ctx, NULL,
3452 timeval_set(lp_keepalive(), 0),
3453 "keepalive", keepalive_fn,
3454 sconn))) {
3455 DEBUG(0, ("Could not add keepalive event\n"));
3456 exit(1);
3459 if (!(event_add_idle(ev_ctx, NULL,
3460 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3461 "deadtime", deadtime_fn, sconn))) {
3462 DEBUG(0, ("Could not add deadtime event\n"));
3463 exit(1);
3466 if (!(event_add_idle(ev_ctx, NULL,
3467 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3468 "housekeeping", housekeeping_fn, sconn))) {
3469 DEBUG(0, ("Could not add housekeeping event\n"));
3470 exit(1);
3473 #ifdef CLUSTER_SUPPORT
3475 if (lp_clustering()) {
3477 * We need to tell ctdb about our client's TCP
3478 * connection, so that for failover ctdbd can send
3479 * tickle acks, triggering a reconnection by the
3480 * client.
3483 struct sockaddr_storage srv, clnt;
3485 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3486 NTSTATUS status;
3487 status = smbd_register_ips(sconn, &srv, &clnt);
3488 if (!NT_STATUS_IS_OK(status)) {
3489 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3490 nt_errstr(status)));
3492 } else
3494 DEBUG(0,("Unable to get tcp info for "
3495 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3496 strerror(errno)));
3500 #endif
3502 sconn->nbt.got_session = false;
3504 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
3506 sconn->smb1.sessions.done_sesssetup = false;
3507 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3508 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3509 /* this holds info on user ids that are already validated for this VC */
3510 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3512 conn_init(sconn);
3513 if (!init_dptrs(sconn)) {
3514 exit_server("init_dptrs() failed");
3517 sconn->smb1.fde = event_add_fd(ev_ctx,
3518 sconn,
3519 sconn->sock,
3520 EVENT_FD_READ,
3521 smbd_server_connection_handler,
3522 sconn);
3523 if (!sconn->smb1.fde) {
3524 exit_server("failed to create smbd_server_connection fde");
3527 sconn->conn->local_address = sconn->local_address;
3528 sconn->conn->remote_address = sconn->remote_address;
3529 sconn->conn->remote_hostname = sconn->remote_hostname;
3530 sconn->conn->protocol = PROTOCOL_NONE;
3532 TALLOC_FREE(frame);
3534 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, conn);
3536 while (True) {
3537 frame = talloc_stackframe_pool(8192);
3539 errno = 0;
3540 if (tevent_loop_once(ev_ctx) == -1) {
3541 if (errno != EINTR) {
3542 DEBUG(3, ("tevent_loop_once failed: %s,"
3543 " exiting\n", strerror(errno) ));
3544 break;
3548 TALLOC_FREE(frame);
3551 exit_server_cleanly(NULL);
3554 bool req_is_in_chain(struct smb_request *req)
3556 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3558 * We're right now handling a subsequent request, so we must
3559 * be in a chain
3561 return true;
3564 if (!is_andx_req(req->cmd)) {
3565 return false;
3568 if (req->wct < 2) {
3570 * Okay, an illegal request, but definitely not chained :-)
3572 return false;
3575 return (CVAL(req->vwv+0, 0) != 0xFF);