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/>.
22 #include "smbd/globals.h"
23 #include "../librpc/gen_ndr/srv_dfs.h"
24 #include "../librpc/gen_ndr/srv_dssetup.h"
25 #include "../librpc/gen_ndr/srv_echo.h"
26 #include "../librpc/gen_ndr/srv_eventlog.h"
27 #include "../librpc/gen_ndr/srv_initshutdown.h"
28 #include "../librpc/gen_ndr/srv_lsa.h"
29 #include "../librpc/gen_ndr/srv_netlogon.h"
30 #include "../librpc/gen_ndr/srv_ntsvcs.h"
31 #include "../librpc/gen_ndr/srv_samr.h"
32 #include "../librpc/gen_ndr/srv_spoolss.h"
33 #include "../librpc/gen_ndr/srv_srvsvc.h"
34 #include "../librpc/gen_ndr/srv_svcctl.h"
35 #include "../librpc/gen_ndr/srv_winreg.h"
36 #include "../librpc/gen_ndr/srv_wkssvc.h"
38 extern bool global_machine_password_needs_changing;
40 static void construct_reply_common(struct smb_request *req, const char *inbuf,
43 bool smbd_lock_socket(struct smbd_server_connection *sconn)
47 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
51 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
53 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
54 SMB_F_SETLKW, 0, 0, F_WRLCK);
59 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
64 bool smbd_unlock_socket(struct smbd_server_connection *sconn)
68 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
72 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
73 SMB_F_SETLKW, 0, 0, F_UNLCK);
78 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
83 /* Accessor function for smb_read_error for smbd functions. */
85 /****************************************************************************
87 ****************************************************************************/
89 bool srv_send_smb(int fd, char *buffer,
90 bool do_signing, uint32_t seqnum,
92 struct smb_perfcount_data *pcd)
97 char *buf_out = buffer;
100 ok = smbd_lock_socket(smbd_server_conn);
102 exit_server_cleanly("failed to lock socket");
106 /* Sign the outgoing packet if required. */
107 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
111 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
112 if (!NT_STATUS_IS_OK(status)) {
113 DEBUG(0, ("send_smb: SMB encryption failed "
114 "on outgoing packet! Error %s\n",
115 nt_errstr(status) ));
120 len = smb_len(buf_out) + 4;
122 ret = write_data(fd,buf_out+nwritten,len - nwritten);
124 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
125 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
126 srv_free_enc_buffer(buf_out);
130 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
131 srv_free_enc_buffer(buf_out);
133 SMB_PERFCOUNT_END(pcd);
135 ok = smbd_unlock_socket(smbd_server_conn);
137 exit_server_cleanly("failed to unlock socket");
143 /*******************************************************************
144 Setup the word count and byte count for a smb message.
145 ********************************************************************/
147 int srv_set_message(char *buf,
152 if (zero && (num_words || num_bytes)) {
153 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
155 SCVAL(buf,smb_wct,num_words);
156 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
157 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
158 return (smb_size + num_words*2 + num_bytes);
161 static bool valid_smb_header(const uint8_t *inbuf)
163 if (is_encrypted_packet(inbuf)) {
167 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
168 * but it just looks weird to call strncmp for this one.
170 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
173 /* Socket functions for smbd packet processing. */
175 static bool valid_packet_size(size_t len)
178 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
179 * of header. Don't print the error if this fits.... JRA.
182 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
183 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
184 (unsigned long)len));
190 static NTSTATUS read_packet_remainder(int fd, char *buffer,
191 unsigned int timeout, ssize_t len)
197 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
200 /****************************************************************************
201 Attempt a zerocopy writeX read. We know here that len > smb_size-4
202 ****************************************************************************/
205 * Unfortunately, earlier versions of smbclient/libsmbclient
206 * don't send this "standard" writeX header. I've fixed this
207 * for 3.2 but we'll use the old method with earlier versions.
208 * Windows and CIFSFS at least use this standard size. Not
212 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
213 (2*14) + /* word count (including bcc) */ \
216 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
217 const char lenbuf[4],
218 int fd, char **buffer,
219 unsigned int timeout,
223 /* Size of a WRITEX call (+4 byte len). */
224 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
225 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
229 memcpy(writeX_header, lenbuf, 4);
231 status = read_fd_with_timeout(
232 fd, writeX_header + 4,
233 STANDARD_WRITE_AND_X_HEADER_SIZE,
234 STANDARD_WRITE_AND_X_HEADER_SIZE,
237 if (!NT_STATUS_IS_OK(status)) {
242 * Ok - now try and see if this is a possible
246 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
248 * If the data offset is beyond what
249 * we've read, drain the extra bytes.
251 uint16_t doff = SVAL(writeX_header,smb_vwv11);
254 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
255 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
256 if (drain_socket(smbd_server_fd(), drain) != drain) {
257 smb_panic("receive_smb_raw_talloc_partial_read:"
258 " failed to drain pending bytes");
261 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
264 /* Spoof down the length and null out the bcc. */
265 set_message_bcc(writeX_header, 0);
266 newlen = smb_len(writeX_header);
268 /* Copy the header we've written. */
270 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
272 sizeof(writeX_header));
274 if (*buffer == NULL) {
275 DEBUG(0, ("Could not allocate inbuf of length %d\n",
276 (int)sizeof(writeX_header)));
277 return NT_STATUS_NO_MEMORY;
280 /* Work out the remaining bytes. */
281 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
282 *len_ret = newlen + 4;
286 if (!valid_packet_size(len)) {
287 return NT_STATUS_INVALID_PARAMETER;
291 * Not a valid writeX call. Just do the standard
295 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
297 if (*buffer == NULL) {
298 DEBUG(0, ("Could not allocate inbuf of length %d\n",
300 return NT_STATUS_NO_MEMORY;
303 /* Copy in what we already read. */
306 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
307 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
310 status = read_packet_remainder(
311 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
314 if (!NT_STATUS_IS_OK(status)) {
315 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
325 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
326 char **buffer, unsigned int timeout,
327 size_t *p_unread, size_t *plen)
331 int min_recv_size = lp_min_receive_file_size();
336 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
337 if (!NT_STATUS_IS_OK(status)) {
338 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
342 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
343 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
344 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
345 !srv_is_signing_active(smbd_server_conn) &&
346 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
348 return receive_smb_raw_talloc_partial_read(
349 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
352 if (!valid_packet_size(len)) {
353 return NT_STATUS_INVALID_PARAMETER;
357 * The +4 here can't wrap, we've checked the length above already.
360 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
362 if (*buffer == NULL) {
363 DEBUG(0, ("Could not allocate inbuf of length %d\n",
365 return NT_STATUS_NO_MEMORY;
368 memcpy(*buffer, lenbuf, sizeof(lenbuf));
370 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
371 if (!NT_STATUS_IS_OK(status)) {
379 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
380 char **buffer, unsigned int timeout,
381 size_t *p_unread, bool *p_encrypted,
384 bool trusted_channel)
389 *p_encrypted = false;
391 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
393 if (!NT_STATUS_IS_OK(status)) {
397 if (is_encrypted_packet((uint8_t *)*buffer)) {
398 status = srv_decrypt_buffer(*buffer);
399 if (!NT_STATUS_IS_OK(status)) {
400 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
401 "incoming packet! Error %s\n",
402 nt_errstr(status) ));
408 /* Check the incoming SMB signature. */
409 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
410 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
411 "incoming packet!\n"));
412 return NT_STATUS_INVALID_NETWORK_RESPONSE;
420 * Initialize a struct smb_request from an inbuf
423 static bool init_smb_request(struct smb_request *req, const uint8 *inbuf,
424 size_t unread_bytes, bool encrypted,
427 struct smbd_server_connection *sconn = smbd_server_conn;
428 size_t req_size = smb_len(inbuf) + 4;
429 /* Ensure we have at least smb_size bytes. */
430 if (req_size < smb_size) {
431 DEBUG(0,("init_smb_request: invalid request size %u\n",
432 (unsigned int)req_size ));
435 req->cmd = CVAL(inbuf, smb_com);
436 req->flags2 = SVAL(inbuf, smb_flg2);
437 req->smbpid = SVAL(inbuf, smb_pid);
438 req->mid = SVAL(inbuf, smb_mid);
439 req->seqnum = seqnum;
440 req->vuid = SVAL(inbuf, smb_uid);
441 req->tid = SVAL(inbuf, smb_tid);
442 req->wct = CVAL(inbuf, smb_wct);
443 req->vwv = (uint16_t *)(inbuf+smb_vwv);
444 req->buflen = smb_buflen(inbuf);
445 req->buf = (const uint8_t *)smb_buf(inbuf);
446 req->unread_bytes = unread_bytes;
447 req->encrypted = encrypted;
448 req->conn = conn_find(sconn,req->tid);
449 req->chain_fsp = NULL;
450 req->chain_outbuf = NULL;
452 smb_init_perfcount_data(&req->pcd);
454 /* Ensure we have at least wct words and 2 bytes of bcc. */
455 if (smb_size + req->wct*2 > req_size) {
456 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
457 (unsigned int)req->wct,
458 (unsigned int)req_size));
461 /* Ensure bcc is correct. */
462 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
463 DEBUG(0,("init_smb_request: invalid bcc number %u "
464 "(wct = %u, size %u)\n",
465 (unsigned int)req->buflen,
466 (unsigned int)req->wct,
467 (unsigned int)req_size));
475 static void process_smb(struct smbd_server_connection *conn,
476 uint8_t *inbuf, size_t nread, size_t unread_bytes,
477 uint32_t seqnum, bool encrypted,
478 struct smb_perfcount_data *deferred_pcd);
480 static void smbd_deferred_open_timer(struct event_context *ev,
481 struct timed_event *te,
482 struct timeval _tval,
485 struct pending_message_list *msg = talloc_get_type(private_data,
486 struct pending_message_list);
487 TALLOC_CTX *mem_ctx = talloc_tos();
488 uint16_t mid = SVAL(msg->buf.data,smb_mid);
491 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
494 exit_server("smbd_deferred_open_timer: talloc failed\n");
498 /* We leave this message on the queue so the open code can
499 know this is a retry. */
500 DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
501 (unsigned int)mid ));
503 /* Mark the message as processed so this is not
504 * re-processed in error. */
505 msg->processed = true;
507 process_smb(smbd_server_conn, inbuf,
509 msg->seqnum, msg->encrypted, &msg->pcd);
511 /* If it's still there and was processed, remove it. */
512 msg = get_open_deferred_message(mid);
513 if (msg && msg->processed) {
514 remove_deferred_open_smb_message(mid);
518 /****************************************************************************
519 Function to push a message onto the tail of a linked list of smb messages ready
521 ****************************************************************************/
523 static bool push_queued_message(struct smb_request *req,
524 struct timeval request_time,
525 struct timeval end_time,
526 char *private_data, size_t private_len)
528 int msg_len = smb_len(req->inbuf) + 4;
529 struct pending_message_list *msg;
531 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
534 DEBUG(0,("push_message: malloc fail (1)\n"));
538 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
539 if(msg->buf.data == NULL) {
540 DEBUG(0,("push_message: malloc fail (2)\n"));
545 msg->request_time = request_time;
546 msg->seqnum = req->seqnum;
547 msg->encrypted = req->encrypted;
548 msg->processed = false;
549 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
552 msg->private_data = data_blob_talloc(msg, private_data,
554 if (msg->private_data.data == NULL) {
555 DEBUG(0,("push_message: malloc fail (3)\n"));
561 msg->te = event_add_timed(smbd_event_context(),
564 smbd_deferred_open_timer,
567 DEBUG(0,("push_message: event_add_timed failed\n"));
572 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
574 DEBUG(10,("push_message: pushed message length %u on "
575 "deferred_open_queue\n", (unsigned int)msg_len));
580 /****************************************************************************
581 Function to delete a sharing violation open message by mid.
582 ****************************************************************************/
584 void remove_deferred_open_smb_message(uint16 mid)
586 struct pending_message_list *pml;
588 for (pml = deferred_open_queue; pml; pml = pml->next) {
589 if (mid == SVAL(pml->buf.data,smb_mid)) {
590 DEBUG(10,("remove_deferred_open_smb_message: "
591 "deleting mid %u len %u\n",
593 (unsigned int)pml->buf.length ));
594 DLIST_REMOVE(deferred_open_queue, pml);
601 /****************************************************************************
602 Move a sharing violation open retry message to the front of the list and
603 schedule it for immediate processing.
604 ****************************************************************************/
606 void schedule_deferred_open_smb_message(uint16 mid)
608 struct pending_message_list *pml;
611 for (pml = deferred_open_queue; pml; pml = pml->next) {
612 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
614 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
615 (unsigned int)msg_mid ));
617 if (mid == msg_mid) {
618 struct timed_event *te;
620 if (pml->processed) {
621 /* A processed message should not be
623 DEBUG(0,("schedule_deferred_open_smb_message: LOGIC ERROR "
624 "message mid %u was already processed\n",
629 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
632 te = event_add_timed(smbd_event_context(),
635 smbd_deferred_open_timer,
638 DEBUG(10,("schedule_deferred_open_smb_message: "
639 "event_add_timed() failed, skipping mid %u\n",
643 TALLOC_FREE(pml->te);
645 DLIST_PROMOTE(deferred_open_queue, pml);
650 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
654 /****************************************************************************
655 Return true if this mid is on the deferred queue and was not yet processed.
656 ****************************************************************************/
658 bool open_was_deferred(uint16 mid)
660 struct pending_message_list *pml;
662 for (pml = deferred_open_queue; pml; pml = pml->next) {
663 if (SVAL(pml->buf.data,smb_mid) == mid && !pml->processed) {
670 /****************************************************************************
671 Return the message queued by this mid.
672 ****************************************************************************/
674 struct pending_message_list *get_open_deferred_message(uint16 mid)
676 struct pending_message_list *pml;
678 for (pml = deferred_open_queue; pml; pml = pml->next) {
679 if (SVAL(pml->buf.data,smb_mid) == mid) {
686 /****************************************************************************
687 Function to push a deferred open smb message onto a linked list of local smb
688 messages ready for processing.
689 ****************************************************************************/
691 bool push_deferred_smb_message(struct smb_request *req,
692 struct timeval request_time,
693 struct timeval timeout,
694 char *private_data, size_t priv_len)
696 struct timeval end_time;
698 if (req->unread_bytes) {
699 DEBUG(0,("push_deferred_smb_message: logic error ! "
700 "unread_bytes = %u\n",
701 (unsigned int)req->unread_bytes ));
702 smb_panic("push_deferred_smb_message: "
703 "logic error unread_bytes != 0" );
706 end_time = timeval_sum(&request_time, &timeout);
708 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
709 "timeout time [%u.%06u]\n",
710 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
711 (unsigned int)end_time.tv_sec,
712 (unsigned int)end_time.tv_usec));
714 return push_queued_message(req, request_time, end_time,
715 private_data, priv_len);
719 struct timed_event *te;
720 struct timeval interval;
722 bool (*handler)(const struct timeval *now, void *private_data);
726 static void smbd_idle_event_handler(struct event_context *ctx,
727 struct timed_event *te,
731 struct idle_event *event =
732 talloc_get_type_abort(private_data, struct idle_event);
734 TALLOC_FREE(event->te);
736 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
737 event->name, event->te));
739 if (!event->handler(&now, event->private_data)) {
740 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
741 event->name, event->te));
742 /* Don't repeat, delete ourselves */
747 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
748 event->name, event->te));
750 event->te = event_add_timed(ctx, event,
751 timeval_sum(&now, &event->interval),
752 smbd_idle_event_handler, event);
754 /* We can't do much but fail here. */
755 SMB_ASSERT(event->te != NULL);
758 struct idle_event *event_add_idle(struct event_context *event_ctx,
760 struct timeval interval,
762 bool (*handler)(const struct timeval *now,
766 struct idle_event *result;
767 struct timeval now = timeval_current();
769 result = TALLOC_P(mem_ctx, struct idle_event);
770 if (result == NULL) {
771 DEBUG(0, ("talloc failed\n"));
775 result->interval = interval;
776 result->handler = handler;
777 result->private_data = private_data;
779 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
780 DEBUG(0, ("talloc failed\n"));
785 result->te = event_add_timed(event_ctx, result,
786 timeval_sum(&now, &interval),
787 smbd_idle_event_handler, result);
788 if (result->te == NULL) {
789 DEBUG(0, ("event_add_timed failed\n"));
794 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
798 static void smbd_sig_term_handler(struct tevent_context *ev,
799 struct tevent_signal *se,
805 exit_server_cleanly("termination signal");
808 void smbd_setup_sig_term_handler(void)
810 struct tevent_signal *se;
812 se = tevent_add_signal(smbd_event_context(),
813 smbd_event_context(),
815 smbd_sig_term_handler,
818 exit_server("failed to setup SIGTERM handler");
822 static void smbd_sig_hup_handler(struct tevent_context *ev,
823 struct tevent_signal *se,
829 change_to_root_user();
830 DEBUG(1,("Reloading services after SIGHUP\n"));
831 reload_services(False);
834 void smbd_setup_sig_hup_handler(void)
836 struct tevent_signal *se;
838 se = tevent_add_signal(smbd_event_context(),
839 smbd_event_context(),
841 smbd_sig_hup_handler,
844 exit_server("failed to setup SIGHUP handler");
848 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
855 to.tv_sec = SMBD_SELECT_TIMEOUT;
859 * Setup the select fd sets.
866 * Are there any timed events waiting ? If so, ensure we don't
867 * select for longer than it would take to wait for them.
874 event_add_to_select_args(smbd_event_context(), &now,
875 &r_fds, &w_fds, &to, &maxfd);
878 /* Process a signal and timed events now... */
879 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
880 return NT_STATUS_RETRY;
885 START_PROFILE(smbd_idle);
887 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
890 END_PROFILE(smbd_idle);
894 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
895 return NT_STATUS_RETRY;
900 /* something is wrong. Maybe the socket is dead? */
901 return map_nt_error_from_unix(errno);
904 /* Did we timeout ? */
906 return NT_STATUS_RETRY;
909 /* should not be reached */
910 return NT_STATUS_INTERNAL_ERROR;
914 * Only allow 5 outstanding trans requests. We're allocating memory, so
918 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
921 for (; list != NULL; list = list->next) {
923 if (list->mid == mid) {
924 return NT_STATUS_INVALID_PARAMETER;
930 return NT_STATUS_INSUFFICIENT_RESOURCES;
937 These flags determine some of the permissions required to do an operation
939 Note that I don't set NEED_WRITE on some write operations because they
940 are used by some brain-dead clients when printing, and I don't want to
941 force write permissions on print services.
943 #define AS_USER (1<<0)
944 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
945 #define TIME_INIT (1<<2)
946 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
947 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
948 #define DO_CHDIR (1<<6)
951 define a list of possible SMB messages and their corresponding
952 functions. Any message that has a NULL function is unimplemented -
953 please feel free to contribute implementations!
955 static const struct smb_message_struct {
957 void (*fn)(struct smb_request *req);
959 } smb_messages[256] = {
961 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
962 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
963 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
964 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
965 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
966 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
967 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
968 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
969 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
970 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
971 /* 0x0a */ { "SMBread",reply_read,AS_USER},
972 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
973 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
974 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
975 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
976 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
977 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
978 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
979 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
980 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
981 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
982 /* 0x15 */ { NULL, NULL, 0 },
983 /* 0x16 */ { NULL, NULL, 0 },
984 /* 0x17 */ { NULL, NULL, 0 },
985 /* 0x18 */ { NULL, NULL, 0 },
986 /* 0x19 */ { NULL, NULL, 0 },
987 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
988 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
989 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
990 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
991 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
992 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
993 /* 0x20 */ { "SMBwritec", NULL,0},
994 /* 0x21 */ { NULL, NULL, 0 },
995 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
996 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
997 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
998 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
999 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1000 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1001 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1002 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1003 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1004 /* 0x2b */ { "SMBecho",reply_echo,0},
1005 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1006 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1007 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1008 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1009 /* 0x30 */ { NULL, NULL, 0 },
1010 /* 0x31 */ { NULL, NULL, 0 },
1011 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1012 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1013 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1014 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1015 /* 0x36 */ { NULL, NULL, 0 },
1016 /* 0x37 */ { NULL, NULL, 0 },
1017 /* 0x38 */ { NULL, NULL, 0 },
1018 /* 0x39 */ { NULL, NULL, 0 },
1019 /* 0x3a */ { NULL, NULL, 0 },
1020 /* 0x3b */ { NULL, NULL, 0 },
1021 /* 0x3c */ { NULL, NULL, 0 },
1022 /* 0x3d */ { NULL, NULL, 0 },
1023 /* 0x3e */ { NULL, NULL, 0 },
1024 /* 0x3f */ { NULL, NULL, 0 },
1025 /* 0x40 */ { NULL, NULL, 0 },
1026 /* 0x41 */ { NULL, NULL, 0 },
1027 /* 0x42 */ { NULL, NULL, 0 },
1028 /* 0x43 */ { NULL, NULL, 0 },
1029 /* 0x44 */ { NULL, NULL, 0 },
1030 /* 0x45 */ { NULL, NULL, 0 },
1031 /* 0x46 */ { NULL, NULL, 0 },
1032 /* 0x47 */ { NULL, NULL, 0 },
1033 /* 0x48 */ { NULL, NULL, 0 },
1034 /* 0x49 */ { NULL, NULL, 0 },
1035 /* 0x4a */ { NULL, NULL, 0 },
1036 /* 0x4b */ { NULL, NULL, 0 },
1037 /* 0x4c */ { NULL, NULL, 0 },
1038 /* 0x4d */ { NULL, NULL, 0 },
1039 /* 0x4e */ { NULL, NULL, 0 },
1040 /* 0x4f */ { NULL, NULL, 0 },
1041 /* 0x50 */ { NULL, NULL, 0 },
1042 /* 0x51 */ { NULL, NULL, 0 },
1043 /* 0x52 */ { NULL, NULL, 0 },
1044 /* 0x53 */ { NULL, NULL, 0 },
1045 /* 0x54 */ { NULL, NULL, 0 },
1046 /* 0x55 */ { NULL, NULL, 0 },
1047 /* 0x56 */ { NULL, NULL, 0 },
1048 /* 0x57 */ { NULL, NULL, 0 },
1049 /* 0x58 */ { NULL, NULL, 0 },
1050 /* 0x59 */ { NULL, NULL, 0 },
1051 /* 0x5a */ { NULL, NULL, 0 },
1052 /* 0x5b */ { NULL, NULL, 0 },
1053 /* 0x5c */ { NULL, NULL, 0 },
1054 /* 0x5d */ { NULL, NULL, 0 },
1055 /* 0x5e */ { NULL, NULL, 0 },
1056 /* 0x5f */ { NULL, NULL, 0 },
1057 /* 0x60 */ { NULL, NULL, 0 },
1058 /* 0x61 */ { NULL, NULL, 0 },
1059 /* 0x62 */ { NULL, NULL, 0 },
1060 /* 0x63 */ { NULL, NULL, 0 },
1061 /* 0x64 */ { NULL, NULL, 0 },
1062 /* 0x65 */ { NULL, NULL, 0 },
1063 /* 0x66 */ { NULL, NULL, 0 },
1064 /* 0x67 */ { NULL, NULL, 0 },
1065 /* 0x68 */ { NULL, NULL, 0 },
1066 /* 0x69 */ { NULL, NULL, 0 },
1067 /* 0x6a */ { NULL, NULL, 0 },
1068 /* 0x6b */ { NULL, NULL, 0 },
1069 /* 0x6c */ { NULL, NULL, 0 },
1070 /* 0x6d */ { NULL, NULL, 0 },
1071 /* 0x6e */ { NULL, NULL, 0 },
1072 /* 0x6f */ { NULL, NULL, 0 },
1073 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1074 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1075 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1076 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1077 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1078 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1079 /* 0x76 */ { NULL, NULL, 0 },
1080 /* 0x77 */ { NULL, NULL, 0 },
1081 /* 0x78 */ { NULL, NULL, 0 },
1082 /* 0x79 */ { NULL, NULL, 0 },
1083 /* 0x7a */ { NULL, NULL, 0 },
1084 /* 0x7b */ { NULL, NULL, 0 },
1085 /* 0x7c */ { NULL, NULL, 0 },
1086 /* 0x7d */ { NULL, NULL, 0 },
1087 /* 0x7e */ { NULL, NULL, 0 },
1088 /* 0x7f */ { NULL, NULL, 0 },
1089 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1090 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1091 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1092 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1093 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1094 /* 0x85 */ { NULL, NULL, 0 },
1095 /* 0x86 */ { NULL, NULL, 0 },
1096 /* 0x87 */ { NULL, NULL, 0 },
1097 /* 0x88 */ { NULL, NULL, 0 },
1098 /* 0x89 */ { NULL, NULL, 0 },
1099 /* 0x8a */ { NULL, NULL, 0 },
1100 /* 0x8b */ { NULL, NULL, 0 },
1101 /* 0x8c */ { NULL, NULL, 0 },
1102 /* 0x8d */ { NULL, NULL, 0 },
1103 /* 0x8e */ { NULL, NULL, 0 },
1104 /* 0x8f */ { NULL, NULL, 0 },
1105 /* 0x90 */ { NULL, NULL, 0 },
1106 /* 0x91 */ { NULL, NULL, 0 },
1107 /* 0x92 */ { NULL, NULL, 0 },
1108 /* 0x93 */ { NULL, NULL, 0 },
1109 /* 0x94 */ { NULL, NULL, 0 },
1110 /* 0x95 */ { NULL, NULL, 0 },
1111 /* 0x96 */ { NULL, NULL, 0 },
1112 /* 0x97 */ { NULL, NULL, 0 },
1113 /* 0x98 */ { NULL, NULL, 0 },
1114 /* 0x99 */ { NULL, NULL, 0 },
1115 /* 0x9a */ { NULL, NULL, 0 },
1116 /* 0x9b */ { NULL, NULL, 0 },
1117 /* 0x9c */ { NULL, NULL, 0 },
1118 /* 0x9d */ { NULL, NULL, 0 },
1119 /* 0x9e */ { NULL, NULL, 0 },
1120 /* 0x9f */ { NULL, NULL, 0 },
1121 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1122 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1123 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1124 /* 0xa3 */ { NULL, NULL, 0 },
1125 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1126 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1127 /* 0xa6 */ { NULL, NULL, 0 },
1128 /* 0xa7 */ { NULL, NULL, 0 },
1129 /* 0xa8 */ { NULL, NULL, 0 },
1130 /* 0xa9 */ { NULL, NULL, 0 },
1131 /* 0xaa */ { NULL, NULL, 0 },
1132 /* 0xab */ { NULL, NULL, 0 },
1133 /* 0xac */ { NULL, NULL, 0 },
1134 /* 0xad */ { NULL, NULL, 0 },
1135 /* 0xae */ { NULL, NULL, 0 },
1136 /* 0xaf */ { NULL, NULL, 0 },
1137 /* 0xb0 */ { NULL, NULL, 0 },
1138 /* 0xb1 */ { NULL, NULL, 0 },
1139 /* 0xb2 */ { NULL, NULL, 0 },
1140 /* 0xb3 */ { NULL, NULL, 0 },
1141 /* 0xb4 */ { NULL, NULL, 0 },
1142 /* 0xb5 */ { NULL, NULL, 0 },
1143 /* 0xb6 */ { NULL, NULL, 0 },
1144 /* 0xb7 */ { NULL, NULL, 0 },
1145 /* 0xb8 */ { NULL, NULL, 0 },
1146 /* 0xb9 */ { NULL, NULL, 0 },
1147 /* 0xba */ { NULL, NULL, 0 },
1148 /* 0xbb */ { NULL, NULL, 0 },
1149 /* 0xbc */ { NULL, NULL, 0 },
1150 /* 0xbd */ { NULL, NULL, 0 },
1151 /* 0xbe */ { NULL, NULL, 0 },
1152 /* 0xbf */ { NULL, NULL, 0 },
1153 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1154 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1155 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1156 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1157 /* 0xc4 */ { NULL, NULL, 0 },
1158 /* 0xc5 */ { NULL, NULL, 0 },
1159 /* 0xc6 */ { NULL, NULL, 0 },
1160 /* 0xc7 */ { NULL, NULL, 0 },
1161 /* 0xc8 */ { NULL, NULL, 0 },
1162 /* 0xc9 */ { NULL, NULL, 0 },
1163 /* 0xca */ { NULL, NULL, 0 },
1164 /* 0xcb */ { NULL, NULL, 0 },
1165 /* 0xcc */ { NULL, NULL, 0 },
1166 /* 0xcd */ { NULL, NULL, 0 },
1167 /* 0xce */ { NULL, NULL, 0 },
1168 /* 0xcf */ { NULL, NULL, 0 },
1169 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1170 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1171 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1172 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1173 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1174 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1175 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1176 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1177 /* 0xd8 */ { NULL, NULL, 0 },
1178 /* 0xd9 */ { NULL, NULL, 0 },
1179 /* 0xda */ { NULL, NULL, 0 },
1180 /* 0xdb */ { NULL, NULL, 0 },
1181 /* 0xdc */ { NULL, NULL, 0 },
1182 /* 0xdd */ { NULL, NULL, 0 },
1183 /* 0xde */ { NULL, NULL, 0 },
1184 /* 0xdf */ { NULL, NULL, 0 },
1185 /* 0xe0 */ { NULL, NULL, 0 },
1186 /* 0xe1 */ { NULL, NULL, 0 },
1187 /* 0xe2 */ { NULL, NULL, 0 },
1188 /* 0xe3 */ { NULL, NULL, 0 },
1189 /* 0xe4 */ { NULL, NULL, 0 },
1190 /* 0xe5 */ { NULL, NULL, 0 },
1191 /* 0xe6 */ { NULL, NULL, 0 },
1192 /* 0xe7 */ { NULL, NULL, 0 },
1193 /* 0xe8 */ { NULL, NULL, 0 },
1194 /* 0xe9 */ { NULL, NULL, 0 },
1195 /* 0xea */ { NULL, NULL, 0 },
1196 /* 0xeb */ { NULL, NULL, 0 },
1197 /* 0xec */ { NULL, NULL, 0 },
1198 /* 0xed */ { NULL, NULL, 0 },
1199 /* 0xee */ { NULL, NULL, 0 },
1200 /* 0xef */ { NULL, NULL, 0 },
1201 /* 0xf0 */ { NULL, NULL, 0 },
1202 /* 0xf1 */ { NULL, NULL, 0 },
1203 /* 0xf2 */ { NULL, NULL, 0 },
1204 /* 0xf3 */ { NULL, NULL, 0 },
1205 /* 0xf4 */ { NULL, NULL, 0 },
1206 /* 0xf5 */ { NULL, NULL, 0 },
1207 /* 0xf6 */ { NULL, NULL, 0 },
1208 /* 0xf7 */ { NULL, NULL, 0 },
1209 /* 0xf8 */ { NULL, NULL, 0 },
1210 /* 0xf9 */ { NULL, NULL, 0 },
1211 /* 0xfa */ { NULL, NULL, 0 },
1212 /* 0xfb */ { NULL, NULL, 0 },
1213 /* 0xfc */ { NULL, NULL, 0 },
1214 /* 0xfd */ { NULL, NULL, 0 },
1215 /* 0xfe */ { NULL, NULL, 0 },
1216 /* 0xff */ { NULL, NULL, 0 }
1220 /*******************************************************************
1221 allocate and initialize a reply packet
1222 ********************************************************************/
1224 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1225 const char *inbuf, char **outbuf, uint8_t num_words,
1229 * Protect against integer wrap
1231 if ((num_bytes > 0xffffff)
1232 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1234 if (asprintf(&msg, "num_bytes too large: %u",
1235 (unsigned)num_bytes) == -1) {
1236 msg = CONST_DISCARD(char *, "num_bytes too large");
1241 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1242 smb_size + num_words*2 + num_bytes);
1243 if (*outbuf == NULL) {
1247 construct_reply_common(req, inbuf, *outbuf);
1248 srv_set_message(*outbuf, num_words, num_bytes, false);
1250 * Zero out the word area, the caller has to take care of the bcc area
1253 if (num_words != 0) {
1254 memset(*outbuf + smb_vwv0, 0, num_words*2);
1260 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1263 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1265 smb_panic("could not allocate output buffer\n");
1267 req->outbuf = (uint8_t *)outbuf;
1271 /*******************************************************************
1272 Dump a packet to a file.
1273 ********************************************************************/
1275 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1279 if (DEBUGLEVEL < 50) {
1283 if (len < 4) len = smb_len(data)+4;
1284 for (i=1;i<100;i++) {
1285 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1286 type ? "req" : "resp") == -1) {
1289 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1290 if (fd != -1 || errno != EEXIST) break;
1293 ssize_t ret = write(fd, data, len);
1295 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1297 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1302 /****************************************************************************
1303 Prepare everything for calling the actual request function, and potentially
1304 call the request function via the "new" interface.
1306 Return False if the "legacy" function needs to be called, everything is
1309 Return True if we're done.
1311 I know this API sucks, but it is the one with the least code change I could
1313 ****************************************************************************/
1315 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1319 connection_struct *conn = NULL;
1320 struct smbd_server_connection *sconn = smbd_server_conn;
1324 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1325 * so subtract 4 from it. */
1326 if (!valid_smb_header(req->inbuf)
1327 || (size < (smb_size - 4))) {
1328 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1329 smb_len(req->inbuf)));
1330 exit_server_cleanly("Non-SMB packet");
1333 if (smb_messages[type].fn == NULL) {
1334 DEBUG(0,("Unknown message type %d!\n",type));
1335 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1336 reply_unknown_new(req, type);
1340 flags = smb_messages[type].flags;
1342 /* In share mode security we must ignore the vuid. */
1343 session_tag = (lp_security() == SEC_SHARE)
1344 ? UID_FIELD_INVALID : req->vuid;
1347 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1348 (int)sys_getpid(), (unsigned long)conn));
1350 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1352 /* Ensure this value is replaced in the incoming packet. */
1353 SSVAL(req->inbuf,smb_uid,session_tag);
1356 * Ensure the correct username is in current_user_info. This is a
1357 * really ugly bugfix for problems with multiple session_setup_and_X's
1358 * being done and allowing %U and %G substitutions to work correctly.
1359 * There is a reason this code is done here, don't move it unless you
1360 * know what you're doing... :-).
1364 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1365 user_struct *vuser = NULL;
1367 sconn->smb1.sessions.last_session_tag = session_tag;
1368 if(session_tag != UID_FIELD_INVALID) {
1369 vuser = get_valid_user_struct(sconn, session_tag);
1371 set_current_user_info(
1372 vuser->server_info->sanitized_username,
1373 vuser->server_info->unix_name,
1374 pdb_get_domain(vuser->server_info
1380 /* Does this call need to be run as the connected user? */
1381 if (flags & AS_USER) {
1383 /* Does this call need a valid tree connection? */
1386 * Amazingly, the error code depends on the command
1389 if (type == SMBntcreateX) {
1390 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1392 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1397 if (!change_to_user(conn,session_tag)) {
1398 DEBUG(0, ("Error: Could not change to user. Removing "
1399 "deferred open, mid=%d.\n", req->mid));
1400 reply_force_doserror(req, ERRSRV, ERRbaduid);
1404 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1406 /* Does it need write permission? */
1407 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1408 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1412 /* IPC services are limited */
1413 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1414 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1418 /* This call needs to be run as root */
1419 change_to_root_user();
1422 /* load service specific parameters */
1424 if (req->encrypted) {
1425 conn->encrypted_tid = true;
1426 /* encrypted required from now on. */
1427 conn->encrypt_level = Required;
1428 } else if (ENCRYPTION_REQUIRED(conn)) {
1429 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1430 exit_server_cleanly("encryption required "
1436 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1437 (flags & (AS_USER|DO_CHDIR)
1439 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1442 conn->num_smb_operations++;
1445 /* does this protocol need to be run as guest? */
1446 if ((flags & AS_GUEST)
1447 && (!change_to_guest() ||
1448 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1449 lp_hostsdeny(-1)))) {
1450 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1454 smb_messages[type].fn(req);
1458 /****************************************************************************
1459 Construct a reply to the incoming packet.
1460 ****************************************************************************/
1462 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1463 uint32_t seqnum, bool encrypted,
1464 struct smb_perfcount_data *deferred_pcd)
1466 connection_struct *conn;
1467 struct smb_request *req;
1469 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1470 smb_panic("could not allocate smb_request");
1473 if (!init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted,
1475 exit_server_cleanly("Invalid SMB request");
1478 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1480 /* we popped this message off the queue - keep original perf data */
1482 req->pcd = *deferred_pcd;
1484 SMB_PERFCOUNT_START(&req->pcd);
1485 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1486 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1489 conn = switch_message(req->cmd, req, size);
1491 if (req->unread_bytes) {
1492 /* writeX failed. drain socket. */
1493 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1494 req->unread_bytes) {
1495 smb_panic("failed to drain pending bytes");
1497 req->unread_bytes = 0;
1505 if (req->outbuf == NULL) {
1509 if (CVAL(req->outbuf,0) == 0) {
1510 show_msg((char *)req->outbuf);
1513 if (!srv_send_smb(smbd_server_fd(),
1514 (char *)req->outbuf,
1515 true, req->seqnum+1,
1516 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1518 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1526 /****************************************************************************
1527 Process an smb from the client
1528 ****************************************************************************/
1529 static void process_smb(struct smbd_server_connection *conn,
1530 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1531 uint32_t seqnum, bool encrypted,
1532 struct smb_perfcount_data *deferred_pcd)
1534 int msg_type = CVAL(inbuf,0);
1536 DO_PROFILE_INC(smb_count);
1538 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1540 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1542 (unsigned int)unread_bytes ));
1544 if (msg_type != 0) {
1546 * NetBIOS session request, keepalive, etc.
1548 reply_special((char *)inbuf);
1552 if (smbd_server_conn->allow_smb2) {
1553 if (smbd_is_smb2_header(inbuf, nread)) {
1554 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1557 smbd_server_conn->allow_smb2 = false;
1560 show_msg((char *)inbuf);
1562 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1566 conn->smb1.num_requests++;
1568 /* The timeout_processing function isn't run nearly
1569 often enough to implement 'max log size' without
1570 overrunning the size of the file by many megabytes.
1571 This is especially true if we are running at debug
1572 level 10. Checking every 50 SMBs is a nice
1573 tradeoff of performance vs log file size overrun. */
1575 if ((conn->smb1.num_requests % 50) == 0 &&
1576 need_to_check_log_size()) {
1577 change_to_root_user();
1582 /****************************************************************************
1583 Return a string containing the function name of a SMB command.
1584 ****************************************************************************/
1586 const char *smb_fn_name(int type)
1588 const char *unknown_name = "SMBunknown";
1590 if (smb_messages[type].name == NULL)
1591 return(unknown_name);
1593 return(smb_messages[type].name);
1596 /****************************************************************************
1597 Helper functions for contruct_reply.
1598 ****************************************************************************/
1600 void add_to_common_flags2(uint32 v)
1605 void remove_from_common_flags2(uint32 v)
1607 common_flags2 &= ~v;
1610 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1613 srv_set_message(outbuf,0,0,false);
1615 SCVAL(outbuf, smb_com, req->cmd);
1616 SIVAL(outbuf,smb_rcls,0);
1617 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1618 SSVAL(outbuf,smb_flg2,
1619 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1621 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1623 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1624 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1625 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1626 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1629 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1631 construct_reply_common(req, (char *)req->inbuf, outbuf);
1635 * How many bytes have we already accumulated up to the current wct field
1639 size_t req_wct_ofs(struct smb_request *req)
1643 if (req->chain_outbuf == NULL) {
1646 buf_size = talloc_get_size(req->chain_outbuf);
1647 if ((buf_size % 4) != 0) {
1648 buf_size += (4 - (buf_size % 4));
1650 return buf_size - 4;
1654 * Hack around reply_nterror & friends not being aware of chained requests,
1655 * generating illegal (i.e. wct==0) chain replies.
1658 static void fixup_chain_error_packet(struct smb_request *req)
1660 uint8_t *outbuf = req->outbuf;
1662 reply_outbuf(req, 2, 0);
1663 memcpy(req->outbuf, outbuf, smb_wct);
1664 TALLOC_FREE(outbuf);
1665 SCVAL(req->outbuf, smb_vwv0, 0xff);
1669 * @brief Find the smb_cmd offset of the last command pushed
1670 * @param[in] buf The buffer we're building up
1671 * @retval Where can we put our next andx cmd?
1673 * While chaining requests, the "next" request we're looking at needs to put
1674 * its SMB_Command before the data the previous request already built up added
1675 * to the chain. Find the offset to the place where we have to put our cmd.
1678 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1683 cmd = CVAL(buf, smb_com);
1685 SMB_ASSERT(is_andx_req(cmd));
1689 while (CVAL(buf, ofs) != 0xff) {
1691 if (!is_andx_req(CVAL(buf, ofs))) {
1696 * ofs is from start of smb header, so add the 4 length
1697 * bytes. The next cmd is right after the wct field.
1699 ofs = SVAL(buf, ofs+2) + 4 + 1;
1701 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1709 * @brief Do the smb chaining at a buffer level
1710 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1711 * @param[in] smb_command The command that we want to issue
1712 * @param[in] wct How many words?
1713 * @param[in] vwv The words, already in network order
1714 * @param[in] bytes_alignment How shall we align "bytes"?
1715 * @param[in] num_bytes How many bytes?
1716 * @param[in] bytes The data the request ships
1718 * smb_splice_chain() adds the vwv and bytes to the request already present in
1722 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1723 uint8_t wct, const uint16_t *vwv,
1724 size_t bytes_alignment,
1725 uint32_t num_bytes, const uint8_t *bytes)
1728 size_t old_size, new_size;
1730 size_t chain_padding = 0;
1731 size_t bytes_padding = 0;
1734 old_size = talloc_get_size(*poutbuf);
1737 * old_size == smb_wct means we're pushing the first request in for
1741 first_request = (old_size == smb_wct);
1743 if (!first_request && ((old_size % 4) != 0)) {
1745 * Align the wct field of subsequent requests to a 4-byte
1748 chain_padding = 4 - (old_size % 4);
1752 * After the old request comes the new wct field (1 byte), the vwv's
1753 * and the num_bytes field. After at we might need to align the bytes
1754 * given to us to "bytes_alignment", increasing the num_bytes value.
1757 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1759 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1760 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1763 new_size += bytes_padding + num_bytes;
1765 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1766 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1767 (unsigned)new_size));
1771 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1772 if (outbuf == NULL) {
1773 DEBUG(0, ("talloc failed\n"));
1778 if (first_request) {
1779 SCVAL(outbuf, smb_com, smb_command);
1781 size_t andx_cmd_ofs;
1783 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1784 DEBUG(1, ("invalid command chain\n"));
1785 *poutbuf = TALLOC_REALLOC_ARRAY(
1786 NULL, *poutbuf, uint8_t, old_size);
1790 if (chain_padding != 0) {
1791 memset(outbuf + old_size, 0, chain_padding);
1792 old_size += chain_padding;
1795 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1796 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1802 * Push the chained request:
1807 SCVAL(outbuf, ofs, wct);
1814 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1815 ofs += sizeof(uint16_t) * wct;
1821 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1822 ofs += sizeof(uint16_t);
1828 if (bytes_padding != 0) {
1829 memset(outbuf + ofs, 0, bytes_padding);
1830 ofs += bytes_padding;
1837 memcpy(outbuf + ofs, bytes, num_bytes);
1842 /****************************************************************************
1843 Construct a chained reply and add it to the already made reply
1844 ****************************************************************************/
1846 void chain_reply(struct smb_request *req)
1848 size_t smblen = smb_len(req->inbuf);
1849 size_t already_used, length_needed;
1851 uint32_t chain_offset; /* uint32_t to avoid overflow */
1858 if (IVAL(req->outbuf, smb_rcls) != 0) {
1859 fixup_chain_error_packet(req);
1863 * Any of the AndX requests and replies have at least a wct of
1864 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1865 * beginning of the SMB header to the next wct field.
1867 * None of the AndX requests put anything valuable in vwv[0] and [1],
1868 * so we can overwrite it here to form the chain.
1871 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1872 if (req->chain_outbuf == NULL) {
1873 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1874 req, req->outbuf, uint8_t,
1875 smb_len(req->outbuf) + 4);
1876 if (req->chain_outbuf == NULL) {
1877 smb_panic("talloc failed");
1885 * Here we assume that this is the end of the chain. For that we need
1886 * to set "next command" to 0xff and the offset to 0. If we later find
1887 * more commands in the chain, this will be overwritten again.
1890 SCVAL(req->outbuf, smb_vwv0, 0xff);
1891 SCVAL(req->outbuf, smb_vwv0+1, 0);
1892 SSVAL(req->outbuf, smb_vwv1, 0);
1894 if (req->chain_outbuf == NULL) {
1896 * In req->chain_outbuf we collect all the replies. Start the
1897 * chain by copying in the first reply.
1899 * We do the realloc because later on we depend on
1900 * talloc_get_size to determine the length of
1901 * chain_outbuf. The reply_xxx routines might have
1902 * over-allocated (reply_pipe_read_and_X used to be such an
1905 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1906 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1907 if (req->chain_outbuf == NULL) {
1908 smb_panic("talloc failed");
1913 * Update smb headers where subsequent chained commands
1914 * may have updated them.
1916 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1917 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1919 if (!smb_splice_chain(&req->chain_outbuf,
1920 CVAL(req->outbuf, smb_com),
1921 CVAL(req->outbuf, smb_wct),
1922 (uint16_t *)(req->outbuf + smb_vwv),
1923 0, smb_buflen(req->outbuf),
1924 (uint8_t *)smb_buf(req->outbuf))) {
1927 TALLOC_FREE(req->outbuf);
1931 * We use the old request's vwv field to grab the next chained command
1932 * and offset into the chained fields.
1935 chain_cmd = CVAL(req->vwv+0, 0);
1936 chain_offset = SVAL(req->vwv+1, 0);
1938 if (chain_cmd == 0xff) {
1940 * End of chain, no more requests from the client. So ship the
1943 smb_setlen((char *)(req->chain_outbuf),
1944 talloc_get_size(req->chain_outbuf) - 4);
1946 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1947 true, req->seqnum+1,
1948 IS_CONN_ENCRYPTED(req->conn)
1951 exit_server_cleanly("chain_reply: srv_send_smb "
1954 TALLOC_FREE(req->chain_outbuf);
1959 /* add a new perfcounter for this element of chain */
1960 SMB_PERFCOUNT_ADD(&req->pcd);
1961 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1962 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1965 * Check if the client tries to fool us. The request so far uses the
1966 * space to the end of the byte buffer in the request just
1967 * processed. The chain_offset can't point into that area. If that was
1968 * the case, we could end up with an endless processing of the chain,
1969 * we would always handle the same request.
1972 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1973 if (chain_offset < already_used) {
1978 * Next check: Make sure the chain offset does not point beyond the
1979 * overall smb request length.
1982 length_needed = chain_offset+1; /* wct */
1983 if (length_needed > smblen) {
1988 * Now comes the pointer magic. Goal here is to set up req->vwv and
1989 * req->buf correctly again to be able to call the subsequent
1990 * switch_message(). The chain offset (the former vwv[1]) points at
1991 * the new wct field.
1994 wct = CVAL(smb_base(req->inbuf), chain_offset);
1997 * Next consistency check: Make the new vwv array fits in the overall
2001 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2002 if (length_needed > smblen) {
2005 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2008 * Now grab the new byte buffer....
2011 buflen = SVAL(vwv+wct, 0);
2014 * .. and check that it fits.
2017 length_needed += buflen;
2018 if (length_needed > smblen) {
2021 buf = (uint8_t *)(vwv+wct+1);
2023 req->cmd = chain_cmd;
2026 req->buflen = buflen;
2029 switch_message(chain_cmd, req, smblen);
2031 if (req->outbuf == NULL) {
2033 * This happens if the chained command has suspended itself or
2034 * if it has called srv_send_smb() itself.
2040 * We end up here if the chained command was not itself chained or
2041 * suspended, but for example a close() command. We now need to splice
2042 * the chained commands' outbuf into the already built up chain_outbuf
2043 * and ship the result.
2049 * We end up here if there's any error in the chain syntax. Report a
2050 * DOS error, just like Windows does.
2052 reply_force_doserror(req, ERRSRV, ERRerror);
2053 fixup_chain_error_packet(req);
2057 * This scary statement intends to set the
2058 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2059 * to the value req->outbuf carries
2061 SSVAL(req->chain_outbuf, smb_flg2,
2062 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2063 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2066 * Transfer the error codes from the subrequest to the main one
2068 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2069 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2071 if (!smb_splice_chain(&req->chain_outbuf,
2072 CVAL(req->outbuf, smb_com),
2073 CVAL(req->outbuf, smb_wct),
2074 (uint16_t *)(req->outbuf + smb_vwv),
2075 0, smb_buflen(req->outbuf),
2076 (uint8_t *)smb_buf(req->outbuf))) {
2077 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2079 TALLOC_FREE(req->outbuf);
2081 smb_setlen((char *)(req->chain_outbuf),
2082 talloc_get_size(req->chain_outbuf) - 4);
2084 show_msg((char *)(req->chain_outbuf));
2086 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2087 true, req->seqnum+1,
2088 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2090 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2092 TALLOC_FREE(req->chain_outbuf);
2096 /****************************************************************************
2097 Check if services need reloading.
2098 ****************************************************************************/
2100 void check_reload(time_t t)
2102 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2104 if(last_smb_conf_reload_time == 0) {
2105 last_smb_conf_reload_time = t;
2106 /* Our printing subsystem might not be ready at smbd start up.
2107 Then no printer is available till the first printers check
2108 is performed. A lower initial interval circumvents this. */
2109 if ( printcap_cache_time > 60 )
2110 last_printer_reload_time = t - printcap_cache_time + 60;
2112 last_printer_reload_time = t;
2115 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2116 /* randomize over 60 second the printcap reload to avoid all
2117 * process hitting cupsd at the same time */
2118 int time_range = 60;
2120 last_printer_reload_time += random() % time_range;
2124 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2125 reload_services(True);
2126 last_smb_conf_reload_time = t;
2129 /* 'printcap cache time = 0' disable the feature */
2131 if ( printcap_cache_time != 0 )
2133 /* see if it's time to reload or if the clock has been set back */
2135 if ( (t >= last_printer_reload_time+printcap_cache_time)
2136 || (t-last_printer_reload_time < 0) )
2138 DEBUG( 3,( "Printcap cache time expired.\n"));
2140 last_printer_reload_time = t;
2145 static bool fd_is_readable(int fd)
2148 struct timeval timeout = {0, };
2154 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2158 return FD_ISSET(fd, &fds);
2161 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2163 /* TODO: make write nonblocking */
2166 static void smbd_server_connection_read_handler(
2167 struct smbd_server_connection *conn, int fd)
2169 uint8_t *inbuf = NULL;
2170 size_t inbuf_len = 0;
2171 size_t unread_bytes = 0;
2172 bool encrypted = false;
2173 TALLOC_CTX *mem_ctx = talloc_tos();
2179 bool from_client = (smbd_server_fd() == fd)?true:false;
2182 ok = smbd_lock_socket(conn);
2184 exit_server_cleanly("failed to lock socket");
2187 if (!fd_is_readable(smbd_server_fd())) {
2188 DEBUG(10,("the echo listener was faster\n"));
2189 ok = smbd_unlock_socket(conn);
2191 exit_server_cleanly("failed to unlock");
2196 /* TODO: make this completely nonblocking */
2197 status = receive_smb_talloc(mem_ctx, fd,
2198 (char **)(void *)&inbuf,
2202 &inbuf_len, &seqnum,
2203 false /* trusted channel */);
2204 ok = smbd_unlock_socket(conn);
2206 exit_server_cleanly("failed to unlock");
2209 /* TODO: make this completely nonblocking */
2210 status = receive_smb_talloc(mem_ctx, fd,
2211 (char **)(void *)&inbuf,
2215 &inbuf_len, &seqnum,
2216 true /* trusted channel */);
2219 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2222 if (NT_STATUS_IS_ERR(status)) {
2223 exit_server_cleanly("failed to receive smb request");
2225 if (!NT_STATUS_IS_OK(status)) {
2230 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2231 seqnum, encrypted, NULL);
2234 static void smbd_server_connection_handler(struct event_context *ev,
2235 struct fd_event *fde,
2239 struct smbd_server_connection *conn = talloc_get_type(private_data,
2240 struct smbd_server_connection);
2242 if (flags & EVENT_FD_WRITE) {
2243 smbd_server_connection_write_handler(conn);
2244 } else if (flags & EVENT_FD_READ) {
2245 smbd_server_connection_read_handler(conn, smbd_server_fd());
2249 static void smbd_server_echo_handler(struct event_context *ev,
2250 struct fd_event *fde,
2254 struct smbd_server_connection *conn = talloc_get_type(private_data,
2255 struct smbd_server_connection);
2257 if (flags & EVENT_FD_WRITE) {
2258 smbd_server_connection_write_handler(conn);
2259 } else if (flags & EVENT_FD_READ) {
2260 smbd_server_connection_read_handler(
2261 conn, conn->smb1.echo_handler.trusted_fd);
2265 /****************************************************************************
2266 received when we should release a specific IP
2267 ****************************************************************************/
2268 static void release_ip(const char *ip, void *priv)
2270 char addr[INET6_ADDRSTRLEN];
2273 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2275 if (strncmp("::ffff:", addr, 7) == 0) {
2279 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2280 /* we can't afford to do a clean exit - that involves
2281 database writes, which would potentially mean we
2282 are still running after the failover has finished -
2283 we have to get rid of this process ID straight
2285 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2287 /* note we must exit with non-zero status so the unclean handler gets
2288 called in the parent, so that the brl database is tickled */
2293 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2294 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2296 release_ip((char *)data->data, NULL);
2299 #ifdef CLUSTER_SUPPORT
2300 static int client_get_tcp_info(struct sockaddr_storage *server,
2301 struct sockaddr_storage *client)
2304 if (server_fd == -1) {
2307 length = sizeof(*server);
2308 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2311 length = sizeof(*client);
2312 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2320 * Send keepalive packets to our client
2322 static bool keepalive_fn(const struct timeval *now, void *private_data)
2327 ok = smbd_lock_socket(smbd_server_conn);
2329 exit_server_cleanly("failed to lock socket");
2332 ret = send_keepalive(smbd_server_fd());
2334 ok = smbd_unlock_socket(smbd_server_conn);
2336 exit_server_cleanly("failed to unlock socket");
2340 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2347 * Do the recurring check if we're idle
2349 static bool deadtime_fn(const struct timeval *now, void *private_data)
2351 struct smbd_server_connection *sconn = smbd_server_conn;
2353 if (sconn->allow_smb2) {
2354 /* TODO: implement real idle check */
2355 if (sconn->smb2.sessions.list) {
2358 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2359 messaging_send(smbd_messaging_context(), procid_self(),
2360 MSG_SHUTDOWN, &data_blob_null);
2364 if ((conn_num_open(sconn) == 0)
2365 || (conn_idle_all(sconn, now->tv_sec))) {
2366 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2367 messaging_send(smbd_messaging_context(), procid_self(),
2368 MSG_SHUTDOWN, &data_blob_null);
2376 * Do the recurring log file and smb.conf reload checks.
2379 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2381 change_to_root_user();
2383 /* update printer queue caches if necessary */
2384 update_monitored_printq_cache();
2386 /* check if we need to reload services */
2387 check_reload(time(NULL));
2389 /* Change machine password if neccessary. */
2390 attempt_machine_password_change();
2393 * Force a log file check.
2395 force_check_log_size();
2400 static int create_unlink_tmp(const char *dir)
2405 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2406 if (fname == NULL) {
2410 fd = mkstemp(fname);
2415 if (unlink(fname) == -1) {
2416 int sys_errno = errno;
2426 struct smbd_echo_state {
2427 struct tevent_context *ev;
2428 struct iovec *pending;
2429 struct smbd_server_connection *sconn;
2432 struct tevent_fd *parent_fde;
2434 struct tevent_fd *read_fde;
2435 struct tevent_req *write_req;
2438 static void smbd_echo_writer_done(struct tevent_req *req);
2440 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2444 if (state->write_req != NULL) {
2448 num_pending = talloc_array_length(state->pending);
2449 if (num_pending == 0) {
2453 state->write_req = writev_send(state, state->ev, NULL,
2454 state->parent_pipe, false,
2455 state->pending, num_pending);
2456 if (state->write_req == NULL) {
2457 DEBUG(1, ("writev_send failed\n"));
2461 talloc_steal(state->write_req, state->pending);
2462 state->pending = NULL;
2464 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2468 static void smbd_echo_writer_done(struct tevent_req *req)
2470 struct smbd_echo_state *state = tevent_req_callback_data(
2471 req, struct smbd_echo_state);
2475 written = writev_recv(req, &err);
2477 state->write_req = NULL;
2478 if (written == -1) {
2479 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2482 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2483 smbd_echo_activate_writer(state);
2486 static bool smbd_echo_reply(int fd,
2487 uint8_t *inbuf, size_t inbuf_len,
2490 struct smb_request req;
2491 uint16_t num_replies;
2496 if (inbuf_len < smb_size) {
2497 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2500 if (!valid_smb_header(inbuf)) {
2501 DEBUG(10, ("Got invalid SMB header\n"));
2505 if (!init_smb_request(&req, inbuf, 0, false, seqnum)) {
2510 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2511 smb_messages[req.cmd].name
2512 ? smb_messages[req.cmd].name : "unknown"));
2514 if (req.cmd != SMBecho) {
2521 num_replies = SVAL(req.vwv+0, 0);
2522 if (num_replies != 1) {
2523 /* Not a Windows "Hey, you're still there?" request */
2527 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2529 DEBUG(10, ("create_outbuf failed\n"));
2532 req.outbuf = (uint8_t *)outbuf;
2534 SSVAL(req.outbuf, smb_vwv0, num_replies);
2536 if (req.buflen > 0) {
2537 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2540 out_len = smb_len(req.outbuf) + 4;
2542 ok = srv_send_smb(smbd_server_fd(),
2546 TALLOC_FREE(outbuf);
2554 static void smbd_echo_exit(struct tevent_context *ev,
2555 struct tevent_fd *fde, uint16_t flags,
2558 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2562 static void smbd_echo_reader(struct tevent_context *ev,
2563 struct tevent_fd *fde, uint16_t flags,
2566 struct smbd_echo_state *state = talloc_get_type_abort(
2567 private_data, struct smbd_echo_state);
2568 struct smbd_server_connection *sconn = state->sconn;
2569 size_t unread, num_pending;
2572 uint32_t seqnum = 0;
2575 bool encrypted = false;
2577 ok = smbd_lock_socket(sconn);
2579 DEBUG(0, ("%s: failed to lock socket\n",
2584 if (!fd_is_readable(smbd_server_fd())) {
2585 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2586 (int)sys_getpid()));
2587 ok = smbd_unlock_socket(sconn);
2589 DEBUG(1, ("%s: failed to unlock socket in\n",
2596 num_pending = talloc_array_length(state->pending);
2597 tmp = talloc_realloc(state, state->pending, struct iovec,
2600 DEBUG(1, ("talloc_realloc failed\n"));
2603 state->pending = tmp;
2605 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2607 status = receive_smb_talloc(state, smbd_server_fd(),
2608 (char **)(void *)&state->pending[num_pending].iov_base,
2612 &state->pending[num_pending].iov_len,
2614 false /* trusted_channel*/);
2615 if (!NT_STATUS_IS_OK(status)) {
2616 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2617 (int)sys_getpid(), nt_errstr(status)));
2621 ok = smbd_unlock_socket(sconn);
2623 DEBUG(1, ("%s: failed to unlock socket in\n",
2629 * place the seqnum in the packet so that the main process can reply
2632 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2633 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2635 reply = smbd_echo_reply(smbd_server_fd(),
2636 (uint8_t *)state->pending[num_pending].iov_base,
2637 state->pending[num_pending].iov_len,
2640 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2641 /* no check, shrinking by some bytes does not fail */
2642 state->pending = talloc_realloc(state, state->pending,
2646 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2647 smbd_echo_activate_writer(state);
2651 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2654 struct smbd_echo_state *state;
2656 state = talloc_zero(sconn, struct smbd_echo_state);
2657 if (state == NULL) {
2658 DEBUG(1, ("talloc failed\n"));
2661 state->sconn = sconn;
2662 state->parent_pipe = parent_pipe;
2663 state->ev = s3_tevent_context_init(state);
2664 if (state->ev == NULL) {
2665 DEBUG(1, ("tevent_context_init failed\n"));
2669 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2670 TEVENT_FD_READ, smbd_echo_exit,
2672 if (state->parent_fde == NULL) {
2673 DEBUG(1, ("tevent_add_fd failed\n"));
2677 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2678 TEVENT_FD_READ, smbd_echo_reader,
2680 if (state->read_fde == NULL) {
2681 DEBUG(1, ("tevent_add_fd failed\n"));
2687 if (tevent_loop_once(state->ev) == -1) {
2688 DEBUG(1, ("tevent_loop_once failed: %s\n",
2697 * Handle SMBecho requests in a forked child process
2699 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2701 int listener_pipe[2];
2705 res = pipe(listener_pipe);
2707 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2710 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2711 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2712 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2720 close(listener_pipe[0]);
2722 status = reinit_after_fork(smbd_messaging_context(),
2723 smbd_event_context(), false);
2724 if (!NT_STATUS_IS_OK(status)) {
2725 DEBUG(1, ("reinit_after_fork failed: %s\n",
2726 nt_errstr(status)));
2729 smbd_echo_loop(sconn, listener_pipe[1]);
2732 close(listener_pipe[1]);
2733 listener_pipe[1] = -1;
2734 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2736 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2739 * Without smb signing this is the same as the normal smbd
2740 * listener. This needs to change once signing comes in.
2742 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2744 sconn->smb1.echo_handler.trusted_fd,
2746 smbd_server_echo_handler,
2748 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2749 DEBUG(1, ("event_add_fd failed\n"));
2756 if (listener_pipe[0] != -1) {
2757 close(listener_pipe[0]);
2759 if (listener_pipe[1] != -1) {
2760 close(listener_pipe[1]);
2762 sconn->smb1.echo_handler.trusted_fd = -1;
2763 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2764 close(sconn->smb1.echo_handler.socket_lock_fd);
2766 sconn->smb1.echo_handler.trusted_fd = -1;
2767 sconn->smb1.echo_handler.socket_lock_fd = -1;
2771 /****************************************************************************
2772 Process commands from the client
2773 ****************************************************************************/
2775 void smbd_process(void)
2777 TALLOC_CTX *frame = talloc_stackframe();
2778 char remaddr[INET6_ADDRSTRLEN];
2780 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2781 lp_security() != SEC_SHARE &&
2782 !lp_async_smb_echo_handler()) {
2783 smbd_server_conn->allow_smb2 = true;
2786 /* Ensure child is set to blocking mode */
2787 set_blocking(smbd_server_fd(),True);
2789 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2790 set_socket_options(smbd_server_fd(), lp_socket_options());
2792 /* this is needed so that we get decent entries
2793 in smbstatus for port 445 connects */
2794 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2798 reload_services(true);
2801 * Before the first packet, check the global hosts allow/ hosts deny
2802 * parameters before doing any parsing of packets passed to us by the
2803 * client. This prevents attacks on our parsing code from hosts not in
2804 * the hosts allow list.
2807 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2808 lp_hostsdeny(-1))) {
2809 char addr[INET6_ADDRSTRLEN];
2812 * send a negative session response "not listening on calling
2815 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2816 DEBUG( 1, ("Connection denied from %s\n",
2817 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2818 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2820 exit_server_cleanly("connection denied");
2827 smb_perfcount_init();
2829 if (!init_account_policy()) {
2830 exit_server("Could not open account policy tdb.\n");
2833 if (*lp_rootdir()) {
2834 if (chroot(lp_rootdir()) != 0) {
2835 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2836 exit_server("Failed to chroot()");
2838 if (chdir("/") == -1) {
2839 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2840 exit_server("Failed to chroot()");
2842 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2845 if (!srv_init_signing(smbd_server_conn)) {
2846 exit_server("Failed to init smb_signing");
2849 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2850 exit_server("Failed to fork echo handler");
2854 if (!init_oplocks(smbd_messaging_context()))
2855 exit_server("Failed to init oplocks");
2857 /* Setup aio signal handler. */
2858 initialize_async_io_handler();
2860 /* register our message handlers */
2861 messaging_register(smbd_messaging_context(), NULL,
2862 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2863 messaging_register(smbd_messaging_context(), NULL,
2864 MSG_SMB_RELEASE_IP, msg_release_ip);
2865 messaging_register(smbd_messaging_context(), NULL,
2866 MSG_SMB_CLOSE_FILE, msg_close_file);
2869 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2870 * MSGs to all child processes
2872 messaging_deregister(smbd_messaging_context(),
2874 messaging_register(smbd_messaging_context(), NULL,
2875 MSG_DEBUG, debug_message);
2877 if ((lp_keepalive() != 0)
2878 && !(event_add_idle(smbd_event_context(), NULL,
2879 timeval_set(lp_keepalive(), 0),
2880 "keepalive", keepalive_fn,
2882 DEBUG(0, ("Could not add keepalive event\n"));
2886 if (!(event_add_idle(smbd_event_context(), NULL,
2887 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2888 "deadtime", deadtime_fn, NULL))) {
2889 DEBUG(0, ("Could not add deadtime event\n"));
2893 if (!(event_add_idle(smbd_event_context(), NULL,
2894 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2895 "housekeeping", housekeeping_fn, NULL))) {
2896 DEBUG(0, ("Could not add housekeeping event\n"));
2900 #ifdef CLUSTER_SUPPORT
2902 if (lp_clustering()) {
2904 * We need to tell ctdb about our client's TCP
2905 * connection, so that for failover ctdbd can send
2906 * tickle acks, triggering a reconnection by the
2910 struct sockaddr_storage srv, clnt;
2912 if (client_get_tcp_info(&srv, &clnt) == 0) {
2916 status = ctdbd_register_ips(
2917 messaging_ctdbd_connection(),
2918 &srv, &clnt, release_ip, NULL);
2920 if (!NT_STATUS_IS_OK(status)) {
2921 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2922 nt_errstr(status)));
2926 DEBUG(0,("Unable to get tcp info for "
2927 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2934 smbd_server_conn->nbt.got_session = false;
2936 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2938 smbd_server_conn->smb1.sessions.done_sesssetup = false;
2939 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
2940 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
2941 /* users from session setup */
2942 smbd_server_conn->smb1.sessions.session_userlist = NULL;
2943 /* workgroup from session setup. */
2944 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
2945 /* this holds info on user ids that are already validated for this VC */
2946 smbd_server_conn->smb1.sessions.validated_users = NULL;
2947 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
2948 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
2949 #ifdef HAVE_NETGROUP
2950 smbd_server_conn->smb1.sessions.my_yp_domain = NULL;
2953 conn_init(smbd_server_conn);
2954 if (!init_dptrs(smbd_server_conn)) {
2955 exit_server("init_dptrs() failed");
2958 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
2962 smbd_server_connection_handler,
2964 if (!smbd_server_conn->smb1.fde) {
2965 exit_server("failed to create smbd_server_connection fde");
2973 frame = talloc_stackframe_pool(8192);
2977 status = smbd_server_connection_loop_once(smbd_server_conn);
2978 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2979 !NT_STATUS_IS_OK(status)) {
2980 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2981 " exiting\n", nt_errstr(status)));
2988 exit_server_cleanly(NULL);
2991 bool req_is_in_chain(struct smb_request *req)
2993 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2995 * We're right now handling a subsequent request, so we must
3001 if (!is_andx_req(req->cmd)) {
3007 * Okay, an illegal request, but definitely not chained :-)
3012 return (CVAL(req->vwv+0, 0) != 0xFF);