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)
34 bool smbd_unlock_socket(struct smbd_server_connection *sconn)
39 /* Accessor function for smb_read_error for smbd functions. */
41 /****************************************************************************
43 ****************************************************************************/
45 bool srv_send_smb(int fd, char *buffer,
46 bool do_signing, uint32_t seqnum,
48 struct smb_perfcount_data *pcd)
53 char *buf_out = buffer;
56 ok = smbd_lock_socket(smbd_server_conn);
58 exit_server_cleanly("failed to lock socket");
62 /* Sign the outgoing packet if required. */
63 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
67 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
68 if (!NT_STATUS_IS_OK(status)) {
69 DEBUG(0, ("send_smb: SMB encryption failed "
70 "on outgoing packet! Error %s\n",
76 len = smb_len(buf_out) + 4;
78 while (nwritten < len) {
79 ret = write_data(fd,buf_out+nwritten,len - nwritten);
81 DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
82 (int)len,(int)ret, strerror(errno) ));
83 srv_free_enc_buffer(buf_out);
89 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
90 srv_free_enc_buffer(buf_out);
92 SMB_PERFCOUNT_END(pcd);
94 ok = smbd_unlock_socket(smbd_server_conn);
96 exit_server_cleanly("failed to unlock socket");
102 /*******************************************************************
103 Setup the word count and byte count for a smb message.
104 ********************************************************************/
106 int srv_set_message(char *buf,
111 if (zero && (num_words || num_bytes)) {
112 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
114 SCVAL(buf,smb_wct,num_words);
115 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
116 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
117 return (smb_size + num_words*2 + num_bytes);
120 static bool valid_smb_header(const uint8_t *inbuf)
122 if (is_encrypted_packet(inbuf)) {
126 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
127 * but it just looks weird to call strncmp for this one.
129 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
132 /* Socket functions for smbd packet processing. */
134 static bool valid_packet_size(size_t len)
137 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
138 * of header. Don't print the error if this fits.... JRA.
141 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
142 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
143 (unsigned long)len));
149 static NTSTATUS read_packet_remainder(int fd, char *buffer,
150 unsigned int timeout, ssize_t len)
156 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
159 /****************************************************************************
160 Attempt a zerocopy writeX read. We know here that len > smb_size-4
161 ****************************************************************************/
164 * Unfortunately, earlier versions of smbclient/libsmbclient
165 * don't send this "standard" writeX header. I've fixed this
166 * for 3.2 but we'll use the old method with earlier versions.
167 * Windows and CIFSFS at least use this standard size. Not
171 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
172 (2*14) + /* word count (including bcc) */ \
175 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
176 const char lenbuf[4],
177 int fd, char **buffer,
178 unsigned int timeout,
182 /* Size of a WRITEX call (+4 byte len). */
183 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
184 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
188 memcpy(writeX_header, lenbuf, 4);
190 status = read_fd_with_timeout(
191 fd, writeX_header + 4,
192 STANDARD_WRITE_AND_X_HEADER_SIZE,
193 STANDARD_WRITE_AND_X_HEADER_SIZE,
196 if (!NT_STATUS_IS_OK(status)) {
201 * Ok - now try and see if this is a possible
205 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
207 * If the data offset is beyond what
208 * we've read, drain the extra bytes.
210 uint16_t doff = SVAL(writeX_header,smb_vwv11);
213 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
214 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
215 if (drain_socket(smbd_server_fd(), drain) != drain) {
216 smb_panic("receive_smb_raw_talloc_partial_read:"
217 " failed to drain pending bytes");
220 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
223 /* Spoof down the length and null out the bcc. */
224 set_message_bcc(writeX_header, 0);
225 newlen = smb_len(writeX_header);
227 /* Copy the header we've written. */
229 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
231 sizeof(writeX_header));
233 if (*buffer == NULL) {
234 DEBUG(0, ("Could not allocate inbuf of length %d\n",
235 (int)sizeof(writeX_header)));
236 return NT_STATUS_NO_MEMORY;
239 /* Work out the remaining bytes. */
240 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
241 *len_ret = newlen + 4;
245 if (!valid_packet_size(len)) {
246 return NT_STATUS_INVALID_PARAMETER;
250 * Not a valid writeX call. Just do the standard
254 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
256 if (*buffer == NULL) {
257 DEBUG(0, ("Could not allocate inbuf of length %d\n",
259 return NT_STATUS_NO_MEMORY;
262 /* Copy in what we already read. */
265 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
266 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
269 status = read_packet_remainder(
270 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
273 if (!NT_STATUS_IS_OK(status)) {
274 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
284 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
285 char **buffer, unsigned int timeout,
286 size_t *p_unread, size_t *plen)
290 int min_recv_size = lp_min_receive_file_size();
295 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
296 if (!NT_STATUS_IS_OK(status)) {
297 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
301 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
302 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
303 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
304 !srv_is_signing_active(smbd_server_conn) &&
305 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
307 return receive_smb_raw_talloc_partial_read(
308 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
311 if (!valid_packet_size(len)) {
312 return NT_STATUS_INVALID_PARAMETER;
316 * The +4 here can't wrap, we've checked the length above already.
319 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
321 if (*buffer == NULL) {
322 DEBUG(0, ("Could not allocate inbuf of length %d\n",
324 return NT_STATUS_NO_MEMORY;
327 memcpy(*buffer, lenbuf, sizeof(lenbuf));
329 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
330 if (!NT_STATUS_IS_OK(status)) {
338 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
339 char **buffer, unsigned int timeout,
340 size_t *p_unread, bool *p_encrypted,
343 bool trusted_channel)
348 *p_encrypted = false;
350 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
352 if (!NT_STATUS_IS_OK(status)) {
356 if (is_encrypted_packet((uint8_t *)*buffer)) {
357 status = srv_decrypt_buffer(*buffer);
358 if (!NT_STATUS_IS_OK(status)) {
359 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
360 "incoming packet! Error %s\n",
361 nt_errstr(status) ));
367 /* Check the incoming SMB signature. */
368 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
369 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
370 "incoming packet!\n"));
371 return NT_STATUS_INVALID_NETWORK_RESPONSE;
379 * Initialize a struct smb_request from an inbuf
382 void init_smb_request(struct smb_request *req,
387 size_t req_size = smb_len(inbuf) + 4;
388 /* Ensure we have at least smb_size bytes. */
389 if (req_size < smb_size) {
390 DEBUG(0,("init_smb_request: invalid request size %u\n",
391 (unsigned int)req_size ));
392 exit_server_cleanly("Invalid SMB request");
394 req->cmd = CVAL(inbuf, smb_com);
395 req->flags2 = SVAL(inbuf, smb_flg2);
396 req->smbpid = SVAL(inbuf, smb_pid);
397 req->mid = SVAL(inbuf, smb_mid);
399 req->vuid = SVAL(inbuf, smb_uid);
400 req->tid = SVAL(inbuf, smb_tid);
401 req->wct = CVAL(inbuf, smb_wct);
402 req->vwv = (uint16_t *)(inbuf+smb_vwv);
403 req->buflen = smb_buflen(inbuf);
404 req->buf = (const uint8_t *)smb_buf(inbuf);
405 req->unread_bytes = unread_bytes;
406 req->encrypted = encrypted;
407 req->conn = conn_find(req->tid);
408 req->chain_fsp = NULL;
409 req->chain_outbuf = NULL;
411 smb_init_perfcount_data(&req->pcd);
413 /* Ensure we have at least wct words and 2 bytes of bcc. */
414 if (smb_size + req->wct*2 > req_size) {
415 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
416 (unsigned int)req->wct,
417 (unsigned int)req_size));
418 exit_server_cleanly("Invalid SMB request");
420 /* Ensure bcc is correct. */
421 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
422 DEBUG(0,("init_smb_request: invalid bcc number %u "
423 "(wct = %u, size %u)\n",
424 (unsigned int)req->buflen,
425 (unsigned int)req->wct,
426 (unsigned int)req_size));
427 exit_server_cleanly("Invalid SMB request");
433 static void process_smb(struct smbd_server_connection *conn,
434 uint8_t *inbuf, size_t nread, size_t unread_bytes,
435 uint32_t seqnum, bool encrypted,
436 struct smb_perfcount_data *deferred_pcd);
438 static void smbd_deferred_open_timer(struct event_context *ev,
439 struct timed_event *te,
440 struct timeval _tval,
443 struct pending_message_list *msg = talloc_get_type(private_data,
444 struct pending_message_list);
445 TALLOC_CTX *mem_ctx = talloc_tos();
446 uint16_t mid = SVAL(msg->buf.data,smb_mid);
449 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
452 exit_server("smbd_deferred_open_timer: talloc failed\n");
456 /* We leave this message on the queue so the open code can
457 know this is a retry. */
458 DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
461 /* Mark the message as processed so this is not
462 * re-processed in error. */
463 msg->processed = true;
465 process_smb(smbd_server_conn, inbuf,
467 msg->seqnum, msg->encrypted, &msg->pcd);
469 /* If it's still there and was processed, remove it. */
470 msg = get_open_deferred_message(mid);
471 if (msg && msg->processed) {
472 remove_deferred_open_smb_message(mid);
476 /****************************************************************************
477 Function to push a message onto the tail of a linked list of smb messages ready
479 ****************************************************************************/
481 static bool push_queued_message(struct smb_request *req,
482 struct timeval request_time,
483 struct timeval end_time,
484 char *private_data, size_t private_len)
486 int msg_len = smb_len(req->inbuf) + 4;
487 struct pending_message_list *msg;
489 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
492 DEBUG(0,("push_message: malloc fail (1)\n"));
496 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
497 if(msg->buf.data == NULL) {
498 DEBUG(0,("push_message: malloc fail (2)\n"));
503 msg->request_time = request_time;
504 msg->seqnum = req->seqnum;
505 msg->encrypted = req->encrypted;
506 msg->processed = false;
507 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
510 msg->private_data = data_blob_talloc(msg, private_data,
512 if (msg->private_data.data == NULL) {
513 DEBUG(0,("push_message: malloc fail (3)\n"));
519 msg->te = event_add_timed(smbd_event_context(),
522 smbd_deferred_open_timer,
525 DEBUG(0,("push_message: event_add_timed failed\n"));
530 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
532 DEBUG(10,("push_message: pushed message length %u on "
533 "deferred_open_queue\n", (unsigned int)msg_len));
538 /****************************************************************************
539 Function to delete a sharing violation open message by mid.
540 ****************************************************************************/
542 void remove_deferred_open_smb_message(uint16 mid)
544 struct pending_message_list *pml;
546 for (pml = deferred_open_queue; pml; pml = pml->next) {
547 if (mid == SVAL(pml->buf.data,smb_mid)) {
548 DEBUG(10,("remove_deferred_open_smb_message: "
549 "deleting mid %u len %u\n",
551 (unsigned int)pml->buf.length ));
552 DLIST_REMOVE(deferred_open_queue, pml);
559 /****************************************************************************
560 Move a sharing violation open retry message to the front of the list and
561 schedule it for immediate processing.
562 ****************************************************************************/
564 void schedule_deferred_open_smb_message(uint16 mid)
566 struct pending_message_list *pml;
569 for (pml = deferred_open_queue; pml; pml = pml->next) {
570 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
572 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
573 (unsigned int)msg_mid ));
575 if (mid == msg_mid) {
576 struct timed_event *te;
578 if (pml->processed) {
579 /* A processed message should not be
581 DEBUG(0,("schedule_deferred_open_smb_message: LOGIC ERROR "
582 "message mid %u was already processed\n",
587 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
590 te = event_add_timed(smbd_event_context(),
593 smbd_deferred_open_timer,
596 DEBUG(10,("schedule_deferred_open_smb_message: "
597 "event_add_timed() failed, skipping mid %u\n",
601 TALLOC_FREE(pml->te);
603 DLIST_PROMOTE(deferred_open_queue, pml);
608 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
612 /****************************************************************************
613 Return true if this mid is on the deferred queue and was not yet processed.
614 ****************************************************************************/
616 bool open_was_deferred(uint16 mid)
618 struct pending_message_list *pml;
620 for (pml = deferred_open_queue; pml; pml = pml->next) {
621 if (SVAL(pml->buf.data,smb_mid) == mid && !pml->processed) {
628 /****************************************************************************
629 Return the message queued by this mid.
630 ****************************************************************************/
632 struct pending_message_list *get_open_deferred_message(uint16 mid)
634 struct pending_message_list *pml;
636 for (pml = deferred_open_queue; pml; pml = pml->next) {
637 if (SVAL(pml->buf.data,smb_mid) == mid) {
644 /****************************************************************************
645 Function to push a deferred open smb message onto a linked list of local smb
646 messages ready for processing.
647 ****************************************************************************/
649 bool push_deferred_smb_message(struct smb_request *req,
650 struct timeval request_time,
651 struct timeval timeout,
652 char *private_data, size_t priv_len)
654 struct timeval end_time;
656 if (req->unread_bytes) {
657 DEBUG(0,("push_deferred_smb_message: logic error ! "
658 "unread_bytes = %u\n",
659 (unsigned int)req->unread_bytes ));
660 smb_panic("push_deferred_smb_message: "
661 "logic error unread_bytes != 0" );
664 end_time = timeval_sum(&request_time, &timeout);
666 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
667 "timeout time [%u.%06u]\n",
668 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
669 (unsigned int)end_time.tv_sec,
670 (unsigned int)end_time.tv_usec));
672 return push_queued_message(req, request_time, end_time,
673 private_data, priv_len);
677 struct timed_event *te;
678 struct timeval interval;
680 bool (*handler)(const struct timeval *now, void *private_data);
684 static void smbd_idle_event_handler(struct event_context *ctx,
685 struct timed_event *te,
689 struct idle_event *event =
690 talloc_get_type_abort(private_data, struct idle_event);
692 TALLOC_FREE(event->te);
694 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
695 event->name, event->te));
697 if (!event->handler(&now, event->private_data)) {
698 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
699 event->name, event->te));
700 /* Don't repeat, delete ourselves */
705 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
706 event->name, event->te));
708 event->te = event_add_timed(ctx, event,
709 timeval_sum(&now, &event->interval),
710 smbd_idle_event_handler, event);
712 /* We can't do much but fail here. */
713 SMB_ASSERT(event->te != NULL);
716 struct idle_event *event_add_idle(struct event_context *event_ctx,
718 struct timeval interval,
720 bool (*handler)(const struct timeval *now,
724 struct idle_event *result;
725 struct timeval now = timeval_current();
727 result = TALLOC_P(mem_ctx, struct idle_event);
728 if (result == NULL) {
729 DEBUG(0, ("talloc failed\n"));
733 result->interval = interval;
734 result->handler = handler;
735 result->private_data = private_data;
737 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
738 DEBUG(0, ("talloc failed\n"));
743 result->te = event_add_timed(event_ctx, result,
744 timeval_sum(&now, &interval),
745 smbd_idle_event_handler, result);
746 if (result->te == NULL) {
747 DEBUG(0, ("event_add_timed failed\n"));
752 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
756 static void smbd_sig_term_handler(struct tevent_context *ev,
757 struct tevent_signal *se,
763 exit_server_cleanly("termination signal");
766 void smbd_setup_sig_term_handler(void)
768 struct tevent_signal *se;
770 se = tevent_add_signal(smbd_event_context(),
771 smbd_event_context(),
773 smbd_sig_term_handler,
776 exit_server("failed to setup SIGTERM handler");
780 static void smbd_sig_hup_handler(struct tevent_context *ev,
781 struct tevent_signal *se,
787 change_to_root_user();
788 DEBUG(1,("Reloading services after SIGHUP\n"));
789 reload_services(False);
792 void smbd_setup_sig_hup_handler(void)
794 struct tevent_signal *se;
796 se = tevent_add_signal(smbd_event_context(),
797 smbd_event_context(),
799 smbd_sig_hup_handler,
802 exit_server("failed to setup SIGHUP handler");
806 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
813 to.tv_sec = SMBD_SELECT_TIMEOUT;
817 * Setup the select fd sets.
824 * Are there any timed events waiting ? If so, ensure we don't
825 * select for longer than it would take to wait for them.
832 event_add_to_select_args(smbd_event_context(), &now,
833 &r_fds, &w_fds, &to, &maxfd);
836 /* Process a signal and timed events now... */
837 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
838 return NT_STATUS_RETRY;
843 START_PROFILE(smbd_idle);
845 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
848 END_PROFILE(smbd_idle);
852 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
853 return NT_STATUS_RETRY;
858 /* something is wrong. Maybe the socket is dead? */
859 return map_nt_error_from_unix(errno);
862 /* Did we timeout ? */
864 return NT_STATUS_RETRY;
867 /* should not be reached */
868 return NT_STATUS_INTERNAL_ERROR;
872 * Only allow 5 outstanding trans requests. We're allocating memory, so
876 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
879 for (; list != NULL; list = list->next) {
881 if (list->mid == mid) {
882 return NT_STATUS_INVALID_PARAMETER;
888 return NT_STATUS_INSUFFICIENT_RESOURCES;
895 These flags determine some of the permissions required to do an operation
897 Note that I don't set NEED_WRITE on some write operations because they
898 are used by some brain-dead clients when printing, and I don't want to
899 force write permissions on print services.
901 #define AS_USER (1<<0)
902 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
903 #define TIME_INIT (1<<2)
904 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
905 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
906 #define DO_CHDIR (1<<6)
909 define a list of possible SMB messages and their corresponding
910 functions. Any message that has a NULL function is unimplemented -
911 please feel free to contribute implementations!
913 static const struct smb_message_struct {
915 void (*fn)(struct smb_request *req);
917 } smb_messages[256] = {
919 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
920 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
921 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
922 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
923 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
924 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
925 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
926 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
927 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
928 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
929 /* 0x0a */ { "SMBread",reply_read,AS_USER},
930 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
931 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
932 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
933 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
934 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
935 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
936 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
937 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
938 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
939 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
940 /* 0x15 */ { NULL, NULL, 0 },
941 /* 0x16 */ { NULL, NULL, 0 },
942 /* 0x17 */ { NULL, NULL, 0 },
943 /* 0x18 */ { NULL, NULL, 0 },
944 /* 0x19 */ { NULL, NULL, 0 },
945 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
946 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
947 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
948 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
949 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
950 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
951 /* 0x20 */ { "SMBwritec", NULL,0},
952 /* 0x21 */ { NULL, NULL, 0 },
953 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
954 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
955 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
956 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
957 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
958 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
959 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
960 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
961 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
962 /* 0x2b */ { "SMBecho",reply_echo,0},
963 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
964 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
965 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
966 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
967 /* 0x30 */ { NULL, NULL, 0 },
968 /* 0x31 */ { NULL, NULL, 0 },
969 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
970 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
971 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
972 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
973 /* 0x36 */ { NULL, NULL, 0 },
974 /* 0x37 */ { NULL, NULL, 0 },
975 /* 0x38 */ { NULL, NULL, 0 },
976 /* 0x39 */ { NULL, NULL, 0 },
977 /* 0x3a */ { NULL, NULL, 0 },
978 /* 0x3b */ { NULL, NULL, 0 },
979 /* 0x3c */ { NULL, NULL, 0 },
980 /* 0x3d */ { NULL, NULL, 0 },
981 /* 0x3e */ { NULL, NULL, 0 },
982 /* 0x3f */ { NULL, NULL, 0 },
983 /* 0x40 */ { NULL, NULL, 0 },
984 /* 0x41 */ { NULL, NULL, 0 },
985 /* 0x42 */ { NULL, NULL, 0 },
986 /* 0x43 */ { NULL, NULL, 0 },
987 /* 0x44 */ { NULL, NULL, 0 },
988 /* 0x45 */ { NULL, NULL, 0 },
989 /* 0x46 */ { NULL, NULL, 0 },
990 /* 0x47 */ { NULL, NULL, 0 },
991 /* 0x48 */ { NULL, NULL, 0 },
992 /* 0x49 */ { NULL, NULL, 0 },
993 /* 0x4a */ { NULL, NULL, 0 },
994 /* 0x4b */ { NULL, NULL, 0 },
995 /* 0x4c */ { NULL, NULL, 0 },
996 /* 0x4d */ { NULL, NULL, 0 },
997 /* 0x4e */ { NULL, NULL, 0 },
998 /* 0x4f */ { NULL, NULL, 0 },
999 /* 0x50 */ { NULL, NULL, 0 },
1000 /* 0x51 */ { NULL, NULL, 0 },
1001 /* 0x52 */ { NULL, NULL, 0 },
1002 /* 0x53 */ { NULL, NULL, 0 },
1003 /* 0x54 */ { NULL, NULL, 0 },
1004 /* 0x55 */ { NULL, NULL, 0 },
1005 /* 0x56 */ { NULL, NULL, 0 },
1006 /* 0x57 */ { NULL, NULL, 0 },
1007 /* 0x58 */ { NULL, NULL, 0 },
1008 /* 0x59 */ { NULL, NULL, 0 },
1009 /* 0x5a */ { NULL, NULL, 0 },
1010 /* 0x5b */ { NULL, NULL, 0 },
1011 /* 0x5c */ { NULL, NULL, 0 },
1012 /* 0x5d */ { NULL, NULL, 0 },
1013 /* 0x5e */ { NULL, NULL, 0 },
1014 /* 0x5f */ { NULL, NULL, 0 },
1015 /* 0x60 */ { NULL, NULL, 0 },
1016 /* 0x61 */ { NULL, NULL, 0 },
1017 /* 0x62 */ { NULL, NULL, 0 },
1018 /* 0x63 */ { NULL, NULL, 0 },
1019 /* 0x64 */ { NULL, NULL, 0 },
1020 /* 0x65 */ { NULL, NULL, 0 },
1021 /* 0x66 */ { NULL, NULL, 0 },
1022 /* 0x67 */ { NULL, NULL, 0 },
1023 /* 0x68 */ { NULL, NULL, 0 },
1024 /* 0x69 */ { NULL, NULL, 0 },
1025 /* 0x6a */ { NULL, NULL, 0 },
1026 /* 0x6b */ { NULL, NULL, 0 },
1027 /* 0x6c */ { NULL, NULL, 0 },
1028 /* 0x6d */ { NULL, NULL, 0 },
1029 /* 0x6e */ { NULL, NULL, 0 },
1030 /* 0x6f */ { NULL, NULL, 0 },
1031 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1032 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1033 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1034 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1035 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1036 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1037 /* 0x76 */ { NULL, NULL, 0 },
1038 /* 0x77 */ { NULL, NULL, 0 },
1039 /* 0x78 */ { NULL, NULL, 0 },
1040 /* 0x79 */ { NULL, NULL, 0 },
1041 /* 0x7a */ { NULL, NULL, 0 },
1042 /* 0x7b */ { NULL, NULL, 0 },
1043 /* 0x7c */ { NULL, NULL, 0 },
1044 /* 0x7d */ { NULL, NULL, 0 },
1045 /* 0x7e */ { NULL, NULL, 0 },
1046 /* 0x7f */ { NULL, NULL, 0 },
1047 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1048 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1049 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1050 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1051 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1052 /* 0x85 */ { NULL, NULL, 0 },
1053 /* 0x86 */ { NULL, NULL, 0 },
1054 /* 0x87 */ { NULL, NULL, 0 },
1055 /* 0x88 */ { NULL, NULL, 0 },
1056 /* 0x89 */ { NULL, NULL, 0 },
1057 /* 0x8a */ { NULL, NULL, 0 },
1058 /* 0x8b */ { NULL, NULL, 0 },
1059 /* 0x8c */ { NULL, NULL, 0 },
1060 /* 0x8d */ { NULL, NULL, 0 },
1061 /* 0x8e */ { NULL, NULL, 0 },
1062 /* 0x8f */ { NULL, NULL, 0 },
1063 /* 0x90 */ { NULL, NULL, 0 },
1064 /* 0x91 */ { NULL, NULL, 0 },
1065 /* 0x92 */ { NULL, NULL, 0 },
1066 /* 0x93 */ { NULL, NULL, 0 },
1067 /* 0x94 */ { NULL, NULL, 0 },
1068 /* 0x95 */ { NULL, NULL, 0 },
1069 /* 0x96 */ { NULL, NULL, 0 },
1070 /* 0x97 */ { NULL, NULL, 0 },
1071 /* 0x98 */ { NULL, NULL, 0 },
1072 /* 0x99 */ { NULL, NULL, 0 },
1073 /* 0x9a */ { NULL, NULL, 0 },
1074 /* 0x9b */ { NULL, NULL, 0 },
1075 /* 0x9c */ { NULL, NULL, 0 },
1076 /* 0x9d */ { NULL, NULL, 0 },
1077 /* 0x9e */ { NULL, NULL, 0 },
1078 /* 0x9f */ { NULL, NULL, 0 },
1079 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1080 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1081 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1082 /* 0xa3 */ { NULL, NULL, 0 },
1083 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1084 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1085 /* 0xa6 */ { NULL, NULL, 0 },
1086 /* 0xa7 */ { NULL, NULL, 0 },
1087 /* 0xa8 */ { NULL, NULL, 0 },
1088 /* 0xa9 */ { NULL, NULL, 0 },
1089 /* 0xaa */ { NULL, NULL, 0 },
1090 /* 0xab */ { NULL, NULL, 0 },
1091 /* 0xac */ { NULL, NULL, 0 },
1092 /* 0xad */ { NULL, NULL, 0 },
1093 /* 0xae */ { NULL, NULL, 0 },
1094 /* 0xaf */ { NULL, NULL, 0 },
1095 /* 0xb0 */ { NULL, NULL, 0 },
1096 /* 0xb1 */ { NULL, NULL, 0 },
1097 /* 0xb2 */ { NULL, NULL, 0 },
1098 /* 0xb3 */ { NULL, NULL, 0 },
1099 /* 0xb4 */ { NULL, NULL, 0 },
1100 /* 0xb5 */ { NULL, NULL, 0 },
1101 /* 0xb6 */ { NULL, NULL, 0 },
1102 /* 0xb7 */ { NULL, NULL, 0 },
1103 /* 0xb8 */ { NULL, NULL, 0 },
1104 /* 0xb9 */ { NULL, NULL, 0 },
1105 /* 0xba */ { NULL, NULL, 0 },
1106 /* 0xbb */ { NULL, NULL, 0 },
1107 /* 0xbc */ { NULL, NULL, 0 },
1108 /* 0xbd */ { NULL, NULL, 0 },
1109 /* 0xbe */ { NULL, NULL, 0 },
1110 /* 0xbf */ { NULL, NULL, 0 },
1111 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1112 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1113 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1114 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1115 /* 0xc4 */ { NULL, NULL, 0 },
1116 /* 0xc5 */ { NULL, NULL, 0 },
1117 /* 0xc6 */ { NULL, NULL, 0 },
1118 /* 0xc7 */ { NULL, NULL, 0 },
1119 /* 0xc8 */ { NULL, NULL, 0 },
1120 /* 0xc9 */ { NULL, NULL, 0 },
1121 /* 0xca */ { NULL, NULL, 0 },
1122 /* 0xcb */ { NULL, NULL, 0 },
1123 /* 0xcc */ { NULL, NULL, 0 },
1124 /* 0xcd */ { NULL, NULL, 0 },
1125 /* 0xce */ { NULL, NULL, 0 },
1126 /* 0xcf */ { NULL, NULL, 0 },
1127 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1128 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1129 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1130 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1131 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1132 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1133 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1134 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1135 /* 0xd8 */ { NULL, NULL, 0 },
1136 /* 0xd9 */ { NULL, NULL, 0 },
1137 /* 0xda */ { NULL, NULL, 0 },
1138 /* 0xdb */ { NULL, NULL, 0 },
1139 /* 0xdc */ { NULL, NULL, 0 },
1140 /* 0xdd */ { NULL, NULL, 0 },
1141 /* 0xde */ { NULL, NULL, 0 },
1142 /* 0xdf */ { NULL, NULL, 0 },
1143 /* 0xe0 */ { NULL, NULL, 0 },
1144 /* 0xe1 */ { NULL, NULL, 0 },
1145 /* 0xe2 */ { NULL, NULL, 0 },
1146 /* 0xe3 */ { NULL, NULL, 0 },
1147 /* 0xe4 */ { NULL, NULL, 0 },
1148 /* 0xe5 */ { NULL, NULL, 0 },
1149 /* 0xe6 */ { NULL, NULL, 0 },
1150 /* 0xe7 */ { NULL, NULL, 0 },
1151 /* 0xe8 */ { NULL, NULL, 0 },
1152 /* 0xe9 */ { NULL, NULL, 0 },
1153 /* 0xea */ { NULL, NULL, 0 },
1154 /* 0xeb */ { NULL, NULL, 0 },
1155 /* 0xec */ { NULL, NULL, 0 },
1156 /* 0xed */ { NULL, NULL, 0 },
1157 /* 0xee */ { NULL, NULL, 0 },
1158 /* 0xef */ { NULL, NULL, 0 },
1159 /* 0xf0 */ { NULL, NULL, 0 },
1160 /* 0xf1 */ { NULL, NULL, 0 },
1161 /* 0xf2 */ { NULL, NULL, 0 },
1162 /* 0xf3 */ { NULL, NULL, 0 },
1163 /* 0xf4 */ { NULL, NULL, 0 },
1164 /* 0xf5 */ { NULL, NULL, 0 },
1165 /* 0xf6 */ { NULL, NULL, 0 },
1166 /* 0xf7 */ { NULL, NULL, 0 },
1167 /* 0xf8 */ { NULL, NULL, 0 },
1168 /* 0xf9 */ { NULL, NULL, 0 },
1169 /* 0xfa */ { NULL, NULL, 0 },
1170 /* 0xfb */ { NULL, NULL, 0 },
1171 /* 0xfc */ { NULL, NULL, 0 },
1172 /* 0xfd */ { NULL, NULL, 0 },
1173 /* 0xfe */ { NULL, NULL, 0 },
1174 /* 0xff */ { NULL, NULL, 0 }
1178 /*******************************************************************
1179 allocate and initialize a reply packet
1180 ********************************************************************/
1182 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1183 const char *inbuf, char **outbuf, uint8_t num_words,
1187 * Protect against integer wrap
1189 if ((num_bytes > 0xffffff)
1190 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1192 if (asprintf(&msg, "num_bytes too large: %u",
1193 (unsigned)num_bytes) == -1) {
1194 msg = CONST_DISCARD(char *, "num_bytes too large");
1199 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1200 smb_size + num_words*2 + num_bytes);
1201 if (*outbuf == NULL) {
1205 construct_reply_common(req, inbuf, *outbuf);
1206 srv_set_message(*outbuf, num_words, num_bytes, false);
1208 * Zero out the word area, the caller has to take care of the bcc area
1211 if (num_words != 0) {
1212 memset(*outbuf + smb_vwv0, 0, num_words*2);
1218 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1221 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1223 smb_panic("could not allocate output buffer\n");
1225 req->outbuf = (uint8_t *)outbuf;
1229 /*******************************************************************
1230 Dump a packet to a file.
1231 ********************************************************************/
1233 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1237 if (DEBUGLEVEL < 50) {
1241 if (len < 4) len = smb_len(data)+4;
1242 for (i=1;i<100;i++) {
1243 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1244 type ? "req" : "resp") == -1) {
1247 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1248 if (fd != -1 || errno != EEXIST) break;
1251 ssize_t ret = write(fd, data, len);
1253 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1255 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1260 /****************************************************************************
1261 Prepare everything for calling the actual request function, and potentially
1262 call the request function via the "new" interface.
1264 Return False if the "legacy" function needs to be called, everything is
1267 Return True if we're done.
1269 I know this API sucks, but it is the one with the least code change I could
1271 ****************************************************************************/
1273 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1277 connection_struct *conn = NULL;
1281 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1282 * so subtract 4 from it. */
1283 if (!valid_smb_header(req->inbuf)
1284 || (size < (smb_size - 4))) {
1285 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1286 smb_len(req->inbuf)));
1287 exit_server_cleanly("Non-SMB packet");
1290 if (smb_messages[type].fn == NULL) {
1291 DEBUG(0,("Unknown message type %d!\n",type));
1292 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1293 reply_unknown_new(req, type);
1297 flags = smb_messages[type].flags;
1299 /* In share mode security we must ignore the vuid. */
1300 session_tag = (lp_security() == SEC_SHARE)
1301 ? UID_FIELD_INVALID : req->vuid;
1304 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1305 (int)sys_getpid(), (unsigned long)conn));
1307 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1309 /* Ensure this value is replaced in the incoming packet. */
1310 SSVAL(req->inbuf,smb_uid,session_tag);
1313 * Ensure the correct username is in current_user_info. This is a
1314 * really ugly bugfix for problems with multiple session_setup_and_X's
1315 * being done and allowing %U and %G substitutions to work correctly.
1316 * There is a reason this code is done here, don't move it unless you
1317 * know what you're doing... :-).
1321 if (session_tag != last_session_tag) {
1322 user_struct *vuser = NULL;
1324 last_session_tag = session_tag;
1325 if(session_tag != UID_FIELD_INVALID) {
1326 vuser = get_valid_user_struct(session_tag);
1328 set_current_user_info(
1329 vuser->server_info->sanitized_username,
1330 vuser->server_info->unix_name,
1331 pdb_get_domain(vuser->server_info
1337 /* Does this call need to be run as the connected user? */
1338 if (flags & AS_USER) {
1340 /* Does this call need a valid tree connection? */
1343 * Amazingly, the error code depends on the command
1346 if (type == SMBntcreateX) {
1347 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1349 reply_doserror(req, ERRSRV, ERRinvnid);
1354 if (!change_to_user(conn,session_tag)) {
1355 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1359 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1361 /* Does it need write permission? */
1362 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1363 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1367 /* IPC services are limited */
1368 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1369 reply_doserror(req, ERRSRV,ERRaccess);
1373 /* This call needs to be run as root */
1374 change_to_root_user();
1377 /* load service specific parameters */
1379 if (req->encrypted) {
1380 conn->encrypted_tid = true;
1381 /* encrypted required from now on. */
1382 conn->encrypt_level = Required;
1383 } else if (ENCRYPTION_REQUIRED(conn)) {
1384 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1385 exit_server_cleanly("encryption required "
1391 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1392 (flags & (AS_USER|DO_CHDIR)
1394 reply_doserror(req, ERRSRV, ERRaccess);
1397 conn->num_smb_operations++;
1400 /* does this protocol need to be run as guest? */
1401 if ((flags & AS_GUEST)
1402 && (!change_to_guest() ||
1403 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1404 lp_hostsdeny(-1)))) {
1405 reply_doserror(req, ERRSRV, ERRaccess);
1409 smb_messages[type].fn(req);
1413 /****************************************************************************
1414 Construct a reply to the incoming packet.
1415 ****************************************************************************/
1417 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1418 uint32_t seqnum, bool encrypted,
1419 struct smb_perfcount_data *deferred_pcd)
1421 connection_struct *conn;
1422 struct smb_request *req;
1424 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1425 smb_panic("could not allocate smb_request");
1428 init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1429 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1430 req->seqnum = seqnum;
1432 /* we popped this message off the queue - keep original perf data */
1434 req->pcd = *deferred_pcd;
1436 SMB_PERFCOUNT_START(&req->pcd);
1437 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1438 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1441 conn = switch_message(req->cmd, req, size);
1443 if (req->unread_bytes) {
1444 /* writeX failed. drain socket. */
1445 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1446 req->unread_bytes) {
1447 smb_panic("failed to drain pending bytes");
1449 req->unread_bytes = 0;
1457 if (req->outbuf == NULL) {
1461 if (CVAL(req->outbuf,0) == 0) {
1462 show_msg((char *)req->outbuf);
1465 if (!srv_send_smb(smbd_server_fd(),
1466 (char *)req->outbuf,
1467 true, req->seqnum+1,
1468 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1470 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1478 /****************************************************************************
1479 Process an smb from the client
1480 ****************************************************************************/
1481 static void process_smb(struct smbd_server_connection *conn,
1482 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1483 uint32_t seqnum, bool encrypted,
1484 struct smb_perfcount_data *deferred_pcd)
1486 int msg_type = CVAL(inbuf,0);
1488 DO_PROFILE_INC(smb_count);
1490 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1492 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1494 (unsigned int)unread_bytes ));
1496 if (msg_type != 0) {
1498 * NetBIOS session request, keepalive, etc.
1500 reply_special((char *)inbuf);
1504 show_msg((char *)inbuf);
1506 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1510 conn->num_requests++;
1512 /* The timeout_processing function isn't run nearly
1513 often enough to implement 'max log size' without
1514 overrunning the size of the file by many megabytes.
1515 This is especially true if we are running at debug
1516 level 10. Checking every 50 SMBs is a nice
1517 tradeoff of performance vs log file size overrun. */
1519 if ((conn->num_requests % 50) == 0 &&
1520 need_to_check_log_size()) {
1521 change_to_root_user();
1526 /****************************************************************************
1527 Return a string containing the function name of a SMB command.
1528 ****************************************************************************/
1530 const char *smb_fn_name(int type)
1532 const char *unknown_name = "SMBunknown";
1534 if (smb_messages[type].name == NULL)
1535 return(unknown_name);
1537 return(smb_messages[type].name);
1540 /****************************************************************************
1541 Helper functions for contruct_reply.
1542 ****************************************************************************/
1544 void add_to_common_flags2(uint32 v)
1549 void remove_from_common_flags2(uint32 v)
1551 common_flags2 &= ~v;
1554 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1557 srv_set_message(outbuf,0,0,false);
1559 SCVAL(outbuf, smb_com, req->cmd);
1560 SIVAL(outbuf,smb_rcls,0);
1561 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1562 SSVAL(outbuf,smb_flg2,
1563 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1565 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1567 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1568 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1569 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1570 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1573 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1575 construct_reply_common(req, (char *)req->inbuf, outbuf);
1579 * How many bytes have we already accumulated up to the current wct field
1583 size_t req_wct_ofs(struct smb_request *req)
1587 if (req->chain_outbuf == NULL) {
1590 buf_size = talloc_get_size(req->chain_outbuf);
1591 if ((buf_size % 4) != 0) {
1592 buf_size += (4 - (buf_size % 4));
1594 return buf_size - 4;
1598 * Hack around reply_nterror & friends not being aware of chained requests,
1599 * generating illegal (i.e. wct==0) chain replies.
1602 static void fixup_chain_error_packet(struct smb_request *req)
1604 uint8_t *outbuf = req->outbuf;
1606 reply_outbuf(req, 2, 0);
1607 memcpy(req->outbuf, outbuf, smb_wct);
1608 TALLOC_FREE(outbuf);
1609 SCVAL(req->outbuf, smb_vwv0, 0xff);
1612 /****************************************************************************
1613 Construct a chained reply and add it to the already made reply
1614 ****************************************************************************/
1616 void chain_reply(struct smb_request *req)
1618 size_t smblen = smb_len(req->inbuf);
1619 size_t already_used, length_needed;
1621 uint32_t chain_offset; /* uint32_t to avoid overflow */
1628 if (IVAL(req->outbuf, smb_rcls) != 0) {
1629 fixup_chain_error_packet(req);
1633 * Any of the AndX requests and replies have at least a wct of
1634 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1635 * beginning of the SMB header to the next wct field.
1637 * None of the AndX requests put anything valuable in vwv[0] and [1],
1638 * so we can overwrite it here to form the chain.
1641 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1646 * Here we assume that this is the end of the chain. For that we need
1647 * to set "next command" to 0xff and the offset to 0. If we later find
1648 * more commands in the chain, this will be overwritten again.
1651 SCVAL(req->outbuf, smb_vwv0, 0xff);
1652 SCVAL(req->outbuf, smb_vwv0+1, 0);
1653 SSVAL(req->outbuf, smb_vwv1, 0);
1655 if (req->chain_outbuf == NULL) {
1657 * In req->chain_outbuf we collect all the replies. Start the
1658 * chain by copying in the first reply.
1660 * We do the realloc because later on we depend on
1661 * talloc_get_size to determine the length of
1662 * chain_outbuf. The reply_xxx routines might have
1663 * over-allocated (reply_pipe_read_and_X used to be such an
1666 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1667 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1668 if (req->chain_outbuf == NULL) {
1674 * Update smb headers where subsequent chained commands
1675 * may have updated them.
1677 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1678 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1680 if (!smb_splice_chain(&req->chain_outbuf,
1681 CVAL(req->outbuf, smb_com),
1682 CVAL(req->outbuf, smb_wct),
1683 (uint16_t *)(req->outbuf + smb_vwv),
1684 0, smb_buflen(req->outbuf),
1685 (uint8_t *)smb_buf(req->outbuf))) {
1688 TALLOC_FREE(req->outbuf);
1692 * We use the old request's vwv field to grab the next chained command
1693 * and offset into the chained fields.
1696 chain_cmd = CVAL(req->vwv+0, 0);
1697 chain_offset = SVAL(req->vwv+1, 0);
1699 if (chain_cmd == 0xff) {
1701 * End of chain, no more requests from the client. So ship the
1704 smb_setlen((char *)(req->chain_outbuf),
1705 talloc_get_size(req->chain_outbuf) - 4);
1707 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1708 true, req->seqnum+1,
1709 IS_CONN_ENCRYPTED(req->conn)
1712 exit_server_cleanly("chain_reply: srv_send_smb "
1715 TALLOC_FREE(req->chain_outbuf);
1720 /* add a new perfcounter for this element of chain */
1721 SMB_PERFCOUNT_ADD(&req->pcd);
1722 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1723 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1726 * Check if the client tries to fool us. The request so far uses the
1727 * space to the end of the byte buffer in the request just
1728 * processed. The chain_offset can't point into that area. If that was
1729 * the case, we could end up with an endless processing of the chain,
1730 * we would always handle the same request.
1733 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1734 if (chain_offset < already_used) {
1739 * Next check: Make sure the chain offset does not point beyond the
1740 * overall smb request length.
1743 length_needed = chain_offset+1; /* wct */
1744 if (length_needed > smblen) {
1749 * Now comes the pointer magic. Goal here is to set up req->vwv and
1750 * req->buf correctly again to be able to call the subsequent
1751 * switch_message(). The chain offset (the former vwv[1]) points at
1752 * the new wct field.
1755 wct = CVAL(smb_base(req->inbuf), chain_offset);
1758 * Next consistency check: Make the new vwv array fits in the overall
1762 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1763 if (length_needed > smblen) {
1766 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1769 * Now grab the new byte buffer....
1772 buflen = SVAL(vwv+wct, 0);
1775 * .. and check that it fits.
1778 length_needed += buflen;
1779 if (length_needed > smblen) {
1782 buf = (uint8_t *)(vwv+wct+1);
1784 req->cmd = chain_cmd;
1787 req->buflen = buflen;
1790 switch_message(chain_cmd, req, smblen);
1792 if (req->outbuf == NULL) {
1794 * This happens if the chained command has suspended itself or
1795 * if it has called srv_send_smb() itself.
1801 * We end up here if the chained command was not itself chained or
1802 * suspended, but for example a close() command. We now need to splice
1803 * the chained commands' outbuf into the already built up chain_outbuf
1804 * and ship the result.
1810 * We end up here if there's any error in the chain syntax. Report a
1811 * DOS error, just like Windows does.
1813 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1814 fixup_chain_error_packet(req);
1817 if (!smb_splice_chain(&req->chain_outbuf,
1818 CVAL(req->outbuf, smb_com),
1819 CVAL(req->outbuf, smb_wct),
1820 (uint16_t *)(req->outbuf + smb_vwv),
1821 0, smb_buflen(req->outbuf),
1822 (uint8_t *)smb_buf(req->outbuf))) {
1823 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1825 TALLOC_FREE(req->outbuf);
1827 smb_setlen((char *)(req->chain_outbuf),
1828 talloc_get_size(req->chain_outbuf) - 4);
1830 show_msg((char *)(req->chain_outbuf));
1832 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1833 true, req->seqnum+1,
1834 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1836 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1838 TALLOC_FREE(req->chain_outbuf);
1842 /****************************************************************************
1843 Check if services need reloading.
1844 ****************************************************************************/
1846 void check_reload(time_t t)
1848 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1850 if(last_smb_conf_reload_time == 0) {
1851 last_smb_conf_reload_time = t;
1852 /* Our printing subsystem might not be ready at smbd start up.
1853 Then no printer is available till the first printers check
1854 is performed. A lower initial interval circumvents this. */
1855 if ( printcap_cache_time > 60 )
1856 last_printer_reload_time = t - printcap_cache_time + 60;
1858 last_printer_reload_time = t;
1861 if (mypid != getpid()) { /* First time or fork happened meanwhile */
1862 /* randomize over 60 second the printcap reload to avoid all
1863 * process hitting cupsd at the same time */
1864 int time_range = 60;
1866 last_printer_reload_time += random() % time_range;
1870 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1871 reload_services(True);
1872 last_smb_conf_reload_time = t;
1875 /* 'printcap cache time = 0' disable the feature */
1877 if ( printcap_cache_time != 0 )
1879 /* see if it's time to reload or if the clock has been set back */
1881 if ( (t >= last_printer_reload_time+printcap_cache_time)
1882 || (t-last_printer_reload_time < 0) )
1884 DEBUG( 3,( "Printcap cache time expired.\n"));
1886 last_printer_reload_time = t;
1891 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1893 /* TODO: make write nonblocking */
1896 static void smbd_server_connection_read_handler(struct smbd_server_connection *conn)
1898 uint8_t *inbuf = NULL;
1899 size_t inbuf_len = 0;
1900 size_t unread_bytes = 0;
1901 bool encrypted = false;
1902 TALLOC_CTX *mem_ctx = talloc_tos();
1908 ok = smbd_lock_socket(conn);
1910 exit_server_cleanly("failed to lock socket");
1913 /* TODO: make this completely nonblocking */
1914 status = receive_smb_talloc(mem_ctx, smbd_server_fd(),
1915 (char **)(void *)&inbuf,
1919 &inbuf_len, &seqnum,
1920 false /* trusted channel */);
1921 ok = smbd_unlock_socket(conn);
1923 exit_server_cleanly("failed to unlock");
1926 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1929 if (NT_STATUS_IS_ERR(status)) {
1930 exit_server_cleanly("failed to receive smb request");
1932 if (!NT_STATUS_IS_OK(status)) {
1937 process_smb(conn, inbuf, inbuf_len, unread_bytes,
1938 seqnum, encrypted, NULL);
1941 static void smbd_server_connection_handler(struct event_context *ev,
1942 struct fd_event *fde,
1946 struct smbd_server_connection *conn = talloc_get_type(private_data,
1947 struct smbd_server_connection);
1949 if (flags & EVENT_FD_WRITE) {
1950 smbd_server_connection_write_handler(conn);
1951 } else if (flags & EVENT_FD_READ) {
1952 smbd_server_connection_read_handler(conn);
1957 /****************************************************************************
1958 received when we should release a specific IP
1959 ****************************************************************************/
1960 static void release_ip(const char *ip, void *priv)
1962 char addr[INET6_ADDRSTRLEN];
1965 client_socket_addr(get_client_fd(),addr,sizeof(addr));
1967 if (strncmp("::ffff:", addr, 7) == 0) {
1971 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
1972 /* we can't afford to do a clean exit - that involves
1973 database writes, which would potentially mean we
1974 are still running after the failover has finished -
1975 we have to get rid of this process ID straight
1977 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
1979 /* note we must exit with non-zero status so the unclean handler gets
1980 called in the parent, so that the brl database is tickled */
1985 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
1986 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
1988 release_ip((char *)data->data, NULL);
1991 #ifdef CLUSTER_SUPPORT
1992 static int client_get_tcp_info(struct sockaddr_storage *server,
1993 struct sockaddr_storage *client)
1996 if (server_fd == -1) {
1999 length = sizeof(*server);
2000 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2003 length = sizeof(*client);
2004 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2012 * Send keepalive packets to our client
2014 static bool keepalive_fn(const struct timeval *now, void *private_data)
2019 ok = smbd_lock_socket(smbd_server_conn);
2021 exit_server_cleanly("failed to lock socket");
2024 ret = send_keepalive(smbd_server_fd());
2026 ok = smbd_unlock_socket(smbd_server_conn);
2028 exit_server_cleanly("failed to unlock socket");
2032 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2039 * Do the recurring check if we're idle
2041 static bool deadtime_fn(const struct timeval *now, void *private_data)
2043 if ((conn_num_open() == 0)
2044 || (conn_idle_all(now->tv_sec))) {
2045 DEBUG( 2, ( "Closing idle connection\n" ) );
2046 messaging_send(smbd_messaging_context(), procid_self(),
2047 MSG_SHUTDOWN, &data_blob_null);
2055 * Do the recurring log file and smb.conf reload checks.
2058 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2060 change_to_root_user();
2062 /* update printer queue caches if necessary */
2063 update_monitored_printq_cache();
2065 /* check if we need to reload services */
2066 check_reload(time(NULL));
2068 /* Change machine password if neccessary. */
2069 attempt_machine_password_change();
2072 * Force a log file check.
2074 force_check_log_size();
2079 /****************************************************************************
2080 Process commands from the client
2081 ****************************************************************************/
2083 void smbd_process(void)
2085 TALLOC_CTX *frame = talloc_stackframe();
2086 char remaddr[INET6_ADDRSTRLEN];
2088 smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
2089 if (!smbd_server_conn) {
2090 exit_server("failed to create smbd_server_connection");
2093 smbd_server_conn->smb1.echo_handler.socket_lock_fd = -1;
2094 smbd_server_conn->smb1.echo_handler.trusted_fd = -1;
2096 /* Ensure child is set to blocking mode */
2097 set_blocking(smbd_server_fd(),True);
2099 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2100 set_socket_options(smbd_server_fd(), lp_socket_options());
2102 /* this is needed so that we get decent entries
2103 in smbstatus for port 445 connects */
2104 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2108 reload_services(true);
2111 * Before the first packet, check the global hosts allow/ hosts deny
2112 * parameters before doing any parsing of packets passed to us by the
2113 * client. This prevents attacks on our parsing code from hosts not in
2114 * the hosts allow list.
2117 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2118 lp_hostsdeny(-1))) {
2119 char addr[INET6_ADDRSTRLEN];
2122 * send a negative session response "not listening on calling
2125 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2126 DEBUG( 1, ("Connection denied from %s\n",
2127 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2128 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2130 exit_server_cleanly("connection denied");
2137 smb_perfcount_init();
2139 if (!init_account_policy()) {
2140 exit_server("Could not open account policy tdb.\n");
2143 if (*lp_rootdir()) {
2144 if (chroot(lp_rootdir()) != 0) {
2145 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2146 exit_server("Failed to chroot()");
2148 if (chdir("/") == -1) {
2149 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2150 exit_server("Failed to chroot()");
2152 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2155 if (!srv_init_signing(smbd_server_conn)) {
2156 exit_server("Failed to init smb_signing");
2160 if (!init_oplocks(smbd_messaging_context()))
2161 exit_server("Failed to init oplocks");
2163 /* Setup aio signal handler. */
2164 initialize_async_io_handler();
2166 /* register our message handlers */
2167 messaging_register(smbd_messaging_context(), NULL,
2168 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2169 messaging_register(smbd_messaging_context(), NULL,
2170 MSG_SMB_RELEASE_IP, msg_release_ip);
2171 messaging_register(smbd_messaging_context(), NULL,
2172 MSG_SMB_CLOSE_FILE, msg_close_file);
2174 if ((lp_keepalive() != 0)
2175 && !(event_add_idle(smbd_event_context(), NULL,
2176 timeval_set(lp_keepalive(), 0),
2177 "keepalive", keepalive_fn,
2179 DEBUG(0, ("Could not add keepalive event\n"));
2183 if (!(event_add_idle(smbd_event_context(), NULL,
2184 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2185 "deadtime", deadtime_fn, NULL))) {
2186 DEBUG(0, ("Could not add deadtime event\n"));
2190 if (!(event_add_idle(smbd_event_context(), NULL,
2191 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2192 "housekeeping", housekeeping_fn, NULL))) {
2193 DEBUG(0, ("Could not add housekeeping event\n"));
2197 #ifdef CLUSTER_SUPPORT
2199 if (lp_clustering()) {
2201 * We need to tell ctdb about our client's TCP
2202 * connection, so that for failover ctdbd can send
2203 * tickle acks, triggering a reconnection by the
2207 struct sockaddr_storage srv, clnt;
2209 if (client_get_tcp_info(&srv, &clnt) == 0) {
2213 status = ctdbd_register_ips(
2214 messaging_ctdbd_connection(),
2215 &srv, &clnt, release_ip, NULL);
2217 if (!NT_STATUS_IS_OK(status)) {
2218 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2219 nt_errstr(status)));
2223 DEBUG(0,("Unable to get tcp info for "
2224 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2231 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2233 smbd_server_conn->fde = event_add_fd(smbd_event_context(),
2237 smbd_server_connection_handler,
2239 if (!smbd_server_conn->fde) {
2240 exit_server("failed to create smbd_server_connection fde");
2248 frame = talloc_stackframe_pool(8192);
2252 status = smbd_server_connection_loop_once(smbd_server_conn);
2253 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2254 !NT_STATUS_IS_OK(status)) {
2255 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2256 " exiting\n", nt_errstr(status)));
2263 exit_server_cleanly(NULL);
2266 bool req_is_in_chain(struct smb_request *req)
2268 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2270 * We're right now handling a subsequent request, so we must
2276 if (!is_andx_req(req->cmd)) {
2282 * Okay, an illegal request, but definitely not chained :-)
2287 return (CVAL(req->vwv+0, 0) != 0xFF);