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 (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
883 return NT_STATUS_RETRY;
888 /* something is wrong. Maybe the socket is dead? */
889 return map_nt_error_from_unix(errno);
892 /* Did we timeout ? */
894 return NT_STATUS_RETRY;
897 /* should not be reached */
898 return NT_STATUS_INTERNAL_ERROR;
902 * Only allow 5 outstanding trans requests. We're allocating memory, so
906 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
909 for (; list != NULL; list = list->next) {
911 if (list->mid == mid) {
912 return NT_STATUS_INVALID_PARAMETER;
918 return NT_STATUS_INSUFFICIENT_RESOURCES;
925 These flags determine some of the permissions required to do an operation
927 Note that I don't set NEED_WRITE on some write operations because they
928 are used by some brain-dead clients when printing, and I don't want to
929 force write permissions on print services.
931 #define AS_USER (1<<0)
932 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
933 #define TIME_INIT (1<<2)
934 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
935 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
936 #define DO_CHDIR (1<<6)
939 define a list of possible SMB messages and their corresponding
940 functions. Any message that has a NULL function is unimplemented -
941 please feel free to contribute implementations!
943 static const struct smb_message_struct {
945 void (*fn)(struct smb_request *req);
947 } smb_messages[256] = {
949 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
950 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
951 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
952 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
953 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
954 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
955 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
956 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
957 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
958 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
959 /* 0x0a */ { "SMBread",reply_read,AS_USER},
960 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
961 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
962 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
963 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
964 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
965 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
966 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
967 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
968 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
969 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
970 /* 0x15 */ { NULL, NULL, 0 },
971 /* 0x16 */ { NULL, NULL, 0 },
972 /* 0x17 */ { NULL, NULL, 0 },
973 /* 0x18 */ { NULL, NULL, 0 },
974 /* 0x19 */ { NULL, NULL, 0 },
975 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
976 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
977 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
978 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
979 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
980 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
981 /* 0x20 */ { "SMBwritec", NULL,0},
982 /* 0x21 */ { NULL, NULL, 0 },
983 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
984 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
985 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
986 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
987 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
988 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
989 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
990 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
991 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
992 /* 0x2b */ { "SMBecho",reply_echo,0},
993 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
994 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
995 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
996 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
997 /* 0x30 */ { NULL, NULL, 0 },
998 /* 0x31 */ { NULL, NULL, 0 },
999 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1000 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1001 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1002 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1003 /* 0x36 */ { NULL, NULL, 0 },
1004 /* 0x37 */ { NULL, NULL, 0 },
1005 /* 0x38 */ { NULL, NULL, 0 },
1006 /* 0x39 */ { NULL, NULL, 0 },
1007 /* 0x3a */ { NULL, NULL, 0 },
1008 /* 0x3b */ { NULL, NULL, 0 },
1009 /* 0x3c */ { NULL, NULL, 0 },
1010 /* 0x3d */ { NULL, NULL, 0 },
1011 /* 0x3e */ { NULL, NULL, 0 },
1012 /* 0x3f */ { NULL, NULL, 0 },
1013 /* 0x40 */ { NULL, NULL, 0 },
1014 /* 0x41 */ { NULL, NULL, 0 },
1015 /* 0x42 */ { NULL, NULL, 0 },
1016 /* 0x43 */ { NULL, NULL, 0 },
1017 /* 0x44 */ { NULL, NULL, 0 },
1018 /* 0x45 */ { NULL, NULL, 0 },
1019 /* 0x46 */ { NULL, NULL, 0 },
1020 /* 0x47 */ { NULL, NULL, 0 },
1021 /* 0x48 */ { NULL, NULL, 0 },
1022 /* 0x49 */ { NULL, NULL, 0 },
1023 /* 0x4a */ { NULL, NULL, 0 },
1024 /* 0x4b */ { NULL, NULL, 0 },
1025 /* 0x4c */ { NULL, NULL, 0 },
1026 /* 0x4d */ { NULL, NULL, 0 },
1027 /* 0x4e */ { NULL, NULL, 0 },
1028 /* 0x4f */ { NULL, NULL, 0 },
1029 /* 0x50 */ { NULL, NULL, 0 },
1030 /* 0x51 */ { NULL, NULL, 0 },
1031 /* 0x52 */ { NULL, NULL, 0 },
1032 /* 0x53 */ { NULL, NULL, 0 },
1033 /* 0x54 */ { NULL, NULL, 0 },
1034 /* 0x55 */ { NULL, NULL, 0 },
1035 /* 0x56 */ { NULL, NULL, 0 },
1036 /* 0x57 */ { NULL, NULL, 0 },
1037 /* 0x58 */ { NULL, NULL, 0 },
1038 /* 0x59 */ { NULL, NULL, 0 },
1039 /* 0x5a */ { NULL, NULL, 0 },
1040 /* 0x5b */ { NULL, NULL, 0 },
1041 /* 0x5c */ { NULL, NULL, 0 },
1042 /* 0x5d */ { NULL, NULL, 0 },
1043 /* 0x5e */ { NULL, NULL, 0 },
1044 /* 0x5f */ { NULL, NULL, 0 },
1045 /* 0x60 */ { NULL, NULL, 0 },
1046 /* 0x61 */ { NULL, NULL, 0 },
1047 /* 0x62 */ { NULL, NULL, 0 },
1048 /* 0x63 */ { NULL, NULL, 0 },
1049 /* 0x64 */ { NULL, NULL, 0 },
1050 /* 0x65 */ { NULL, NULL, 0 },
1051 /* 0x66 */ { NULL, NULL, 0 },
1052 /* 0x67 */ { NULL, NULL, 0 },
1053 /* 0x68 */ { NULL, NULL, 0 },
1054 /* 0x69 */ { NULL, NULL, 0 },
1055 /* 0x6a */ { NULL, NULL, 0 },
1056 /* 0x6b */ { NULL, NULL, 0 },
1057 /* 0x6c */ { NULL, NULL, 0 },
1058 /* 0x6d */ { NULL, NULL, 0 },
1059 /* 0x6e */ { NULL, NULL, 0 },
1060 /* 0x6f */ { NULL, NULL, 0 },
1061 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1062 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1063 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1064 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1065 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1066 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1067 /* 0x76 */ { NULL, NULL, 0 },
1068 /* 0x77 */ { NULL, NULL, 0 },
1069 /* 0x78 */ { NULL, NULL, 0 },
1070 /* 0x79 */ { NULL, NULL, 0 },
1071 /* 0x7a */ { NULL, NULL, 0 },
1072 /* 0x7b */ { NULL, NULL, 0 },
1073 /* 0x7c */ { NULL, NULL, 0 },
1074 /* 0x7d */ { NULL, NULL, 0 },
1075 /* 0x7e */ { NULL, NULL, 0 },
1076 /* 0x7f */ { NULL, NULL, 0 },
1077 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1078 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1079 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1080 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1081 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1082 /* 0x85 */ { NULL, NULL, 0 },
1083 /* 0x86 */ { NULL, NULL, 0 },
1084 /* 0x87 */ { NULL, NULL, 0 },
1085 /* 0x88 */ { NULL, NULL, 0 },
1086 /* 0x89 */ { NULL, NULL, 0 },
1087 /* 0x8a */ { NULL, NULL, 0 },
1088 /* 0x8b */ { NULL, NULL, 0 },
1089 /* 0x8c */ { NULL, NULL, 0 },
1090 /* 0x8d */ { NULL, NULL, 0 },
1091 /* 0x8e */ { NULL, NULL, 0 },
1092 /* 0x8f */ { NULL, NULL, 0 },
1093 /* 0x90 */ { NULL, NULL, 0 },
1094 /* 0x91 */ { NULL, NULL, 0 },
1095 /* 0x92 */ { NULL, NULL, 0 },
1096 /* 0x93 */ { NULL, NULL, 0 },
1097 /* 0x94 */ { NULL, NULL, 0 },
1098 /* 0x95 */ { NULL, NULL, 0 },
1099 /* 0x96 */ { NULL, NULL, 0 },
1100 /* 0x97 */ { NULL, NULL, 0 },
1101 /* 0x98 */ { NULL, NULL, 0 },
1102 /* 0x99 */ { NULL, NULL, 0 },
1103 /* 0x9a */ { NULL, NULL, 0 },
1104 /* 0x9b */ { NULL, NULL, 0 },
1105 /* 0x9c */ { NULL, NULL, 0 },
1106 /* 0x9d */ { NULL, NULL, 0 },
1107 /* 0x9e */ { NULL, NULL, 0 },
1108 /* 0x9f */ { NULL, NULL, 0 },
1109 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1110 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1111 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1112 /* 0xa3 */ { NULL, NULL, 0 },
1113 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1114 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1115 /* 0xa6 */ { NULL, NULL, 0 },
1116 /* 0xa7 */ { NULL, NULL, 0 },
1117 /* 0xa8 */ { NULL, NULL, 0 },
1118 /* 0xa9 */ { NULL, NULL, 0 },
1119 /* 0xaa */ { NULL, NULL, 0 },
1120 /* 0xab */ { NULL, NULL, 0 },
1121 /* 0xac */ { NULL, NULL, 0 },
1122 /* 0xad */ { NULL, NULL, 0 },
1123 /* 0xae */ { NULL, NULL, 0 },
1124 /* 0xaf */ { NULL, NULL, 0 },
1125 /* 0xb0 */ { NULL, NULL, 0 },
1126 /* 0xb1 */ { NULL, NULL, 0 },
1127 /* 0xb2 */ { NULL, NULL, 0 },
1128 /* 0xb3 */ { NULL, NULL, 0 },
1129 /* 0xb4 */ { NULL, NULL, 0 },
1130 /* 0xb5 */ { NULL, NULL, 0 },
1131 /* 0xb6 */ { NULL, NULL, 0 },
1132 /* 0xb7 */ { NULL, NULL, 0 },
1133 /* 0xb8 */ { NULL, NULL, 0 },
1134 /* 0xb9 */ { NULL, NULL, 0 },
1135 /* 0xba */ { NULL, NULL, 0 },
1136 /* 0xbb */ { NULL, NULL, 0 },
1137 /* 0xbc */ { NULL, NULL, 0 },
1138 /* 0xbd */ { NULL, NULL, 0 },
1139 /* 0xbe */ { NULL, NULL, 0 },
1140 /* 0xbf */ { NULL, NULL, 0 },
1141 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1142 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1143 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1144 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1145 /* 0xc4 */ { NULL, NULL, 0 },
1146 /* 0xc5 */ { NULL, NULL, 0 },
1147 /* 0xc6 */ { NULL, NULL, 0 },
1148 /* 0xc7 */ { NULL, NULL, 0 },
1149 /* 0xc8 */ { NULL, NULL, 0 },
1150 /* 0xc9 */ { NULL, NULL, 0 },
1151 /* 0xca */ { NULL, NULL, 0 },
1152 /* 0xcb */ { NULL, NULL, 0 },
1153 /* 0xcc */ { NULL, NULL, 0 },
1154 /* 0xcd */ { NULL, NULL, 0 },
1155 /* 0xce */ { NULL, NULL, 0 },
1156 /* 0xcf */ { NULL, NULL, 0 },
1157 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1158 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1159 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1160 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1161 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1162 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1163 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1164 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1165 /* 0xd8 */ { NULL, NULL, 0 },
1166 /* 0xd9 */ { NULL, NULL, 0 },
1167 /* 0xda */ { NULL, NULL, 0 },
1168 /* 0xdb */ { NULL, NULL, 0 },
1169 /* 0xdc */ { NULL, NULL, 0 },
1170 /* 0xdd */ { NULL, NULL, 0 },
1171 /* 0xde */ { NULL, NULL, 0 },
1172 /* 0xdf */ { NULL, NULL, 0 },
1173 /* 0xe0 */ { NULL, NULL, 0 },
1174 /* 0xe1 */ { NULL, NULL, 0 },
1175 /* 0xe2 */ { NULL, NULL, 0 },
1176 /* 0xe3 */ { NULL, NULL, 0 },
1177 /* 0xe4 */ { NULL, NULL, 0 },
1178 /* 0xe5 */ { NULL, NULL, 0 },
1179 /* 0xe6 */ { NULL, NULL, 0 },
1180 /* 0xe7 */ { NULL, NULL, 0 },
1181 /* 0xe8 */ { NULL, NULL, 0 },
1182 /* 0xe9 */ { NULL, NULL, 0 },
1183 /* 0xea */ { NULL, NULL, 0 },
1184 /* 0xeb */ { NULL, NULL, 0 },
1185 /* 0xec */ { NULL, NULL, 0 },
1186 /* 0xed */ { NULL, NULL, 0 },
1187 /* 0xee */ { NULL, NULL, 0 },
1188 /* 0xef */ { NULL, NULL, 0 },
1189 /* 0xf0 */ { NULL, NULL, 0 },
1190 /* 0xf1 */ { NULL, NULL, 0 },
1191 /* 0xf2 */ { NULL, NULL, 0 },
1192 /* 0xf3 */ { NULL, NULL, 0 },
1193 /* 0xf4 */ { NULL, NULL, 0 },
1194 /* 0xf5 */ { NULL, NULL, 0 },
1195 /* 0xf6 */ { NULL, NULL, 0 },
1196 /* 0xf7 */ { NULL, NULL, 0 },
1197 /* 0xf8 */ { NULL, NULL, 0 },
1198 /* 0xf9 */ { NULL, NULL, 0 },
1199 /* 0xfa */ { NULL, NULL, 0 },
1200 /* 0xfb */ { NULL, NULL, 0 },
1201 /* 0xfc */ { NULL, NULL, 0 },
1202 /* 0xfd */ { NULL, NULL, 0 },
1203 /* 0xfe */ { NULL, NULL, 0 },
1204 /* 0xff */ { NULL, NULL, 0 }
1208 /*******************************************************************
1209 allocate and initialize a reply packet
1210 ********************************************************************/
1212 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1213 const char *inbuf, char **outbuf, uint8_t num_words,
1217 * Protect against integer wrap
1219 if ((num_bytes > 0xffffff)
1220 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1222 if (asprintf(&msg, "num_bytes too large: %u",
1223 (unsigned)num_bytes) == -1) {
1224 msg = CONST_DISCARD(char *, "num_bytes too large");
1229 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1230 smb_size + num_words*2 + num_bytes);
1231 if (*outbuf == NULL) {
1235 construct_reply_common(req, inbuf, *outbuf);
1236 srv_set_message(*outbuf, num_words, num_bytes, false);
1238 * Zero out the word area, the caller has to take care of the bcc area
1241 if (num_words != 0) {
1242 memset(*outbuf + smb_vwv0, 0, num_words*2);
1248 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1251 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1253 smb_panic("could not allocate output buffer\n");
1255 req->outbuf = (uint8_t *)outbuf;
1259 /*******************************************************************
1260 Dump a packet to a file.
1261 ********************************************************************/
1263 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1267 if (DEBUGLEVEL < 50) {
1271 if (len < 4) len = smb_len(data)+4;
1272 for (i=1;i<100;i++) {
1273 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1274 type ? "req" : "resp") == -1) {
1277 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1278 if (fd != -1 || errno != EEXIST) break;
1281 ssize_t ret = write(fd, data, len);
1283 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1285 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1290 /****************************************************************************
1291 Prepare everything for calling the actual request function, and potentially
1292 call the request function via the "new" interface.
1294 Return False if the "legacy" function needs to be called, everything is
1297 Return True if we're done.
1299 I know this API sucks, but it is the one with the least code change I could
1301 ****************************************************************************/
1303 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1307 connection_struct *conn = NULL;
1311 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1312 * so subtract 4 from it. */
1313 if (!valid_smb_header(req->inbuf)
1314 || (size < (smb_size - 4))) {
1315 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1316 smb_len(req->inbuf)));
1317 exit_server_cleanly("Non-SMB packet");
1320 if (smb_messages[type].fn == NULL) {
1321 DEBUG(0,("Unknown message type %d!\n",type));
1322 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1323 reply_unknown_new(req, type);
1327 flags = smb_messages[type].flags;
1329 /* In share mode security we must ignore the vuid. */
1330 session_tag = (lp_security() == SEC_SHARE)
1331 ? UID_FIELD_INVALID : req->vuid;
1334 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1335 (int)sys_getpid(), (unsigned long)conn));
1337 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1339 /* Ensure this value is replaced in the incoming packet. */
1340 SSVAL(req->inbuf,smb_uid,session_tag);
1343 * Ensure the correct username is in current_user_info. This is a
1344 * really ugly bugfix for problems with multiple session_setup_and_X's
1345 * being done and allowing %U and %G substitutions to work correctly.
1346 * There is a reason this code is done here, don't move it unless you
1347 * know what you're doing... :-).
1351 if (session_tag != last_session_tag) {
1352 user_struct *vuser = NULL;
1354 last_session_tag = session_tag;
1355 if(session_tag != UID_FIELD_INVALID) {
1356 vuser = get_valid_user_struct(session_tag);
1358 set_current_user_info(
1359 vuser->server_info->sanitized_username,
1360 vuser->server_info->unix_name,
1361 pdb_get_domain(vuser->server_info
1367 /* Does this call need to be run as the connected user? */
1368 if (flags & AS_USER) {
1370 /* Does this call need a valid tree connection? */
1373 * Amazingly, the error code depends on the command
1376 if (type == SMBntcreateX) {
1377 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1379 reply_doserror(req, ERRSRV, ERRinvnid);
1384 if (!change_to_user(conn,session_tag)) {
1385 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1389 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1391 /* Does it need write permission? */
1392 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1393 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1397 /* IPC services are limited */
1398 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1399 reply_doserror(req, ERRSRV,ERRaccess);
1403 /* This call needs to be run as root */
1404 change_to_root_user();
1407 /* load service specific parameters */
1409 if (req->encrypted) {
1410 conn->encrypted_tid = true;
1411 /* encrypted required from now on. */
1412 conn->encrypt_level = Required;
1413 } else if (ENCRYPTION_REQUIRED(conn)) {
1414 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1415 exit_server_cleanly("encryption required "
1421 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1422 (flags & (AS_USER|DO_CHDIR)
1424 reply_doserror(req, ERRSRV, ERRaccess);
1427 conn->num_smb_operations++;
1430 /* does this protocol need to be run as guest? */
1431 if ((flags & AS_GUEST)
1432 && (!change_to_guest() ||
1433 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1434 lp_hostsdeny(-1)))) {
1435 reply_doserror(req, ERRSRV, ERRaccess);
1439 smb_messages[type].fn(req);
1443 /****************************************************************************
1444 Construct a reply to the incoming packet.
1445 ****************************************************************************/
1447 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1448 uint32_t seqnum, bool encrypted,
1449 struct smb_perfcount_data *deferred_pcd)
1451 connection_struct *conn;
1452 struct smb_request *req;
1454 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1455 smb_panic("could not allocate smb_request");
1458 init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1459 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1460 req->seqnum = seqnum;
1462 /* we popped this message off the queue - keep original perf data */
1464 req->pcd = *deferred_pcd;
1466 SMB_PERFCOUNT_START(&req->pcd);
1467 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1468 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1471 conn = switch_message(req->cmd, req, size);
1473 if (req->unread_bytes) {
1474 /* writeX failed. drain socket. */
1475 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1476 req->unread_bytes) {
1477 smb_panic("failed to drain pending bytes");
1479 req->unread_bytes = 0;
1487 if (req->outbuf == NULL) {
1491 if (CVAL(req->outbuf,0) == 0) {
1492 show_msg((char *)req->outbuf);
1495 if (!srv_send_smb(smbd_server_fd(),
1496 (char *)req->outbuf,
1497 true, req->seqnum+1,
1498 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1500 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1508 /****************************************************************************
1509 Process an smb from the client
1510 ****************************************************************************/
1511 static void process_smb(struct smbd_server_connection *conn,
1512 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1513 uint32_t seqnum, bool encrypted,
1514 struct smb_perfcount_data *deferred_pcd)
1516 int msg_type = CVAL(inbuf,0);
1518 DO_PROFILE_INC(smb_count);
1520 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1522 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1524 (unsigned int)unread_bytes ));
1526 if (msg_type != 0) {
1528 * NetBIOS session request, keepalive, etc.
1530 reply_special((char *)inbuf);
1534 show_msg((char *)inbuf);
1536 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1540 conn->num_requests++;
1542 /* The timeout_processing function isn't run nearly
1543 often enough to implement 'max log size' without
1544 overrunning the size of the file by many megabytes.
1545 This is especially true if we are running at debug
1546 level 10. Checking every 50 SMBs is a nice
1547 tradeoff of performance vs log file size overrun. */
1549 if ((conn->num_requests % 50) == 0 &&
1550 need_to_check_log_size()) {
1551 change_to_root_user();
1556 /****************************************************************************
1557 Return a string containing the function name of a SMB command.
1558 ****************************************************************************/
1560 const char *smb_fn_name(int type)
1562 const char *unknown_name = "SMBunknown";
1564 if (smb_messages[type].name == NULL)
1565 return(unknown_name);
1567 return(smb_messages[type].name);
1570 /****************************************************************************
1571 Helper functions for contruct_reply.
1572 ****************************************************************************/
1574 void add_to_common_flags2(uint32 v)
1579 void remove_from_common_flags2(uint32 v)
1581 common_flags2 &= ~v;
1584 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1587 srv_set_message(outbuf,0,0,false);
1589 SCVAL(outbuf, smb_com, req->cmd);
1590 SIVAL(outbuf,smb_rcls,0);
1591 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1592 SSVAL(outbuf,smb_flg2,
1593 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1595 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1597 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1598 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1599 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1600 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1603 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1605 construct_reply_common(req, (char *)req->inbuf, outbuf);
1609 * How many bytes have we already accumulated up to the current wct field
1613 size_t req_wct_ofs(struct smb_request *req)
1617 if (req->chain_outbuf == NULL) {
1620 buf_size = talloc_get_size(req->chain_outbuf);
1621 if ((buf_size % 4) != 0) {
1622 buf_size += (4 - (buf_size % 4));
1624 return buf_size - 4;
1628 * Hack around reply_nterror & friends not being aware of chained requests,
1629 * generating illegal (i.e. wct==0) chain replies.
1632 static void fixup_chain_error_packet(struct smb_request *req)
1634 uint8_t *outbuf = req->outbuf;
1636 reply_outbuf(req, 2, 0);
1637 memcpy(req->outbuf, outbuf, smb_wct);
1638 TALLOC_FREE(outbuf);
1639 SCVAL(req->outbuf, smb_vwv0, 0xff);
1642 /****************************************************************************
1643 Construct a chained reply and add it to the already made reply
1644 ****************************************************************************/
1646 void chain_reply(struct smb_request *req)
1648 size_t smblen = smb_len(req->inbuf);
1649 size_t already_used, length_needed;
1651 uint32_t chain_offset; /* uint32_t to avoid overflow */
1658 if (IVAL(req->outbuf, smb_rcls) != 0) {
1659 fixup_chain_error_packet(req);
1663 * Any of the AndX requests and replies have at least a wct of
1664 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1665 * beginning of the SMB header to the next wct field.
1667 * None of the AndX requests put anything valuable in vwv[0] and [1],
1668 * so we can overwrite it here to form the chain.
1671 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1676 * Here we assume that this is the end of the chain. For that we need
1677 * to set "next command" to 0xff and the offset to 0. If we later find
1678 * more commands in the chain, this will be overwritten again.
1681 SCVAL(req->outbuf, smb_vwv0, 0xff);
1682 SCVAL(req->outbuf, smb_vwv0+1, 0);
1683 SSVAL(req->outbuf, smb_vwv1, 0);
1685 if (req->chain_outbuf == NULL) {
1687 * In req->chain_outbuf we collect all the replies. Start the
1688 * chain by copying in the first reply.
1690 * We do the realloc because later on we depend on
1691 * talloc_get_size to determine the length of
1692 * chain_outbuf. The reply_xxx routines might have
1693 * over-allocated (reply_pipe_read_and_X used to be such an
1696 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1697 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1698 if (req->chain_outbuf == NULL) {
1704 * Update smb headers where subsequent chained commands
1705 * may have updated them.
1707 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1708 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1710 if (!smb_splice_chain(&req->chain_outbuf,
1711 CVAL(req->outbuf, smb_com),
1712 CVAL(req->outbuf, smb_wct),
1713 (uint16_t *)(req->outbuf + smb_vwv),
1714 0, smb_buflen(req->outbuf),
1715 (uint8_t *)smb_buf(req->outbuf))) {
1718 TALLOC_FREE(req->outbuf);
1722 * We use the old request's vwv field to grab the next chained command
1723 * and offset into the chained fields.
1726 chain_cmd = CVAL(req->vwv+0, 0);
1727 chain_offset = SVAL(req->vwv+1, 0);
1729 if (chain_cmd == 0xff) {
1731 * End of chain, no more requests from the client. So ship the
1734 smb_setlen((char *)(req->chain_outbuf),
1735 talloc_get_size(req->chain_outbuf) - 4);
1737 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1738 true, req->seqnum+1,
1739 IS_CONN_ENCRYPTED(req->conn)
1742 exit_server_cleanly("chain_reply: srv_send_smb "
1745 TALLOC_FREE(req->chain_outbuf);
1750 /* add a new perfcounter for this element of chain */
1751 SMB_PERFCOUNT_ADD(&req->pcd);
1752 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1753 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1756 * Check if the client tries to fool us. The request so far uses the
1757 * space to the end of the byte buffer in the request just
1758 * processed. The chain_offset can't point into that area. If that was
1759 * the case, we could end up with an endless processing of the chain,
1760 * we would always handle the same request.
1763 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1764 if (chain_offset < already_used) {
1769 * Next check: Make sure the chain offset does not point beyond the
1770 * overall smb request length.
1773 length_needed = chain_offset+1; /* wct */
1774 if (length_needed > smblen) {
1779 * Now comes the pointer magic. Goal here is to set up req->vwv and
1780 * req->buf correctly again to be able to call the subsequent
1781 * switch_message(). The chain offset (the former vwv[1]) points at
1782 * the new wct field.
1785 wct = CVAL(smb_base(req->inbuf), chain_offset);
1788 * Next consistency check: Make the new vwv array fits in the overall
1792 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1793 if (length_needed > smblen) {
1796 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1799 * Now grab the new byte buffer....
1802 buflen = SVAL(vwv+wct, 0);
1805 * .. and check that it fits.
1808 length_needed += buflen;
1809 if (length_needed > smblen) {
1812 buf = (uint8_t *)(vwv+wct+1);
1814 req->cmd = chain_cmd;
1817 req->buflen = buflen;
1820 switch_message(chain_cmd, req, smblen);
1822 if (req->outbuf == NULL) {
1824 * This happens if the chained command has suspended itself or
1825 * if it has called srv_send_smb() itself.
1831 * We end up here if the chained command was not itself chained or
1832 * suspended, but for example a close() command. We now need to splice
1833 * the chained commands' outbuf into the already built up chain_outbuf
1834 * and ship the result.
1840 * We end up here if there's any error in the chain syntax. Report a
1841 * DOS error, just like Windows does.
1843 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1844 fixup_chain_error_packet(req);
1847 if (!smb_splice_chain(&req->chain_outbuf,
1848 CVAL(req->outbuf, smb_com),
1849 CVAL(req->outbuf, smb_wct),
1850 (uint16_t *)(req->outbuf + smb_vwv),
1851 0, smb_buflen(req->outbuf),
1852 (uint8_t *)smb_buf(req->outbuf))) {
1853 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1855 TALLOC_FREE(req->outbuf);
1857 smb_setlen((char *)(req->chain_outbuf),
1858 talloc_get_size(req->chain_outbuf) - 4);
1860 show_msg((char *)(req->chain_outbuf));
1862 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1863 true, req->seqnum+1,
1864 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1866 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1868 TALLOC_FREE(req->chain_outbuf);
1872 /****************************************************************************
1873 Check if services need reloading.
1874 ****************************************************************************/
1876 void check_reload(time_t t)
1878 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1880 if(last_smb_conf_reload_time == 0) {
1881 last_smb_conf_reload_time = t;
1882 /* Our printing subsystem might not be ready at smbd start up.
1883 Then no printer is available till the first printers check
1884 is performed. A lower initial interval circumvents this. */
1885 if ( printcap_cache_time > 60 )
1886 last_printer_reload_time = t - printcap_cache_time + 60;
1888 last_printer_reload_time = t;
1891 if (mypid != getpid()) { /* First time or fork happened meanwhile */
1892 /* randomize over 60 second the printcap reload to avoid all
1893 * process hitting cupsd at the same time */
1894 int time_range = 60;
1896 last_printer_reload_time += random() % time_range;
1900 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1901 reload_services(True);
1902 last_smb_conf_reload_time = t;
1905 /* 'printcap cache time = 0' disable the feature */
1907 if ( printcap_cache_time != 0 )
1909 /* see if it's time to reload or if the clock has been set back */
1911 if ( (t >= last_printer_reload_time+printcap_cache_time)
1912 || (t-last_printer_reload_time < 0) )
1914 DEBUG( 3,( "Printcap cache time expired.\n"));
1916 last_printer_reload_time = t;
1921 static bool fd_is_readable(int fd)
1924 struct timeval timeout = {0, };
1930 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
1934 return FD_ISSET(fd, &fds);
1937 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1939 /* TODO: make write nonblocking */
1942 static void smbd_server_connection_read_handler(
1943 struct smbd_server_connection *conn, int fd)
1945 uint8_t *inbuf = NULL;
1946 size_t inbuf_len = 0;
1947 size_t unread_bytes = 0;
1948 bool encrypted = false;
1949 TALLOC_CTX *mem_ctx = talloc_tos();
1955 bool from_client = (smbd_server_fd() == fd)?true:false;
1958 ok = smbd_lock_socket(conn);
1960 exit_server_cleanly("failed to lock socket");
1963 if (!fd_is_readable(smbd_server_fd())) {
1964 DEBUG(10,("the echo listener was faster\n"));
1965 ok = smbd_unlock_socket(conn);
1967 exit_server_cleanly("failed to unlock");
1972 /* TODO: make this completely nonblocking */
1973 status = receive_smb_talloc(mem_ctx, fd,
1974 (char **)(void *)&inbuf,
1978 &inbuf_len, &seqnum,
1979 false /* trusted channel */);
1980 ok = smbd_unlock_socket(conn);
1982 exit_server_cleanly("failed to unlock");
1985 /* TODO: make this completely nonblocking */
1986 status = receive_smb_talloc(mem_ctx, fd,
1987 (char **)(void *)&inbuf,
1991 &inbuf_len, &seqnum,
1992 true /* trusted channel */);
1995 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1998 if (NT_STATUS_IS_ERR(status)) {
1999 exit_server_cleanly("failed to receive smb request");
2001 if (!NT_STATUS_IS_OK(status)) {
2006 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2007 seqnum, encrypted, NULL);
2010 static void smbd_server_connection_handler(struct event_context *ev,
2011 struct fd_event *fde,
2015 struct smbd_server_connection *conn = talloc_get_type(private_data,
2016 struct smbd_server_connection);
2018 if (flags & EVENT_FD_WRITE) {
2019 smbd_server_connection_write_handler(conn);
2020 } else if (flags & EVENT_FD_READ) {
2021 smbd_server_connection_read_handler(conn, smbd_server_fd());
2025 static void smbd_server_echo_handler(struct event_context *ev,
2026 struct fd_event *fde,
2030 struct smbd_server_connection *conn = talloc_get_type(private_data,
2031 struct smbd_server_connection);
2033 if (flags & EVENT_FD_WRITE) {
2034 smbd_server_connection_write_handler(conn);
2035 } else if (flags & EVENT_FD_READ) {
2036 smbd_server_connection_read_handler(
2037 conn, conn->smb1.echo_handler.trusted_fd);
2041 /****************************************************************************
2042 received when we should release a specific IP
2043 ****************************************************************************/
2044 static void release_ip(const char *ip, void *priv)
2046 char addr[INET6_ADDRSTRLEN];
2049 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2051 if (strncmp("::ffff:", addr, 7) == 0) {
2055 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2056 /* we can't afford to do a clean exit - that involves
2057 database writes, which would potentially mean we
2058 are still running after the failover has finished -
2059 we have to get rid of this process ID straight
2061 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2063 /* note we must exit with non-zero status so the unclean handler gets
2064 called in the parent, so that the brl database is tickled */
2069 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2070 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2072 release_ip((char *)data->data, NULL);
2075 #ifdef CLUSTER_SUPPORT
2076 static int client_get_tcp_info(struct sockaddr_storage *server,
2077 struct sockaddr_storage *client)
2080 if (server_fd == -1) {
2083 length = sizeof(*server);
2084 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2087 length = sizeof(*client);
2088 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2096 * Send keepalive packets to our client
2098 static bool keepalive_fn(const struct timeval *now, void *private_data)
2103 ok = smbd_lock_socket(smbd_server_conn);
2105 exit_server_cleanly("failed to lock socket");
2108 ret = send_keepalive(smbd_server_fd());
2110 ok = smbd_unlock_socket(smbd_server_conn);
2112 exit_server_cleanly("failed to unlock socket");
2116 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2123 * Do the recurring check if we're idle
2125 static bool deadtime_fn(const struct timeval *now, void *private_data)
2127 if ((conn_num_open() == 0)
2128 || (conn_idle_all(now->tv_sec))) {
2129 DEBUG( 2, ( "Closing idle connection\n" ) );
2130 messaging_send(smbd_messaging_context(), procid_self(),
2131 MSG_SHUTDOWN, &data_blob_null);
2139 * Do the recurring log file and smb.conf reload checks.
2142 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2144 change_to_root_user();
2146 /* update printer queue caches if necessary */
2147 update_monitored_printq_cache();
2149 /* check if we need to reload services */
2150 check_reload(time(NULL));
2152 /* Change machine password if neccessary. */
2153 attempt_machine_password_change();
2156 * Force a log file check.
2158 force_check_log_size();
2163 static int create_unlink_tmp(const char *dir)
2168 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2169 if (fname == NULL) {
2173 fd = mkstemp(fname);
2178 if (unlink(fname) == -1) {
2179 int sys_errno = errno;
2189 struct smbd_echo_state {
2190 struct tevent_context *ev;
2191 struct iovec *pending;
2192 struct smbd_server_connection *sconn;
2195 struct tevent_fd *parent_fde;
2197 struct tevent_fd *read_fde;
2198 struct tevent_req *write_req;
2201 static void smbd_echo_writer_done(struct tevent_req *req);
2203 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2207 if (state->write_req != NULL) {
2211 num_pending = talloc_array_length(state->pending);
2212 if (num_pending == 0) {
2216 state->write_req = writev_send(state, state->ev, NULL,
2218 state->pending, num_pending);
2219 if (state->write_req == NULL) {
2220 DEBUG(1, ("writev_send failed\n"));
2224 talloc_steal(state->write_req, state->pending);
2225 state->pending = NULL;
2227 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2231 static void smbd_echo_writer_done(struct tevent_req *req)
2233 struct smbd_echo_state *state = tevent_req_callback_data(
2234 req, struct smbd_echo_state);
2238 written = writev_recv(req, &err);
2240 state->write_req = NULL;
2241 if (written == -1) {
2242 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2245 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2246 smbd_echo_activate_writer(state);
2249 static bool smbd_echo_reply(int fd,
2250 uint8_t *inbuf, size_t inbuf_len,
2253 struct smb_request req;
2254 uint16_t num_replies;
2259 if (inbuf_len < smb_size) {
2260 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2263 if (!valid_smb_header(inbuf)) {
2264 DEBUG(10, ("Got invalid SMB header\n"));
2268 init_smb_request(&req, inbuf, 0, false);
2270 req.seqnum = seqnum;
2272 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2273 smb_messages[req.cmd].name
2274 ? smb_messages[req.cmd].name : "unknown"));
2276 if (req.cmd != SMBecho) {
2283 num_replies = SVAL(req.vwv+0, 0);
2284 if (num_replies != 1) {
2285 /* Not a Windows "Hey, you're still there?" request */
2289 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2291 DEBUG(10, ("create_outbuf failed\n"));
2294 req.outbuf = (uint8_t *)outbuf;
2296 SSVAL(req.outbuf, smb_vwv0, num_replies);
2298 if (req.buflen > 0) {
2299 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2302 out_len = smb_len(req.outbuf) + 4;
2304 ok = srv_send_smb(smbd_server_fd(),
2308 TALLOC_FREE(outbuf);
2316 static void smbd_echo_exit(struct tevent_context *ev,
2317 struct tevent_fd *fde, uint16_t flags,
2320 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2324 static void smbd_echo_reader(struct tevent_context *ev,
2325 struct tevent_fd *fde, uint16_t flags,
2328 struct smbd_echo_state *state = talloc_get_type_abort(
2329 private_data, struct smbd_echo_state);
2330 struct smbd_server_connection *sconn = state->sconn;
2331 size_t unread, num_pending;
2334 uint32_t seqnum = 0;
2337 bool encrypted = false;
2339 ok = smbd_lock_socket(sconn);
2341 DEBUG(0, ("%s: failed to lock socket\n",
2346 if (!fd_is_readable(smbd_server_fd())) {
2347 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2348 (int)sys_getpid()));
2349 ok = smbd_unlock_socket(sconn);
2351 DEBUG(1, ("%s: failed to unlock socket in\n",
2358 num_pending = talloc_array_length(state->pending);
2359 tmp = talloc_realloc(state, state->pending, struct iovec,
2362 DEBUG(1, ("talloc_realloc failed\n"));
2365 state->pending = tmp;
2367 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2369 status = receive_smb_talloc(state, smbd_server_fd(),
2370 (char **)(void *)&state->pending[num_pending].iov_base,
2374 &state->pending[num_pending].iov_len,
2376 false /* trusted_channel*/);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2379 (int)sys_getpid(), nt_errstr(status)));
2383 ok = smbd_unlock_socket(sconn);
2385 DEBUG(1, ("%s: failed to unlock socket in\n",
2391 * place the seqnum in the packet so that the main process can reply
2394 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2395 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2397 reply = smbd_echo_reply(smbd_server_fd(),
2398 (uint8_t *)state->pending[num_pending].iov_base,
2399 state->pending[num_pending].iov_len,
2402 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2403 /* no check, shrinking by some bytes does not fail */
2404 state->pending = talloc_realloc(state, state->pending,
2408 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2409 smbd_echo_activate_writer(state);
2413 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2416 struct smbd_echo_state *state;
2418 state = talloc_zero(sconn, struct smbd_echo_state);
2419 if (state == NULL) {
2420 DEBUG(1, ("talloc failed\n"));
2423 state->sconn = sconn;
2424 state->parent_pipe = parent_pipe;
2425 state->ev = s3_tevent_context_init(state);
2426 if (state->ev == NULL) {
2427 DEBUG(1, ("tevent_context_init failed\n"));
2431 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2432 TEVENT_FD_READ, smbd_echo_exit,
2434 if (state->parent_fde == NULL) {
2435 DEBUG(1, ("tevent_add_fd failed\n"));
2439 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2440 TEVENT_FD_READ, smbd_echo_reader,
2442 if (state->read_fde == NULL) {
2443 DEBUG(1, ("tevent_add_fd failed\n"));
2449 if (tevent_loop_once(state->ev) == -1) {
2450 DEBUG(1, ("tevent_loop_once failed: %s\n",
2459 * Handle SMBecho requests in a forked child process
2461 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2463 int listener_pipe[2];
2467 res = pipe(listener_pipe);
2469 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2472 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2473 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2474 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2482 close(listener_pipe[0]);
2484 status = reinit_after_fork(smbd_messaging_context(),
2485 smbd_event_context(), false);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 DEBUG(1, ("reinit_after_fork failed: %s\n",
2488 nt_errstr(status)));
2491 smbd_echo_loop(sconn, listener_pipe[1]);
2494 close(listener_pipe[1]);
2495 listener_pipe[1] = -1;
2496 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2498 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2501 * Without smb signing this is the same as the normal smbd
2502 * listener. This needs to change once signing comes in.
2504 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2506 sconn->smb1.echo_handler.trusted_fd,
2508 smbd_server_echo_handler,
2510 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2511 DEBUG(1, ("event_add_fd failed\n"));
2518 if (listener_pipe[0] != -1) {
2519 close(listener_pipe[0]);
2521 if (listener_pipe[1] != -1) {
2522 close(listener_pipe[1]);
2524 sconn->smb1.echo_handler.trusted_fd = -1;
2525 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2526 close(sconn->smb1.echo_handler.socket_lock_fd);
2528 sconn->smb1.echo_handler.trusted_fd = -1;
2529 sconn->smb1.echo_handler.socket_lock_fd = -1;
2533 /****************************************************************************
2534 Process commands from the client
2535 ****************************************************************************/
2537 void smbd_process(void)
2539 TALLOC_CTX *frame = talloc_stackframe();
2540 char remaddr[INET6_ADDRSTRLEN];
2542 smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
2543 if (!smbd_server_conn) {
2544 exit_server("failed to create smbd_server_connection");
2547 smbd_server_conn->smb1.echo_handler.socket_lock_fd = -1;
2548 smbd_server_conn->smb1.echo_handler.trusted_fd = -1;
2550 /* Ensure child is set to blocking mode */
2551 set_blocking(smbd_server_fd(),True);
2553 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2554 set_socket_options(smbd_server_fd(), lp_socket_options());
2556 /* this is needed so that we get decent entries
2557 in smbstatus for port 445 connects */
2558 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2562 reload_services(true);
2565 * Before the first packet, check the global hosts allow/ hosts deny
2566 * parameters before doing any parsing of packets passed to us by the
2567 * client. This prevents attacks on our parsing code from hosts not in
2568 * the hosts allow list.
2571 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2572 lp_hostsdeny(-1))) {
2573 char addr[INET6_ADDRSTRLEN];
2576 * send a negative session response "not listening on calling
2579 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2580 DEBUG( 1, ("Connection denied from %s\n",
2581 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2582 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2584 exit_server_cleanly("connection denied");
2591 smb_perfcount_init();
2593 if (!init_account_policy()) {
2594 exit_server("Could not open account policy tdb.\n");
2597 if (*lp_rootdir()) {
2598 if (chroot(lp_rootdir()) != 0) {
2599 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2600 exit_server("Failed to chroot()");
2602 if (chdir("/") == -1) {
2603 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2604 exit_server("Failed to chroot()");
2606 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2609 if (!srv_init_signing(smbd_server_conn)) {
2610 exit_server("Failed to init smb_signing");
2613 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2614 exit_server("Failed to fork echo handler");
2618 if (!init_oplocks(smbd_messaging_context()))
2619 exit_server("Failed to init oplocks");
2621 /* Setup aio signal handler. */
2622 initialize_async_io_handler();
2624 /* register our message handlers */
2625 messaging_register(smbd_messaging_context(), NULL,
2626 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2627 messaging_register(smbd_messaging_context(), NULL,
2628 MSG_SMB_RELEASE_IP, msg_release_ip);
2629 messaging_register(smbd_messaging_context(), NULL,
2630 MSG_SMB_CLOSE_FILE, msg_close_file);
2632 if ((lp_keepalive() != 0)
2633 && !(event_add_idle(smbd_event_context(), NULL,
2634 timeval_set(lp_keepalive(), 0),
2635 "keepalive", keepalive_fn,
2637 DEBUG(0, ("Could not add keepalive event\n"));
2641 if (!(event_add_idle(smbd_event_context(), NULL,
2642 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2643 "deadtime", deadtime_fn, NULL))) {
2644 DEBUG(0, ("Could not add deadtime event\n"));
2648 if (!(event_add_idle(smbd_event_context(), NULL,
2649 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2650 "housekeeping", housekeeping_fn, NULL))) {
2651 DEBUG(0, ("Could not add housekeeping event\n"));
2655 #ifdef CLUSTER_SUPPORT
2657 if (lp_clustering()) {
2659 * We need to tell ctdb about our client's TCP
2660 * connection, so that for failover ctdbd can send
2661 * tickle acks, triggering a reconnection by the
2665 struct sockaddr_storage srv, clnt;
2667 if (client_get_tcp_info(&srv, &clnt) == 0) {
2671 status = ctdbd_register_ips(
2672 messaging_ctdbd_connection(),
2673 &srv, &clnt, release_ip, NULL);
2675 if (!NT_STATUS_IS_OK(status)) {
2676 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2677 nt_errstr(status)));
2681 DEBUG(0,("Unable to get tcp info for "
2682 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2689 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2691 smbd_server_conn->fde = event_add_fd(smbd_event_context(),
2695 smbd_server_connection_handler,
2697 if (!smbd_server_conn->fde) {
2698 exit_server("failed to create smbd_server_connection fde");
2706 frame = talloc_stackframe_pool(8192);
2710 status = smbd_server_connection_loop_once(smbd_server_conn);
2711 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2712 !NT_STATUS_IS_OK(status)) {
2713 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2714 " exiting\n", nt_errstr(status)));
2721 exit_server_cleanly(NULL);
2724 bool req_is_in_chain(struct smb_request *req)
2726 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2728 * We're right now handling a subsequent request, so we must
2734 if (!is_andx_req(req->cmd)) {
2740 * Okay, an illegal request, but definitely not chained :-)
2745 return (CVAL(req->vwv+0, 0) != 0xFF);