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()));
39 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
40 SMB_F_SETLKW, 0, 0, F_WRLCK);
45 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
50 bool smbd_unlock_socket(struct smbd_server_connection *sconn)
54 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
58 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
59 SMB_F_SETLKW, 0, 0, F_UNLCK);
64 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
69 /* Accessor function for smb_read_error for smbd functions. */
71 /****************************************************************************
73 ****************************************************************************/
75 bool srv_send_smb(int fd, char *buffer,
76 bool do_signing, uint32_t seqnum,
78 struct smb_perfcount_data *pcd)
83 char *buf_out = buffer;
86 ok = smbd_lock_socket(smbd_server_conn);
88 exit_server_cleanly("failed to lock socket");
92 /* Sign the outgoing packet if required. */
93 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
97 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
98 if (!NT_STATUS_IS_OK(status)) {
99 DEBUG(0, ("send_smb: SMB encryption failed "
100 "on outgoing packet! Error %s\n",
101 nt_errstr(status) ));
106 len = smb_len(buf_out) + 4;
108 while (nwritten < len) {
109 ret = write_data(fd,buf_out+nwritten,len - nwritten);
111 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
112 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
113 srv_free_enc_buffer(buf_out);
119 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
120 srv_free_enc_buffer(buf_out);
122 SMB_PERFCOUNT_END(pcd);
124 ok = smbd_unlock_socket(smbd_server_conn);
126 exit_server_cleanly("failed to unlock socket");
132 /*******************************************************************
133 Setup the word count and byte count for a smb message.
134 ********************************************************************/
136 int srv_set_message(char *buf,
141 if (zero && (num_words || num_bytes)) {
142 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
144 SCVAL(buf,smb_wct,num_words);
145 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
146 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
147 return (smb_size + num_words*2 + num_bytes);
150 static bool valid_smb_header(const uint8_t *inbuf)
152 if (is_encrypted_packet(inbuf)) {
156 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
157 * but it just looks weird to call strncmp for this one.
159 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
162 /* Socket functions for smbd packet processing. */
164 static bool valid_packet_size(size_t len)
167 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
168 * of header. Don't print the error if this fits.... JRA.
171 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
172 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
173 (unsigned long)len));
179 static NTSTATUS read_packet_remainder(int fd, char *buffer,
180 unsigned int timeout, ssize_t len)
186 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
189 /****************************************************************************
190 Attempt a zerocopy writeX read. We know here that len > smb_size-4
191 ****************************************************************************/
194 * Unfortunately, earlier versions of smbclient/libsmbclient
195 * don't send this "standard" writeX header. I've fixed this
196 * for 3.2 but we'll use the old method with earlier versions.
197 * Windows and CIFSFS at least use this standard size. Not
201 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
202 (2*14) + /* word count (including bcc) */ \
205 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
206 const char lenbuf[4],
207 int fd, char **buffer,
208 unsigned int timeout,
212 /* Size of a WRITEX call (+4 byte len). */
213 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
214 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
218 memcpy(writeX_header, lenbuf, 4);
220 status = read_fd_with_timeout(
221 fd, writeX_header + 4,
222 STANDARD_WRITE_AND_X_HEADER_SIZE,
223 STANDARD_WRITE_AND_X_HEADER_SIZE,
226 if (!NT_STATUS_IS_OK(status)) {
231 * Ok - now try and see if this is a possible
235 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
237 * If the data offset is beyond what
238 * we've read, drain the extra bytes.
240 uint16_t doff = SVAL(writeX_header,smb_vwv11);
243 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
244 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
245 if (drain_socket(smbd_server_fd(), drain) != drain) {
246 smb_panic("receive_smb_raw_talloc_partial_read:"
247 " failed to drain pending bytes");
250 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
253 /* Spoof down the length and null out the bcc. */
254 set_message_bcc(writeX_header, 0);
255 newlen = smb_len(writeX_header);
257 /* Copy the header we've written. */
259 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
261 sizeof(writeX_header));
263 if (*buffer == NULL) {
264 DEBUG(0, ("Could not allocate inbuf of length %d\n",
265 (int)sizeof(writeX_header)));
266 return NT_STATUS_NO_MEMORY;
269 /* Work out the remaining bytes. */
270 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
271 *len_ret = newlen + 4;
275 if (!valid_packet_size(len)) {
276 return NT_STATUS_INVALID_PARAMETER;
280 * Not a valid writeX call. Just do the standard
284 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
286 if (*buffer == NULL) {
287 DEBUG(0, ("Could not allocate inbuf of length %d\n",
289 return NT_STATUS_NO_MEMORY;
292 /* Copy in what we already read. */
295 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
296 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
299 status = read_packet_remainder(
300 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
303 if (!NT_STATUS_IS_OK(status)) {
304 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
314 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
315 char **buffer, unsigned int timeout,
316 size_t *p_unread, size_t *plen)
320 int min_recv_size = lp_min_receive_file_size();
325 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
326 if (!NT_STATUS_IS_OK(status)) {
327 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
331 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
332 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
333 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
334 !srv_is_signing_active(smbd_server_conn) &&
335 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
337 return receive_smb_raw_talloc_partial_read(
338 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
341 if (!valid_packet_size(len)) {
342 return NT_STATUS_INVALID_PARAMETER;
346 * The +4 here can't wrap, we've checked the length above already.
349 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
351 if (*buffer == NULL) {
352 DEBUG(0, ("Could not allocate inbuf of length %d\n",
354 return NT_STATUS_NO_MEMORY;
357 memcpy(*buffer, lenbuf, sizeof(lenbuf));
359 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
360 if (!NT_STATUS_IS_OK(status)) {
368 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
369 char **buffer, unsigned int timeout,
370 size_t *p_unread, bool *p_encrypted,
373 bool trusted_channel)
378 *p_encrypted = false;
380 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
382 if (!NT_STATUS_IS_OK(status)) {
386 if (is_encrypted_packet((uint8_t *)*buffer)) {
387 status = srv_decrypt_buffer(*buffer);
388 if (!NT_STATUS_IS_OK(status)) {
389 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
390 "incoming packet! Error %s\n",
391 nt_errstr(status) ));
397 /* Check the incoming SMB signature. */
398 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
399 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
400 "incoming packet!\n"));
401 return NT_STATUS_INVALID_NETWORK_RESPONSE;
409 * Initialize a struct smb_request from an inbuf
412 void init_smb_request(struct smb_request *req,
417 size_t req_size = smb_len(inbuf) + 4;
418 /* Ensure we have at least smb_size bytes. */
419 if (req_size < smb_size) {
420 DEBUG(0,("init_smb_request: invalid request size %u\n",
421 (unsigned int)req_size ));
422 exit_server_cleanly("Invalid SMB request");
424 req->cmd = CVAL(inbuf, smb_com);
425 req->flags2 = SVAL(inbuf, smb_flg2);
426 req->smbpid = SVAL(inbuf, smb_pid);
427 req->mid = SVAL(inbuf, smb_mid);
429 req->vuid = SVAL(inbuf, smb_uid);
430 req->tid = SVAL(inbuf, smb_tid);
431 req->wct = CVAL(inbuf, smb_wct);
432 req->vwv = (uint16_t *)(inbuf+smb_vwv);
433 req->buflen = smb_buflen(inbuf);
434 req->buf = (const uint8_t *)smb_buf(inbuf);
435 req->unread_bytes = unread_bytes;
436 req->encrypted = encrypted;
437 req->conn = conn_find(req->tid);
438 req->chain_fsp = NULL;
439 req->chain_outbuf = NULL;
441 smb_init_perfcount_data(&req->pcd);
443 /* Ensure we have at least wct words and 2 bytes of bcc. */
444 if (smb_size + req->wct*2 > req_size) {
445 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
446 (unsigned int)req->wct,
447 (unsigned int)req_size));
448 exit_server_cleanly("Invalid SMB request");
450 /* Ensure bcc is correct. */
451 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
452 DEBUG(0,("init_smb_request: invalid bcc number %u "
453 "(wct = %u, size %u)\n",
454 (unsigned int)req->buflen,
455 (unsigned int)req->wct,
456 (unsigned int)req_size));
457 exit_server_cleanly("Invalid SMB request");
463 static void process_smb(struct smbd_server_connection *conn,
464 uint8_t *inbuf, size_t nread, size_t unread_bytes,
465 uint32_t seqnum, bool encrypted,
466 struct smb_perfcount_data *deferred_pcd);
468 static void smbd_deferred_open_timer(struct event_context *ev,
469 struct timed_event *te,
470 struct timeval _tval,
473 struct pending_message_list *msg = talloc_get_type(private_data,
474 struct pending_message_list);
475 TALLOC_CTX *mem_ctx = talloc_tos();
476 uint16_t mid = SVAL(msg->buf.data,smb_mid);
479 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
482 exit_server("smbd_deferred_open_timer: talloc failed\n");
486 /* We leave this message on the queue so the open code can
487 know this is a retry. */
488 DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
491 /* Mark the message as processed so this is not
492 * re-processed in error. */
493 msg->processed = true;
495 process_smb(smbd_server_conn, inbuf,
497 msg->seqnum, msg->encrypted, &msg->pcd);
499 /* If it's still there and was processed, remove it. */
500 msg = get_open_deferred_message(mid);
501 if (msg && msg->processed) {
502 remove_deferred_open_smb_message(mid);
506 /****************************************************************************
507 Function to push a message onto the tail of a linked list of smb messages ready
509 ****************************************************************************/
511 static bool push_queued_message(struct smb_request *req,
512 struct timeval request_time,
513 struct timeval end_time,
514 char *private_data, size_t private_len)
516 int msg_len = smb_len(req->inbuf) + 4;
517 struct pending_message_list *msg;
519 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
522 DEBUG(0,("push_message: malloc fail (1)\n"));
526 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
527 if(msg->buf.data == NULL) {
528 DEBUG(0,("push_message: malloc fail (2)\n"));
533 msg->request_time = request_time;
534 msg->seqnum = req->seqnum;
535 msg->encrypted = req->encrypted;
536 msg->processed = false;
537 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
540 msg->private_data = data_blob_talloc(msg, private_data,
542 if (msg->private_data.data == NULL) {
543 DEBUG(0,("push_message: malloc fail (3)\n"));
549 msg->te = event_add_timed(smbd_event_context(),
552 smbd_deferred_open_timer,
555 DEBUG(0,("push_message: event_add_timed failed\n"));
560 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
562 DEBUG(10,("push_message: pushed message length %u on "
563 "deferred_open_queue\n", (unsigned int)msg_len));
568 /****************************************************************************
569 Function to delete a sharing violation open message by mid.
570 ****************************************************************************/
572 void remove_deferred_open_smb_message(uint16 mid)
574 struct pending_message_list *pml;
576 for (pml = deferred_open_queue; pml; pml = pml->next) {
577 if (mid == SVAL(pml->buf.data,smb_mid)) {
578 DEBUG(10,("remove_deferred_open_smb_message: "
579 "deleting mid %u len %u\n",
581 (unsigned int)pml->buf.length ));
582 DLIST_REMOVE(deferred_open_queue, pml);
589 /****************************************************************************
590 Move a sharing violation open retry message to the front of the list and
591 schedule it for immediate processing.
592 ****************************************************************************/
594 void schedule_deferred_open_smb_message(uint16 mid)
596 struct pending_message_list *pml;
599 for (pml = deferred_open_queue; pml; pml = pml->next) {
600 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
602 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
603 (unsigned int)msg_mid ));
605 if (mid == msg_mid) {
606 struct timed_event *te;
608 if (pml->processed) {
609 /* A processed message should not be
611 DEBUG(0,("schedule_deferred_open_smb_message: LOGIC ERROR "
612 "message mid %u was already processed\n",
617 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
620 te = event_add_timed(smbd_event_context(),
623 smbd_deferred_open_timer,
626 DEBUG(10,("schedule_deferred_open_smb_message: "
627 "event_add_timed() failed, skipping mid %u\n",
631 TALLOC_FREE(pml->te);
633 DLIST_PROMOTE(deferred_open_queue, pml);
638 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
642 /****************************************************************************
643 Return true if this mid is on the deferred queue and was not yet processed.
644 ****************************************************************************/
646 bool open_was_deferred(uint16 mid)
648 struct pending_message_list *pml;
650 for (pml = deferred_open_queue; pml; pml = pml->next) {
651 if (SVAL(pml->buf.data,smb_mid) == mid && !pml->processed) {
658 /****************************************************************************
659 Return the message queued by this mid.
660 ****************************************************************************/
662 struct pending_message_list *get_open_deferred_message(uint16 mid)
664 struct pending_message_list *pml;
666 for (pml = deferred_open_queue; pml; pml = pml->next) {
667 if (SVAL(pml->buf.data,smb_mid) == mid) {
674 /****************************************************************************
675 Function to push a deferred open smb message onto a linked list of local smb
676 messages ready for processing.
677 ****************************************************************************/
679 bool push_deferred_smb_message(struct smb_request *req,
680 struct timeval request_time,
681 struct timeval timeout,
682 char *private_data, size_t priv_len)
684 struct timeval end_time;
686 if (req->unread_bytes) {
687 DEBUG(0,("push_deferred_smb_message: logic error ! "
688 "unread_bytes = %u\n",
689 (unsigned int)req->unread_bytes ));
690 smb_panic("push_deferred_smb_message: "
691 "logic error unread_bytes != 0" );
694 end_time = timeval_sum(&request_time, &timeout);
696 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
697 "timeout time [%u.%06u]\n",
698 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
699 (unsigned int)end_time.tv_sec,
700 (unsigned int)end_time.tv_usec));
702 return push_queued_message(req, request_time, end_time,
703 private_data, priv_len);
707 struct timed_event *te;
708 struct timeval interval;
710 bool (*handler)(const struct timeval *now, void *private_data);
714 static void smbd_idle_event_handler(struct event_context *ctx,
715 struct timed_event *te,
719 struct idle_event *event =
720 talloc_get_type_abort(private_data, struct idle_event);
722 TALLOC_FREE(event->te);
724 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
725 event->name, event->te));
727 if (!event->handler(&now, event->private_data)) {
728 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
729 event->name, event->te));
730 /* Don't repeat, delete ourselves */
735 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
736 event->name, event->te));
738 event->te = event_add_timed(ctx, event,
739 timeval_sum(&now, &event->interval),
740 smbd_idle_event_handler, event);
742 /* We can't do much but fail here. */
743 SMB_ASSERT(event->te != NULL);
746 struct idle_event *event_add_idle(struct event_context *event_ctx,
748 struct timeval interval,
750 bool (*handler)(const struct timeval *now,
754 struct idle_event *result;
755 struct timeval now = timeval_current();
757 result = TALLOC_P(mem_ctx, struct idle_event);
758 if (result == NULL) {
759 DEBUG(0, ("talloc failed\n"));
763 result->interval = interval;
764 result->handler = handler;
765 result->private_data = private_data;
767 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
768 DEBUG(0, ("talloc failed\n"));
773 result->te = event_add_timed(event_ctx, result,
774 timeval_sum(&now, &interval),
775 smbd_idle_event_handler, result);
776 if (result->te == NULL) {
777 DEBUG(0, ("event_add_timed failed\n"));
782 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
786 static void smbd_sig_term_handler(struct tevent_context *ev,
787 struct tevent_signal *se,
793 exit_server_cleanly("termination signal");
796 void smbd_setup_sig_term_handler(void)
798 struct tevent_signal *se;
800 se = tevent_add_signal(smbd_event_context(),
801 smbd_event_context(),
803 smbd_sig_term_handler,
806 exit_server("failed to setup SIGTERM handler");
810 static void smbd_sig_hup_handler(struct tevent_context *ev,
811 struct tevent_signal *se,
817 change_to_root_user();
818 DEBUG(1,("Reloading services after SIGHUP\n"));
819 reload_services(False);
822 void smbd_setup_sig_hup_handler(void)
824 struct tevent_signal *se;
826 se = tevent_add_signal(smbd_event_context(),
827 smbd_event_context(),
829 smbd_sig_hup_handler,
832 exit_server("failed to setup SIGHUP handler");
836 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
843 to.tv_sec = SMBD_SELECT_TIMEOUT;
847 * Setup the select fd sets.
854 * Are there any timed events waiting ? If so, ensure we don't
855 * select for longer than it would take to wait for them.
862 event_add_to_select_args(smbd_event_context(), &now,
863 &r_fds, &w_fds, &to, &maxfd);
866 /* Process a signal and timed events now... */
867 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
868 return NT_STATUS_RETRY;
873 START_PROFILE(smbd_idle);
875 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
878 END_PROFILE(smbd_idle);
882 if ((conn->smb1.echo_handler.trusted_fd != -1)
883 && FD_ISSET(smbd_server_fd(), &r_fds)
884 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
886 * Prefer to read pending requests from the echo handler. To
887 * quote Jeremy (da70f8ab1): This is a hack of monstrous
890 FD_CLR(smbd_server_fd(), &r_fds);
893 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
894 return NT_STATUS_RETRY;
899 /* something is wrong. Maybe the socket is dead? */
900 return map_nt_error_from_unix(errno);
903 /* Did we timeout ? */
905 return NT_STATUS_RETRY;
908 /* should not be reached */
909 return NT_STATUS_INTERNAL_ERROR;
913 * Only allow 5 outstanding trans requests. We're allocating memory, so
917 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
920 for (; list != NULL; list = list->next) {
922 if (list->mid == mid) {
923 return NT_STATUS_INVALID_PARAMETER;
929 return NT_STATUS_INSUFFICIENT_RESOURCES;
936 These flags determine some of the permissions required to do an operation
938 Note that I don't set NEED_WRITE on some write operations because they
939 are used by some brain-dead clients when printing, and I don't want to
940 force write permissions on print services.
942 #define AS_USER (1<<0)
943 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
944 #define TIME_INIT (1<<2)
945 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
946 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
947 #define DO_CHDIR (1<<6)
950 define a list of possible SMB messages and their corresponding
951 functions. Any message that has a NULL function is unimplemented -
952 please feel free to contribute implementations!
954 static const struct smb_message_struct {
956 void (*fn)(struct smb_request *req);
958 } smb_messages[256] = {
960 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
961 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
962 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
963 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
964 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
965 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
966 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
967 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
968 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
969 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
970 /* 0x0a */ { "SMBread",reply_read,AS_USER},
971 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
972 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
973 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
974 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
975 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
976 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
977 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
978 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
979 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
980 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
981 /* 0x15 */ { NULL, NULL, 0 },
982 /* 0x16 */ { NULL, NULL, 0 },
983 /* 0x17 */ { NULL, NULL, 0 },
984 /* 0x18 */ { NULL, NULL, 0 },
985 /* 0x19 */ { NULL, NULL, 0 },
986 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
987 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
988 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
989 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
990 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
991 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
992 /* 0x20 */ { "SMBwritec", NULL,0},
993 /* 0x21 */ { NULL, NULL, 0 },
994 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
995 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
996 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
997 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
998 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
999 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1000 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1001 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1002 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1003 /* 0x2b */ { "SMBecho",reply_echo,0},
1004 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1005 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1006 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1007 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1008 /* 0x30 */ { NULL, NULL, 0 },
1009 /* 0x31 */ { NULL, NULL, 0 },
1010 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1011 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1012 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1013 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1014 /* 0x36 */ { NULL, NULL, 0 },
1015 /* 0x37 */ { NULL, NULL, 0 },
1016 /* 0x38 */ { NULL, NULL, 0 },
1017 /* 0x39 */ { NULL, NULL, 0 },
1018 /* 0x3a */ { NULL, NULL, 0 },
1019 /* 0x3b */ { NULL, NULL, 0 },
1020 /* 0x3c */ { NULL, NULL, 0 },
1021 /* 0x3d */ { NULL, NULL, 0 },
1022 /* 0x3e */ { NULL, NULL, 0 },
1023 /* 0x3f */ { NULL, NULL, 0 },
1024 /* 0x40 */ { NULL, NULL, 0 },
1025 /* 0x41 */ { NULL, NULL, 0 },
1026 /* 0x42 */ { NULL, NULL, 0 },
1027 /* 0x43 */ { NULL, NULL, 0 },
1028 /* 0x44 */ { NULL, NULL, 0 },
1029 /* 0x45 */ { NULL, NULL, 0 },
1030 /* 0x46 */ { NULL, NULL, 0 },
1031 /* 0x47 */ { NULL, NULL, 0 },
1032 /* 0x48 */ { NULL, NULL, 0 },
1033 /* 0x49 */ { NULL, NULL, 0 },
1034 /* 0x4a */ { NULL, NULL, 0 },
1035 /* 0x4b */ { NULL, NULL, 0 },
1036 /* 0x4c */ { NULL, NULL, 0 },
1037 /* 0x4d */ { NULL, NULL, 0 },
1038 /* 0x4e */ { NULL, NULL, 0 },
1039 /* 0x4f */ { NULL, NULL, 0 },
1040 /* 0x50 */ { NULL, NULL, 0 },
1041 /* 0x51 */ { NULL, NULL, 0 },
1042 /* 0x52 */ { NULL, NULL, 0 },
1043 /* 0x53 */ { NULL, NULL, 0 },
1044 /* 0x54 */ { NULL, NULL, 0 },
1045 /* 0x55 */ { NULL, NULL, 0 },
1046 /* 0x56 */ { NULL, NULL, 0 },
1047 /* 0x57 */ { NULL, NULL, 0 },
1048 /* 0x58 */ { NULL, NULL, 0 },
1049 /* 0x59 */ { NULL, NULL, 0 },
1050 /* 0x5a */ { NULL, NULL, 0 },
1051 /* 0x5b */ { NULL, NULL, 0 },
1052 /* 0x5c */ { NULL, NULL, 0 },
1053 /* 0x5d */ { NULL, NULL, 0 },
1054 /* 0x5e */ { NULL, NULL, 0 },
1055 /* 0x5f */ { NULL, NULL, 0 },
1056 /* 0x60 */ { NULL, NULL, 0 },
1057 /* 0x61 */ { NULL, NULL, 0 },
1058 /* 0x62 */ { NULL, NULL, 0 },
1059 /* 0x63 */ { NULL, NULL, 0 },
1060 /* 0x64 */ { NULL, NULL, 0 },
1061 /* 0x65 */ { NULL, NULL, 0 },
1062 /* 0x66 */ { NULL, NULL, 0 },
1063 /* 0x67 */ { NULL, NULL, 0 },
1064 /* 0x68 */ { NULL, NULL, 0 },
1065 /* 0x69 */ { NULL, NULL, 0 },
1066 /* 0x6a */ { NULL, NULL, 0 },
1067 /* 0x6b */ { NULL, NULL, 0 },
1068 /* 0x6c */ { NULL, NULL, 0 },
1069 /* 0x6d */ { NULL, NULL, 0 },
1070 /* 0x6e */ { NULL, NULL, 0 },
1071 /* 0x6f */ { NULL, NULL, 0 },
1072 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1073 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1074 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1075 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1076 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1077 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1078 /* 0x76 */ { NULL, NULL, 0 },
1079 /* 0x77 */ { NULL, NULL, 0 },
1080 /* 0x78 */ { NULL, NULL, 0 },
1081 /* 0x79 */ { NULL, NULL, 0 },
1082 /* 0x7a */ { NULL, NULL, 0 },
1083 /* 0x7b */ { NULL, NULL, 0 },
1084 /* 0x7c */ { NULL, NULL, 0 },
1085 /* 0x7d */ { NULL, NULL, 0 },
1086 /* 0x7e */ { NULL, NULL, 0 },
1087 /* 0x7f */ { NULL, NULL, 0 },
1088 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1089 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1090 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1091 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1092 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1093 /* 0x85 */ { NULL, NULL, 0 },
1094 /* 0x86 */ { NULL, NULL, 0 },
1095 /* 0x87 */ { NULL, NULL, 0 },
1096 /* 0x88 */ { NULL, NULL, 0 },
1097 /* 0x89 */ { NULL, NULL, 0 },
1098 /* 0x8a */ { NULL, NULL, 0 },
1099 /* 0x8b */ { NULL, NULL, 0 },
1100 /* 0x8c */ { NULL, NULL, 0 },
1101 /* 0x8d */ { NULL, NULL, 0 },
1102 /* 0x8e */ { NULL, NULL, 0 },
1103 /* 0x8f */ { NULL, NULL, 0 },
1104 /* 0x90 */ { NULL, NULL, 0 },
1105 /* 0x91 */ { NULL, NULL, 0 },
1106 /* 0x92 */ { NULL, NULL, 0 },
1107 /* 0x93 */ { NULL, NULL, 0 },
1108 /* 0x94 */ { NULL, NULL, 0 },
1109 /* 0x95 */ { NULL, NULL, 0 },
1110 /* 0x96 */ { NULL, NULL, 0 },
1111 /* 0x97 */ { NULL, NULL, 0 },
1112 /* 0x98 */ { NULL, NULL, 0 },
1113 /* 0x99 */ { NULL, NULL, 0 },
1114 /* 0x9a */ { NULL, NULL, 0 },
1115 /* 0x9b */ { NULL, NULL, 0 },
1116 /* 0x9c */ { NULL, NULL, 0 },
1117 /* 0x9d */ { NULL, NULL, 0 },
1118 /* 0x9e */ { NULL, NULL, 0 },
1119 /* 0x9f */ { NULL, NULL, 0 },
1120 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1121 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1122 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1123 /* 0xa3 */ { NULL, NULL, 0 },
1124 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1125 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1126 /* 0xa6 */ { NULL, NULL, 0 },
1127 /* 0xa7 */ { NULL, NULL, 0 },
1128 /* 0xa8 */ { NULL, NULL, 0 },
1129 /* 0xa9 */ { NULL, NULL, 0 },
1130 /* 0xaa */ { NULL, NULL, 0 },
1131 /* 0xab */ { NULL, NULL, 0 },
1132 /* 0xac */ { NULL, NULL, 0 },
1133 /* 0xad */ { NULL, NULL, 0 },
1134 /* 0xae */ { NULL, NULL, 0 },
1135 /* 0xaf */ { NULL, NULL, 0 },
1136 /* 0xb0 */ { NULL, NULL, 0 },
1137 /* 0xb1 */ { NULL, NULL, 0 },
1138 /* 0xb2 */ { NULL, NULL, 0 },
1139 /* 0xb3 */ { NULL, NULL, 0 },
1140 /* 0xb4 */ { NULL, NULL, 0 },
1141 /* 0xb5 */ { NULL, NULL, 0 },
1142 /* 0xb6 */ { NULL, NULL, 0 },
1143 /* 0xb7 */ { NULL, NULL, 0 },
1144 /* 0xb8 */ { NULL, NULL, 0 },
1145 /* 0xb9 */ { NULL, NULL, 0 },
1146 /* 0xba */ { NULL, NULL, 0 },
1147 /* 0xbb */ { NULL, NULL, 0 },
1148 /* 0xbc */ { NULL, NULL, 0 },
1149 /* 0xbd */ { NULL, NULL, 0 },
1150 /* 0xbe */ { NULL, NULL, 0 },
1151 /* 0xbf */ { NULL, NULL, 0 },
1152 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1153 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1154 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1155 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1156 /* 0xc4 */ { NULL, NULL, 0 },
1157 /* 0xc5 */ { NULL, NULL, 0 },
1158 /* 0xc6 */ { NULL, NULL, 0 },
1159 /* 0xc7 */ { NULL, NULL, 0 },
1160 /* 0xc8 */ { NULL, NULL, 0 },
1161 /* 0xc9 */ { NULL, NULL, 0 },
1162 /* 0xca */ { NULL, NULL, 0 },
1163 /* 0xcb */ { NULL, NULL, 0 },
1164 /* 0xcc */ { NULL, NULL, 0 },
1165 /* 0xcd */ { NULL, NULL, 0 },
1166 /* 0xce */ { NULL, NULL, 0 },
1167 /* 0xcf */ { NULL, NULL, 0 },
1168 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1169 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1170 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1171 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1172 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1173 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1174 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1175 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1176 /* 0xd8 */ { NULL, NULL, 0 },
1177 /* 0xd9 */ { NULL, NULL, 0 },
1178 /* 0xda */ { NULL, NULL, 0 },
1179 /* 0xdb */ { NULL, NULL, 0 },
1180 /* 0xdc */ { NULL, NULL, 0 },
1181 /* 0xdd */ { NULL, NULL, 0 },
1182 /* 0xde */ { NULL, NULL, 0 },
1183 /* 0xdf */ { NULL, NULL, 0 },
1184 /* 0xe0 */ { NULL, NULL, 0 },
1185 /* 0xe1 */ { NULL, NULL, 0 },
1186 /* 0xe2 */ { NULL, NULL, 0 },
1187 /* 0xe3 */ { NULL, NULL, 0 },
1188 /* 0xe4 */ { NULL, NULL, 0 },
1189 /* 0xe5 */ { NULL, NULL, 0 },
1190 /* 0xe6 */ { NULL, NULL, 0 },
1191 /* 0xe7 */ { NULL, NULL, 0 },
1192 /* 0xe8 */ { NULL, NULL, 0 },
1193 /* 0xe9 */ { NULL, NULL, 0 },
1194 /* 0xea */ { NULL, NULL, 0 },
1195 /* 0xeb */ { NULL, NULL, 0 },
1196 /* 0xec */ { NULL, NULL, 0 },
1197 /* 0xed */ { NULL, NULL, 0 },
1198 /* 0xee */ { NULL, NULL, 0 },
1199 /* 0xef */ { NULL, NULL, 0 },
1200 /* 0xf0 */ { NULL, NULL, 0 },
1201 /* 0xf1 */ { NULL, NULL, 0 },
1202 /* 0xf2 */ { NULL, NULL, 0 },
1203 /* 0xf3 */ { NULL, NULL, 0 },
1204 /* 0xf4 */ { NULL, NULL, 0 },
1205 /* 0xf5 */ { NULL, NULL, 0 },
1206 /* 0xf6 */ { NULL, NULL, 0 },
1207 /* 0xf7 */ { NULL, NULL, 0 },
1208 /* 0xf8 */ { NULL, NULL, 0 },
1209 /* 0xf9 */ { NULL, NULL, 0 },
1210 /* 0xfa */ { NULL, NULL, 0 },
1211 /* 0xfb */ { NULL, NULL, 0 },
1212 /* 0xfc */ { NULL, NULL, 0 },
1213 /* 0xfd */ { NULL, NULL, 0 },
1214 /* 0xfe */ { NULL, NULL, 0 },
1215 /* 0xff */ { NULL, NULL, 0 }
1219 /*******************************************************************
1220 allocate and initialize a reply packet
1221 ********************************************************************/
1223 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1224 const char *inbuf, char **outbuf, uint8_t num_words,
1228 * Protect against integer wrap
1230 if ((num_bytes > 0xffffff)
1231 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1233 if (asprintf(&msg, "num_bytes too large: %u",
1234 (unsigned)num_bytes) == -1) {
1235 msg = CONST_DISCARD(char *, "num_bytes too large");
1240 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1241 smb_size + num_words*2 + num_bytes);
1242 if (*outbuf == NULL) {
1246 construct_reply_common(req, inbuf, *outbuf);
1247 srv_set_message(*outbuf, num_words, num_bytes, false);
1249 * Zero out the word area, the caller has to take care of the bcc area
1252 if (num_words != 0) {
1253 memset(*outbuf + smb_vwv0, 0, num_words*2);
1259 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1262 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1264 smb_panic("could not allocate output buffer\n");
1266 req->outbuf = (uint8_t *)outbuf;
1270 /*******************************************************************
1271 Dump a packet to a file.
1272 ********************************************************************/
1274 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1278 if (DEBUGLEVEL < 50) {
1282 if (len < 4) len = smb_len(data)+4;
1283 for (i=1;i<100;i++) {
1284 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1285 type ? "req" : "resp") == -1) {
1288 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1289 if (fd != -1 || errno != EEXIST) break;
1292 ssize_t ret = write(fd, data, len);
1294 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1296 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1301 /****************************************************************************
1302 Prepare everything for calling the actual request function, and potentially
1303 call the request function via the "new" interface.
1305 Return False if the "legacy" function needs to be called, everything is
1308 Return True if we're done.
1310 I know this API sucks, but it is the one with the least code change I could
1312 ****************************************************************************/
1314 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1318 connection_struct *conn = NULL;
1322 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1323 * so subtract 4 from it. */
1324 if (!valid_smb_header(req->inbuf)
1325 || (size < (smb_size - 4))) {
1326 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1327 smb_len(req->inbuf)));
1328 exit_server_cleanly("Non-SMB packet");
1331 if (smb_messages[type].fn == NULL) {
1332 DEBUG(0,("Unknown message type %d!\n",type));
1333 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1334 reply_unknown_new(req, type);
1338 flags = smb_messages[type].flags;
1340 /* In share mode security we must ignore the vuid. */
1341 session_tag = (lp_security() == SEC_SHARE)
1342 ? UID_FIELD_INVALID : req->vuid;
1345 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1346 (int)sys_getpid(), (unsigned long)conn));
1348 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1350 /* Ensure this value is replaced in the incoming packet. */
1351 SSVAL(req->inbuf,smb_uid,session_tag);
1354 * Ensure the correct username is in current_user_info. This is a
1355 * really ugly bugfix for problems with multiple session_setup_and_X's
1356 * being done and allowing %U and %G substitutions to work correctly.
1357 * There is a reason this code is done here, don't move it unless you
1358 * know what you're doing... :-).
1362 if (session_tag != last_session_tag) {
1363 user_struct *vuser = NULL;
1365 last_session_tag = session_tag;
1366 if(session_tag != UID_FIELD_INVALID) {
1367 vuser = get_valid_user_struct(session_tag);
1369 set_current_user_info(
1370 vuser->server_info->sanitized_username,
1371 vuser->server_info->unix_name,
1372 pdb_get_domain(vuser->server_info
1378 /* Does this call need to be run as the connected user? */
1379 if (flags & AS_USER) {
1381 /* Does this call need a valid tree connection? */
1384 * Amazingly, the error code depends on the command
1387 if (type == SMBntcreateX) {
1388 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1390 reply_doserror(req, ERRSRV, ERRinvnid);
1395 if (!change_to_user(conn,session_tag)) {
1396 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1400 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1402 /* Does it need write permission? */
1403 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1404 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1408 /* IPC services are limited */
1409 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1410 reply_doserror(req, ERRSRV,ERRaccess);
1414 /* This call needs to be run as root */
1415 change_to_root_user();
1418 /* load service specific parameters */
1420 if (req->encrypted) {
1421 conn->encrypted_tid = true;
1422 /* encrypted required from now on. */
1423 conn->encrypt_level = Required;
1424 } else if (ENCRYPTION_REQUIRED(conn)) {
1425 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1426 exit_server_cleanly("encryption required "
1432 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1433 (flags & (AS_USER|DO_CHDIR)
1435 reply_doserror(req, ERRSRV, ERRaccess);
1438 conn->num_smb_operations++;
1441 /* does this protocol need to be run as guest? */
1442 if ((flags & AS_GUEST)
1443 && (!change_to_guest() ||
1444 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1445 lp_hostsdeny(-1)))) {
1446 reply_doserror(req, ERRSRV, ERRaccess);
1450 smb_messages[type].fn(req);
1454 /****************************************************************************
1455 Construct a reply to the incoming packet.
1456 ****************************************************************************/
1458 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1459 uint32_t seqnum, bool encrypted,
1460 struct smb_perfcount_data *deferred_pcd)
1462 connection_struct *conn;
1463 struct smb_request *req;
1465 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1466 smb_panic("could not allocate smb_request");
1469 init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1470 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1471 req->seqnum = seqnum;
1473 /* we popped this message off the queue - keep original perf data */
1475 req->pcd = *deferred_pcd;
1477 SMB_PERFCOUNT_START(&req->pcd);
1478 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1479 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1482 conn = switch_message(req->cmd, req, size);
1484 if (req->unread_bytes) {
1485 /* writeX failed. drain socket. */
1486 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1487 req->unread_bytes) {
1488 smb_panic("failed to drain pending bytes");
1490 req->unread_bytes = 0;
1498 if (req->outbuf == NULL) {
1502 if (CVAL(req->outbuf,0) == 0) {
1503 show_msg((char *)req->outbuf);
1506 if (!srv_send_smb(smbd_server_fd(),
1507 (char *)req->outbuf,
1508 true, req->seqnum+1,
1509 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1511 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1519 /****************************************************************************
1520 Process an smb from the client
1521 ****************************************************************************/
1522 static void process_smb(struct smbd_server_connection *conn,
1523 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1524 uint32_t seqnum, bool encrypted,
1525 struct smb_perfcount_data *deferred_pcd)
1527 int msg_type = CVAL(inbuf,0);
1529 DO_PROFILE_INC(smb_count);
1531 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1533 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1535 (unsigned int)unread_bytes ));
1537 if (msg_type != 0) {
1539 * NetBIOS session request, keepalive, etc.
1541 reply_special((char *)inbuf);
1545 show_msg((char *)inbuf);
1547 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1551 conn->num_requests++;
1553 /* The timeout_processing function isn't run nearly
1554 often enough to implement 'max log size' without
1555 overrunning the size of the file by many megabytes.
1556 This is especially true if we are running at debug
1557 level 10. Checking every 50 SMBs is a nice
1558 tradeoff of performance vs log file size overrun. */
1560 if ((conn->num_requests % 50) == 0 &&
1561 need_to_check_log_size()) {
1562 change_to_root_user();
1567 /****************************************************************************
1568 Return a string containing the function name of a SMB command.
1569 ****************************************************************************/
1571 const char *smb_fn_name(int type)
1573 const char *unknown_name = "SMBunknown";
1575 if (smb_messages[type].name == NULL)
1576 return(unknown_name);
1578 return(smb_messages[type].name);
1581 /****************************************************************************
1582 Helper functions for contruct_reply.
1583 ****************************************************************************/
1585 void add_to_common_flags2(uint32 v)
1590 void remove_from_common_flags2(uint32 v)
1592 common_flags2 &= ~v;
1595 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1598 srv_set_message(outbuf,0,0,false);
1600 SCVAL(outbuf, smb_com, req->cmd);
1601 SIVAL(outbuf,smb_rcls,0);
1602 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1603 SSVAL(outbuf,smb_flg2,
1604 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1606 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1608 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1609 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1610 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1611 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1614 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1616 construct_reply_common(req, (char *)req->inbuf, outbuf);
1620 * How many bytes have we already accumulated up to the current wct field
1624 size_t req_wct_ofs(struct smb_request *req)
1628 if (req->chain_outbuf == NULL) {
1631 buf_size = talloc_get_size(req->chain_outbuf);
1632 if ((buf_size % 4) != 0) {
1633 buf_size += (4 - (buf_size % 4));
1635 return buf_size - 4;
1639 * Hack around reply_nterror & friends not being aware of chained requests,
1640 * generating illegal (i.e. wct==0) chain replies.
1643 static void fixup_chain_error_packet(struct smb_request *req)
1645 uint8_t *outbuf = req->outbuf;
1647 reply_outbuf(req, 2, 0);
1648 memcpy(req->outbuf, outbuf, smb_wct);
1649 TALLOC_FREE(outbuf);
1650 SCVAL(req->outbuf, smb_vwv0, 0xff);
1653 /****************************************************************************
1654 Construct a chained reply and add it to the already made reply
1655 ****************************************************************************/
1657 void chain_reply(struct smb_request *req)
1659 size_t smblen = smb_len(req->inbuf);
1660 size_t already_used, length_needed;
1662 uint32_t chain_offset; /* uint32_t to avoid overflow */
1669 if (IVAL(req->outbuf, smb_rcls) != 0) {
1670 fixup_chain_error_packet(req);
1674 * Any of the AndX requests and replies have at least a wct of
1675 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1676 * beginning of the SMB header to the next wct field.
1678 * None of the AndX requests put anything valuable in vwv[0] and [1],
1679 * so we can overwrite it here to form the chain.
1682 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1687 * Here we assume that this is the end of the chain. For that we need
1688 * to set "next command" to 0xff and the offset to 0. If we later find
1689 * more commands in the chain, this will be overwritten again.
1692 SCVAL(req->outbuf, smb_vwv0, 0xff);
1693 SCVAL(req->outbuf, smb_vwv0+1, 0);
1694 SSVAL(req->outbuf, smb_vwv1, 0);
1696 if (req->chain_outbuf == NULL) {
1698 * In req->chain_outbuf we collect all the replies. Start the
1699 * chain by copying in the first reply.
1701 * We do the realloc because later on we depend on
1702 * talloc_get_size to determine the length of
1703 * chain_outbuf. The reply_xxx routines might have
1704 * over-allocated (reply_pipe_read_and_X used to be such an
1707 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1708 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1709 if (req->chain_outbuf == NULL) {
1715 * Update smb headers where subsequent chained commands
1716 * may have updated them.
1718 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1719 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1721 if (!smb_splice_chain(&req->chain_outbuf,
1722 CVAL(req->outbuf, smb_com),
1723 CVAL(req->outbuf, smb_wct),
1724 (uint16_t *)(req->outbuf + smb_vwv),
1725 0, smb_buflen(req->outbuf),
1726 (uint8_t *)smb_buf(req->outbuf))) {
1729 TALLOC_FREE(req->outbuf);
1733 * We use the old request's vwv field to grab the next chained command
1734 * and offset into the chained fields.
1737 chain_cmd = CVAL(req->vwv+0, 0);
1738 chain_offset = SVAL(req->vwv+1, 0);
1740 if (chain_cmd == 0xff) {
1742 * End of chain, no more requests from the client. So ship the
1745 smb_setlen((char *)(req->chain_outbuf),
1746 talloc_get_size(req->chain_outbuf) - 4);
1748 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1749 true, req->seqnum+1,
1750 IS_CONN_ENCRYPTED(req->conn)
1753 exit_server_cleanly("chain_reply: srv_send_smb "
1756 TALLOC_FREE(req->chain_outbuf);
1761 /* add a new perfcounter for this element of chain */
1762 SMB_PERFCOUNT_ADD(&req->pcd);
1763 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1764 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1767 * Check if the client tries to fool us. The request so far uses the
1768 * space to the end of the byte buffer in the request just
1769 * processed. The chain_offset can't point into that area. If that was
1770 * the case, we could end up with an endless processing of the chain,
1771 * we would always handle the same request.
1774 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1775 if (chain_offset < already_used) {
1780 * Next check: Make sure the chain offset does not point beyond the
1781 * overall smb request length.
1784 length_needed = chain_offset+1; /* wct */
1785 if (length_needed > smblen) {
1790 * Now comes the pointer magic. Goal here is to set up req->vwv and
1791 * req->buf correctly again to be able to call the subsequent
1792 * switch_message(). The chain offset (the former vwv[1]) points at
1793 * the new wct field.
1796 wct = CVAL(smb_base(req->inbuf), chain_offset);
1799 * Next consistency check: Make the new vwv array fits in the overall
1803 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1804 if (length_needed > smblen) {
1807 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1810 * Now grab the new byte buffer....
1813 buflen = SVAL(vwv+wct, 0);
1816 * .. and check that it fits.
1819 length_needed += buflen;
1820 if (length_needed > smblen) {
1823 buf = (uint8_t *)(vwv+wct+1);
1825 req->cmd = chain_cmd;
1828 req->buflen = buflen;
1831 switch_message(chain_cmd, req, smblen);
1833 if (req->outbuf == NULL) {
1835 * This happens if the chained command has suspended itself or
1836 * if it has called srv_send_smb() itself.
1842 * We end up here if the chained command was not itself chained or
1843 * suspended, but for example a close() command. We now need to splice
1844 * the chained commands' outbuf into the already built up chain_outbuf
1845 * and ship the result.
1851 * We end up here if there's any error in the chain syntax. Report a
1852 * DOS error, just like Windows does.
1854 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1855 fixup_chain_error_packet(req);
1858 if (!smb_splice_chain(&req->chain_outbuf,
1859 CVAL(req->outbuf, smb_com),
1860 CVAL(req->outbuf, smb_wct),
1861 (uint16_t *)(req->outbuf + smb_vwv),
1862 0, smb_buflen(req->outbuf),
1863 (uint8_t *)smb_buf(req->outbuf))) {
1864 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1866 TALLOC_FREE(req->outbuf);
1868 smb_setlen((char *)(req->chain_outbuf),
1869 talloc_get_size(req->chain_outbuf) - 4);
1871 show_msg((char *)(req->chain_outbuf));
1873 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1874 true, req->seqnum+1,
1875 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1877 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1879 TALLOC_FREE(req->chain_outbuf);
1883 /****************************************************************************
1884 Check if services need reloading.
1885 ****************************************************************************/
1887 void check_reload(time_t t)
1889 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1891 if(last_smb_conf_reload_time == 0) {
1892 last_smb_conf_reload_time = t;
1893 /* Our printing subsystem might not be ready at smbd start up.
1894 Then no printer is available till the first printers check
1895 is performed. A lower initial interval circumvents this. */
1896 if ( printcap_cache_time > 60 )
1897 last_printer_reload_time = t - printcap_cache_time + 60;
1899 last_printer_reload_time = t;
1902 if (mypid != getpid()) { /* First time or fork happened meanwhile */
1903 /* randomize over 60 second the printcap reload to avoid all
1904 * process hitting cupsd at the same time */
1905 int time_range = 60;
1907 last_printer_reload_time += random() % time_range;
1911 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1912 reload_services(True);
1913 last_smb_conf_reload_time = t;
1916 /* 'printcap cache time = 0' disable the feature */
1918 if ( printcap_cache_time != 0 )
1920 /* see if it's time to reload or if the clock has been set back */
1922 if ( (t >= last_printer_reload_time+printcap_cache_time)
1923 || (t-last_printer_reload_time < 0) )
1925 DEBUG( 3,( "Printcap cache time expired.\n"));
1927 last_printer_reload_time = t;
1932 static bool fd_is_readable(int fd)
1935 struct timeval timeout = {0, };
1941 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
1945 return FD_ISSET(fd, &fds);
1948 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1950 /* TODO: make write nonblocking */
1953 static void smbd_server_connection_read_handler(
1954 struct smbd_server_connection *conn, int fd)
1956 uint8_t *inbuf = NULL;
1957 size_t inbuf_len = 0;
1958 size_t unread_bytes = 0;
1959 bool encrypted = false;
1960 TALLOC_CTX *mem_ctx = talloc_tos();
1966 bool from_client = (smbd_server_fd() == fd)?true:false;
1969 ok = smbd_lock_socket(conn);
1971 exit_server_cleanly("failed to lock socket");
1974 if (!fd_is_readable(smbd_server_fd())) {
1975 DEBUG(10,("the echo listener was faster\n"));
1976 ok = smbd_unlock_socket(conn);
1978 exit_server_cleanly("failed to unlock");
1983 /* TODO: make this completely nonblocking */
1984 status = receive_smb_talloc(mem_ctx, fd,
1985 (char **)(void *)&inbuf,
1989 &inbuf_len, &seqnum,
1990 false /* trusted channel */);
1991 ok = smbd_unlock_socket(conn);
1993 exit_server_cleanly("failed to unlock");
1996 /* TODO: make this completely nonblocking */
1997 status = receive_smb_talloc(mem_ctx, fd,
1998 (char **)(void *)&inbuf,
2002 &inbuf_len, &seqnum,
2003 true /* trusted channel */);
2006 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2009 if (NT_STATUS_IS_ERR(status)) {
2010 exit_server_cleanly("failed to receive smb request");
2012 if (!NT_STATUS_IS_OK(status)) {
2017 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2018 seqnum, encrypted, NULL);
2021 static void smbd_server_connection_handler(struct event_context *ev,
2022 struct fd_event *fde,
2026 struct smbd_server_connection *conn = talloc_get_type(private_data,
2027 struct smbd_server_connection);
2029 if (flags & EVENT_FD_WRITE) {
2030 smbd_server_connection_write_handler(conn);
2031 } else if (flags & EVENT_FD_READ) {
2032 smbd_server_connection_read_handler(conn, smbd_server_fd());
2036 static void smbd_server_echo_handler(struct event_context *ev,
2037 struct fd_event *fde,
2041 struct smbd_server_connection *conn = talloc_get_type(private_data,
2042 struct smbd_server_connection);
2044 if (flags & EVENT_FD_WRITE) {
2045 smbd_server_connection_write_handler(conn);
2046 } else if (flags & EVENT_FD_READ) {
2047 smbd_server_connection_read_handler(
2048 conn, conn->smb1.echo_handler.trusted_fd);
2052 /****************************************************************************
2053 received when we should release a specific IP
2054 ****************************************************************************/
2055 static void release_ip(const char *ip, void *priv)
2057 char addr[INET6_ADDRSTRLEN];
2060 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2062 if (strncmp("::ffff:", addr, 7) == 0) {
2066 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2067 /* we can't afford to do a clean exit - that involves
2068 database writes, which would potentially mean we
2069 are still running after the failover has finished -
2070 we have to get rid of this process ID straight
2072 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2074 /* note we must exit with non-zero status so the unclean handler gets
2075 called in the parent, so that the brl database is tickled */
2080 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2081 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2083 release_ip((char *)data->data, NULL);
2086 #ifdef CLUSTER_SUPPORT
2087 static int client_get_tcp_info(struct sockaddr_storage *server,
2088 struct sockaddr_storage *client)
2091 if (server_fd == -1) {
2094 length = sizeof(*server);
2095 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2098 length = sizeof(*client);
2099 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2107 * Send keepalive packets to our client
2109 static bool keepalive_fn(const struct timeval *now, void *private_data)
2114 ok = smbd_lock_socket(smbd_server_conn);
2116 exit_server_cleanly("failed to lock socket");
2119 ret = send_keepalive(smbd_server_fd());
2121 ok = smbd_unlock_socket(smbd_server_conn);
2123 exit_server_cleanly("failed to unlock socket");
2127 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2134 * Do the recurring check if we're idle
2136 static bool deadtime_fn(const struct timeval *now, void *private_data)
2138 if ((conn_num_open() == 0)
2139 || (conn_idle_all(now->tv_sec))) {
2140 DEBUG( 2, ( "Closing idle connection\n" ) );
2141 messaging_send(smbd_messaging_context(), procid_self(),
2142 MSG_SHUTDOWN, &data_blob_null);
2150 * Do the recurring log file and smb.conf reload checks.
2153 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2155 change_to_root_user();
2157 /* update printer queue caches if necessary */
2158 update_monitored_printq_cache();
2160 /* check if we need to reload services */
2161 check_reload(time(NULL));
2163 /* Change machine password if neccessary. */
2164 attempt_machine_password_change();
2167 * Force a log file check.
2169 force_check_log_size();
2174 static int create_unlink_tmp(const char *dir)
2179 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2180 if (fname == NULL) {
2184 fd = mkstemp(fname);
2189 if (unlink(fname) == -1) {
2190 int sys_errno = errno;
2200 struct smbd_echo_state {
2201 struct tevent_context *ev;
2202 struct iovec *pending;
2203 struct smbd_server_connection *sconn;
2206 struct tevent_fd *parent_fde;
2208 struct tevent_fd *read_fde;
2209 struct tevent_req *write_req;
2212 static void smbd_echo_writer_done(struct tevent_req *req);
2214 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2218 if (state->write_req != NULL) {
2222 num_pending = talloc_array_length(state->pending);
2223 if (num_pending == 0) {
2227 state->write_req = writev_send(state, state->ev, NULL,
2229 state->pending, num_pending);
2230 if (state->write_req == NULL) {
2231 DEBUG(1, ("writev_send failed\n"));
2235 talloc_steal(state->write_req, state->pending);
2236 state->pending = NULL;
2238 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2242 static void smbd_echo_writer_done(struct tevent_req *req)
2244 struct smbd_echo_state *state = tevent_req_callback_data(
2245 req, struct smbd_echo_state);
2249 written = writev_recv(req, &err);
2251 state->write_req = NULL;
2252 if (written == -1) {
2253 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2256 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2257 smbd_echo_activate_writer(state);
2260 static bool smbd_echo_reply(int fd,
2261 uint8_t *inbuf, size_t inbuf_len,
2264 struct smb_request req;
2265 uint16_t num_replies;
2270 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2271 DEBUG(10, ("Got netbios keepalive\n"));
2278 if (inbuf_len < smb_size) {
2279 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2282 if (!valid_smb_header(inbuf)) {
2283 DEBUG(10, ("Got invalid SMB header\n"));
2287 init_smb_request(&req, inbuf, 0, false);
2289 req.seqnum = seqnum;
2291 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2292 smb_messages[req.cmd].name
2293 ? smb_messages[req.cmd].name : "unknown"));
2295 if (req.cmd != SMBecho) {
2302 num_replies = SVAL(req.vwv+0, 0);
2303 if (num_replies != 1) {
2304 /* Not a Windows "Hey, you're still there?" request */
2308 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2310 DEBUG(10, ("create_outbuf failed\n"));
2313 req.outbuf = (uint8_t *)outbuf;
2315 SSVAL(req.outbuf, smb_vwv0, num_replies);
2317 if (req.buflen > 0) {
2318 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2321 out_len = smb_len(req.outbuf) + 4;
2323 ok = srv_send_smb(smbd_server_fd(),
2327 TALLOC_FREE(outbuf);
2335 static void smbd_echo_exit(struct tevent_context *ev,
2336 struct tevent_fd *fde, uint16_t flags,
2339 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2343 static void smbd_echo_reader(struct tevent_context *ev,
2344 struct tevent_fd *fde, uint16_t flags,
2347 struct smbd_echo_state *state = talloc_get_type_abort(
2348 private_data, struct smbd_echo_state);
2349 struct smbd_server_connection *sconn = state->sconn;
2350 size_t unread, num_pending;
2353 uint32_t seqnum = 0;
2356 bool encrypted = false;
2360 ok = smbd_lock_socket(sconn);
2362 DEBUG(0, ("%s: failed to lock socket\n",
2367 if (!fd_is_readable(smbd_server_fd())) {
2368 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2369 (int)sys_getpid()));
2370 ok = smbd_unlock_socket(sconn);
2372 DEBUG(1, ("%s: failed to unlock socket in\n",
2379 num_pending = talloc_array_length(state->pending);
2380 tmp = talloc_realloc(state, state->pending, struct iovec,
2383 DEBUG(1, ("talloc_realloc failed\n"));
2386 state->pending = tmp;
2388 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2390 status = receive_smb_talloc(state->pending, smbd_server_fd(),
2391 (char **)(void *)&state->pending[num_pending].iov_base,
2395 &state->pending[num_pending].iov_len,
2397 false /* trusted_channel*/);
2398 if (!NT_STATUS_IS_OK(status)) {
2399 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2400 (int)sys_getpid(), nt_errstr(status)));
2404 ok = smbd_unlock_socket(sconn);
2406 DEBUG(1, ("%s: failed to unlock socket in\n",
2411 reply = smbd_echo_reply(smbd_server_fd(),
2412 (uint8_t *)state->pending[num_pending].iov_base,
2413 state->pending[num_pending].iov_len,
2416 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2417 /* no check, shrinking by some bytes does not fail */
2418 state->pending = talloc_realloc(state, state->pending,
2424 if (state->pending[num_pending].iov_len >= smb_size) {
2426 * place the seqnum in the packet so that the main process
2427 * can reply with signing
2429 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2430 smb_ss_field, seqnum);
2431 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2432 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2435 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2436 smbd_echo_activate_writer(state);
2439 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2442 struct smbd_echo_state *state;
2444 state = talloc_zero(sconn, struct smbd_echo_state);
2445 if (state == NULL) {
2446 DEBUG(1, ("talloc failed\n"));
2449 state->sconn = sconn;
2450 state->parent_pipe = parent_pipe;
2451 state->ev = s3_tevent_context_init(state);
2452 if (state->ev == NULL) {
2453 DEBUG(1, ("tevent_context_init failed\n"));
2457 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2458 TEVENT_FD_READ, smbd_echo_exit,
2460 if (state->parent_fde == NULL) {
2461 DEBUG(1, ("tevent_add_fd failed\n"));
2465 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2466 TEVENT_FD_READ, smbd_echo_reader,
2468 if (state->read_fde == NULL) {
2469 DEBUG(1, ("tevent_add_fd failed\n"));
2475 if (tevent_loop_once(state->ev) == -1) {
2476 DEBUG(1, ("tevent_loop_once failed: %s\n",
2485 * Handle SMBecho requests in a forked child process
2487 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2489 int listener_pipe[2];
2493 res = pipe(listener_pipe);
2495 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2498 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2499 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2500 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2508 close(listener_pipe[0]);
2509 set_blocking(listener_pipe[1], false);
2511 status = reinit_after_fork(smbd_messaging_context(),
2512 smbd_event_context(), false);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 DEBUG(1, ("reinit_after_fork failed: %s\n",
2515 nt_errstr(status)));
2518 smbd_echo_loop(sconn, listener_pipe[1]);
2521 close(listener_pipe[1]);
2522 listener_pipe[1] = -1;
2523 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2525 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2528 * Without smb signing this is the same as the normal smbd
2529 * listener. This needs to change once signing comes in.
2531 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2533 sconn->smb1.echo_handler.trusted_fd,
2535 smbd_server_echo_handler,
2537 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2538 DEBUG(1, ("event_add_fd failed\n"));
2545 if (listener_pipe[0] != -1) {
2546 close(listener_pipe[0]);
2548 if (listener_pipe[1] != -1) {
2549 close(listener_pipe[1]);
2551 sconn->smb1.echo_handler.trusted_fd = -1;
2552 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2553 close(sconn->smb1.echo_handler.socket_lock_fd);
2555 sconn->smb1.echo_handler.trusted_fd = -1;
2556 sconn->smb1.echo_handler.socket_lock_fd = -1;
2560 /****************************************************************************
2561 Process commands from the client
2562 ****************************************************************************/
2564 void smbd_process(void)
2566 TALLOC_CTX *frame = talloc_stackframe();
2567 char remaddr[INET6_ADDRSTRLEN];
2569 smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
2570 if (!smbd_server_conn) {
2571 exit_server("failed to create smbd_server_connection");
2574 smbd_server_conn->smb1.echo_handler.socket_lock_fd = -1;
2575 smbd_server_conn->smb1.echo_handler.trusted_fd = -1;
2577 /* Ensure child is set to blocking mode */
2578 set_blocking(smbd_server_fd(),True);
2580 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2581 set_socket_options(smbd_server_fd(), lp_socket_options());
2583 /* this is needed so that we get decent entries
2584 in smbstatus for port 445 connects */
2585 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2589 reload_services(true);
2592 * Before the first packet, check the global hosts allow/ hosts deny
2593 * parameters before doing any parsing of packets passed to us by the
2594 * client. This prevents attacks on our parsing code from hosts not in
2595 * the hosts allow list.
2598 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2599 lp_hostsdeny(-1))) {
2600 char addr[INET6_ADDRSTRLEN];
2603 * send a negative session response "not listening on calling
2606 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2607 DEBUG( 1, ("Connection denied from %s\n",
2608 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2609 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2611 exit_server_cleanly("connection denied");
2618 smb_perfcount_init();
2620 if (!init_account_policy()) {
2621 exit_server("Could not open account policy tdb.\n");
2624 if (*lp_rootdir()) {
2625 if (chroot(lp_rootdir()) != 0) {
2626 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2627 exit_server("Failed to chroot()");
2629 if (chdir("/") == -1) {
2630 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2631 exit_server("Failed to chroot()");
2633 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2636 if (!srv_init_signing(smbd_server_conn)) {
2637 exit_server("Failed to init smb_signing");
2640 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2641 exit_server("Failed to fork echo handler");
2645 if (!init_oplocks(smbd_messaging_context()))
2646 exit_server("Failed to init oplocks");
2648 /* Setup aio signal handler. */
2649 initialize_async_io_handler();
2651 /* register our message handlers */
2652 messaging_register(smbd_messaging_context(), NULL,
2653 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2654 messaging_register(smbd_messaging_context(), NULL,
2655 MSG_SMB_RELEASE_IP, msg_release_ip);
2656 messaging_register(smbd_messaging_context(), NULL,
2657 MSG_SMB_CLOSE_FILE, msg_close_file);
2659 if ((lp_keepalive() != 0)
2660 && !(event_add_idle(smbd_event_context(), NULL,
2661 timeval_set(lp_keepalive(), 0),
2662 "keepalive", keepalive_fn,
2664 DEBUG(0, ("Could not add keepalive event\n"));
2668 if (!(event_add_idle(smbd_event_context(), NULL,
2669 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2670 "deadtime", deadtime_fn, NULL))) {
2671 DEBUG(0, ("Could not add deadtime event\n"));
2675 if (!(event_add_idle(smbd_event_context(), NULL,
2676 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2677 "housekeeping", housekeeping_fn, NULL))) {
2678 DEBUG(0, ("Could not add housekeeping event\n"));
2682 #ifdef CLUSTER_SUPPORT
2684 if (lp_clustering()) {
2686 * We need to tell ctdb about our client's TCP
2687 * connection, so that for failover ctdbd can send
2688 * tickle acks, triggering a reconnection by the
2692 struct sockaddr_storage srv, clnt;
2694 if (client_get_tcp_info(&srv, &clnt) == 0) {
2698 status = ctdbd_register_ips(
2699 messaging_ctdbd_connection(),
2700 &srv, &clnt, release_ip, NULL);
2702 if (!NT_STATUS_IS_OK(status)) {
2703 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2704 nt_errstr(status)));
2708 DEBUG(0,("Unable to get tcp info for "
2709 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2716 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2718 smbd_server_conn->fde = event_add_fd(smbd_event_context(),
2722 smbd_server_connection_handler,
2724 if (!smbd_server_conn->fde) {
2725 exit_server("failed to create smbd_server_connection fde");
2733 frame = talloc_stackframe_pool(8192);
2737 status = smbd_server_connection_loop_once(smbd_server_conn);
2738 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2739 !NT_STATUS_IS_OK(status)) {
2740 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2741 " exiting\n", nt_errstr(status)));
2748 exit_server_cleanly(NULL);
2751 bool req_is_in_chain(struct smb_request *req)
2753 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2755 * We're right now handling a subsequent request, so we must
2761 if (!is_andx_req(req->cmd)) {
2767 * Okay, an illegal request, but definitely not chained :-)
2772 return (CVAL(req->vwv+0, 0) != 0xFF);