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