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"
24 extern bool global_machine_password_needs_changing;
26 static void construct_reply_common(struct smb_request *req, const char *inbuf,
29 bool smbd_lock_socket(struct smbd_server_connection *sconn)
33 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
37 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
41 smbd_server_conn->smb1.echo_handler.socket_lock_fd,
42 SMB_F_SETLKW, 0, 0, F_WRLCK);
43 } while (!ok && (errno == EINTR));
49 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
54 bool smbd_unlock_socket(struct smbd_server_connection *sconn)
58 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
64 smbd_server_conn->smb1.echo_handler.socket_lock_fd,
65 SMB_F_SETLKW, 0, 0, F_UNLCK);
66 } while (!ok && (errno == EINTR));
72 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
77 /* Accessor function for smb_read_error for smbd functions. */
79 /****************************************************************************
81 ****************************************************************************/
83 bool srv_send_smb(int fd, char *buffer,
84 bool do_signing, uint32_t seqnum,
86 struct smb_perfcount_data *pcd)
91 char *buf_out = buffer;
94 ok = smbd_lock_socket(smbd_server_conn);
96 exit_server_cleanly("failed to lock socket");
100 /* Sign the outgoing packet if required. */
101 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
105 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
106 if (!NT_STATUS_IS_OK(status)) {
107 DEBUG(0, ("send_smb: SMB encryption failed "
108 "on outgoing packet! Error %s\n",
109 nt_errstr(status) ));
114 len = smb_len(buf_out) + 4;
116 while (nwritten < len) {
117 ret = write_data(fd,buf_out+nwritten,len - nwritten);
119 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
120 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
121 srv_free_enc_buffer(buf_out);
127 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
128 srv_free_enc_buffer(buf_out);
130 SMB_PERFCOUNT_END(pcd);
132 ok = smbd_unlock_socket(smbd_server_conn);
134 exit_server_cleanly("failed to unlock socket");
140 /*******************************************************************
141 Setup the word count and byte count for a smb message.
142 ********************************************************************/
144 int srv_set_message(char *buf,
149 if (zero && (num_words || num_bytes)) {
150 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
152 SCVAL(buf,smb_wct,num_words);
153 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
154 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
155 return (smb_size + num_words*2 + num_bytes);
158 static bool valid_smb_header(const uint8_t *inbuf)
160 if (is_encrypted_packet(inbuf)) {
164 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
165 * but it just looks weird to call strncmp for this one.
167 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
170 /* Socket functions for smbd packet processing. */
172 static bool valid_packet_size(size_t len)
175 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
176 * of header. Don't print the error if this fits.... JRA.
179 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
180 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
181 (unsigned long)len));
187 static NTSTATUS read_packet_remainder(int fd, char *buffer,
188 unsigned int timeout, ssize_t len)
194 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
197 /****************************************************************************
198 Attempt a zerocopy writeX read. We know here that len > smb_size-4
199 ****************************************************************************/
202 * Unfortunately, earlier versions of smbclient/libsmbclient
203 * don't send this "standard" writeX header. I've fixed this
204 * for 3.2 but we'll use the old method with earlier versions.
205 * Windows and CIFSFS at least use this standard size. Not
209 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
210 (2*14) + /* word count (including bcc) */ \
213 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
214 const char lenbuf[4],
215 int fd, char **buffer,
216 unsigned int timeout,
220 /* Size of a WRITEX call (+4 byte len). */
221 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
222 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
226 memcpy(writeX_header, lenbuf, 4);
228 status = read_fd_with_timeout(
229 fd, writeX_header + 4,
230 STANDARD_WRITE_AND_X_HEADER_SIZE,
231 STANDARD_WRITE_AND_X_HEADER_SIZE,
234 if (!NT_STATUS_IS_OK(status)) {
239 * Ok - now try and see if this is a possible
243 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
245 * If the data offset is beyond what
246 * we've read, drain the extra bytes.
248 uint16_t doff = SVAL(writeX_header,smb_vwv11);
251 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
252 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
253 if (drain_socket(smbd_server_fd(), drain) != drain) {
254 smb_panic("receive_smb_raw_talloc_partial_read:"
255 " failed to drain pending bytes");
258 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
261 /* Spoof down the length and null out the bcc. */
262 set_message_bcc(writeX_header, 0);
263 newlen = smb_len(writeX_header);
265 /* Copy the header we've written. */
267 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
269 sizeof(writeX_header));
271 if (*buffer == NULL) {
272 DEBUG(0, ("Could not allocate inbuf of length %d\n",
273 (int)sizeof(writeX_header)));
274 return NT_STATUS_NO_MEMORY;
277 /* Work out the remaining bytes. */
278 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
279 *len_ret = newlen + 4;
283 if (!valid_packet_size(len)) {
284 return NT_STATUS_INVALID_PARAMETER;
288 * Not a valid writeX call. Just do the standard
292 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
294 if (*buffer == NULL) {
295 DEBUG(0, ("Could not allocate inbuf of length %d\n",
297 return NT_STATUS_NO_MEMORY;
300 /* Copy in what we already read. */
303 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
304 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
307 status = read_packet_remainder(
308 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
311 if (!NT_STATUS_IS_OK(status)) {
312 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
322 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
323 char **buffer, unsigned int timeout,
324 size_t *p_unread, size_t *plen)
328 int min_recv_size = lp_min_receive_file_size();
333 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
334 if (!NT_STATUS_IS_OK(status)) {
335 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
339 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
340 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
341 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
342 !srv_is_signing_active(smbd_server_conn) &&
343 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
345 return receive_smb_raw_talloc_partial_read(
346 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
349 if (!valid_packet_size(len)) {
350 return NT_STATUS_INVALID_PARAMETER;
354 * The +4 here can't wrap, we've checked the length above already.
357 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
359 if (*buffer == NULL) {
360 DEBUG(0, ("Could not allocate inbuf of length %d\n",
362 return NT_STATUS_NO_MEMORY;
365 memcpy(*buffer, lenbuf, sizeof(lenbuf));
367 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
368 if (!NT_STATUS_IS_OK(status)) {
376 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
377 char **buffer, unsigned int timeout,
378 size_t *p_unread, bool *p_encrypted,
381 bool trusted_channel)
386 *p_encrypted = false;
388 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
390 if (!NT_STATUS_IS_OK(status)) {
394 if (is_encrypted_packet((uint8_t *)*buffer)) {
395 status = srv_decrypt_buffer(*buffer);
396 if (!NT_STATUS_IS_OK(status)) {
397 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
398 "incoming packet! Error %s\n",
399 nt_errstr(status) ));
405 /* Check the incoming SMB signature. */
406 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
407 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
408 "incoming packet!\n"));
409 return NT_STATUS_INVALID_NETWORK_RESPONSE;
417 * Initialize a struct smb_request from an inbuf
420 void init_smb_request(struct smb_request *req,
425 size_t req_size = smb_len(inbuf) + 4;
426 /* Ensure we have at least smb_size bytes. */
427 if (req_size < smb_size) {
428 DEBUG(0,("init_smb_request: invalid request size %u\n",
429 (unsigned int)req_size ));
430 exit_server_cleanly("Invalid SMB request");
432 req->cmd = CVAL(inbuf, smb_com);
433 req->flags2 = SVAL(inbuf, smb_flg2);
434 req->smbpid = SVAL(inbuf, smb_pid);
435 req->mid = SVAL(inbuf, smb_mid);
437 req->vuid = SVAL(inbuf, smb_uid);
438 req->tid = SVAL(inbuf, smb_tid);
439 req->wct = CVAL(inbuf, smb_wct);
440 req->vwv = (uint16_t *)(inbuf+smb_vwv);
441 req->buflen = smb_buflen(inbuf);
442 req->buf = (const uint8_t *)smb_buf(inbuf);
443 req->unread_bytes = unread_bytes;
444 req->encrypted = encrypted;
445 req->conn = conn_find(req->tid);
446 req->chain_fsp = NULL;
447 req->chain_outbuf = NULL;
449 smb_init_perfcount_data(&req->pcd);
451 /* Ensure we have at least wct words and 2 bytes of bcc. */
452 if (smb_size + req->wct*2 > req_size) {
453 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
454 (unsigned int)req->wct,
455 (unsigned int)req_size));
456 exit_server_cleanly("Invalid SMB request");
458 /* Ensure bcc is correct. */
459 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
460 DEBUG(0,("init_smb_request: invalid bcc number %u "
461 "(wct = %u, size %u)\n",
462 (unsigned int)req->buflen,
463 (unsigned int)req->wct,
464 (unsigned int)req_size));
465 exit_server_cleanly("Invalid SMB request");
471 static void process_smb(struct smbd_server_connection *conn,
472 uint8_t *inbuf, size_t nread, size_t unread_bytes,
473 uint32_t seqnum, bool encrypted,
474 struct smb_perfcount_data *deferred_pcd);
476 static void smbd_deferred_open_timer(struct event_context *ev,
477 struct timed_event *te,
478 struct timeval _tval,
481 struct pending_message_list *msg = talloc_get_type(private_data,
482 struct pending_message_list);
483 TALLOC_CTX *mem_ctx = talloc_tos();
484 uint16_t mid = SVAL(msg->buf.data,smb_mid);
487 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
490 exit_server("smbd_deferred_open_timer: talloc failed\n");
494 /* We leave this message on the queue so the open code can
495 know this is a retry. */
496 DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
499 /* Mark the message as processed so this is not
500 * re-processed in error. */
501 msg->processed = true;
503 process_smb(smbd_server_conn, inbuf,
505 msg->seqnum, msg->encrypted, &msg->pcd);
507 /* If it's still there and was processed, remove it. */
508 msg = get_open_deferred_message(mid);
509 if (msg && msg->processed) {
510 remove_deferred_open_smb_message(mid);
514 /****************************************************************************
515 Function to push a message onto the tail of a linked list of smb messages ready
517 ****************************************************************************/
519 static bool push_queued_message(struct smb_request *req,
520 struct timeval request_time,
521 struct timeval end_time,
522 char *private_data, size_t private_len)
524 int msg_len = smb_len(req->inbuf) + 4;
525 struct pending_message_list *msg;
527 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
530 DEBUG(0,("push_message: malloc fail (1)\n"));
534 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
535 if(msg->buf.data == NULL) {
536 DEBUG(0,("push_message: malloc fail (2)\n"));
541 msg->request_time = request_time;
542 msg->seqnum = req->seqnum;
543 msg->encrypted = req->encrypted;
544 msg->processed = false;
545 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
548 msg->private_data = data_blob_talloc(msg, private_data,
550 if (msg->private_data.data == NULL) {
551 DEBUG(0,("push_message: malloc fail (3)\n"));
557 msg->te = event_add_timed(smbd_event_context(),
560 smbd_deferred_open_timer,
563 DEBUG(0,("push_message: event_add_timed failed\n"));
568 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
570 DEBUG(10,("push_message: pushed message length %u on "
571 "deferred_open_queue\n", (unsigned int)msg_len));
576 /****************************************************************************
577 Function to delete a sharing violation open message by mid.
578 ****************************************************************************/
580 void remove_deferred_open_smb_message(uint16 mid)
582 struct pending_message_list *pml;
584 for (pml = deferred_open_queue; pml; pml = pml->next) {
585 if (mid == SVAL(pml->buf.data,smb_mid)) {
586 DEBUG(10,("remove_deferred_open_smb_message: "
587 "deleting mid %u len %u\n",
589 (unsigned int)pml->buf.length ));
590 DLIST_REMOVE(deferred_open_queue, pml);
597 /****************************************************************************
598 Move a sharing violation open retry message to the front of the list and
599 schedule it for immediate processing.
600 ****************************************************************************/
602 void schedule_deferred_open_smb_message(uint16 mid)
604 struct pending_message_list *pml;
607 for (pml = deferred_open_queue; pml; pml = pml->next) {
608 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
610 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
611 (unsigned int)msg_mid ));
613 if (mid == msg_mid) {
614 struct timed_event *te;
616 if (pml->processed) {
617 /* A processed message should not be
619 DEBUG(0,("schedule_deferred_open_smb_message: LOGIC ERROR "
620 "message mid %u was already processed\n",
625 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
628 te = event_add_timed(smbd_event_context(),
631 smbd_deferred_open_timer,
634 DEBUG(10,("schedule_deferred_open_smb_message: "
635 "event_add_timed() failed, skipping mid %u\n",
639 TALLOC_FREE(pml->te);
641 DLIST_PROMOTE(deferred_open_queue, pml);
646 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
650 /****************************************************************************
651 Return true if this mid is on the deferred queue and was not yet processed.
652 ****************************************************************************/
654 bool open_was_deferred(uint16 mid)
656 struct pending_message_list *pml;
658 for (pml = deferred_open_queue; pml; pml = pml->next) {
659 if (SVAL(pml->buf.data,smb_mid) == mid && !pml->processed) {
666 /****************************************************************************
667 Return the message queued by this mid.
668 ****************************************************************************/
670 struct pending_message_list *get_open_deferred_message(uint16 mid)
672 struct pending_message_list *pml;
674 for (pml = deferred_open_queue; pml; pml = pml->next) {
675 if (SVAL(pml->buf.data,smb_mid) == mid) {
682 /****************************************************************************
683 Function to push a deferred open smb message onto a linked list of local smb
684 messages ready for processing.
685 ****************************************************************************/
687 bool push_deferred_smb_message(struct smb_request *req,
688 struct timeval request_time,
689 struct timeval timeout,
690 char *private_data, size_t priv_len)
692 struct timeval end_time;
694 if (req->unread_bytes) {
695 DEBUG(0,("push_deferred_smb_message: logic error ! "
696 "unread_bytes = %u\n",
697 (unsigned int)req->unread_bytes ));
698 smb_panic("push_deferred_smb_message: "
699 "logic error unread_bytes != 0" );
702 end_time = timeval_sum(&request_time, &timeout);
704 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
705 "timeout time [%u.%06u]\n",
706 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
707 (unsigned int)end_time.tv_sec,
708 (unsigned int)end_time.tv_usec));
710 return push_queued_message(req, request_time, end_time,
711 private_data, priv_len);
715 struct timed_event *te;
716 struct timeval interval;
718 bool (*handler)(const struct timeval *now, void *private_data);
722 static void smbd_idle_event_handler(struct event_context *ctx,
723 struct timed_event *te,
727 struct idle_event *event =
728 talloc_get_type_abort(private_data, struct idle_event);
730 TALLOC_FREE(event->te);
732 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
733 event->name, event->te));
735 if (!event->handler(&now, event->private_data)) {
736 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
737 event->name, event->te));
738 /* Don't repeat, delete ourselves */
743 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
744 event->name, event->te));
746 event->te = event_add_timed(ctx, event,
747 timeval_sum(&now, &event->interval),
748 smbd_idle_event_handler, event);
750 /* We can't do much but fail here. */
751 SMB_ASSERT(event->te != NULL);
754 struct idle_event *event_add_idle(struct event_context *event_ctx,
756 struct timeval interval,
758 bool (*handler)(const struct timeval *now,
762 struct idle_event *result;
763 struct timeval now = timeval_current();
765 result = TALLOC_P(mem_ctx, struct idle_event);
766 if (result == NULL) {
767 DEBUG(0, ("talloc failed\n"));
771 result->interval = interval;
772 result->handler = handler;
773 result->private_data = private_data;
775 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
776 DEBUG(0, ("talloc failed\n"));
781 result->te = event_add_timed(event_ctx, result,
782 timeval_sum(&now, &interval),
783 smbd_idle_event_handler, result);
784 if (result->te == NULL) {
785 DEBUG(0, ("event_add_timed failed\n"));
790 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
794 static void smbd_sig_term_handler(struct tevent_context *ev,
795 struct tevent_signal *se,
801 exit_server_cleanly("termination signal");
804 void smbd_setup_sig_term_handler(void)
806 struct tevent_signal *se;
808 se = tevent_add_signal(smbd_event_context(),
809 smbd_event_context(),
811 smbd_sig_term_handler,
814 exit_server("failed to setup SIGTERM handler");
818 static void smbd_sig_hup_handler(struct tevent_context *ev,
819 struct tevent_signal *se,
825 change_to_root_user();
826 DEBUG(1,("Reloading services after SIGHUP\n"));
827 reload_services(False);
830 void smbd_setup_sig_hup_handler(void)
832 struct tevent_signal *se;
834 se = tevent_add_signal(smbd_event_context(),
835 smbd_event_context(),
837 smbd_sig_hup_handler,
840 exit_server("failed to setup SIGHUP handler");
844 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
851 to.tv_sec = SMBD_SELECT_TIMEOUT;
855 * Setup the select fd sets.
862 * Are there any timed events waiting ? If so, ensure we don't
863 * select for longer than it would take to wait for them.
870 event_add_to_select_args(smbd_event_context(), &now,
871 &r_fds, &w_fds, &to, &maxfd);
874 /* Process a signal and timed events now... */
875 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
876 return NT_STATUS_RETRY;
881 START_PROFILE(smbd_idle);
883 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
886 END_PROFILE(smbd_idle);
890 if ((conn->smb1.echo_handler.trusted_fd != -1)
891 && FD_ISSET(smbd_server_fd(), &r_fds)
892 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
894 * Prefer to read pending requests from the echo handler. To
895 * quote Jeremy (da70f8ab1): This is a hack of monstrous
898 FD_CLR(smbd_server_fd(), &r_fds);
901 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
902 return NT_STATUS_RETRY;
907 /* something is wrong. Maybe the socket is dead? */
908 return map_nt_error_from_unix(errno);
911 /* Did we timeout ? */
913 return NT_STATUS_RETRY;
916 /* should not be reached */
917 return NT_STATUS_INTERNAL_ERROR;
921 * Only allow 5 outstanding trans requests. We're allocating memory, so
925 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
928 for (; list != NULL; list = list->next) {
930 if (list->mid == mid) {
931 return NT_STATUS_INVALID_PARAMETER;
937 return NT_STATUS_INSUFFICIENT_RESOURCES;
944 These flags determine some of the permissions required to do an operation
946 Note that I don't set NEED_WRITE on some write operations because they
947 are used by some brain-dead clients when printing, and I don't want to
948 force write permissions on print services.
950 #define AS_USER (1<<0)
951 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
952 #define TIME_INIT (1<<2)
953 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
954 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
955 #define DO_CHDIR (1<<6)
958 define a list of possible SMB messages and their corresponding
959 functions. Any message that has a NULL function is unimplemented -
960 please feel free to contribute implementations!
962 static const struct smb_message_struct {
964 void (*fn)(struct smb_request *req);
966 } smb_messages[256] = {
968 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
969 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
970 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
971 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
972 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
973 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
974 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
975 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
976 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
977 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
978 /* 0x0a */ { "SMBread",reply_read,AS_USER},
979 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
980 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
981 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
982 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
983 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
984 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
985 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
986 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
987 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
988 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
989 /* 0x15 */ { NULL, NULL, 0 },
990 /* 0x16 */ { NULL, NULL, 0 },
991 /* 0x17 */ { NULL, NULL, 0 },
992 /* 0x18 */ { NULL, NULL, 0 },
993 /* 0x19 */ { NULL, NULL, 0 },
994 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
995 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
996 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
997 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
998 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
999 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1000 /* 0x20 */ { "SMBwritec", NULL,0},
1001 /* 0x21 */ { NULL, NULL, 0 },
1002 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1003 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1004 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1005 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1006 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1007 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1008 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1009 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1010 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1011 /* 0x2b */ { "SMBecho",reply_echo,0},
1012 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1013 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1014 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1015 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1016 /* 0x30 */ { NULL, NULL, 0 },
1017 /* 0x31 */ { NULL, NULL, 0 },
1018 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1019 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1020 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1021 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1022 /* 0x36 */ { NULL, NULL, 0 },
1023 /* 0x37 */ { NULL, NULL, 0 },
1024 /* 0x38 */ { NULL, NULL, 0 },
1025 /* 0x39 */ { NULL, NULL, 0 },
1026 /* 0x3a */ { NULL, NULL, 0 },
1027 /* 0x3b */ { NULL, NULL, 0 },
1028 /* 0x3c */ { NULL, NULL, 0 },
1029 /* 0x3d */ { NULL, NULL, 0 },
1030 /* 0x3e */ { NULL, NULL, 0 },
1031 /* 0x3f */ { NULL, NULL, 0 },
1032 /* 0x40 */ { NULL, NULL, 0 },
1033 /* 0x41 */ { NULL, NULL, 0 },
1034 /* 0x42 */ { NULL, NULL, 0 },
1035 /* 0x43 */ { NULL, NULL, 0 },
1036 /* 0x44 */ { NULL, NULL, 0 },
1037 /* 0x45 */ { NULL, NULL, 0 },
1038 /* 0x46 */ { NULL, NULL, 0 },
1039 /* 0x47 */ { NULL, NULL, 0 },
1040 /* 0x48 */ { NULL, NULL, 0 },
1041 /* 0x49 */ { NULL, NULL, 0 },
1042 /* 0x4a */ { NULL, NULL, 0 },
1043 /* 0x4b */ { NULL, NULL, 0 },
1044 /* 0x4c */ { NULL, NULL, 0 },
1045 /* 0x4d */ { NULL, NULL, 0 },
1046 /* 0x4e */ { NULL, NULL, 0 },
1047 /* 0x4f */ { NULL, NULL, 0 },
1048 /* 0x50 */ { NULL, NULL, 0 },
1049 /* 0x51 */ { NULL, NULL, 0 },
1050 /* 0x52 */ { NULL, NULL, 0 },
1051 /* 0x53 */ { NULL, NULL, 0 },
1052 /* 0x54 */ { NULL, NULL, 0 },
1053 /* 0x55 */ { NULL, NULL, 0 },
1054 /* 0x56 */ { NULL, NULL, 0 },
1055 /* 0x57 */ { NULL, NULL, 0 },
1056 /* 0x58 */ { NULL, NULL, 0 },
1057 /* 0x59 */ { NULL, NULL, 0 },
1058 /* 0x5a */ { NULL, NULL, 0 },
1059 /* 0x5b */ { NULL, NULL, 0 },
1060 /* 0x5c */ { NULL, NULL, 0 },
1061 /* 0x5d */ { NULL, NULL, 0 },
1062 /* 0x5e */ { NULL, NULL, 0 },
1063 /* 0x5f */ { NULL, NULL, 0 },
1064 /* 0x60 */ { NULL, NULL, 0 },
1065 /* 0x61 */ { NULL, NULL, 0 },
1066 /* 0x62 */ { NULL, NULL, 0 },
1067 /* 0x63 */ { NULL, NULL, 0 },
1068 /* 0x64 */ { NULL, NULL, 0 },
1069 /* 0x65 */ { NULL, NULL, 0 },
1070 /* 0x66 */ { NULL, NULL, 0 },
1071 /* 0x67 */ { NULL, NULL, 0 },
1072 /* 0x68 */ { NULL, NULL, 0 },
1073 /* 0x69 */ { NULL, NULL, 0 },
1074 /* 0x6a */ { NULL, NULL, 0 },
1075 /* 0x6b */ { NULL, NULL, 0 },
1076 /* 0x6c */ { NULL, NULL, 0 },
1077 /* 0x6d */ { NULL, NULL, 0 },
1078 /* 0x6e */ { NULL, NULL, 0 },
1079 /* 0x6f */ { NULL, NULL, 0 },
1080 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1081 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1082 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1083 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1084 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1085 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1086 /* 0x76 */ { NULL, NULL, 0 },
1087 /* 0x77 */ { NULL, NULL, 0 },
1088 /* 0x78 */ { NULL, NULL, 0 },
1089 /* 0x79 */ { NULL, NULL, 0 },
1090 /* 0x7a */ { NULL, NULL, 0 },
1091 /* 0x7b */ { NULL, NULL, 0 },
1092 /* 0x7c */ { NULL, NULL, 0 },
1093 /* 0x7d */ { NULL, NULL, 0 },
1094 /* 0x7e */ { NULL, NULL, 0 },
1095 /* 0x7f */ { NULL, NULL, 0 },
1096 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1097 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1098 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1099 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1100 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1101 /* 0x85 */ { NULL, NULL, 0 },
1102 /* 0x86 */ { NULL, NULL, 0 },
1103 /* 0x87 */ { NULL, NULL, 0 },
1104 /* 0x88 */ { NULL, NULL, 0 },
1105 /* 0x89 */ { NULL, NULL, 0 },
1106 /* 0x8a */ { NULL, NULL, 0 },
1107 /* 0x8b */ { NULL, NULL, 0 },
1108 /* 0x8c */ { NULL, NULL, 0 },
1109 /* 0x8d */ { NULL, NULL, 0 },
1110 /* 0x8e */ { NULL, NULL, 0 },
1111 /* 0x8f */ { NULL, NULL, 0 },
1112 /* 0x90 */ { NULL, NULL, 0 },
1113 /* 0x91 */ { NULL, NULL, 0 },
1114 /* 0x92 */ { NULL, NULL, 0 },
1115 /* 0x93 */ { NULL, NULL, 0 },
1116 /* 0x94 */ { NULL, NULL, 0 },
1117 /* 0x95 */ { NULL, NULL, 0 },
1118 /* 0x96 */ { NULL, NULL, 0 },
1119 /* 0x97 */ { NULL, NULL, 0 },
1120 /* 0x98 */ { NULL, NULL, 0 },
1121 /* 0x99 */ { NULL, NULL, 0 },
1122 /* 0x9a */ { NULL, NULL, 0 },
1123 /* 0x9b */ { NULL, NULL, 0 },
1124 /* 0x9c */ { NULL, NULL, 0 },
1125 /* 0x9d */ { NULL, NULL, 0 },
1126 /* 0x9e */ { NULL, NULL, 0 },
1127 /* 0x9f */ { NULL, NULL, 0 },
1128 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1129 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1130 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1131 /* 0xa3 */ { NULL, NULL, 0 },
1132 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1133 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1134 /* 0xa6 */ { NULL, NULL, 0 },
1135 /* 0xa7 */ { NULL, NULL, 0 },
1136 /* 0xa8 */ { NULL, NULL, 0 },
1137 /* 0xa9 */ { NULL, NULL, 0 },
1138 /* 0xaa */ { NULL, NULL, 0 },
1139 /* 0xab */ { NULL, NULL, 0 },
1140 /* 0xac */ { NULL, NULL, 0 },
1141 /* 0xad */ { NULL, NULL, 0 },
1142 /* 0xae */ { NULL, NULL, 0 },
1143 /* 0xaf */ { NULL, NULL, 0 },
1144 /* 0xb0 */ { NULL, NULL, 0 },
1145 /* 0xb1 */ { NULL, NULL, 0 },
1146 /* 0xb2 */ { NULL, NULL, 0 },
1147 /* 0xb3 */ { NULL, NULL, 0 },
1148 /* 0xb4 */ { NULL, NULL, 0 },
1149 /* 0xb5 */ { NULL, NULL, 0 },
1150 /* 0xb6 */ { NULL, NULL, 0 },
1151 /* 0xb7 */ { NULL, NULL, 0 },
1152 /* 0xb8 */ { NULL, NULL, 0 },
1153 /* 0xb9 */ { NULL, NULL, 0 },
1154 /* 0xba */ { NULL, NULL, 0 },
1155 /* 0xbb */ { NULL, NULL, 0 },
1156 /* 0xbc */ { NULL, NULL, 0 },
1157 /* 0xbd */ { NULL, NULL, 0 },
1158 /* 0xbe */ { NULL, NULL, 0 },
1159 /* 0xbf */ { NULL, NULL, 0 },
1160 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1161 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1162 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1163 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1164 /* 0xc4 */ { NULL, NULL, 0 },
1165 /* 0xc5 */ { NULL, NULL, 0 },
1166 /* 0xc6 */ { NULL, NULL, 0 },
1167 /* 0xc7 */ { NULL, NULL, 0 },
1168 /* 0xc8 */ { NULL, NULL, 0 },
1169 /* 0xc9 */ { NULL, NULL, 0 },
1170 /* 0xca */ { NULL, NULL, 0 },
1171 /* 0xcb */ { NULL, NULL, 0 },
1172 /* 0xcc */ { NULL, NULL, 0 },
1173 /* 0xcd */ { NULL, NULL, 0 },
1174 /* 0xce */ { NULL, NULL, 0 },
1175 /* 0xcf */ { NULL, NULL, 0 },
1176 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1177 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1178 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1179 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1180 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1181 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1182 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1183 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1184 /* 0xd8 */ { NULL, NULL, 0 },
1185 /* 0xd9 */ { NULL, NULL, 0 },
1186 /* 0xda */ { NULL, NULL, 0 },
1187 /* 0xdb */ { NULL, NULL, 0 },
1188 /* 0xdc */ { NULL, NULL, 0 },
1189 /* 0xdd */ { NULL, NULL, 0 },
1190 /* 0xde */ { NULL, NULL, 0 },
1191 /* 0xdf */ { NULL, NULL, 0 },
1192 /* 0xe0 */ { NULL, NULL, 0 },
1193 /* 0xe1 */ { NULL, NULL, 0 },
1194 /* 0xe2 */ { NULL, NULL, 0 },
1195 /* 0xe3 */ { NULL, NULL, 0 },
1196 /* 0xe4 */ { NULL, NULL, 0 },
1197 /* 0xe5 */ { NULL, NULL, 0 },
1198 /* 0xe6 */ { NULL, NULL, 0 },
1199 /* 0xe7 */ { NULL, NULL, 0 },
1200 /* 0xe8 */ { NULL, NULL, 0 },
1201 /* 0xe9 */ { NULL, NULL, 0 },
1202 /* 0xea */ { NULL, NULL, 0 },
1203 /* 0xeb */ { NULL, NULL, 0 },
1204 /* 0xec */ { NULL, NULL, 0 },
1205 /* 0xed */ { NULL, NULL, 0 },
1206 /* 0xee */ { NULL, NULL, 0 },
1207 /* 0xef */ { NULL, NULL, 0 },
1208 /* 0xf0 */ { NULL, NULL, 0 },
1209 /* 0xf1 */ { NULL, NULL, 0 },
1210 /* 0xf2 */ { NULL, NULL, 0 },
1211 /* 0xf3 */ { NULL, NULL, 0 },
1212 /* 0xf4 */ { NULL, NULL, 0 },
1213 /* 0xf5 */ { NULL, NULL, 0 },
1214 /* 0xf6 */ { NULL, NULL, 0 },
1215 /* 0xf7 */ { NULL, NULL, 0 },
1216 /* 0xf8 */ { NULL, NULL, 0 },
1217 /* 0xf9 */ { NULL, NULL, 0 },
1218 /* 0xfa */ { NULL, NULL, 0 },
1219 /* 0xfb */ { NULL, NULL, 0 },
1220 /* 0xfc */ { NULL, NULL, 0 },
1221 /* 0xfd */ { NULL, NULL, 0 },
1222 /* 0xfe */ { NULL, NULL, 0 },
1223 /* 0xff */ { NULL, NULL, 0 }
1227 /*******************************************************************
1228 allocate and initialize a reply packet
1229 ********************************************************************/
1231 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1232 const char *inbuf, char **outbuf, uint8_t num_words,
1236 * Protect against integer wrap
1238 if ((num_bytes > 0xffffff)
1239 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1241 if (asprintf(&msg, "num_bytes too large: %u",
1242 (unsigned)num_bytes) == -1) {
1243 msg = CONST_DISCARD(char *, "num_bytes too large");
1248 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1249 smb_size + num_words*2 + num_bytes);
1250 if (*outbuf == NULL) {
1254 construct_reply_common(req, inbuf, *outbuf);
1255 srv_set_message(*outbuf, num_words, num_bytes, false);
1257 * Zero out the word area, the caller has to take care of the bcc area
1260 if (num_words != 0) {
1261 memset(*outbuf + smb_vwv0, 0, num_words*2);
1267 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1270 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1272 smb_panic("could not allocate output buffer\n");
1274 req->outbuf = (uint8_t *)outbuf;
1278 /*******************************************************************
1279 Dump a packet to a file.
1280 ********************************************************************/
1282 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1286 if (DEBUGLEVEL < 50) {
1290 if (len < 4) len = smb_len(data)+4;
1291 for (i=1;i<100;i++) {
1292 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1293 type ? "req" : "resp") == -1) {
1296 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1297 if (fd != -1 || errno != EEXIST) break;
1300 ssize_t ret = write(fd, data, len);
1302 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1304 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1309 /****************************************************************************
1310 Prepare everything for calling the actual request function, and potentially
1311 call the request function via the "new" interface.
1313 Return False if the "legacy" function needs to be called, everything is
1316 Return True if we're done.
1318 I know this API sucks, but it is the one with the least code change I could
1320 ****************************************************************************/
1322 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1326 connection_struct *conn = NULL;
1330 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1331 * so subtract 4 from it. */
1332 if (!valid_smb_header(req->inbuf)
1333 || (size < (smb_size - 4))) {
1334 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1335 smb_len(req->inbuf)));
1336 exit_server_cleanly("Non-SMB packet");
1339 if (smb_messages[type].fn == NULL) {
1340 DEBUG(0,("Unknown message type %d!\n",type));
1341 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1342 reply_unknown_new(req, type);
1346 flags = smb_messages[type].flags;
1348 /* In share mode security we must ignore the vuid. */
1349 session_tag = (lp_security() == SEC_SHARE)
1350 ? UID_FIELD_INVALID : req->vuid;
1353 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1354 (int)sys_getpid(), (unsigned long)conn));
1356 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1358 /* Ensure this value is replaced in the incoming packet. */
1359 SSVAL(req->inbuf,smb_uid,session_tag);
1362 * Ensure the correct username is in current_user_info. This is a
1363 * really ugly bugfix for problems with multiple session_setup_and_X's
1364 * being done and allowing %U and %G substitutions to work correctly.
1365 * There is a reason this code is done here, don't move it unless you
1366 * know what you're doing... :-).
1370 if (session_tag != last_session_tag) {
1371 user_struct *vuser = NULL;
1373 last_session_tag = session_tag;
1374 if(session_tag != UID_FIELD_INVALID) {
1375 vuser = get_valid_user_struct(session_tag);
1377 set_current_user_info(
1378 vuser->server_info->sanitized_username,
1379 vuser->server_info->unix_name,
1380 pdb_get_domain(vuser->server_info
1386 /* Does this call need to be run as the connected user? */
1387 if (flags & AS_USER) {
1389 /* Does this call need a valid tree connection? */
1392 * Amazingly, the error code depends on the command
1395 if (type == SMBntcreateX) {
1396 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1398 reply_doserror(req, ERRSRV, ERRinvnid);
1403 if (!change_to_user(conn,session_tag)) {
1404 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1408 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1410 /* Does it need write permission? */
1411 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1412 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1416 /* IPC services are limited */
1417 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1418 reply_doserror(req, ERRSRV,ERRaccess);
1422 /* This call needs to be run as root */
1423 change_to_root_user();
1426 /* load service specific parameters */
1428 if (req->encrypted) {
1429 conn->encrypted_tid = true;
1430 /* encrypted required from now on. */
1431 conn->encrypt_level = Required;
1432 } else if (ENCRYPTION_REQUIRED(conn)) {
1433 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1434 exit_server_cleanly("encryption required "
1440 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1441 (flags & (AS_USER|DO_CHDIR)
1443 reply_doserror(req, ERRSRV, ERRaccess);
1446 conn->num_smb_operations++;
1449 /* does this protocol need to be run as guest? */
1450 if ((flags & AS_GUEST)
1451 && (!change_to_guest() ||
1452 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1453 lp_hostsdeny(-1)))) {
1454 reply_doserror(req, ERRSRV, ERRaccess);
1458 smb_messages[type].fn(req);
1462 /****************************************************************************
1463 Construct a reply to the incoming packet.
1464 ****************************************************************************/
1466 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1467 uint32_t seqnum, bool encrypted,
1468 struct smb_perfcount_data *deferred_pcd)
1470 connection_struct *conn;
1471 struct smb_request *req;
1473 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1474 smb_panic("could not allocate smb_request");
1477 init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1478 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1479 req->seqnum = seqnum;
1481 /* we popped this message off the queue - keep original perf data */
1483 req->pcd = *deferred_pcd;
1485 SMB_PERFCOUNT_START(&req->pcd);
1486 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1487 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1490 conn = switch_message(req->cmd, req, size);
1492 if (req->unread_bytes) {
1493 /* writeX failed. drain socket. */
1494 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1495 req->unread_bytes) {
1496 smb_panic("failed to drain pending bytes");
1498 req->unread_bytes = 0;
1506 if (req->outbuf == NULL) {
1510 if (CVAL(req->outbuf,0) == 0) {
1511 show_msg((char *)req->outbuf);
1514 if (!srv_send_smb(smbd_server_fd(),
1515 (char *)req->outbuf,
1516 true, req->seqnum+1,
1517 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1519 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1527 /****************************************************************************
1528 Process an smb from the client
1529 ****************************************************************************/
1530 static void process_smb(struct smbd_server_connection *conn,
1531 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1532 uint32_t seqnum, bool encrypted,
1533 struct smb_perfcount_data *deferred_pcd)
1535 int msg_type = CVAL(inbuf,0);
1537 DO_PROFILE_INC(smb_count);
1539 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1541 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1543 (unsigned int)unread_bytes ));
1545 if (msg_type != 0) {
1547 * NetBIOS session request, keepalive, etc.
1549 reply_special((char *)inbuf);
1553 show_msg((char *)inbuf);
1555 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1559 conn->num_requests++;
1561 /* The timeout_processing function isn't run nearly
1562 often enough to implement 'max log size' without
1563 overrunning the size of the file by many megabytes.
1564 This is especially true if we are running at debug
1565 level 10. Checking every 50 SMBs is a nice
1566 tradeoff of performance vs log file size overrun. */
1568 if ((conn->num_requests % 50) == 0 &&
1569 need_to_check_log_size()) {
1570 change_to_root_user();
1575 /****************************************************************************
1576 Return a string containing the function name of a SMB command.
1577 ****************************************************************************/
1579 const char *smb_fn_name(int type)
1581 const char *unknown_name = "SMBunknown";
1583 if (smb_messages[type].name == NULL)
1584 return(unknown_name);
1586 return(smb_messages[type].name);
1589 /****************************************************************************
1590 Helper functions for contruct_reply.
1591 ****************************************************************************/
1593 void add_to_common_flags2(uint32 v)
1598 void remove_from_common_flags2(uint32 v)
1600 common_flags2 &= ~v;
1603 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1606 srv_set_message(outbuf,0,0,false);
1608 SCVAL(outbuf, smb_com, req->cmd);
1609 SIVAL(outbuf,smb_rcls,0);
1610 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1611 SSVAL(outbuf,smb_flg2,
1612 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1614 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1616 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1617 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1618 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1619 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1622 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1624 construct_reply_common(req, (char *)req->inbuf, outbuf);
1628 * How many bytes have we already accumulated up to the current wct field
1632 size_t req_wct_ofs(struct smb_request *req)
1636 if (req->chain_outbuf == NULL) {
1639 buf_size = talloc_get_size(req->chain_outbuf);
1640 if ((buf_size % 4) != 0) {
1641 buf_size += (4 - (buf_size % 4));
1643 return buf_size - 4;
1647 * Hack around reply_nterror & friends not being aware of chained requests,
1648 * generating illegal (i.e. wct==0) chain replies.
1651 static void fixup_chain_error_packet(struct smb_request *req)
1653 uint8_t *outbuf = req->outbuf;
1655 reply_outbuf(req, 2, 0);
1656 memcpy(req->outbuf, outbuf, smb_wct);
1657 TALLOC_FREE(outbuf);
1658 SCVAL(req->outbuf, smb_vwv0, 0xff);
1661 /****************************************************************************
1662 Construct a chained reply and add it to the already made reply
1663 ****************************************************************************/
1665 void chain_reply(struct smb_request *req)
1667 size_t smblen = smb_len(req->inbuf);
1668 size_t already_used, length_needed;
1670 uint32_t chain_offset; /* uint32_t to avoid overflow */
1677 if (IVAL(req->outbuf, smb_rcls) != 0) {
1678 fixup_chain_error_packet(req);
1682 * Any of the AndX requests and replies have at least a wct of
1683 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1684 * beginning of the SMB header to the next wct field.
1686 * None of the AndX requests put anything valuable in vwv[0] and [1],
1687 * so we can overwrite it here to form the chain.
1690 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1695 * Here we assume that this is the end of the chain. For that we need
1696 * to set "next command" to 0xff and the offset to 0. If we later find
1697 * more commands in the chain, this will be overwritten again.
1700 SCVAL(req->outbuf, smb_vwv0, 0xff);
1701 SCVAL(req->outbuf, smb_vwv0+1, 0);
1702 SSVAL(req->outbuf, smb_vwv1, 0);
1704 if (req->chain_outbuf == NULL) {
1706 * In req->chain_outbuf we collect all the replies. Start the
1707 * chain by copying in the first reply.
1709 * We do the realloc because later on we depend on
1710 * talloc_get_size to determine the length of
1711 * chain_outbuf. The reply_xxx routines might have
1712 * over-allocated (reply_pipe_read_and_X used to be such an
1715 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1716 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1717 if (req->chain_outbuf == NULL) {
1723 * Update smb headers where subsequent chained commands
1724 * may have updated them.
1726 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1727 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1729 if (!smb_splice_chain(&req->chain_outbuf,
1730 CVAL(req->outbuf, smb_com),
1731 CVAL(req->outbuf, smb_wct),
1732 (uint16_t *)(req->outbuf + smb_vwv),
1733 0, smb_buflen(req->outbuf),
1734 (uint8_t *)smb_buf(req->outbuf))) {
1737 TALLOC_FREE(req->outbuf);
1741 * We use the old request's vwv field to grab the next chained command
1742 * and offset into the chained fields.
1745 chain_cmd = CVAL(req->vwv+0, 0);
1746 chain_offset = SVAL(req->vwv+1, 0);
1748 if (chain_cmd == 0xff) {
1750 * End of chain, no more requests from the client. So ship the
1753 smb_setlen((char *)(req->chain_outbuf),
1754 talloc_get_size(req->chain_outbuf) - 4);
1756 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1757 true, req->seqnum+1,
1758 IS_CONN_ENCRYPTED(req->conn)
1761 exit_server_cleanly("chain_reply: srv_send_smb "
1764 TALLOC_FREE(req->chain_outbuf);
1769 /* add a new perfcounter for this element of chain */
1770 SMB_PERFCOUNT_ADD(&req->pcd);
1771 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1772 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1775 * Check if the client tries to fool us. The request so far uses the
1776 * space to the end of the byte buffer in the request just
1777 * processed. The chain_offset can't point into that area. If that was
1778 * the case, we could end up with an endless processing of the chain,
1779 * we would always handle the same request.
1782 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1783 if (chain_offset < already_used) {
1788 * Next check: Make sure the chain offset does not point beyond the
1789 * overall smb request length.
1792 length_needed = chain_offset+1; /* wct */
1793 if (length_needed > smblen) {
1798 * Now comes the pointer magic. Goal here is to set up req->vwv and
1799 * req->buf correctly again to be able to call the subsequent
1800 * switch_message(). The chain offset (the former vwv[1]) points at
1801 * the new wct field.
1804 wct = CVAL(smb_base(req->inbuf), chain_offset);
1807 * Next consistency check: Make the new vwv array fits in the overall
1811 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1812 if (length_needed > smblen) {
1815 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1818 * Now grab the new byte buffer....
1821 buflen = SVAL(vwv+wct, 0);
1824 * .. and check that it fits.
1827 length_needed += buflen;
1828 if (length_needed > smblen) {
1831 buf = (uint8_t *)(vwv+wct+1);
1833 req->cmd = chain_cmd;
1836 req->buflen = buflen;
1839 switch_message(chain_cmd, req, smblen);
1841 if (req->outbuf == NULL) {
1843 * This happens if the chained command has suspended itself or
1844 * if it has called srv_send_smb() itself.
1850 * We end up here if the chained command was not itself chained or
1851 * suspended, but for example a close() command. We now need to splice
1852 * the chained commands' outbuf into the already built up chain_outbuf
1853 * and ship the result.
1859 * We end up here if there's any error in the chain syntax. Report a
1860 * DOS error, just like Windows does.
1862 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1863 fixup_chain_error_packet(req);
1866 if (!smb_splice_chain(&req->chain_outbuf,
1867 CVAL(req->outbuf, smb_com),
1868 CVAL(req->outbuf, smb_wct),
1869 (uint16_t *)(req->outbuf + smb_vwv),
1870 0, smb_buflen(req->outbuf),
1871 (uint8_t *)smb_buf(req->outbuf))) {
1872 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1874 TALLOC_FREE(req->outbuf);
1876 smb_setlen((char *)(req->chain_outbuf),
1877 talloc_get_size(req->chain_outbuf) - 4);
1879 show_msg((char *)(req->chain_outbuf));
1881 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1882 true, req->seqnum+1,
1883 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1885 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1887 TALLOC_FREE(req->chain_outbuf);
1891 /****************************************************************************
1892 Check if services need reloading.
1893 ****************************************************************************/
1895 void check_reload(time_t t)
1897 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1899 if(last_smb_conf_reload_time == 0) {
1900 last_smb_conf_reload_time = t;
1901 /* Our printing subsystem might not be ready at smbd start up.
1902 Then no printer is available till the first printers check
1903 is performed. A lower initial interval circumvents this. */
1904 if ( printcap_cache_time > 60 )
1905 last_printer_reload_time = t - printcap_cache_time + 60;
1907 last_printer_reload_time = t;
1910 if (mypid != getpid()) { /* First time or fork happened meanwhile */
1911 /* randomize over 60 second the printcap reload to avoid all
1912 * process hitting cupsd at the same time */
1913 int time_range = 60;
1915 last_printer_reload_time += random() % time_range;
1919 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1920 reload_services(True);
1921 last_smb_conf_reload_time = t;
1924 /* 'printcap cache time = 0' disable the feature */
1926 if ( printcap_cache_time != 0 )
1928 /* see if it's time to reload or if the clock has been set back */
1930 if ( (t >= last_printer_reload_time+printcap_cache_time)
1931 || (t-last_printer_reload_time < 0) )
1933 DEBUG( 3,( "Printcap cache time expired.\n"));
1935 last_printer_reload_time = t;
1940 static bool fd_is_readable(int fd)
1943 struct timeval timeout = {0, };
1949 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
1953 return FD_ISSET(fd, &fds);
1956 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1958 /* TODO: make write nonblocking */
1961 static void smbd_server_connection_read_handler(
1962 struct smbd_server_connection *conn, int fd)
1964 uint8_t *inbuf = NULL;
1965 size_t inbuf_len = 0;
1966 size_t unread_bytes = 0;
1967 bool encrypted = false;
1968 TALLOC_CTX *mem_ctx = talloc_tos();
1974 bool from_client = (smbd_server_fd() == fd)?true:false;
1977 ok = smbd_lock_socket(conn);
1979 exit_server_cleanly("failed to lock socket");
1982 if (!fd_is_readable(smbd_server_fd())) {
1983 DEBUG(10,("the echo listener was faster\n"));
1984 ok = smbd_unlock_socket(conn);
1986 exit_server_cleanly("failed to unlock");
1991 /* TODO: make this completely nonblocking */
1992 status = receive_smb_talloc(mem_ctx, fd,
1993 (char **)(void *)&inbuf,
1997 &inbuf_len, &seqnum,
1998 false /* trusted channel */);
1999 ok = smbd_unlock_socket(conn);
2001 exit_server_cleanly("failed to unlock");
2004 /* TODO: make this completely nonblocking */
2005 status = receive_smb_talloc(mem_ctx, fd,
2006 (char **)(void *)&inbuf,
2010 &inbuf_len, &seqnum,
2011 true /* trusted channel */);
2014 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2017 if (NT_STATUS_IS_ERR(status)) {
2018 exit_server_cleanly("failed to receive smb request");
2020 if (!NT_STATUS_IS_OK(status)) {
2025 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2026 seqnum, encrypted, NULL);
2029 static void smbd_server_connection_handler(struct event_context *ev,
2030 struct fd_event *fde,
2034 struct smbd_server_connection *conn = talloc_get_type(private_data,
2035 struct smbd_server_connection);
2037 if (flags & EVENT_FD_WRITE) {
2038 smbd_server_connection_write_handler(conn);
2039 } else if (flags & EVENT_FD_READ) {
2040 smbd_server_connection_read_handler(conn, smbd_server_fd());
2044 static void smbd_server_echo_handler(struct event_context *ev,
2045 struct fd_event *fde,
2049 struct smbd_server_connection *conn = talloc_get_type(private_data,
2050 struct smbd_server_connection);
2052 if (flags & EVENT_FD_WRITE) {
2053 smbd_server_connection_write_handler(conn);
2054 } else if (flags & EVENT_FD_READ) {
2055 smbd_server_connection_read_handler(
2056 conn, conn->smb1.echo_handler.trusted_fd);
2060 /****************************************************************************
2061 received when we should release a specific IP
2062 ****************************************************************************/
2063 static void release_ip(const char *ip, void *priv)
2065 char addr[INET6_ADDRSTRLEN];
2068 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2070 if (strncmp("::ffff:", addr, 7) == 0) {
2074 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2075 /* we can't afford to do a clean exit - that involves
2076 database writes, which would potentially mean we
2077 are still running after the failover has finished -
2078 we have to get rid of this process ID straight
2080 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2082 /* note we must exit with non-zero status so the unclean handler gets
2083 called in the parent, so that the brl database is tickled */
2088 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2089 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2091 release_ip((char *)data->data, NULL);
2094 #ifdef CLUSTER_SUPPORT
2095 static int client_get_tcp_info(struct sockaddr_storage *server,
2096 struct sockaddr_storage *client)
2099 if (server_fd == -1) {
2102 length = sizeof(*server);
2103 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2106 length = sizeof(*client);
2107 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2115 * Send keepalive packets to our client
2117 static bool keepalive_fn(const struct timeval *now, void *private_data)
2122 ok = smbd_lock_socket(smbd_server_conn);
2124 exit_server_cleanly("failed to lock socket");
2127 ret = send_keepalive(smbd_server_fd());
2129 ok = smbd_unlock_socket(smbd_server_conn);
2131 exit_server_cleanly("failed to unlock socket");
2135 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2142 * Do the recurring check if we're idle
2144 static bool deadtime_fn(const struct timeval *now, void *private_data)
2146 if ((conn_num_open() == 0)
2147 || (conn_idle_all(now->tv_sec))) {
2148 DEBUG( 2, ( "Closing idle connection\n" ) );
2149 messaging_send(smbd_messaging_context(), procid_self(),
2150 MSG_SHUTDOWN, &data_blob_null);
2158 * Do the recurring log file and smb.conf reload checks.
2161 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2163 change_to_root_user();
2165 /* update printer queue caches if necessary */
2166 update_monitored_printq_cache();
2168 /* check if we need to reload services */
2169 check_reload(time(NULL));
2171 /* Change machine password if neccessary. */
2172 attempt_machine_password_change();
2175 * Force a log file check.
2177 force_check_log_size();
2182 static int create_unlink_tmp(const char *dir)
2187 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2188 if (fname == NULL) {
2192 fd = mkstemp(fname);
2197 if (unlink(fname) == -1) {
2198 int sys_errno = errno;
2208 struct smbd_echo_state {
2209 struct tevent_context *ev;
2210 struct iovec *pending;
2211 struct smbd_server_connection *sconn;
2214 struct tevent_fd *parent_fde;
2216 struct tevent_fd *read_fde;
2217 struct tevent_req *write_req;
2220 static void smbd_echo_writer_done(struct tevent_req *req);
2222 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2226 if (state->write_req != NULL) {
2230 num_pending = talloc_array_length(state->pending);
2231 if (num_pending == 0) {
2235 state->write_req = writev_send(state, state->ev, NULL,
2237 state->pending, num_pending);
2238 if (state->write_req == NULL) {
2239 DEBUG(1, ("writev_send failed\n"));
2243 talloc_steal(state->write_req, state->pending);
2244 state->pending = NULL;
2246 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2250 static void smbd_echo_writer_done(struct tevent_req *req)
2252 struct smbd_echo_state *state = tevent_req_callback_data(
2253 req, struct smbd_echo_state);
2257 written = writev_recv(req, &err);
2259 state->write_req = NULL;
2260 if (written == -1) {
2261 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2264 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2265 smbd_echo_activate_writer(state);
2268 static bool smbd_echo_reply(int fd,
2269 uint8_t *inbuf, size_t inbuf_len,
2272 struct smb_request req;
2273 uint16_t num_replies;
2278 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2279 DEBUG(10, ("Got netbios keepalive\n"));
2286 if (inbuf_len < smb_size) {
2287 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2290 if (!valid_smb_header(inbuf)) {
2291 DEBUG(10, ("Got invalid SMB header\n"));
2295 init_smb_request(&req, inbuf, 0, false);
2297 req.seqnum = seqnum;
2299 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2300 smb_messages[req.cmd].name
2301 ? smb_messages[req.cmd].name : "unknown"));
2303 if (req.cmd != SMBecho) {
2310 num_replies = SVAL(req.vwv+0, 0);
2311 if (num_replies != 1) {
2312 /* Not a Windows "Hey, you're still there?" request */
2316 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2318 DEBUG(10, ("create_outbuf failed\n"));
2321 req.outbuf = (uint8_t *)outbuf;
2323 SSVAL(req.outbuf, smb_vwv0, num_replies);
2325 if (req.buflen > 0) {
2326 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2329 out_len = smb_len(req.outbuf) + 4;
2331 ok = srv_send_smb(smbd_server_fd(),
2335 TALLOC_FREE(outbuf);
2343 static void smbd_echo_exit(struct tevent_context *ev,
2344 struct tevent_fd *fde, uint16_t flags,
2347 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2351 static void smbd_echo_reader(struct tevent_context *ev,
2352 struct tevent_fd *fde, uint16_t flags,
2355 struct smbd_echo_state *state = talloc_get_type_abort(
2356 private_data, struct smbd_echo_state);
2357 struct smbd_server_connection *sconn = state->sconn;
2358 size_t unread, num_pending;
2361 uint32_t seqnum = 0;
2364 bool encrypted = false;
2368 ok = smbd_lock_socket(sconn);
2370 DEBUG(0, ("%s: failed to lock socket\n",
2375 if (!fd_is_readable(smbd_server_fd())) {
2376 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2377 (int)sys_getpid()));
2378 ok = smbd_unlock_socket(sconn);
2380 DEBUG(1, ("%s: failed to unlock socket in\n",
2387 num_pending = talloc_array_length(state->pending);
2388 tmp = talloc_realloc(state, state->pending, struct iovec,
2391 DEBUG(1, ("talloc_realloc failed\n"));
2394 state->pending = tmp;
2396 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2398 status = receive_smb_talloc(state->pending, smbd_server_fd(),
2399 (char **)(void *)&state->pending[num_pending].iov_base,
2403 &state->pending[num_pending].iov_len,
2405 false /* trusted_channel*/);
2406 if (!NT_STATUS_IS_OK(status)) {
2407 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2408 (int)sys_getpid(), nt_errstr(status)));
2412 ok = smbd_unlock_socket(sconn);
2414 DEBUG(1, ("%s: failed to unlock socket in\n",
2419 reply = smbd_echo_reply(smbd_server_fd(),
2420 (uint8_t *)state->pending[num_pending].iov_base,
2421 state->pending[num_pending].iov_len,
2424 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2425 /* no check, shrinking by some bytes does not fail */
2426 state->pending = talloc_realloc(state, state->pending,
2432 if (state->pending[num_pending].iov_len >= smb_size) {
2434 * place the seqnum in the packet so that the main process
2435 * can reply with signing
2437 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2438 smb_ss_field, seqnum);
2439 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2440 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2443 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2444 smbd_echo_activate_writer(state);
2447 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2450 struct smbd_echo_state *state;
2452 state = talloc_zero(sconn, struct smbd_echo_state);
2453 if (state == NULL) {
2454 DEBUG(1, ("talloc failed\n"));
2457 state->sconn = sconn;
2458 state->parent_pipe = parent_pipe;
2459 state->ev = s3_tevent_context_init(state);
2460 if (state->ev == NULL) {
2461 DEBUG(1, ("tevent_context_init failed\n"));
2465 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2466 TEVENT_FD_READ, smbd_echo_exit,
2468 if (state->parent_fde == NULL) {
2469 DEBUG(1, ("tevent_add_fd failed\n"));
2473 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2474 TEVENT_FD_READ, smbd_echo_reader,
2476 if (state->read_fde == NULL) {
2477 DEBUG(1, ("tevent_add_fd failed\n"));
2483 if (tevent_loop_once(state->ev) == -1) {
2484 DEBUG(1, ("tevent_loop_once failed: %s\n",
2493 * Handle SMBecho requests in a forked child process
2495 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2497 int listener_pipe[2];
2501 res = pipe(listener_pipe);
2503 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2506 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2507 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2508 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2516 close(listener_pipe[0]);
2517 set_blocking(listener_pipe[1], false);
2519 status = reinit_after_fork(smbd_messaging_context(),
2520 smbd_event_context(), false);
2521 if (!NT_STATUS_IS_OK(status)) {
2522 DEBUG(1, ("reinit_after_fork failed: %s\n",
2523 nt_errstr(status)));
2526 smbd_echo_loop(sconn, listener_pipe[1]);
2529 close(listener_pipe[1]);
2530 listener_pipe[1] = -1;
2531 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2533 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2536 * Without smb signing this is the same as the normal smbd
2537 * listener. This needs to change once signing comes in.
2539 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2541 sconn->smb1.echo_handler.trusted_fd,
2543 smbd_server_echo_handler,
2545 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2546 DEBUG(1, ("event_add_fd failed\n"));
2553 if (listener_pipe[0] != -1) {
2554 close(listener_pipe[0]);
2556 if (listener_pipe[1] != -1) {
2557 close(listener_pipe[1]);
2559 sconn->smb1.echo_handler.trusted_fd = -1;
2560 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2561 close(sconn->smb1.echo_handler.socket_lock_fd);
2563 sconn->smb1.echo_handler.trusted_fd = -1;
2564 sconn->smb1.echo_handler.socket_lock_fd = -1;
2568 /****************************************************************************
2569 Process commands from the client
2570 ****************************************************************************/
2572 void smbd_process(void)
2574 TALLOC_CTX *frame = talloc_stackframe();
2575 char remaddr[INET6_ADDRSTRLEN];
2577 smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
2578 if (!smbd_server_conn) {
2579 exit_server("failed to create smbd_server_connection");
2582 smbd_server_conn->smb1.echo_handler.socket_lock_fd = -1;
2583 smbd_server_conn->smb1.echo_handler.trusted_fd = -1;
2585 /* Ensure child is set to blocking mode */
2586 set_blocking(smbd_server_fd(),True);
2588 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2589 set_socket_options(smbd_server_fd(), lp_socket_options());
2591 /* this is needed so that we get decent entries
2592 in smbstatus for port 445 connects */
2593 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2597 reload_services(true);
2600 * Before the first packet, check the global hosts allow/ hosts deny
2601 * parameters before doing any parsing of packets passed to us by the
2602 * client. This prevents attacks on our parsing code from hosts not in
2603 * the hosts allow list.
2606 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2607 lp_hostsdeny(-1))) {
2608 char addr[INET6_ADDRSTRLEN];
2611 * send a negative session response "not listening on calling
2614 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2615 DEBUG( 1, ("Connection denied from %s\n",
2616 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2617 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2619 exit_server_cleanly("connection denied");
2626 smb_perfcount_init();
2628 if (!init_account_policy()) {
2629 exit_server("Could not open account policy tdb.\n");
2632 if (*lp_rootdir()) {
2633 if (chroot(lp_rootdir()) != 0) {
2634 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2635 exit_server("Failed to chroot()");
2637 if (chdir("/") == -1) {
2638 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2639 exit_server("Failed to chroot()");
2641 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2644 if (!srv_init_signing(smbd_server_conn)) {
2645 exit_server("Failed to init smb_signing");
2648 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2649 exit_server("Failed to fork echo handler");
2653 if (!init_oplocks(smbd_messaging_context()))
2654 exit_server("Failed to init oplocks");
2656 /* Setup aio signal handler. */
2657 initialize_async_io_handler();
2659 /* register our message handlers */
2660 messaging_register(smbd_messaging_context(), NULL,
2661 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2662 messaging_register(smbd_messaging_context(), NULL,
2663 MSG_SMB_RELEASE_IP, msg_release_ip);
2664 messaging_register(smbd_messaging_context(), NULL,
2665 MSG_SMB_CLOSE_FILE, msg_close_file);
2667 if ((lp_keepalive() != 0)
2668 && !(event_add_idle(smbd_event_context(), NULL,
2669 timeval_set(lp_keepalive(), 0),
2670 "keepalive", keepalive_fn,
2672 DEBUG(0, ("Could not add keepalive event\n"));
2676 if (!(event_add_idle(smbd_event_context(), NULL,
2677 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2678 "deadtime", deadtime_fn, NULL))) {
2679 DEBUG(0, ("Could not add deadtime event\n"));
2683 if (!(event_add_idle(smbd_event_context(), NULL,
2684 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2685 "housekeeping", housekeeping_fn, NULL))) {
2686 DEBUG(0, ("Could not add housekeeping event\n"));
2690 #ifdef CLUSTER_SUPPORT
2692 if (lp_clustering()) {
2694 * We need to tell ctdb about our client's TCP
2695 * connection, so that for failover ctdbd can send
2696 * tickle acks, triggering a reconnection by the
2700 struct sockaddr_storage srv, clnt;
2702 if (client_get_tcp_info(&srv, &clnt) == 0) {
2706 status = ctdbd_register_ips(
2707 messaging_ctdbd_connection(),
2708 &srv, &clnt, release_ip, NULL);
2710 if (!NT_STATUS_IS_OK(status)) {
2711 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2712 nt_errstr(status)));
2716 DEBUG(0,("Unable to get tcp info for "
2717 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2724 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2726 smbd_server_conn->fde = event_add_fd(smbd_event_context(),
2730 smbd_server_connection_handler,
2732 if (!smbd_server_conn->fde) {
2733 exit_server("failed to create smbd_server_connection fde");
2741 frame = talloc_stackframe_pool(8192);
2745 status = smbd_server_connection_loop_once(smbd_server_conn);
2746 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2747 !NT_STATUS_IS_OK(status)) {
2748 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2749 " exiting\n", nt_errstr(status)));
2756 exit_server_cleanly(NULL);
2759 bool req_is_in_chain(struct smb_request *req)
2761 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2763 * We're right now handling a subsequent request, so we must
2769 if (!is_andx_req(req->cmd)) {
2775 * Okay, an illegal request, but definitely not chained :-)
2780 return (CVAL(req->vwv+0, 0) != 0xFF);