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 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
47 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
51 smbd_server_conn->smb1.echo_handler.ref_count++;
53 if (smbd_server_conn->smb1.echo_handler.ref_count > 1) {
57 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
59 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
60 SMB_F_SETLKW, 0, 0, F_WRLCK);
65 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
70 void smbd_lock_socket(struct smbd_server_connection *sconn)
72 if (!smbd_lock_socket_internal(sconn)) {
73 exit_server_cleanly("failed to lock socket");
77 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
81 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
85 smbd_server_conn->smb1.echo_handler.ref_count--;
87 if (smbd_server_conn->smb1.echo_handler.ref_count > 0) {
91 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
92 SMB_F_SETLKW, 0, 0, F_UNLCK);
97 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
102 void smbd_unlock_socket(struct smbd_server_connection *sconn)
104 if (!smbd_unlock_socket_internal(sconn)) {
105 exit_server_cleanly("failed to unlock socket");
109 /* Accessor function for smb_read_error for smbd functions. */
111 /****************************************************************************
113 ****************************************************************************/
115 bool srv_send_smb(int fd, char *buffer,
116 bool do_signing, uint32_t seqnum,
118 struct smb_perfcount_data *pcd)
123 char *buf_out = buffer;
125 smbd_lock_socket(smbd_server_conn);
128 /* Sign the outgoing packet if required. */
129 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
133 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
134 if (!NT_STATUS_IS_OK(status)) {
135 DEBUG(0, ("send_smb: SMB encryption failed "
136 "on outgoing packet! Error %s\n",
137 nt_errstr(status) ));
142 len = smb_len(buf_out) + 4;
144 ret = write_data(fd,buf_out+nwritten,len - nwritten);
146 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
147 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
148 srv_free_enc_buffer(buf_out);
152 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
153 srv_free_enc_buffer(buf_out);
155 SMB_PERFCOUNT_END(pcd);
157 smbd_unlock_socket(smbd_server_conn);
161 /*******************************************************************
162 Setup the word count and byte count for a smb message.
163 ********************************************************************/
165 int srv_set_message(char *buf,
170 if (zero && (num_words || num_bytes)) {
171 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
173 SCVAL(buf,smb_wct,num_words);
174 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
175 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
176 return (smb_size + num_words*2 + num_bytes);
179 static bool valid_smb_header(const uint8_t *inbuf)
181 if (is_encrypted_packet(inbuf)) {
185 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
186 * but it just looks weird to call strncmp for this one.
188 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
191 /* Socket functions for smbd packet processing. */
193 static bool valid_packet_size(size_t len)
196 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
197 * of header. Don't print the error if this fits.... JRA.
200 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
201 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
202 (unsigned long)len));
208 static NTSTATUS read_packet_remainder(int fd, char *buffer,
209 unsigned int timeout, ssize_t len)
215 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
218 /****************************************************************************
219 Attempt a zerocopy writeX read. We know here that len > smb_size-4
220 ****************************************************************************/
223 * Unfortunately, earlier versions of smbclient/libsmbclient
224 * don't send this "standard" writeX header. I've fixed this
225 * for 3.2 but we'll use the old method with earlier versions.
226 * Windows and CIFSFS at least use this standard size. Not
230 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
231 (2*14) + /* word count (including bcc) */ \
234 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
235 const char lenbuf[4],
236 int fd, char **buffer,
237 unsigned int timeout,
241 /* Size of a WRITEX call (+4 byte len). */
242 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
243 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
247 memcpy(writeX_header, lenbuf, 4);
249 status = read_fd_with_timeout(
250 fd, writeX_header + 4,
251 STANDARD_WRITE_AND_X_HEADER_SIZE,
252 STANDARD_WRITE_AND_X_HEADER_SIZE,
255 if (!NT_STATUS_IS_OK(status)) {
260 * Ok - now try and see if this is a possible
264 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
266 * If the data offset is beyond what
267 * we've read, drain the extra bytes.
269 uint16_t doff = SVAL(writeX_header,smb_vwv11);
272 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
273 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
274 if (drain_socket(smbd_server_fd(), drain) != drain) {
275 smb_panic("receive_smb_raw_talloc_partial_read:"
276 " failed to drain pending bytes");
279 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
282 /* Spoof down the length and null out the bcc. */
283 set_message_bcc(writeX_header, 0);
284 newlen = smb_len(writeX_header);
286 /* Copy the header we've written. */
288 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
290 sizeof(writeX_header));
292 if (*buffer == NULL) {
293 DEBUG(0, ("Could not allocate inbuf of length %d\n",
294 (int)sizeof(writeX_header)));
295 return NT_STATUS_NO_MEMORY;
298 /* Work out the remaining bytes. */
299 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
300 *len_ret = newlen + 4;
304 if (!valid_packet_size(len)) {
305 return NT_STATUS_INVALID_PARAMETER;
309 * Not a valid writeX call. Just do the standard
313 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
315 if (*buffer == NULL) {
316 DEBUG(0, ("Could not allocate inbuf of length %d\n",
318 return NT_STATUS_NO_MEMORY;
321 /* Copy in what we already read. */
324 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
325 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
328 status = read_packet_remainder(
329 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
332 if (!NT_STATUS_IS_OK(status)) {
333 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
343 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
344 char **buffer, unsigned int timeout,
345 size_t *p_unread, size_t *plen)
349 int min_recv_size = lp_min_receive_file_size();
354 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
355 if (!NT_STATUS_IS_OK(status)) {
356 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
360 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
361 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
362 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
363 !srv_is_signing_active(smbd_server_conn) &&
364 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
366 return receive_smb_raw_talloc_partial_read(
367 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
370 if (!valid_packet_size(len)) {
371 return NT_STATUS_INVALID_PARAMETER;
375 * The +4 here can't wrap, we've checked the length above already.
378 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
380 if (*buffer == NULL) {
381 DEBUG(0, ("Could not allocate inbuf of length %d\n",
383 return NT_STATUS_NO_MEMORY;
386 memcpy(*buffer, lenbuf, sizeof(lenbuf));
388 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
389 if (!NT_STATUS_IS_OK(status)) {
397 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
398 char **buffer, unsigned int timeout,
399 size_t *p_unread, bool *p_encrypted,
402 bool trusted_channel)
407 *p_encrypted = false;
409 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
411 if (!NT_STATUS_IS_OK(status)) {
415 if (is_encrypted_packet((uint8_t *)*buffer)) {
416 status = srv_decrypt_buffer(*buffer);
417 if (!NT_STATUS_IS_OK(status)) {
418 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
419 "incoming packet! Error %s\n",
420 nt_errstr(status) ));
426 /* Check the incoming SMB signature. */
427 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
428 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
429 "incoming packet!\n"));
430 return NT_STATUS_INVALID_NETWORK_RESPONSE;
438 * Initialize a struct smb_request from an inbuf
441 static bool init_smb_request(struct smb_request *req, const uint8 *inbuf,
442 size_t unread_bytes, bool encrypted,
445 struct smbd_server_connection *sconn = smbd_server_conn;
446 size_t req_size = smb_len(inbuf) + 4;
447 /* Ensure we have at least smb_size bytes. */
448 if (req_size < smb_size) {
449 DEBUG(0,("init_smb_request: invalid request size %u\n",
450 (unsigned int)req_size ));
453 req->cmd = CVAL(inbuf, smb_com);
454 req->flags2 = SVAL(inbuf, smb_flg2);
455 req->smbpid = SVAL(inbuf, smb_pid);
456 req->mid = SVAL(inbuf, smb_mid);
457 req->seqnum = seqnum;
458 req->vuid = SVAL(inbuf, smb_uid);
459 req->tid = SVAL(inbuf, smb_tid);
460 req->wct = CVAL(inbuf, smb_wct);
461 req->vwv = (uint16_t *)(inbuf+smb_vwv);
462 req->buflen = smb_buflen(inbuf);
463 req->buf = (const uint8_t *)smb_buf(inbuf);
464 req->unread_bytes = unread_bytes;
465 req->encrypted = encrypted;
466 req->conn = conn_find(sconn,req->tid);
467 req->chain_fsp = NULL;
468 req->chain_outbuf = NULL;
470 smb_init_perfcount_data(&req->pcd);
472 /* Ensure we have at least wct words and 2 bytes of bcc. */
473 if (smb_size + req->wct*2 > req_size) {
474 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
475 (unsigned int)req->wct,
476 (unsigned int)req_size));
479 /* Ensure bcc is correct. */
480 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
481 DEBUG(0,("init_smb_request: invalid bcc number %u "
482 "(wct = %u, size %u)\n",
483 (unsigned int)req->buflen,
484 (unsigned int)req->wct,
485 (unsigned int)req_size));
493 static void process_smb(struct smbd_server_connection *conn,
494 uint8_t *inbuf, size_t nread, size_t unread_bytes,
495 uint32_t seqnum, bool encrypted,
496 struct smb_perfcount_data *deferred_pcd);
498 static void smbd_deferred_open_timer(struct event_context *ev,
499 struct timed_event *te,
500 struct timeval _tval,
503 struct pending_message_list *msg = talloc_get_type(private_data,
504 struct pending_message_list);
505 TALLOC_CTX *mem_ctx = talloc_tos();
506 uint16_t mid = SVAL(msg->buf.data,smb_mid);
509 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
512 exit_server("smbd_deferred_open_timer: talloc failed\n");
516 /* We leave this message on the queue so the open code can
517 know this is a retry. */
518 DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
519 (unsigned int)mid ));
521 /* Mark the message as processed so this is not
522 * re-processed in error. */
523 msg->processed = true;
525 process_smb(smbd_server_conn, inbuf,
527 msg->seqnum, msg->encrypted, &msg->pcd);
529 /* If it's still there and was processed, remove it. */
530 msg = get_open_deferred_message(mid);
531 if (msg && msg->processed) {
532 remove_deferred_open_smb_message(mid);
536 /****************************************************************************
537 Function to push a message onto the tail of a linked list of smb messages ready
539 ****************************************************************************/
541 static bool push_queued_message(struct smb_request *req,
542 struct timeval request_time,
543 struct timeval end_time,
544 char *private_data, size_t private_len)
546 int msg_len = smb_len(req->inbuf) + 4;
547 struct pending_message_list *msg;
549 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
552 DEBUG(0,("push_message: malloc fail (1)\n"));
556 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
557 if(msg->buf.data == NULL) {
558 DEBUG(0,("push_message: malloc fail (2)\n"));
563 msg->request_time = request_time;
564 msg->seqnum = req->seqnum;
565 msg->encrypted = req->encrypted;
566 msg->processed = false;
567 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
570 msg->private_data = data_blob_talloc(msg, private_data,
572 if (msg->private_data.data == NULL) {
573 DEBUG(0,("push_message: malloc fail (3)\n"));
579 msg->te = event_add_timed(smbd_event_context(),
582 smbd_deferred_open_timer,
585 DEBUG(0,("push_message: event_add_timed failed\n"));
590 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
592 DEBUG(10,("push_message: pushed message length %u on "
593 "deferred_open_queue\n", (unsigned int)msg_len));
598 /****************************************************************************
599 Function to delete a sharing violation open message by mid.
600 ****************************************************************************/
602 void remove_deferred_open_smb_message(uint16 mid)
604 struct pending_message_list *pml;
606 for (pml = deferred_open_queue; pml; pml = pml->next) {
607 if (mid == SVAL(pml->buf.data,smb_mid)) {
608 DEBUG(10,("remove_deferred_open_smb_message: "
609 "deleting mid %u len %u\n",
611 (unsigned int)pml->buf.length ));
612 DLIST_REMOVE(deferred_open_queue, pml);
619 /****************************************************************************
620 Move a sharing violation open retry message to the front of the list and
621 schedule it for immediate processing.
622 ****************************************************************************/
624 void schedule_deferred_open_smb_message(uint16 mid)
626 struct pending_message_list *pml;
629 for (pml = deferred_open_queue; pml; pml = pml->next) {
630 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
632 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
633 (unsigned int)msg_mid ));
635 if (mid == msg_mid) {
636 struct timed_event *te;
638 if (pml->processed) {
639 /* A processed message should not be
641 DEBUG(0,("schedule_deferred_open_smb_message: LOGIC ERROR "
642 "message mid %u was already processed\n",
647 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
650 te = event_add_timed(smbd_event_context(),
653 smbd_deferred_open_timer,
656 DEBUG(10,("schedule_deferred_open_smb_message: "
657 "event_add_timed() failed, skipping mid %u\n",
661 TALLOC_FREE(pml->te);
663 DLIST_PROMOTE(deferred_open_queue, pml);
668 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
672 /****************************************************************************
673 Return true if this mid is on the deferred queue and was not yet processed.
674 ****************************************************************************/
676 bool open_was_deferred(uint16 mid)
678 struct pending_message_list *pml;
680 for (pml = deferred_open_queue; pml; pml = pml->next) {
681 if (SVAL(pml->buf.data,smb_mid) == mid && !pml->processed) {
688 /****************************************************************************
689 Return the message queued by this mid.
690 ****************************************************************************/
692 struct pending_message_list *get_open_deferred_message(uint16 mid)
694 struct pending_message_list *pml;
696 for (pml = deferred_open_queue; pml; pml = pml->next) {
697 if (SVAL(pml->buf.data,smb_mid) == mid) {
704 /****************************************************************************
705 Function to push a deferred open smb message onto a linked list of local smb
706 messages ready for processing.
707 ****************************************************************************/
709 bool push_deferred_smb_message(struct smb_request *req,
710 struct timeval request_time,
711 struct timeval timeout,
712 char *private_data, size_t priv_len)
714 struct timeval end_time;
716 if (req->unread_bytes) {
717 DEBUG(0,("push_deferred_smb_message: logic error ! "
718 "unread_bytes = %u\n",
719 (unsigned int)req->unread_bytes ));
720 smb_panic("push_deferred_smb_message: "
721 "logic error unread_bytes != 0" );
724 end_time = timeval_sum(&request_time, &timeout);
726 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
727 "timeout time [%u.%06u]\n",
728 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
729 (unsigned int)end_time.tv_sec,
730 (unsigned int)end_time.tv_usec));
732 return push_queued_message(req, request_time, end_time,
733 private_data, priv_len);
737 struct timed_event *te;
738 struct timeval interval;
740 bool (*handler)(const struct timeval *now, void *private_data);
744 static void smbd_idle_event_handler(struct event_context *ctx,
745 struct timed_event *te,
749 struct idle_event *event =
750 talloc_get_type_abort(private_data, struct idle_event);
752 TALLOC_FREE(event->te);
754 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
755 event->name, event->te));
757 if (!event->handler(&now, event->private_data)) {
758 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
759 event->name, event->te));
760 /* Don't repeat, delete ourselves */
765 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
766 event->name, event->te));
768 event->te = event_add_timed(ctx, event,
769 timeval_sum(&now, &event->interval),
770 smbd_idle_event_handler, event);
772 /* We can't do much but fail here. */
773 SMB_ASSERT(event->te != NULL);
776 struct idle_event *event_add_idle(struct event_context *event_ctx,
778 struct timeval interval,
780 bool (*handler)(const struct timeval *now,
784 struct idle_event *result;
785 struct timeval now = timeval_current();
787 result = TALLOC_P(mem_ctx, struct idle_event);
788 if (result == NULL) {
789 DEBUG(0, ("talloc failed\n"));
793 result->interval = interval;
794 result->handler = handler;
795 result->private_data = private_data;
797 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
798 DEBUG(0, ("talloc failed\n"));
803 result->te = event_add_timed(event_ctx, result,
804 timeval_sum(&now, &interval),
805 smbd_idle_event_handler, result);
806 if (result->te == NULL) {
807 DEBUG(0, ("event_add_timed failed\n"));
812 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
816 static void smbd_sig_term_handler(struct tevent_context *ev,
817 struct tevent_signal *se,
823 exit_server_cleanly("termination signal");
826 void smbd_setup_sig_term_handler(void)
828 struct tevent_signal *se;
830 se = tevent_add_signal(smbd_event_context(),
831 smbd_event_context(),
833 smbd_sig_term_handler,
836 exit_server("failed to setup SIGTERM handler");
840 static void smbd_sig_hup_handler(struct tevent_context *ev,
841 struct tevent_signal *se,
847 change_to_root_user();
848 DEBUG(1,("Reloading services after SIGHUP\n"));
849 reload_services(False);
852 void smbd_setup_sig_hup_handler(void)
854 struct tevent_signal *se;
856 se = tevent_add_signal(smbd_event_context(),
857 smbd_event_context(),
859 smbd_sig_hup_handler,
862 exit_server("failed to setup SIGHUP handler");
866 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
873 to.tv_sec = SMBD_SELECT_TIMEOUT;
877 * Setup the select fd sets.
884 * Are there any timed events waiting ? If so, ensure we don't
885 * select for longer than it would take to wait for them.
892 event_add_to_select_args(smbd_event_context(), &now,
893 &r_fds, &w_fds, &to, &maxfd);
896 /* Process a signal and timed events now... */
897 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
898 return NT_STATUS_RETRY;
903 START_PROFILE(smbd_idle);
905 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
908 END_PROFILE(smbd_idle);
912 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
913 return NT_STATUS_RETRY;
918 /* something is wrong. Maybe the socket is dead? */
919 return map_nt_error_from_unix(errno);
922 /* Did we timeout ? */
924 return NT_STATUS_RETRY;
927 /* should not be reached */
928 return NT_STATUS_INTERNAL_ERROR;
932 * Only allow 5 outstanding trans requests. We're allocating memory, so
936 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
939 for (; list != NULL; list = list->next) {
941 if (list->mid == mid) {
942 return NT_STATUS_INVALID_PARAMETER;
948 return NT_STATUS_INSUFFICIENT_RESOURCES;
955 These flags determine some of the permissions required to do an operation
957 Note that I don't set NEED_WRITE on some write operations because they
958 are used by some brain-dead clients when printing, and I don't want to
959 force write permissions on print services.
961 #define AS_USER (1<<0)
962 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
963 #define TIME_INIT (1<<2)
964 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
965 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
966 #define DO_CHDIR (1<<6)
969 define a list of possible SMB messages and their corresponding
970 functions. Any message that has a NULL function is unimplemented -
971 please feel free to contribute implementations!
973 static const struct smb_message_struct {
975 void (*fn)(struct smb_request *req);
977 } smb_messages[256] = {
979 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
980 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
981 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
982 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
983 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
984 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
985 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
986 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
987 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
988 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
989 /* 0x0a */ { "SMBread",reply_read,AS_USER},
990 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
991 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
992 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
993 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
994 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
995 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
996 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
997 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
998 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
999 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1000 /* 0x15 */ { NULL, NULL, 0 },
1001 /* 0x16 */ { NULL, NULL, 0 },
1002 /* 0x17 */ { NULL, NULL, 0 },
1003 /* 0x18 */ { NULL, NULL, 0 },
1004 /* 0x19 */ { NULL, NULL, 0 },
1005 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1006 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1007 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1008 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1009 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1010 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1011 /* 0x20 */ { "SMBwritec", NULL,0},
1012 /* 0x21 */ { NULL, NULL, 0 },
1013 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1014 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1015 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1016 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1017 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1018 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1019 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1020 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1021 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1022 /* 0x2b */ { "SMBecho",reply_echo,0},
1023 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1024 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1025 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1026 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1027 /* 0x30 */ { NULL, NULL, 0 },
1028 /* 0x31 */ { NULL, NULL, 0 },
1029 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1030 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1031 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1032 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1033 /* 0x36 */ { NULL, NULL, 0 },
1034 /* 0x37 */ { NULL, NULL, 0 },
1035 /* 0x38 */ { NULL, NULL, 0 },
1036 /* 0x39 */ { NULL, NULL, 0 },
1037 /* 0x3a */ { NULL, NULL, 0 },
1038 /* 0x3b */ { NULL, NULL, 0 },
1039 /* 0x3c */ { NULL, NULL, 0 },
1040 /* 0x3d */ { NULL, NULL, 0 },
1041 /* 0x3e */ { NULL, NULL, 0 },
1042 /* 0x3f */ { NULL, NULL, 0 },
1043 /* 0x40 */ { NULL, NULL, 0 },
1044 /* 0x41 */ { NULL, NULL, 0 },
1045 /* 0x42 */ { NULL, NULL, 0 },
1046 /* 0x43 */ { NULL, NULL, 0 },
1047 /* 0x44 */ { NULL, NULL, 0 },
1048 /* 0x45 */ { NULL, NULL, 0 },
1049 /* 0x46 */ { NULL, NULL, 0 },
1050 /* 0x47 */ { NULL, NULL, 0 },
1051 /* 0x48 */ { NULL, NULL, 0 },
1052 /* 0x49 */ { NULL, NULL, 0 },
1053 /* 0x4a */ { NULL, NULL, 0 },
1054 /* 0x4b */ { NULL, NULL, 0 },
1055 /* 0x4c */ { NULL, NULL, 0 },
1056 /* 0x4d */ { NULL, NULL, 0 },
1057 /* 0x4e */ { NULL, NULL, 0 },
1058 /* 0x4f */ { NULL, NULL, 0 },
1059 /* 0x50 */ { NULL, NULL, 0 },
1060 /* 0x51 */ { NULL, NULL, 0 },
1061 /* 0x52 */ { NULL, NULL, 0 },
1062 /* 0x53 */ { NULL, NULL, 0 },
1063 /* 0x54 */ { NULL, NULL, 0 },
1064 /* 0x55 */ { NULL, NULL, 0 },
1065 /* 0x56 */ { NULL, NULL, 0 },
1066 /* 0x57 */ { NULL, NULL, 0 },
1067 /* 0x58 */ { NULL, NULL, 0 },
1068 /* 0x59 */ { NULL, NULL, 0 },
1069 /* 0x5a */ { NULL, NULL, 0 },
1070 /* 0x5b */ { NULL, NULL, 0 },
1071 /* 0x5c */ { NULL, NULL, 0 },
1072 /* 0x5d */ { NULL, NULL, 0 },
1073 /* 0x5e */ { NULL, NULL, 0 },
1074 /* 0x5f */ { NULL, NULL, 0 },
1075 /* 0x60 */ { NULL, NULL, 0 },
1076 /* 0x61 */ { NULL, NULL, 0 },
1077 /* 0x62 */ { NULL, NULL, 0 },
1078 /* 0x63 */ { NULL, NULL, 0 },
1079 /* 0x64 */ { NULL, NULL, 0 },
1080 /* 0x65 */ { NULL, NULL, 0 },
1081 /* 0x66 */ { NULL, NULL, 0 },
1082 /* 0x67 */ { NULL, NULL, 0 },
1083 /* 0x68 */ { NULL, NULL, 0 },
1084 /* 0x69 */ { NULL, NULL, 0 },
1085 /* 0x6a */ { NULL, NULL, 0 },
1086 /* 0x6b */ { NULL, NULL, 0 },
1087 /* 0x6c */ { NULL, NULL, 0 },
1088 /* 0x6d */ { NULL, NULL, 0 },
1089 /* 0x6e */ { NULL, NULL, 0 },
1090 /* 0x6f */ { NULL, NULL, 0 },
1091 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1092 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1093 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1094 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1095 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1096 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1097 /* 0x76 */ { NULL, NULL, 0 },
1098 /* 0x77 */ { NULL, NULL, 0 },
1099 /* 0x78 */ { NULL, NULL, 0 },
1100 /* 0x79 */ { NULL, NULL, 0 },
1101 /* 0x7a */ { NULL, NULL, 0 },
1102 /* 0x7b */ { NULL, NULL, 0 },
1103 /* 0x7c */ { NULL, NULL, 0 },
1104 /* 0x7d */ { NULL, NULL, 0 },
1105 /* 0x7e */ { NULL, NULL, 0 },
1106 /* 0x7f */ { NULL, NULL, 0 },
1107 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1108 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1109 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1110 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1111 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1112 /* 0x85 */ { NULL, NULL, 0 },
1113 /* 0x86 */ { NULL, NULL, 0 },
1114 /* 0x87 */ { NULL, NULL, 0 },
1115 /* 0x88 */ { NULL, NULL, 0 },
1116 /* 0x89 */ { NULL, NULL, 0 },
1117 /* 0x8a */ { NULL, NULL, 0 },
1118 /* 0x8b */ { NULL, NULL, 0 },
1119 /* 0x8c */ { NULL, NULL, 0 },
1120 /* 0x8d */ { NULL, NULL, 0 },
1121 /* 0x8e */ { NULL, NULL, 0 },
1122 /* 0x8f */ { NULL, NULL, 0 },
1123 /* 0x90 */ { NULL, NULL, 0 },
1124 /* 0x91 */ { NULL, NULL, 0 },
1125 /* 0x92 */ { NULL, NULL, 0 },
1126 /* 0x93 */ { NULL, NULL, 0 },
1127 /* 0x94 */ { NULL, NULL, 0 },
1128 /* 0x95 */ { NULL, NULL, 0 },
1129 /* 0x96 */ { NULL, NULL, 0 },
1130 /* 0x97 */ { NULL, NULL, 0 },
1131 /* 0x98 */ { NULL, NULL, 0 },
1132 /* 0x99 */ { NULL, NULL, 0 },
1133 /* 0x9a */ { NULL, NULL, 0 },
1134 /* 0x9b */ { NULL, NULL, 0 },
1135 /* 0x9c */ { NULL, NULL, 0 },
1136 /* 0x9d */ { NULL, NULL, 0 },
1137 /* 0x9e */ { NULL, NULL, 0 },
1138 /* 0x9f */ { NULL, NULL, 0 },
1139 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1140 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1141 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1142 /* 0xa3 */ { NULL, NULL, 0 },
1143 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1144 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1145 /* 0xa6 */ { NULL, NULL, 0 },
1146 /* 0xa7 */ { NULL, NULL, 0 },
1147 /* 0xa8 */ { NULL, NULL, 0 },
1148 /* 0xa9 */ { NULL, NULL, 0 },
1149 /* 0xaa */ { NULL, NULL, 0 },
1150 /* 0xab */ { NULL, NULL, 0 },
1151 /* 0xac */ { NULL, NULL, 0 },
1152 /* 0xad */ { NULL, NULL, 0 },
1153 /* 0xae */ { NULL, NULL, 0 },
1154 /* 0xaf */ { NULL, NULL, 0 },
1155 /* 0xb0 */ { NULL, NULL, 0 },
1156 /* 0xb1 */ { NULL, NULL, 0 },
1157 /* 0xb2 */ { NULL, NULL, 0 },
1158 /* 0xb3 */ { NULL, NULL, 0 },
1159 /* 0xb4 */ { NULL, NULL, 0 },
1160 /* 0xb5 */ { NULL, NULL, 0 },
1161 /* 0xb6 */ { NULL, NULL, 0 },
1162 /* 0xb7 */ { NULL, NULL, 0 },
1163 /* 0xb8 */ { NULL, NULL, 0 },
1164 /* 0xb9 */ { NULL, NULL, 0 },
1165 /* 0xba */ { NULL, NULL, 0 },
1166 /* 0xbb */ { NULL, NULL, 0 },
1167 /* 0xbc */ { NULL, NULL, 0 },
1168 /* 0xbd */ { NULL, NULL, 0 },
1169 /* 0xbe */ { NULL, NULL, 0 },
1170 /* 0xbf */ { NULL, NULL, 0 },
1171 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1172 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1173 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1174 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1175 /* 0xc4 */ { NULL, NULL, 0 },
1176 /* 0xc5 */ { NULL, NULL, 0 },
1177 /* 0xc6 */ { NULL, NULL, 0 },
1178 /* 0xc7 */ { NULL, NULL, 0 },
1179 /* 0xc8 */ { NULL, NULL, 0 },
1180 /* 0xc9 */ { NULL, NULL, 0 },
1181 /* 0xca */ { NULL, NULL, 0 },
1182 /* 0xcb */ { NULL, NULL, 0 },
1183 /* 0xcc */ { NULL, NULL, 0 },
1184 /* 0xcd */ { NULL, NULL, 0 },
1185 /* 0xce */ { NULL, NULL, 0 },
1186 /* 0xcf */ { NULL, NULL, 0 },
1187 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1188 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1189 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1190 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1191 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1192 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1193 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1194 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1195 /* 0xd8 */ { NULL, NULL, 0 },
1196 /* 0xd9 */ { NULL, NULL, 0 },
1197 /* 0xda */ { NULL, NULL, 0 },
1198 /* 0xdb */ { NULL, NULL, 0 },
1199 /* 0xdc */ { NULL, NULL, 0 },
1200 /* 0xdd */ { NULL, NULL, 0 },
1201 /* 0xde */ { NULL, NULL, 0 },
1202 /* 0xdf */ { NULL, NULL, 0 },
1203 /* 0xe0 */ { NULL, NULL, 0 },
1204 /* 0xe1 */ { NULL, NULL, 0 },
1205 /* 0xe2 */ { NULL, NULL, 0 },
1206 /* 0xe3 */ { NULL, NULL, 0 },
1207 /* 0xe4 */ { NULL, NULL, 0 },
1208 /* 0xe5 */ { NULL, NULL, 0 },
1209 /* 0xe6 */ { NULL, NULL, 0 },
1210 /* 0xe7 */ { NULL, NULL, 0 },
1211 /* 0xe8 */ { NULL, NULL, 0 },
1212 /* 0xe9 */ { NULL, NULL, 0 },
1213 /* 0xea */ { NULL, NULL, 0 },
1214 /* 0xeb */ { NULL, NULL, 0 },
1215 /* 0xec */ { NULL, NULL, 0 },
1216 /* 0xed */ { NULL, NULL, 0 },
1217 /* 0xee */ { NULL, NULL, 0 },
1218 /* 0xef */ { NULL, NULL, 0 },
1219 /* 0xf0 */ { NULL, NULL, 0 },
1220 /* 0xf1 */ { NULL, NULL, 0 },
1221 /* 0xf2 */ { NULL, NULL, 0 },
1222 /* 0xf3 */ { NULL, NULL, 0 },
1223 /* 0xf4 */ { NULL, NULL, 0 },
1224 /* 0xf5 */ { NULL, NULL, 0 },
1225 /* 0xf6 */ { NULL, NULL, 0 },
1226 /* 0xf7 */ { NULL, NULL, 0 },
1227 /* 0xf8 */ { NULL, NULL, 0 },
1228 /* 0xf9 */ { NULL, NULL, 0 },
1229 /* 0xfa */ { NULL, NULL, 0 },
1230 /* 0xfb */ { NULL, NULL, 0 },
1231 /* 0xfc */ { NULL, NULL, 0 },
1232 /* 0xfd */ { NULL, NULL, 0 },
1233 /* 0xfe */ { NULL, NULL, 0 },
1234 /* 0xff */ { NULL, NULL, 0 }
1238 /*******************************************************************
1239 allocate and initialize a reply packet
1240 ********************************************************************/
1242 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1243 const char *inbuf, char **outbuf, uint8_t num_words,
1247 * Protect against integer wrap
1249 if ((num_bytes > 0xffffff)
1250 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1252 if (asprintf(&msg, "num_bytes too large: %u",
1253 (unsigned)num_bytes) == -1) {
1254 msg = CONST_DISCARD(char *, "num_bytes too large");
1259 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1260 smb_size + num_words*2 + num_bytes);
1261 if (*outbuf == NULL) {
1265 construct_reply_common(req, inbuf, *outbuf);
1266 srv_set_message(*outbuf, num_words, num_bytes, false);
1268 * Zero out the word area, the caller has to take care of the bcc area
1271 if (num_words != 0) {
1272 memset(*outbuf + smb_vwv0, 0, num_words*2);
1278 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1281 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1283 smb_panic("could not allocate output buffer\n");
1285 req->outbuf = (uint8_t *)outbuf;
1289 /*******************************************************************
1290 Dump a packet to a file.
1291 ********************************************************************/
1293 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1297 if (DEBUGLEVEL < 50) {
1301 if (len < 4) len = smb_len(data)+4;
1302 for (i=1;i<100;i++) {
1303 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1304 type ? "req" : "resp") == -1) {
1307 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1308 if (fd != -1 || errno != EEXIST) break;
1311 ssize_t ret = write(fd, data, len);
1313 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1315 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1320 /****************************************************************************
1321 Prepare everything for calling the actual request function, and potentially
1322 call the request function via the "new" interface.
1324 Return False if the "legacy" function needs to be called, everything is
1327 Return True if we're done.
1329 I know this API sucks, but it is the one with the least code change I could
1331 ****************************************************************************/
1333 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1337 connection_struct *conn = NULL;
1338 struct smbd_server_connection *sconn = smbd_server_conn;
1342 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1343 * so subtract 4 from it. */
1344 if (!valid_smb_header(req->inbuf)
1345 || (size < (smb_size - 4))) {
1346 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1347 smb_len(req->inbuf)));
1348 exit_server_cleanly("Non-SMB packet");
1351 if (smb_messages[type].fn == NULL) {
1352 DEBUG(0,("Unknown message type %d!\n",type));
1353 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1354 reply_unknown_new(req, type);
1358 flags = smb_messages[type].flags;
1360 /* In share mode security we must ignore the vuid. */
1361 session_tag = (lp_security() == SEC_SHARE)
1362 ? UID_FIELD_INVALID : req->vuid;
1365 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1366 (int)sys_getpid(), (unsigned long)conn));
1368 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1370 /* Ensure this value is replaced in the incoming packet. */
1371 SSVAL(req->inbuf,smb_uid,session_tag);
1374 * Ensure the correct username is in current_user_info. This is a
1375 * really ugly bugfix for problems with multiple session_setup_and_X's
1376 * being done and allowing %U and %G substitutions to work correctly.
1377 * There is a reason this code is done here, don't move it unless you
1378 * know what you're doing... :-).
1382 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1383 user_struct *vuser = NULL;
1385 sconn->smb1.sessions.last_session_tag = session_tag;
1386 if(session_tag != UID_FIELD_INVALID) {
1387 vuser = get_valid_user_struct(sconn, session_tag);
1389 set_current_user_info(
1390 vuser->server_info->sanitized_username,
1391 vuser->server_info->unix_name,
1392 pdb_get_domain(vuser->server_info
1398 /* Does this call need to be run as the connected user? */
1399 if (flags & AS_USER) {
1401 /* Does this call need a valid tree connection? */
1404 * Amazingly, the error code depends on the command
1407 if (type == SMBntcreateX) {
1408 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1410 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1415 if (!change_to_user(conn,session_tag)) {
1416 DEBUG(0, ("Error: Could not change to user. Removing "
1417 "deferred open, mid=%d.\n", req->mid));
1418 reply_force_doserror(req, ERRSRV, ERRbaduid);
1422 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1424 /* Does it need write permission? */
1425 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1426 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1430 /* IPC services are limited */
1431 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1432 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1436 /* This call needs to be run as root */
1437 change_to_root_user();
1440 /* load service specific parameters */
1442 if (req->encrypted) {
1443 conn->encrypted_tid = true;
1444 /* encrypted required from now on. */
1445 conn->encrypt_level = Required;
1446 } else if (ENCRYPTION_REQUIRED(conn)) {
1447 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1448 exit_server_cleanly("encryption required "
1454 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1455 (flags & (AS_USER|DO_CHDIR)
1457 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1460 conn->num_smb_operations++;
1463 /* does this protocol need to be run as guest? */
1464 if ((flags & AS_GUEST)
1465 && (!change_to_guest() ||
1466 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1467 lp_hostsdeny(-1)))) {
1468 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1472 smb_messages[type].fn(req);
1476 /****************************************************************************
1477 Construct a reply to the incoming packet.
1478 ****************************************************************************/
1480 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1481 uint32_t seqnum, bool encrypted,
1482 struct smb_perfcount_data *deferred_pcd)
1484 connection_struct *conn;
1485 struct smb_request *req;
1487 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1488 smb_panic("could not allocate smb_request");
1491 if (!init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted,
1493 exit_server_cleanly("Invalid SMB request");
1496 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1498 /* we popped this message off the queue - keep original perf data */
1500 req->pcd = *deferred_pcd;
1502 SMB_PERFCOUNT_START(&req->pcd);
1503 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1504 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1507 conn = switch_message(req->cmd, req, size);
1509 if (req->unread_bytes) {
1510 /* writeX failed. drain socket. */
1511 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1512 req->unread_bytes) {
1513 smb_panic("failed to drain pending bytes");
1515 req->unread_bytes = 0;
1523 if (req->outbuf == NULL) {
1527 if (CVAL(req->outbuf,0) == 0) {
1528 show_msg((char *)req->outbuf);
1531 if (!srv_send_smb(smbd_server_fd(),
1532 (char *)req->outbuf,
1533 true, req->seqnum+1,
1534 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1536 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1544 /****************************************************************************
1545 Process an smb from the client
1546 ****************************************************************************/
1547 static void process_smb(struct smbd_server_connection *conn,
1548 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1549 uint32_t seqnum, bool encrypted,
1550 struct smb_perfcount_data *deferred_pcd)
1552 int msg_type = CVAL(inbuf,0);
1554 DO_PROFILE_INC(smb_count);
1556 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1558 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1560 (unsigned int)unread_bytes ));
1562 if (msg_type != 0) {
1564 * NetBIOS session request, keepalive, etc.
1566 reply_special((char *)inbuf);
1570 if (smbd_server_conn->allow_smb2) {
1571 if (smbd_is_smb2_header(inbuf, nread)) {
1572 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1575 smbd_server_conn->allow_smb2 = false;
1578 show_msg((char *)inbuf);
1580 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1584 conn->smb1.num_requests++;
1586 /* The timeout_processing function isn't run nearly
1587 often enough to implement 'max log size' without
1588 overrunning the size of the file by many megabytes.
1589 This is especially true if we are running at debug
1590 level 10. Checking every 50 SMBs is a nice
1591 tradeoff of performance vs log file size overrun. */
1593 if ((conn->smb1.num_requests % 50) == 0 &&
1594 need_to_check_log_size()) {
1595 change_to_root_user();
1600 /****************************************************************************
1601 Return a string containing the function name of a SMB command.
1602 ****************************************************************************/
1604 const char *smb_fn_name(int type)
1606 const char *unknown_name = "SMBunknown";
1608 if (smb_messages[type].name == NULL)
1609 return(unknown_name);
1611 return(smb_messages[type].name);
1614 /****************************************************************************
1615 Helper functions for contruct_reply.
1616 ****************************************************************************/
1618 void add_to_common_flags2(uint32 v)
1623 void remove_from_common_flags2(uint32 v)
1625 common_flags2 &= ~v;
1628 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1631 srv_set_message(outbuf,0,0,false);
1633 SCVAL(outbuf, smb_com, req->cmd);
1634 SIVAL(outbuf,smb_rcls,0);
1635 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1636 SSVAL(outbuf,smb_flg2,
1637 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1639 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1641 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1642 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1643 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1644 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1647 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1649 construct_reply_common(req, (char *)req->inbuf, outbuf);
1653 * How many bytes have we already accumulated up to the current wct field
1657 size_t req_wct_ofs(struct smb_request *req)
1661 if (req->chain_outbuf == NULL) {
1664 buf_size = talloc_get_size(req->chain_outbuf);
1665 if ((buf_size % 4) != 0) {
1666 buf_size += (4 - (buf_size % 4));
1668 return buf_size - 4;
1672 * Hack around reply_nterror & friends not being aware of chained requests,
1673 * generating illegal (i.e. wct==0) chain replies.
1676 static void fixup_chain_error_packet(struct smb_request *req)
1678 uint8_t *outbuf = req->outbuf;
1680 reply_outbuf(req, 2, 0);
1681 memcpy(req->outbuf, outbuf, smb_wct);
1682 TALLOC_FREE(outbuf);
1683 SCVAL(req->outbuf, smb_vwv0, 0xff);
1687 * @brief Find the smb_cmd offset of the last command pushed
1688 * @param[in] buf The buffer we're building up
1689 * @retval Where can we put our next andx cmd?
1691 * While chaining requests, the "next" request we're looking at needs to put
1692 * its SMB_Command before the data the previous request already built up added
1693 * to the chain. Find the offset to the place where we have to put our cmd.
1696 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1701 cmd = CVAL(buf, smb_com);
1703 SMB_ASSERT(is_andx_req(cmd));
1707 while (CVAL(buf, ofs) != 0xff) {
1709 if (!is_andx_req(CVAL(buf, ofs))) {
1714 * ofs is from start of smb header, so add the 4 length
1715 * bytes. The next cmd is right after the wct field.
1717 ofs = SVAL(buf, ofs+2) + 4 + 1;
1719 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1727 * @brief Do the smb chaining at a buffer level
1728 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1729 * @param[in] smb_command The command that we want to issue
1730 * @param[in] wct How many words?
1731 * @param[in] vwv The words, already in network order
1732 * @param[in] bytes_alignment How shall we align "bytes"?
1733 * @param[in] num_bytes How many bytes?
1734 * @param[in] bytes The data the request ships
1736 * smb_splice_chain() adds the vwv and bytes to the request already present in
1740 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1741 uint8_t wct, const uint16_t *vwv,
1742 size_t bytes_alignment,
1743 uint32_t num_bytes, const uint8_t *bytes)
1746 size_t old_size, new_size;
1748 size_t chain_padding = 0;
1749 size_t bytes_padding = 0;
1752 old_size = talloc_get_size(*poutbuf);
1755 * old_size == smb_wct means we're pushing the first request in for
1759 first_request = (old_size == smb_wct);
1761 if (!first_request && ((old_size % 4) != 0)) {
1763 * Align the wct field of subsequent requests to a 4-byte
1766 chain_padding = 4 - (old_size % 4);
1770 * After the old request comes the new wct field (1 byte), the vwv's
1771 * and the num_bytes field. After at we might need to align the bytes
1772 * given to us to "bytes_alignment", increasing the num_bytes value.
1775 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1777 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1778 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1781 new_size += bytes_padding + num_bytes;
1783 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1784 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1785 (unsigned)new_size));
1789 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1790 if (outbuf == NULL) {
1791 DEBUG(0, ("talloc failed\n"));
1796 if (first_request) {
1797 SCVAL(outbuf, smb_com, smb_command);
1799 size_t andx_cmd_ofs;
1801 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1802 DEBUG(1, ("invalid command chain\n"));
1803 *poutbuf = TALLOC_REALLOC_ARRAY(
1804 NULL, *poutbuf, uint8_t, old_size);
1808 if (chain_padding != 0) {
1809 memset(outbuf + old_size, 0, chain_padding);
1810 old_size += chain_padding;
1813 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1814 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1820 * Push the chained request:
1825 SCVAL(outbuf, ofs, wct);
1832 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1833 ofs += sizeof(uint16_t) * wct;
1839 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1840 ofs += sizeof(uint16_t);
1846 if (bytes_padding != 0) {
1847 memset(outbuf + ofs, 0, bytes_padding);
1848 ofs += bytes_padding;
1855 memcpy(outbuf + ofs, bytes, num_bytes);
1860 /****************************************************************************
1861 Construct a chained reply and add it to the already made reply
1862 ****************************************************************************/
1864 void chain_reply(struct smb_request *req)
1866 size_t smblen = smb_len(req->inbuf);
1867 size_t already_used, length_needed;
1869 uint32_t chain_offset; /* uint32_t to avoid overflow */
1876 if (IVAL(req->outbuf, smb_rcls) != 0) {
1877 fixup_chain_error_packet(req);
1881 * Any of the AndX requests and replies have at least a wct of
1882 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1883 * beginning of the SMB header to the next wct field.
1885 * None of the AndX requests put anything valuable in vwv[0] and [1],
1886 * so we can overwrite it here to form the chain.
1889 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1890 if (req->chain_outbuf == NULL) {
1891 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1892 req, req->outbuf, uint8_t,
1893 smb_len(req->outbuf) + 4);
1894 if (req->chain_outbuf == NULL) {
1895 smb_panic("talloc failed");
1903 * Here we assume that this is the end of the chain. For that we need
1904 * to set "next command" to 0xff and the offset to 0. If we later find
1905 * more commands in the chain, this will be overwritten again.
1908 SCVAL(req->outbuf, smb_vwv0, 0xff);
1909 SCVAL(req->outbuf, smb_vwv0+1, 0);
1910 SSVAL(req->outbuf, smb_vwv1, 0);
1912 if (req->chain_outbuf == NULL) {
1914 * In req->chain_outbuf we collect all the replies. Start the
1915 * chain by copying in the first reply.
1917 * We do the realloc because later on we depend on
1918 * talloc_get_size to determine the length of
1919 * chain_outbuf. The reply_xxx routines might have
1920 * over-allocated (reply_pipe_read_and_X used to be such an
1923 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1924 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1925 if (req->chain_outbuf == NULL) {
1926 smb_panic("talloc failed");
1931 * Update smb headers where subsequent chained commands
1932 * may have updated them.
1934 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1935 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1937 if (!smb_splice_chain(&req->chain_outbuf,
1938 CVAL(req->outbuf, smb_com),
1939 CVAL(req->outbuf, smb_wct),
1940 (uint16_t *)(req->outbuf + smb_vwv),
1941 0, smb_buflen(req->outbuf),
1942 (uint8_t *)smb_buf(req->outbuf))) {
1945 TALLOC_FREE(req->outbuf);
1949 * We use the old request's vwv field to grab the next chained command
1950 * and offset into the chained fields.
1953 chain_cmd = CVAL(req->vwv+0, 0);
1954 chain_offset = SVAL(req->vwv+1, 0);
1956 if (chain_cmd == 0xff) {
1958 * End of chain, no more requests from the client. So ship the
1961 smb_setlen((char *)(req->chain_outbuf),
1962 talloc_get_size(req->chain_outbuf) - 4);
1964 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1965 true, req->seqnum+1,
1966 IS_CONN_ENCRYPTED(req->conn)
1969 exit_server_cleanly("chain_reply: srv_send_smb "
1972 TALLOC_FREE(req->chain_outbuf);
1977 /* add a new perfcounter for this element of chain */
1978 SMB_PERFCOUNT_ADD(&req->pcd);
1979 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1980 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1983 * Check if the client tries to fool us. The request so far uses the
1984 * space to the end of the byte buffer in the request just
1985 * processed. The chain_offset can't point into that area. If that was
1986 * the case, we could end up with an endless processing of the chain,
1987 * we would always handle the same request.
1990 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1991 if (chain_offset < already_used) {
1996 * Next check: Make sure the chain offset does not point beyond the
1997 * overall smb request length.
2000 length_needed = chain_offset+1; /* wct */
2001 if (length_needed > smblen) {
2006 * Now comes the pointer magic. Goal here is to set up req->vwv and
2007 * req->buf correctly again to be able to call the subsequent
2008 * switch_message(). The chain offset (the former vwv[1]) points at
2009 * the new wct field.
2012 wct = CVAL(smb_base(req->inbuf), chain_offset);
2015 * Next consistency check: Make the new vwv array fits in the overall
2019 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2020 if (length_needed > smblen) {
2023 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2026 * Now grab the new byte buffer....
2029 buflen = SVAL(vwv+wct, 0);
2032 * .. and check that it fits.
2035 length_needed += buflen;
2036 if (length_needed > smblen) {
2039 buf = (uint8_t *)(vwv+wct+1);
2041 req->cmd = chain_cmd;
2044 req->buflen = buflen;
2047 switch_message(chain_cmd, req, smblen);
2049 if (req->outbuf == NULL) {
2051 * This happens if the chained command has suspended itself or
2052 * if it has called srv_send_smb() itself.
2058 * We end up here if the chained command was not itself chained or
2059 * suspended, but for example a close() command. We now need to splice
2060 * the chained commands' outbuf into the already built up chain_outbuf
2061 * and ship the result.
2067 * We end up here if there's any error in the chain syntax. Report a
2068 * DOS error, just like Windows does.
2070 reply_force_doserror(req, ERRSRV, ERRerror);
2071 fixup_chain_error_packet(req);
2075 * This scary statement intends to set the
2076 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2077 * to the value req->outbuf carries
2079 SSVAL(req->chain_outbuf, smb_flg2,
2080 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2081 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2084 * Transfer the error codes from the subrequest to the main one
2086 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2087 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2089 if (!smb_splice_chain(&req->chain_outbuf,
2090 CVAL(req->outbuf, smb_com),
2091 CVAL(req->outbuf, smb_wct),
2092 (uint16_t *)(req->outbuf + smb_vwv),
2093 0, smb_buflen(req->outbuf),
2094 (uint8_t *)smb_buf(req->outbuf))) {
2095 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2097 TALLOC_FREE(req->outbuf);
2099 smb_setlen((char *)(req->chain_outbuf),
2100 talloc_get_size(req->chain_outbuf) - 4);
2102 show_msg((char *)(req->chain_outbuf));
2104 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2105 true, req->seqnum+1,
2106 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2108 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2110 TALLOC_FREE(req->chain_outbuf);
2114 /****************************************************************************
2115 Check if services need reloading.
2116 ****************************************************************************/
2118 void check_reload(time_t t)
2120 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2122 if(last_smb_conf_reload_time == 0) {
2123 last_smb_conf_reload_time = t;
2124 /* Our printing subsystem might not be ready at smbd start up.
2125 Then no printer is available till the first printers check
2126 is performed. A lower initial interval circumvents this. */
2127 if ( printcap_cache_time > 60 )
2128 last_printer_reload_time = t - printcap_cache_time + 60;
2130 last_printer_reload_time = t;
2133 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2134 /* randomize over 60 second the printcap reload to avoid all
2135 * process hitting cupsd at the same time */
2136 int time_range = 60;
2138 last_printer_reload_time += random() % time_range;
2142 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2143 reload_services(True);
2144 last_smb_conf_reload_time = t;
2147 /* 'printcap cache time = 0' disable the feature */
2149 if ( printcap_cache_time != 0 )
2151 /* see if it's time to reload or if the clock has been set back */
2153 if ( (t >= last_printer_reload_time+printcap_cache_time)
2154 || (t-last_printer_reload_time < 0) )
2156 DEBUG( 3,( "Printcap cache time expired.\n"));
2158 last_printer_reload_time = t;
2163 static bool fd_is_readable(int fd)
2166 struct timeval timeout = {0, };
2172 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2176 return FD_ISSET(fd, &fds);
2179 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2181 /* TODO: make write nonblocking */
2184 static void smbd_server_connection_read_handler(
2185 struct smbd_server_connection *conn, int fd)
2187 uint8_t *inbuf = NULL;
2188 size_t inbuf_len = 0;
2189 size_t unread_bytes = 0;
2190 bool encrypted = false;
2191 TALLOC_CTX *mem_ctx = talloc_tos();
2195 bool from_client = (smbd_server_fd() == fd)?true:false;
2198 smbd_lock_socket(conn);
2200 if (!fd_is_readable(smbd_server_fd())) {
2201 DEBUG(10,("the echo listener was faster\n"));
2202 smbd_unlock_socket(conn);
2206 /* TODO: make this completely nonblocking */
2207 status = receive_smb_talloc(mem_ctx, fd,
2208 (char **)(void *)&inbuf,
2212 &inbuf_len, &seqnum,
2213 false /* trusted channel */);
2214 smbd_unlock_socket(conn);
2216 /* TODO: make this completely nonblocking */
2217 status = receive_smb_talloc(mem_ctx, fd,
2218 (char **)(void *)&inbuf,
2222 &inbuf_len, &seqnum,
2223 true /* trusted channel */);
2226 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2229 if (NT_STATUS_IS_ERR(status)) {
2230 exit_server_cleanly("failed to receive smb request");
2232 if (!NT_STATUS_IS_OK(status)) {
2237 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2238 seqnum, encrypted, NULL);
2241 static void smbd_server_connection_handler(struct event_context *ev,
2242 struct fd_event *fde,
2246 struct smbd_server_connection *conn = talloc_get_type(private_data,
2247 struct smbd_server_connection);
2249 if (flags & EVENT_FD_WRITE) {
2250 smbd_server_connection_write_handler(conn);
2251 } else if (flags & EVENT_FD_READ) {
2252 smbd_server_connection_read_handler(conn, smbd_server_fd());
2256 static void smbd_server_echo_handler(struct event_context *ev,
2257 struct fd_event *fde,
2261 struct smbd_server_connection *conn = talloc_get_type(private_data,
2262 struct smbd_server_connection);
2264 if (flags & EVENT_FD_WRITE) {
2265 smbd_server_connection_write_handler(conn);
2266 } else if (flags & EVENT_FD_READ) {
2267 smbd_server_connection_read_handler(
2268 conn, conn->smb1.echo_handler.trusted_fd);
2272 /****************************************************************************
2273 received when we should release a specific IP
2274 ****************************************************************************/
2275 static void release_ip(const char *ip, void *priv)
2277 char addr[INET6_ADDRSTRLEN];
2280 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2282 if (strncmp("::ffff:", addr, 7) == 0) {
2286 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2287 /* we can't afford to do a clean exit - that involves
2288 database writes, which would potentially mean we
2289 are still running after the failover has finished -
2290 we have to get rid of this process ID straight
2292 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2294 /* note we must exit with non-zero status so the unclean handler gets
2295 called in the parent, so that the brl database is tickled */
2300 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2301 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2303 release_ip((char *)data->data, NULL);
2306 #ifdef CLUSTER_SUPPORT
2307 static int client_get_tcp_info(struct sockaddr_storage *server,
2308 struct sockaddr_storage *client)
2311 if (server_fd == -1) {
2314 length = sizeof(*server);
2315 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2318 length = sizeof(*client);
2319 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2327 * Send keepalive packets to our client
2329 static bool keepalive_fn(const struct timeval *now, void *private_data)
2333 smbd_lock_socket(smbd_server_conn);
2334 ret = send_keepalive(smbd_server_fd());
2335 smbd_unlock_socket(smbd_server_conn);
2338 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2345 * Do the recurring check if we're idle
2347 static bool deadtime_fn(const struct timeval *now, void *private_data)
2349 struct smbd_server_connection *sconn = smbd_server_conn;
2351 if (sconn->allow_smb2) {
2352 /* TODO: implement real idle check */
2353 if (sconn->smb2.sessions.list) {
2356 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2357 messaging_send(smbd_messaging_context(), procid_self(),
2358 MSG_SHUTDOWN, &data_blob_null);
2362 if ((conn_num_open(sconn) == 0)
2363 || (conn_idle_all(sconn, now->tv_sec))) {
2364 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2365 messaging_send(smbd_messaging_context(), procid_self(),
2366 MSG_SHUTDOWN, &data_blob_null);
2374 * Do the recurring log file and smb.conf reload checks.
2377 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2379 change_to_root_user();
2381 /* update printer queue caches if necessary */
2382 update_monitored_printq_cache();
2384 /* check if we need to reload services */
2385 check_reload(time(NULL));
2387 /* Change machine password if neccessary. */
2388 attempt_machine_password_change();
2391 * Force a log file check.
2393 force_check_log_size();
2398 static int create_unlink_tmp(const char *dir)
2403 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2404 if (fname == NULL) {
2408 fd = mkstemp(fname);
2413 if (unlink(fname) == -1) {
2414 int sys_errno = errno;
2424 struct smbd_echo_state {
2425 struct tevent_context *ev;
2426 struct iovec *pending;
2427 struct smbd_server_connection *sconn;
2430 struct tevent_fd *parent_fde;
2432 struct tevent_fd *read_fde;
2433 struct tevent_req *write_req;
2436 static void smbd_echo_writer_done(struct tevent_req *req);
2438 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2442 if (state->write_req != NULL) {
2446 num_pending = talloc_array_length(state->pending);
2447 if (num_pending == 0) {
2451 state->write_req = writev_send(state, state->ev, NULL,
2452 state->parent_pipe, false,
2453 state->pending, num_pending);
2454 if (state->write_req == NULL) {
2455 DEBUG(1, ("writev_send failed\n"));
2459 talloc_steal(state->write_req, state->pending);
2460 state->pending = NULL;
2462 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2466 static void smbd_echo_writer_done(struct tevent_req *req)
2468 struct smbd_echo_state *state = tevent_req_callback_data(
2469 req, struct smbd_echo_state);
2473 written = writev_recv(req, &err);
2475 state->write_req = NULL;
2476 if (written == -1) {
2477 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2480 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2481 smbd_echo_activate_writer(state);
2484 static bool smbd_echo_reply(int fd,
2485 uint8_t *inbuf, size_t inbuf_len,
2488 struct smb_request req;
2489 uint16_t num_replies;
2494 if (inbuf_len < smb_size) {
2495 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2498 if (!valid_smb_header(inbuf)) {
2499 DEBUG(10, ("Got invalid SMB header\n"));
2503 if (!init_smb_request(&req, inbuf, 0, false, seqnum)) {
2508 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2509 smb_messages[req.cmd].name
2510 ? smb_messages[req.cmd].name : "unknown"));
2512 if (req.cmd != SMBecho) {
2519 num_replies = SVAL(req.vwv+0, 0);
2520 if (num_replies != 1) {
2521 /* Not a Windows "Hey, you're still there?" request */
2525 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2527 DEBUG(10, ("create_outbuf failed\n"));
2530 req.outbuf = (uint8_t *)outbuf;
2532 SSVAL(req.outbuf, smb_vwv0, num_replies);
2534 if (req.buflen > 0) {
2535 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2538 out_len = smb_len(req.outbuf) + 4;
2540 ok = srv_send_smb(smbd_server_fd(),
2544 TALLOC_FREE(outbuf);
2552 static void smbd_echo_exit(struct tevent_context *ev,
2553 struct tevent_fd *fde, uint16_t flags,
2556 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2560 static void smbd_echo_reader(struct tevent_context *ev,
2561 struct tevent_fd *fde, uint16_t flags,
2564 struct smbd_echo_state *state = talloc_get_type_abort(
2565 private_data, struct smbd_echo_state);
2566 struct smbd_server_connection *sconn = state->sconn;
2567 size_t unread, num_pending;
2570 uint32_t seqnum = 0;
2573 bool encrypted = false;
2575 ok = smbd_lock_socket_internal(sconn);
2577 DEBUG(0, ("%s: failed to lock socket\n",
2582 if (!fd_is_readable(smbd_server_fd())) {
2583 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2584 (int)sys_getpid()));
2585 ok = smbd_unlock_socket_internal(sconn);
2587 DEBUG(1, ("%s: failed to unlock socket in\n",
2594 num_pending = talloc_array_length(state->pending);
2595 tmp = talloc_realloc(state, state->pending, struct iovec,
2598 DEBUG(1, ("talloc_realloc failed\n"));
2601 state->pending = tmp;
2603 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2605 status = receive_smb_talloc(state, smbd_server_fd(),
2606 (char **)(void *)&state->pending[num_pending].iov_base,
2610 &state->pending[num_pending].iov_len,
2612 false /* trusted_channel*/);
2613 if (!NT_STATUS_IS_OK(status)) {
2614 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2615 (int)sys_getpid(), nt_errstr(status)));
2619 ok = smbd_unlock_socket_internal(sconn);
2621 DEBUG(1, ("%s: failed to unlock socket in\n",
2627 * place the seqnum in the packet so that the main process can reply
2630 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2631 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2633 reply = smbd_echo_reply(smbd_server_fd(),
2634 (uint8_t *)state->pending[num_pending].iov_base,
2635 state->pending[num_pending].iov_len,
2638 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2639 /* no check, shrinking by some bytes does not fail */
2640 state->pending = talloc_realloc(state, state->pending,
2644 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2645 smbd_echo_activate_writer(state);
2649 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2652 struct smbd_echo_state *state;
2654 state = talloc_zero(sconn, struct smbd_echo_state);
2655 if (state == NULL) {
2656 DEBUG(1, ("talloc failed\n"));
2659 state->sconn = sconn;
2660 state->parent_pipe = parent_pipe;
2661 state->ev = s3_tevent_context_init(state);
2662 if (state->ev == NULL) {
2663 DEBUG(1, ("tevent_context_init failed\n"));
2667 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2668 TEVENT_FD_READ, smbd_echo_exit,
2670 if (state->parent_fde == NULL) {
2671 DEBUG(1, ("tevent_add_fd failed\n"));
2675 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2676 TEVENT_FD_READ, smbd_echo_reader,
2678 if (state->read_fde == NULL) {
2679 DEBUG(1, ("tevent_add_fd failed\n"));
2685 if (tevent_loop_once(state->ev) == -1) {
2686 DEBUG(1, ("tevent_loop_once failed: %s\n",
2695 * Handle SMBecho requests in a forked child process
2697 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2699 int listener_pipe[2];
2703 res = pipe(listener_pipe);
2705 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2708 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2709 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2710 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2718 close(listener_pipe[0]);
2720 status = reinit_after_fork(smbd_messaging_context(),
2721 smbd_event_context(), false);
2722 if (!NT_STATUS_IS_OK(status)) {
2723 DEBUG(1, ("reinit_after_fork failed: %s\n",
2724 nt_errstr(status)));
2727 smbd_echo_loop(sconn, listener_pipe[1]);
2730 close(listener_pipe[1]);
2731 listener_pipe[1] = -1;
2732 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2734 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2737 * Without smb signing this is the same as the normal smbd
2738 * listener. This needs to change once signing comes in.
2740 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2742 sconn->smb1.echo_handler.trusted_fd,
2744 smbd_server_echo_handler,
2746 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2747 DEBUG(1, ("event_add_fd failed\n"));
2754 if (listener_pipe[0] != -1) {
2755 close(listener_pipe[0]);
2757 if (listener_pipe[1] != -1) {
2758 close(listener_pipe[1]);
2760 sconn->smb1.echo_handler.trusted_fd = -1;
2761 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2762 close(sconn->smb1.echo_handler.socket_lock_fd);
2764 sconn->smb1.echo_handler.trusted_fd = -1;
2765 sconn->smb1.echo_handler.socket_lock_fd = -1;
2769 /****************************************************************************
2770 Process commands from the client
2771 ****************************************************************************/
2773 void smbd_process(void)
2775 TALLOC_CTX *frame = talloc_stackframe();
2776 char remaddr[INET6_ADDRSTRLEN];
2778 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2779 lp_security() != SEC_SHARE &&
2780 !lp_async_smb_echo_handler()) {
2781 smbd_server_conn->allow_smb2 = true;
2784 /* Ensure child is set to blocking mode */
2785 set_blocking(smbd_server_fd(),True);
2787 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2788 set_socket_options(smbd_server_fd(), lp_socket_options());
2790 /* this is needed so that we get decent entries
2791 in smbstatus for port 445 connects */
2792 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2796 reload_services(true);
2799 * Before the first packet, check the global hosts allow/ hosts deny
2800 * parameters before doing any parsing of packets passed to us by the
2801 * client. This prevents attacks on our parsing code from hosts not in
2802 * the hosts allow list.
2805 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2806 lp_hostsdeny(-1))) {
2807 char addr[INET6_ADDRSTRLEN];
2810 * send a negative session response "not listening on calling
2813 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2814 DEBUG( 1, ("Connection denied from %s\n",
2815 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2816 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2818 exit_server_cleanly("connection denied");
2825 smb_perfcount_init();
2827 if (!init_account_policy()) {
2828 exit_server("Could not open account policy tdb.\n");
2831 if (*lp_rootdir()) {
2832 if (chroot(lp_rootdir()) != 0) {
2833 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2834 exit_server("Failed to chroot()");
2836 if (chdir("/") == -1) {
2837 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2838 exit_server("Failed to chroot()");
2840 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2843 if (!srv_init_signing(smbd_server_conn)) {
2844 exit_server("Failed to init smb_signing");
2847 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2848 exit_server("Failed to fork echo handler");
2852 if (!init_oplocks(smbd_messaging_context()))
2853 exit_server("Failed to init oplocks");
2855 /* Setup aio signal handler. */
2856 initialize_async_io_handler();
2858 /* register our message handlers */
2859 messaging_register(smbd_messaging_context(), NULL,
2860 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2861 messaging_register(smbd_messaging_context(), NULL,
2862 MSG_SMB_RELEASE_IP, msg_release_ip);
2863 messaging_register(smbd_messaging_context(), NULL,
2864 MSG_SMB_CLOSE_FILE, msg_close_file);
2867 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2868 * MSGs to all child processes
2870 messaging_deregister(smbd_messaging_context(),
2872 messaging_register(smbd_messaging_context(), NULL,
2873 MSG_DEBUG, debug_message);
2875 if ((lp_keepalive() != 0)
2876 && !(event_add_idle(smbd_event_context(), NULL,
2877 timeval_set(lp_keepalive(), 0),
2878 "keepalive", keepalive_fn,
2880 DEBUG(0, ("Could not add keepalive event\n"));
2884 if (!(event_add_idle(smbd_event_context(), NULL,
2885 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2886 "deadtime", deadtime_fn, NULL))) {
2887 DEBUG(0, ("Could not add deadtime event\n"));
2891 if (!(event_add_idle(smbd_event_context(), NULL,
2892 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2893 "housekeeping", housekeeping_fn, NULL))) {
2894 DEBUG(0, ("Could not add housekeeping event\n"));
2898 #ifdef CLUSTER_SUPPORT
2900 if (lp_clustering()) {
2902 * We need to tell ctdb about our client's TCP
2903 * connection, so that for failover ctdbd can send
2904 * tickle acks, triggering a reconnection by the
2908 struct sockaddr_storage srv, clnt;
2910 if (client_get_tcp_info(&srv, &clnt) == 0) {
2914 status = ctdbd_register_ips(
2915 messaging_ctdbd_connection(),
2916 &srv, &clnt, release_ip, NULL);
2918 if (!NT_STATUS_IS_OK(status)) {
2919 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2920 nt_errstr(status)));
2924 DEBUG(0,("Unable to get tcp info for "
2925 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2932 smbd_server_conn->nbt.got_session = false;
2934 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2936 smbd_server_conn->smb1.sessions.done_sesssetup = false;
2937 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
2938 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
2939 /* users from session setup */
2940 smbd_server_conn->smb1.sessions.session_userlist = NULL;
2941 /* workgroup from session setup. */
2942 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
2943 /* this holds info on user ids that are already validated for this VC */
2944 smbd_server_conn->smb1.sessions.validated_users = NULL;
2945 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
2946 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
2947 #ifdef HAVE_NETGROUP
2948 smbd_server_conn->smb1.sessions.my_yp_domain = NULL;
2951 conn_init(smbd_server_conn);
2952 if (!init_dptrs(smbd_server_conn)) {
2953 exit_server("init_dptrs() failed");
2956 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
2960 smbd_server_connection_handler,
2962 if (!smbd_server_conn->smb1.fde) {
2963 exit_server("failed to create smbd_server_connection fde");
2971 frame = talloc_stackframe_pool(8192);
2975 status = smbd_server_connection_loop_once(smbd_server_conn);
2976 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2977 !NT_STATUS_IS_OK(status)) {
2978 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2979 " exiting\n", nt_errstr(status)));
2986 exit_server_cleanly(NULL);
2989 bool req_is_in_chain(struct smb_request *req)
2991 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2993 * We're right now handling a subsequent request, so we must
2999 if (!is_andx_req(req->cmd)) {
3005 * Okay, an illegal request, but definitely not chained :-)
3010 return (CVAL(req->vwv+0, 0) != 0xFF);