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/>.
23 extern struct auth_context *negprot_global_auth_context;
24 extern int smb_echo_count;
26 const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
27 static enum smb_read_errors smb_read_error = SMB_READ_OK;
30 * Size of data we can send to client. Set
31 * by the client for all protocols above CORE.
32 * Set by us for CORE protocol.
34 int max_send = BUFFER_SIZE;
36 * Size of the data we can receive. Set by us.
37 * Can be modified by the max xmit parameter.
39 int max_recv = BUFFER_SIZE;
41 SIG_ATOMIC_T reload_after_sighup = 0;
42 SIG_ATOMIC_T got_sig_term = 0;
43 extern bool global_machine_password_needs_changing;
46 /* Accessor function for smb_read_error for smbd functions. */
48 enum smb_read_errors *get_srv_read_error(void)
50 return &smb_read_error;
53 /* Socket functions for smbd packet processing. */
55 static bool valid_packet_size(size_t len)
58 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
59 * of header. Don't print the error if this fits.... JRA.
62 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
63 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
65 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
68 * Correct fix. smb_read_error may have already been
69 * set. Only set it here if not already set. Global
70 * variables still suck :-). JRA.
73 cond_set_smb_read_error(get_srv_read_error(),
81 static ssize_t read_packet_remainder(int fd,
93 ret = read_socket_with_timeout(fd,
98 get_srv_read_error());
100 ret = read_data(fd, buffer, len, get_srv_read_error());
104 cond_set_smb_read_error(get_srv_read_error(),
112 /****************************************************************************
113 Attempt a zerocopy writeX read. We know here that len > smb_size-4
114 ****************************************************************************/
117 * Unfortunately, earlier versions of smbclient/libsmbclient
118 * don't send this "standard" writeX header. I've fixed this
119 * for 3.2 but we'll use the old method with earlier versions.
120 * Windows and CIFSFS at least use this standard size. Not
124 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
125 (2*14) + /* word count (including bcc) */ \
128 ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
129 const char lenbuf[4],
132 unsigned int timeout,
135 /* Size of a WRITEX call (+4 byte len). */
136 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
137 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
141 memcpy(writeX_header, lenbuf, sizeof(lenbuf));
144 ret = read_socket_with_timeout(fd,
146 STANDARD_WRITE_AND_X_HEADER_SIZE,
147 STANDARD_WRITE_AND_X_HEADER_SIZE,
149 get_srv_read_error());
153 STANDARD_WRITE_AND_X_HEADER_SIZE,
154 get_srv_read_error());
157 if (ret != STANDARD_WRITE_AND_X_HEADER_SIZE) {
158 cond_set_smb_read_error(get_srv_read_error(),
164 * Ok - now try and see if this is a possible
168 if (is_valid_writeX_buffer(writeX_header)) {
170 * If the data offset is beyond what
171 * we've read, drain the extra bytes.
173 uint16_t doff = SVAL(writeX_header,smb_vwv11);
176 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
177 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
178 if (drain_socket(smbd_server_fd(), drain) != drain) {
179 smb_panic("receive_smb_raw_talloc_partial_read:"
180 " failed to drain pending bytes");
183 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
186 /* Spoof down the length and null out the bcc. */
187 set_message_bcc(writeX_header, 0);
188 newlen = smb_len(writeX_header);
190 /* Copy the header we've written. */
192 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
194 sizeof(writeX_header));
196 if (*buffer == NULL) {
197 DEBUG(0, ("Could not allocate inbuf of length %d\n",
198 (int)sizeof(writeX_header)));
199 cond_set_smb_read_error(get_srv_read_error(),
204 /* Work out the remaining bytes. */
205 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
210 if (!valid_packet_size(len)) {
215 * Not a valid writeX call. Just do the standard
219 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
221 if (*buffer == NULL) {
222 DEBUG(0, ("Could not allocate inbuf of length %d\n",
224 cond_set_smb_read_error(get_srv_read_error(),
229 /* Copy in what we already read. */
232 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
233 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
236 ret = read_packet_remainder(fd,
237 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
248 static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
251 unsigned int timeout,
256 int min_recv_size = lp_min_receive_file_size();
258 set_smb_read_error(get_srv_read_error(),SMB_READ_OK);
261 len = read_smb_length_return_keepalive(fd, lenbuf,
262 timeout, get_srv_read_error());
264 DEBUG(10,("receive_smb_raw: length < 0!\n"));
267 * Correct fix. smb_read_error may have already been
268 * set. Only set it here if not already set. Global
269 * variables still suck :-). JRA.
272 cond_set_smb_read_error(get_srv_read_error(),SMB_READ_ERROR);
276 if (CVAL(lenbuf,0) != SMBkeepalive &&
278 smb_len_large(lenbuf) > min_recv_size && /* Could be a UNIX large writeX. */
279 !srv_is_signing_active()) {
281 return receive_smb_raw_talloc_partial_read(mem_ctx,
289 if (!valid_packet_size(len)) {
294 * The +4 here can't wrap, we've checked the length above already.
297 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
299 if (*buffer == NULL) {
300 DEBUG(0, ("Could not allocate inbuf of length %d\n",
302 cond_set_smb_read_error(get_srv_read_error(),SMB_READ_ERROR);
306 memcpy(*buffer, lenbuf, sizeof(lenbuf));
308 ret = read_packet_remainder(fd, (*buffer)+4, timeout, len);
316 ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
317 unsigned int timeout, size_t *p_unread)
321 len = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout, p_unread);
327 /* Check the incoming SMB signature. */
328 if (!srv_check_sign_mac(*buffer, true)) {
329 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
330 "incoming packet!\n"));
331 cond_set_smb_read_error(get_srv_read_error(),SMB_READ_BAD_SIG);
339 * Initialize a struct smb_request from an inbuf
342 void init_smb_request(struct smb_request *req,
346 size_t req_size = smb_len(inbuf) + 4;
347 /* Ensure we have at least smb_size bytes. */
348 if (req_size < smb_size) {
349 DEBUG(0,("init_smb_request: invalid request size %u\n",
350 (unsigned int)req_size ));
351 exit_server_cleanly("Invalid SMB request");
353 req->flags2 = SVAL(inbuf, smb_flg2);
354 req->smbpid = SVAL(inbuf, smb_pid);
355 req->mid = SVAL(inbuf, smb_mid);
356 req->vuid = SVAL(inbuf, smb_uid);
357 req->tid = SVAL(inbuf, smb_tid);
358 req->wct = CVAL(inbuf, smb_wct);
359 req->unread_bytes = unread_bytes;
361 /* Ensure we have at least wct words and 2 bytes of bcc. */
362 if (smb_size + req->wct*2 > req_size) {
363 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
364 (unsigned int)req->wct,
365 (unsigned int)req_size));
366 exit_server_cleanly("Invalid SMB request");
368 /* Ensure bcc is correct. */
369 if (((uint8 *)smb_buf(inbuf)) + smb_buflen(inbuf) > inbuf + req_size) {
370 DEBUG(0,("init_smb_request: invalid bcc number %u "
371 "(wct = %u, size %u)\n",
372 (unsigned int)smb_buflen(inbuf),
373 (unsigned int)req->wct,
374 (unsigned int)req_size));
375 exit_server_cleanly("Invalid SMB request");
381 /****************************************************************************
382 structure to hold a linked list of queued messages.
384 ****************************************************************************/
386 static struct pending_message_list *deferred_open_queue;
388 /****************************************************************************
389 Function to push a message onto the tail of a linked list of smb messages ready
391 ****************************************************************************/
393 static bool push_queued_message(struct smb_request *req,
394 struct timeval request_time,
395 struct timeval end_time,
396 char *private_data, size_t private_len)
398 int msg_len = smb_len(req->inbuf) + 4;
399 struct pending_message_list *msg;
401 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
404 DEBUG(0,("push_message: malloc fail (1)\n"));
408 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
409 if(msg->buf.data == NULL) {
410 DEBUG(0,("push_message: malloc fail (2)\n"));
415 msg->request_time = request_time;
416 msg->end_time = end_time;
419 msg->private_data = data_blob_talloc(msg, private_data,
421 if (msg->private_data.data == NULL) {
422 DEBUG(0,("push_message: malloc fail (3)\n"));
428 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
430 DEBUG(10,("push_message: pushed message length %u on "
431 "deferred_open_queue\n", (unsigned int)msg_len));
436 /****************************************************************************
437 Function to delete a sharing violation open message by mid.
438 ****************************************************************************/
440 void remove_deferred_open_smb_message(uint16 mid)
442 struct pending_message_list *pml;
444 for (pml = deferred_open_queue; pml; pml = pml->next) {
445 if (mid == SVAL(pml->buf.data,smb_mid)) {
446 DEBUG(10,("remove_sharing_violation_open_smb_message: "
447 "deleting mid %u len %u\n",
449 (unsigned int)pml->buf.length ));
450 DLIST_REMOVE(deferred_open_queue, pml);
457 /****************************************************************************
458 Move a sharing violation open retry message to the front of the list and
459 schedule it for immediate processing.
460 ****************************************************************************/
462 void schedule_deferred_open_smb_message(uint16 mid)
464 struct pending_message_list *pml;
467 for (pml = deferred_open_queue; pml; pml = pml->next) {
468 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
469 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
470 (unsigned int)msg_mid ));
471 if (mid == msg_mid) {
472 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
474 pml->end_time.tv_sec = 0;
475 pml->end_time.tv_usec = 0;
476 DLIST_PROMOTE(deferred_open_queue, pml);
481 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
485 /****************************************************************************
486 Return true if this mid is on the deferred queue.
487 ****************************************************************************/
489 bool open_was_deferred(uint16 mid)
491 struct pending_message_list *pml;
493 for (pml = deferred_open_queue; pml; pml = pml->next) {
494 if (SVAL(pml->buf.data,smb_mid) == mid) {
501 /****************************************************************************
502 Return the message queued by this mid.
503 ****************************************************************************/
505 struct pending_message_list *get_open_deferred_message(uint16 mid)
507 struct pending_message_list *pml;
509 for (pml = deferred_open_queue; pml; pml = pml->next) {
510 if (SVAL(pml->buf.data,smb_mid) == mid) {
517 /****************************************************************************
518 Function to push a deferred open smb message onto a linked list of local smb
519 messages ready for processing.
520 ****************************************************************************/
522 bool push_deferred_smb_message(struct smb_request *req,
523 struct timeval request_time,
524 struct timeval timeout,
525 char *private_data, size_t priv_len)
527 struct timeval end_time;
529 if (req->unread_bytes) {
530 DEBUG(0,("push_deferred_smb_message: logic error ! "
531 "unread_bytes = %u\n",
532 (unsigned int)req->unread_bytes ));
533 smb_panic("push_deferred_smb_message: "
534 "logic error unread_bytes != 0" );
537 end_time = timeval_sum(&request_time, &timeout);
539 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
540 "timeout time [%u.%06u]\n",
541 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
542 (unsigned int)end_time.tv_sec,
543 (unsigned int)end_time.tv_usec));
545 return push_queued_message(req, request_time, end_time,
546 private_data, priv_len);
550 struct timed_event *te;
551 struct timeval interval;
553 bool (*handler)(const struct timeval *now, void *private_data);
557 static void idle_event_handler(struct event_context *ctx,
558 struct timed_event *te,
559 const struct timeval *now,
562 struct idle_event *event =
563 talloc_get_type_abort(private_data, struct idle_event);
565 TALLOC_FREE(event->te);
567 if (!event->handler(now, event->private_data)) {
568 /* Don't repeat, delete ourselves */
573 event->te = event_add_timed(ctx, event,
574 timeval_sum(now, &event->interval),
576 idle_event_handler, event);
578 /* We can't do much but fail here. */
579 SMB_ASSERT(event->te != NULL);
582 struct idle_event *event_add_idle(struct event_context *event_ctx,
584 struct timeval interval,
586 bool (*handler)(const struct timeval *now,
590 struct idle_event *result;
591 struct timeval now = timeval_current();
593 result = TALLOC_P(mem_ctx, struct idle_event);
594 if (result == NULL) {
595 DEBUG(0, ("talloc failed\n"));
599 result->interval = interval;
600 result->handler = handler;
601 result->private_data = private_data;
603 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
604 DEBUG(0, ("talloc failed\n"));
609 result->te = event_add_timed(event_ctx, result,
610 timeval_sum(&now, &interval),
612 idle_event_handler, result);
613 if (result->te == NULL) {
614 DEBUG(0, ("event_add_timed failed\n"));
622 /****************************************************************************
623 Do all async processing in here. This includes kernel oplock messages, change
625 ****************************************************************************/
627 static void async_processing(fd_set *pfds)
629 DEBUG(10,("async_processing: Doing async processing.\n"));
633 process_kernel_oplocks(smbd_messaging_context(), pfds);
635 /* Do the aio check again after receive_local_message as it does a
636 select and may have eaten our signal. */
637 /* Is this till true? -- vl */
641 exit_server_cleanly("termination signal");
644 /* check for sighup processing */
645 if (reload_after_sighup) {
646 change_to_root_user();
647 DEBUG(1,("Reloading services after SIGHUP\n"));
648 reload_services(False);
649 reload_after_sighup = 0;
653 /****************************************************************************
654 Add a fd to the set we will be select(2)ing on.
655 ****************************************************************************/
657 static int select_on_fd(int fd, int maxfd, fd_set *fds)
661 maxfd = MAX(maxfd, fd);
667 /****************************************************************************
668 Do a select on an two fd's - with timeout.
670 If a local udp message has been pushed onto the
671 queue (this can only happen during oplock break
672 processing) call async_processing()
674 If a pending smb message has been pushed onto the
675 queue (this can only happen during oplock break
676 processing) return this next.
678 If the first smbfd is ready then read an smb from it.
679 if the second (loopback UDP) fd is ready then read a message
680 from it and setup the buffer header to identify the length
682 Returns False on timeout or error.
685 The timeout is in milliseconds
686 ****************************************************************************/
688 static bool receive_message_or_smb(TALLOC_CTX *mem_ctx,
701 set_smb_read_error(get_srv_read_error(),SMB_READ_OK);
706 to.tv_sec = timeout / 1000;
707 to.tv_usec = (timeout % 1000) * 1000;
709 to.tv_sec = SMBD_SELECT_TIMEOUT;
714 * Note that this call must be before processing any SMB
715 * messages as we need to synchronously process any messages
716 * we may have sent to ourselves from the previous SMB.
718 message_dispatch(smbd_messaging_context());
721 * Check to see if we already have a message on the deferred open queue
722 * and it's time to schedule.
724 if(deferred_open_queue != NULL) {
725 bool pop_message = False;
726 struct pending_message_list *msg = deferred_open_queue;
728 if (timeval_is_zero(&msg->end_time)) {
735 tdif = usec_time_diff(&msg->end_time, &tv);
737 /* Timed out. Schedule...*/
739 DEBUG(10,("receive_message_or_smb: queued message timed out.\n"));
741 /* Make a more accurate select timeout. */
742 to.tv_sec = tdif / 1000000;
743 to.tv_usec = tdif % 1000000;
744 DEBUG(10,("receive_message_or_smb: select with timeout of [%u.%06u]\n",
745 (unsigned int)to.tv_sec, (unsigned int)to.tv_usec ));
751 *buffer = (char *)talloc_memdup(mem_ctx, msg->buf.data,
753 if (*buffer == NULL) {
754 DEBUG(0, ("talloc failed\n"));
755 set_smb_read_error(get_srv_read_error(),SMB_READ_ERROR);
758 *buffer_len = msg->buf.length;
760 /* We leave this message on the queue so the open code can
761 know this is a retry. */
762 DEBUG(5,("receive_message_or_smb: returning deferred open smb message.\n"));
768 * Setup the select fd sets.
775 * Ensure we process oplock break messages by preference.
776 * We have to do this before the select, after the select
777 * and if the select returns EINTR. This is due to the fact
778 * that the selects called from async_processing can eat an EINTR
779 * caused by a signal (we can't take the break message there).
780 * This is hideously complex - *MUST* be simplified for 3.0 ! JRA.
783 if (oplock_message_waiting(&r_fds)) {
784 DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
785 async_processing(&r_fds);
787 * After async processing we must go and do the select again, as
788 * the state of the flag in fds for the server file descriptor is
789 * indeterminate - we may have done I/O on it in the oplock processing. JRA.
795 * Are there any timed events waiting ? If so, ensure we don't
796 * select for longer than it would take to wait for them.
803 event_add_to_select_args(smbd_event_context(), &now,
804 &r_fds, &w_fds, &to, &maxfd);
807 if (timeval_is_zero(&to)) {
808 /* Process a timed event now... */
809 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
816 START_PROFILE(smbd_idle);
818 maxfd = select_on_fd(smbd_server_fd(), maxfd, &r_fds);
819 maxfd = select_on_fd(oplock_notify_fd(), maxfd, &r_fds);
821 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
824 END_PROFILE(smbd_idle);
828 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
832 /* if we get EINTR then maybe we have received an oplock
833 signal - treat this as select returning 1. This is ugly, but
834 is the best we can do until the oplock code knows more about
836 if (selrtn == -1 && errno == EINTR) {
837 async_processing(&r_fds);
839 * After async processing we must go and do the select again, as
840 * the state of the flag in fds for the server file descriptor is
841 * indeterminate - we may have done I/O on it in the oplock processing. JRA.
848 /* something is wrong. Maybe the socket is dead? */
849 set_smb_read_error(get_srv_read_error(),SMB_READ_ERROR);
853 /* Did we timeout ? */
855 set_smb_read_error(get_srv_read_error(),SMB_READ_TIMEOUT);
860 * Ensure we process oplock break messages by preference.
861 * This is IMPORTANT ! Otherwise we can starve other processes
862 * sending us an oplock break message. JRA.
865 if (oplock_message_waiting(&r_fds)) {
866 async_processing(&r_fds);
868 * After async processing we must go and do the select again, as
869 * the state of the flag in fds for the server file descriptor is
870 * indeterminate - we may have done I/O on it in the oplock processing. JRA.
875 len = receive_smb_talloc(mem_ctx, smbd_server_fd(), buffer, 0, p_unread);
881 *buffer_len = (size_t)len;
887 * Only allow 5 outstanding trans requests. We're allocating memory, so
891 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
894 for (; list != NULL; list = list->next) {
896 if (list->mid == mid) {
897 return NT_STATUS_INVALID_PARAMETER;
903 return NT_STATUS_INSUFFICIENT_RESOURCES;
909 /****************************************************************************
910 We're terminating and have closed all our files/connections etc.
911 If there are any pending local messages we need to respond to them
912 before termination so that other smbds don't think we just died whilst
914 ****************************************************************************/
916 void respond_to_all_remaining_local_messages(void)
919 * Assert we have no exclusive open oplocks.
922 if(get_number_of_exclusive_open_oplocks()) {
923 DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
924 get_number_of_exclusive_open_oplocks() ));
928 process_kernel_oplocks(smbd_messaging_context(), NULL);
935 These flags determine some of the permissions required to do an operation
937 Note that I don't set NEED_WRITE on some write operations because they
938 are used by some brain-dead clients when printing, and I don't want to
939 force write permissions on print services.
941 #define AS_USER (1<<0)
942 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
943 #define TIME_INIT (1<<2)
944 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
945 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
946 #define DO_CHDIR (1<<6)
949 define a list of possible SMB messages and their corresponding
950 functions. Any message that has a NULL function is unimplemented -
951 please feel free to contribute implementations!
953 static const struct smb_message_struct {
955 void (*fn_new)(connection_struct *conn, struct smb_request *req);
957 } smb_messages[256] = {
959 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
960 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
961 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
962 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
963 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
964 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
965 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
966 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
967 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
968 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
969 /* 0x0a */ { "SMBread",reply_read,AS_USER},
970 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
971 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
972 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
973 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
974 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
975 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
976 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
977 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
978 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
979 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
980 /* 0x15 */ { NULL, NULL, 0 },
981 /* 0x16 */ { NULL, NULL, 0 },
982 /* 0x17 */ { NULL, NULL, 0 },
983 /* 0x18 */ { NULL, NULL, 0 },
984 /* 0x19 */ { NULL, NULL, 0 },
985 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
986 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
987 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
988 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
989 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
990 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
991 /* 0x20 */ { "SMBwritec", NULL,0},
992 /* 0x21 */ { NULL, NULL, 0 },
993 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
994 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
995 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
996 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
997 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
998 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
999 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1000 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1001 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1002 /* 0x2b */ { "SMBecho",reply_echo,0},
1003 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1004 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1005 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1006 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1007 /* 0x30 */ { NULL, NULL, 0 },
1008 /* 0x31 */ { NULL, NULL, 0 },
1009 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1010 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER},
1011 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1012 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1013 /* 0x36 */ { NULL, NULL, 0 },
1014 /* 0x37 */ { NULL, NULL, 0 },
1015 /* 0x38 */ { NULL, NULL, 0 },
1016 /* 0x39 */ { NULL, NULL, 0 },
1017 /* 0x3a */ { NULL, NULL, 0 },
1018 /* 0x3b */ { NULL, NULL, 0 },
1019 /* 0x3c */ { NULL, NULL, 0 },
1020 /* 0x3d */ { NULL, NULL, 0 },
1021 /* 0x3e */ { NULL, NULL, 0 },
1022 /* 0x3f */ { NULL, NULL, 0 },
1023 /* 0x40 */ { NULL, NULL, 0 },
1024 /* 0x41 */ { NULL, NULL, 0 },
1025 /* 0x42 */ { NULL, NULL, 0 },
1026 /* 0x43 */ { NULL, NULL, 0 },
1027 /* 0x44 */ { NULL, NULL, 0 },
1028 /* 0x45 */ { NULL, NULL, 0 },
1029 /* 0x46 */ { NULL, NULL, 0 },
1030 /* 0x47 */ { NULL, NULL, 0 },
1031 /* 0x48 */ { NULL, NULL, 0 },
1032 /* 0x49 */ { NULL, NULL, 0 },
1033 /* 0x4a */ { NULL, NULL, 0 },
1034 /* 0x4b */ { NULL, NULL, 0 },
1035 /* 0x4c */ { NULL, NULL, 0 },
1036 /* 0x4d */ { NULL, NULL, 0 },
1037 /* 0x4e */ { NULL, NULL, 0 },
1038 /* 0x4f */ { NULL, NULL, 0 },
1039 /* 0x50 */ { NULL, NULL, 0 },
1040 /* 0x51 */ { NULL, NULL, 0 },
1041 /* 0x52 */ { NULL, NULL, 0 },
1042 /* 0x53 */ { NULL, NULL, 0 },
1043 /* 0x54 */ { NULL, NULL, 0 },
1044 /* 0x55 */ { NULL, NULL, 0 },
1045 /* 0x56 */ { NULL, NULL, 0 },
1046 /* 0x57 */ { NULL, NULL, 0 },
1047 /* 0x58 */ { NULL, NULL, 0 },
1048 /* 0x59 */ { NULL, NULL, 0 },
1049 /* 0x5a */ { NULL, NULL, 0 },
1050 /* 0x5b */ { NULL, NULL, 0 },
1051 /* 0x5c */ { NULL, NULL, 0 },
1052 /* 0x5d */ { NULL, NULL, 0 },
1053 /* 0x5e */ { NULL, NULL, 0 },
1054 /* 0x5f */ { NULL, NULL, 0 },
1055 /* 0x60 */ { NULL, NULL, 0 },
1056 /* 0x61 */ { NULL, NULL, 0 },
1057 /* 0x62 */ { NULL, NULL, 0 },
1058 /* 0x63 */ { NULL, NULL, 0 },
1059 /* 0x64 */ { NULL, NULL, 0 },
1060 /* 0x65 */ { NULL, NULL, 0 },
1061 /* 0x66 */ { NULL, NULL, 0 },
1062 /* 0x67 */ { NULL, NULL, 0 },
1063 /* 0x68 */ { NULL, NULL, 0 },
1064 /* 0x69 */ { NULL, NULL, 0 },
1065 /* 0x6a */ { NULL, NULL, 0 },
1066 /* 0x6b */ { NULL, NULL, 0 },
1067 /* 0x6c */ { NULL, NULL, 0 },
1068 /* 0x6d */ { NULL, NULL, 0 },
1069 /* 0x6e */ { NULL, NULL, 0 },
1070 /* 0x6f */ { NULL, NULL, 0 },
1071 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1072 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1073 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1074 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1075 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1076 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1077 /* 0x76 */ { NULL, NULL, 0 },
1078 /* 0x77 */ { NULL, NULL, 0 },
1079 /* 0x78 */ { NULL, NULL, 0 },
1080 /* 0x79 */ { NULL, NULL, 0 },
1081 /* 0x7a */ { NULL, NULL, 0 },
1082 /* 0x7b */ { NULL, NULL, 0 },
1083 /* 0x7c */ { NULL, NULL, 0 },
1084 /* 0x7d */ { NULL, NULL, 0 },
1085 /* 0x7e */ { NULL, NULL, 0 },
1086 /* 0x7f */ { NULL, NULL, 0 },
1087 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1088 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1089 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1090 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1091 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1092 /* 0x85 */ { NULL, NULL, 0 },
1093 /* 0x86 */ { NULL, NULL, 0 },
1094 /* 0x87 */ { NULL, NULL, 0 },
1095 /* 0x88 */ { NULL, NULL, 0 },
1096 /* 0x89 */ { NULL, NULL, 0 },
1097 /* 0x8a */ { NULL, NULL, 0 },
1098 /* 0x8b */ { NULL, NULL, 0 },
1099 /* 0x8c */ { NULL, NULL, 0 },
1100 /* 0x8d */ { NULL, NULL, 0 },
1101 /* 0x8e */ { NULL, NULL, 0 },
1102 /* 0x8f */ { NULL, NULL, 0 },
1103 /* 0x90 */ { NULL, NULL, 0 },
1104 /* 0x91 */ { NULL, NULL, 0 },
1105 /* 0x92 */ { NULL, NULL, 0 },
1106 /* 0x93 */ { NULL, NULL, 0 },
1107 /* 0x94 */ { NULL, NULL, 0 },
1108 /* 0x95 */ { NULL, NULL, 0 },
1109 /* 0x96 */ { NULL, NULL, 0 },
1110 /* 0x97 */ { NULL, NULL, 0 },
1111 /* 0x98 */ { NULL, NULL, 0 },
1112 /* 0x99 */ { NULL, NULL, 0 },
1113 /* 0x9a */ { NULL, NULL, 0 },
1114 /* 0x9b */ { NULL, NULL, 0 },
1115 /* 0x9c */ { NULL, NULL, 0 },
1116 /* 0x9d */ { NULL, NULL, 0 },
1117 /* 0x9e */ { NULL, NULL, 0 },
1118 /* 0x9f */ { NULL, NULL, 0 },
1119 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1120 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1121 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1122 /* 0xa3 */ { NULL, NULL, 0 },
1123 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1124 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1125 /* 0xa6 */ { NULL, NULL, 0 },
1126 /* 0xa7 */ { NULL, NULL, 0 },
1127 /* 0xa8 */ { NULL, NULL, 0 },
1128 /* 0xa9 */ { NULL, NULL, 0 },
1129 /* 0xaa */ { NULL, NULL, 0 },
1130 /* 0xab */ { NULL, NULL, 0 },
1131 /* 0xac */ { NULL, NULL, 0 },
1132 /* 0xad */ { NULL, NULL, 0 },
1133 /* 0xae */ { NULL, NULL, 0 },
1134 /* 0xaf */ { NULL, NULL, 0 },
1135 /* 0xb0 */ { NULL, NULL, 0 },
1136 /* 0xb1 */ { NULL, NULL, 0 },
1137 /* 0xb2 */ { NULL, NULL, 0 },
1138 /* 0xb3 */ { NULL, NULL, 0 },
1139 /* 0xb4 */ { NULL, NULL, 0 },
1140 /* 0xb5 */ { NULL, NULL, 0 },
1141 /* 0xb6 */ { NULL, NULL, 0 },
1142 /* 0xb7 */ { NULL, NULL, 0 },
1143 /* 0xb8 */ { NULL, NULL, 0 },
1144 /* 0xb9 */ { NULL, NULL, 0 },
1145 /* 0xba */ { NULL, NULL, 0 },
1146 /* 0xbb */ { NULL, NULL, 0 },
1147 /* 0xbc */ { NULL, NULL, 0 },
1148 /* 0xbd */ { NULL, NULL, 0 },
1149 /* 0xbe */ { NULL, NULL, 0 },
1150 /* 0xbf */ { NULL, NULL, 0 },
1151 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1152 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1153 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1154 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1155 /* 0xc4 */ { NULL, NULL, 0 },
1156 /* 0xc5 */ { NULL, NULL, 0 },
1157 /* 0xc6 */ { NULL, NULL, 0 },
1158 /* 0xc7 */ { NULL, NULL, 0 },
1159 /* 0xc8 */ { NULL, NULL, 0 },
1160 /* 0xc9 */ { NULL, NULL, 0 },
1161 /* 0xca */ { NULL, NULL, 0 },
1162 /* 0xcb */ { NULL, NULL, 0 },
1163 /* 0xcc */ { NULL, NULL, 0 },
1164 /* 0xcd */ { NULL, NULL, 0 },
1165 /* 0xce */ { NULL, NULL, 0 },
1166 /* 0xcf */ { NULL, NULL, 0 },
1167 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1168 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1169 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1170 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1171 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1172 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1173 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1174 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1175 /* 0xd8 */ { NULL, NULL, 0 },
1176 /* 0xd9 */ { NULL, NULL, 0 },
1177 /* 0xda */ { NULL, NULL, 0 },
1178 /* 0xdb */ { NULL, NULL, 0 },
1179 /* 0xdc */ { NULL, NULL, 0 },
1180 /* 0xdd */ { NULL, NULL, 0 },
1181 /* 0xde */ { NULL, NULL, 0 },
1182 /* 0xdf */ { NULL, NULL, 0 },
1183 /* 0xe0 */ { NULL, NULL, 0 },
1184 /* 0xe1 */ { NULL, NULL, 0 },
1185 /* 0xe2 */ { NULL, NULL, 0 },
1186 /* 0xe3 */ { NULL, NULL, 0 },
1187 /* 0xe4 */ { NULL, NULL, 0 },
1188 /* 0xe5 */ { NULL, NULL, 0 },
1189 /* 0xe6 */ { NULL, NULL, 0 },
1190 /* 0xe7 */ { NULL, NULL, 0 },
1191 /* 0xe8 */ { NULL, NULL, 0 },
1192 /* 0xe9 */ { NULL, NULL, 0 },
1193 /* 0xea */ { NULL, NULL, 0 },
1194 /* 0xeb */ { NULL, NULL, 0 },
1195 /* 0xec */ { NULL, NULL, 0 },
1196 /* 0xed */ { NULL, NULL, 0 },
1197 /* 0xee */ { NULL, NULL, 0 },
1198 /* 0xef */ { NULL, NULL, 0 },
1199 /* 0xf0 */ { NULL, NULL, 0 },
1200 /* 0xf1 */ { NULL, NULL, 0 },
1201 /* 0xf2 */ { NULL, NULL, 0 },
1202 /* 0xf3 */ { NULL, NULL, 0 },
1203 /* 0xf4 */ { NULL, NULL, 0 },
1204 /* 0xf5 */ { NULL, NULL, 0 },
1205 /* 0xf6 */ { NULL, NULL, 0 },
1206 /* 0xf7 */ { NULL, NULL, 0 },
1207 /* 0xf8 */ { NULL, NULL, 0 },
1208 /* 0xf9 */ { NULL, NULL, 0 },
1209 /* 0xfa */ { NULL, NULL, 0 },
1210 /* 0xfb */ { NULL, NULL, 0 },
1211 /* 0xfc */ { NULL, NULL, 0 },
1212 /* 0xfd */ { NULL, NULL, 0 },
1213 /* 0xfe */ { NULL, NULL, 0 },
1214 /* 0xff */ { NULL, NULL, 0 }
1218 /*******************************************************************
1219 allocate and initialize a reply packet
1220 ********************************************************************/
1222 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1225 * Protect against integer wrap
1227 if ((num_bytes > 0xffffff)
1228 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1230 asprintf(&msg, "num_bytes too large: %u",
1231 (unsigned)num_bytes);
1235 if (!(req->outbuf = TALLOC_ARRAY(
1237 smb_size + num_words*2 + num_bytes))) {
1238 smb_panic("could not allocate output buffer\n");
1241 construct_reply_common((char *)req->inbuf, (char *)req->outbuf);
1242 set_message((char *)req->outbuf, num_words, num_bytes, False);
1244 * Zero out the word area, the caller has to take care of the bcc area
1247 if (num_words != 0) {
1248 memset(req->outbuf + smb_vwv0, 0, num_words*2);
1255 /*******************************************************************
1256 Dump a packet to a file.
1257 ********************************************************************/
1259 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1263 if (DEBUGLEVEL < 50) {
1267 if (len < 4) len = smb_len(data)+4;
1268 for (i=1;i<100;i++) {
1269 asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1270 type ? "req" : "resp");
1274 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1275 if (fd != -1 || errno != EEXIST) break;
1278 ssize_t ret = write(fd, data, len);
1280 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1282 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1287 /****************************************************************************
1288 Prepare everything for calling the actual request function, and potentially
1289 call the request function via the "new" interface.
1291 Return False if the "legacy" function needs to be called, everything is
1294 Return True if we're done.
1296 I know this API sucks, but it is the one with the least code change I could
1298 ****************************************************************************/
1300 static void switch_message(uint8 type, struct smb_request *req, int size)
1304 connection_struct *conn;
1306 static uint16 last_session_tag = UID_FIELD_INVALID;
1310 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1311 * so subtract 4 from it. */
1312 if ((strncmp(smb_base(req->inbuf),"\377SMB",4) != 0)
1313 || (size < (smb_size - 4))) {
1314 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1315 smb_len(req->inbuf)));
1316 exit_server_cleanly("Non-SMB packet");
1319 if (smb_messages[type].fn_new == NULL) {
1320 DEBUG(0,("Unknown message type %d!\n",type));
1321 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1322 reply_unknown_new(req, type);
1326 flags = smb_messages[type].flags;
1328 /* In share mode security we must ignore the vuid. */
1329 session_tag = (lp_security() == SEC_SHARE)
1330 ? UID_FIELD_INVALID : req->vuid;
1331 conn = conn_find(req->tid);
1333 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1334 (int)sys_getpid(), (unsigned long)conn));
1336 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1338 /* Ensure this value is replaced in the incoming packet. */
1339 SSVAL(req->inbuf,smb_uid,session_tag);
1342 * Ensure the correct username is in current_user_info. This is a
1343 * really ugly bugfix for problems with multiple session_setup_and_X's
1344 * being done and allowing %U and %G substitutions to work correctly.
1345 * There is a reason this code is done here, don't move it unless you
1346 * know what you're doing... :-).
1350 if (session_tag != last_session_tag) {
1351 user_struct *vuser = NULL;
1353 last_session_tag = session_tag;
1354 if(session_tag != UID_FIELD_INVALID) {
1355 vuser = get_valid_user_struct(session_tag);
1357 set_current_user_info(&vuser->user);
1362 /* Does this call need to be run as the connected user? */
1363 if (flags & AS_USER) {
1365 /* Does this call need a valid tree connection? */
1368 * Amazingly, the error code depends on the command
1371 if (type == SMBntcreateX) {
1372 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1374 reply_doserror(req, ERRSRV, ERRinvnid);
1379 if (!change_to_user(conn,session_tag)) {
1380 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1384 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1386 /* Does it need write permission? */
1387 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1388 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1392 /* IPC services are limited */
1393 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1394 reply_doserror(req, ERRSRV,ERRaccess);
1398 /* This call needs to be run as root */
1399 change_to_root_user();
1402 /* load service specific parameters */
1404 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1405 (flags & (AS_USER|DO_CHDIR)
1407 reply_doserror(req, ERRSRV, ERRaccess);
1410 conn->num_smb_operations++;
1413 /* does this protocol need to be run as guest? */
1414 if ((flags & AS_GUEST)
1415 && (!change_to_guest() ||
1416 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1417 lp_hostsdeny(-1)))) {
1418 reply_doserror(req, ERRSRV, ERRaccess);
1422 smb_messages[type].fn_new(conn, req);
1425 /****************************************************************************
1426 Construct a reply to the incoming packet.
1427 ****************************************************************************/
1429 static void construct_reply(char *inbuf, int size, size_t unread_bytes)
1431 uint8 type = CVAL(inbuf,smb_com);
1432 struct smb_request *req;
1438 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1439 smb_panic("could not allocate smb_request");
1441 init_smb_request(req, (uint8 *)inbuf, unread_bytes);
1443 switch_message(type, req, size);
1445 if (req->unread_bytes) {
1446 /* writeX failed. drain socket. */
1447 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1448 req->unread_bytes) {
1449 smb_panic("failed to drain pending bytes");
1451 req->unread_bytes = 0;
1454 if (req->outbuf == NULL) {
1458 if (CVAL(req->outbuf,0) == 0) {
1459 show_msg((char *)req->outbuf);
1462 if (!send_smb(smbd_server_fd(), (char *)req->outbuf)) {
1463 exit_server_cleanly("construct_reply: send_smb failed.");
1471 /****************************************************************************
1472 Process an smb from the client
1473 ****************************************************************************/
1475 static void process_smb(char *inbuf, size_t nread, size_t unread_bytes)
1477 static int trans_num;
1478 int msg_type = CVAL(inbuf,0);
1480 DO_PROFILE_INC(smb_count);
1482 if (trans_num == 0) {
1483 char addr[INET6_ADDRSTRLEN];
1485 /* on the first packet, check the global hosts allow/ hosts
1486 deny parameters before doing any parsing of the packet
1487 passed to us by the client. This prevents attacks on our
1488 parsing code from hosts not in the hosts allow list */
1490 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
1491 lp_hostsdeny(-1))) {
1492 /* send a negative session response "not listening on calling name" */
1493 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
1494 DEBUG( 1, ( "Connection denied from %s\n",
1495 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
1496 (void)send_smb(smbd_server_fd(),(char *)buf);
1497 exit_server_cleanly("connection denied");
1501 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1503 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1505 (unsigned int)unread_bytes ));
1507 if (msg_type != 0) {
1509 * NetBIOS session request, keepalive, etc.
1511 reply_special(inbuf);
1517 construct_reply(inbuf,nread,unread_bytes);
1522 /****************************************************************************
1523 Return a string containing the function name of a SMB command.
1524 ****************************************************************************/
1526 const char *smb_fn_name(int type)
1528 const char *unknown_name = "SMBunknown";
1530 if (smb_messages[type].name == NULL)
1531 return(unknown_name);
1533 return(smb_messages[type].name);
1536 /****************************************************************************
1537 Helper functions for contruct_reply.
1538 ****************************************************************************/
1540 static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES;
1542 void add_to_common_flags2(uint32 v)
1547 void remove_from_common_flags2(uint32 v)
1549 common_flags2 &= ~v;
1552 void construct_reply_common(const char *inbuf, char *outbuf)
1554 set_message(outbuf,0,0,False);
1556 SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
1557 SIVAL(outbuf,smb_rcls,0);
1558 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1559 SSVAL(outbuf,smb_flg2,
1560 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1562 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1564 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1565 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1566 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1567 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1570 /****************************************************************************
1571 Construct a chained reply and add it to the already made reply
1572 ****************************************************************************/
1574 void chain_reply(struct smb_request *req)
1576 static char *orig_inbuf;
1579 * Dirty little const_discard: We mess with req->inbuf, which is
1580 * declared as const. If maybe at some point this routine gets
1581 * rewritten, this const_discard could go away.
1583 char *inbuf = CONST_DISCARD(char *, req->inbuf);
1584 int size = smb_len(req->inbuf)+4;
1586 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
1587 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
1591 char inbuf_saved[smb_wct];
1592 char *outbuf = (char *)req->outbuf;
1593 size_t outsize = smb_len(outbuf) + 4;
1594 size_t outsize_padded;
1595 size_t ofs, to_move;
1597 struct smb_request *req2;
1598 size_t caller_outputlen;
1599 char *caller_output;
1601 /* Maybe its not chained, or it's an error packet. */
1602 if (smb_com2 == 0xFF || SVAL(outbuf,smb_rcls) != 0) {
1603 SCVAL(outbuf,smb_vwv0,0xFF);
1607 if (chain_size == 0) {
1608 /* this is the first part of the chain */
1613 * We need to save the output the caller added to the chain so that we
1614 * can splice it into the final output buffer later.
1617 caller_outputlen = outsize - smb_wct;
1619 caller_output = (char *)memdup(outbuf + smb_wct, caller_outputlen);
1621 if (caller_output == NULL) {
1622 /* TODO: NT_STATUS_NO_MEMORY */
1623 smb_panic("could not dup outbuf");
1627 * The original Win95 redirector dies on a reply to
1628 * a lockingX and read chain unless the chain reply is
1629 * 4 byte aligned. JRA.
1632 outsize_padded = (outsize + 3) & ~3;
1635 * remember how much the caller added to the chain, only counting
1636 * stuff after the parameter words
1638 chain_size += outsize_padded - smb_wct;
1641 * work out pointers into the original packets. The
1642 * headers on these need to be filled in
1644 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
1646 /* remember the original command type */
1647 smb_com1 = CVAL(orig_inbuf,smb_com);
1649 /* save the data which will be overwritten by the new headers */
1650 memcpy(inbuf_saved,inbuf2,smb_wct);
1652 /* give the new packet the same header as the last part of the SMB */
1653 memmove(inbuf2,inbuf,smb_wct);
1655 /* create the in buffer */
1656 SCVAL(inbuf2,smb_com,smb_com2);
1658 /* work out the new size for the in buffer. */
1659 new_size = size - (inbuf2 - inbuf);
1661 DEBUG(0,("chain_reply: chain packet size incorrect "
1662 "(orig size = %d, offset = %d)\n",
1663 size, (int)(inbuf2 - inbuf) ));
1664 exit_server_cleanly("Bad chained packet");
1668 /* And set it in the header. */
1669 smb_setlen(inbuf2, new_size - 4);
1671 DEBUG(3,("Chained message\n"));
1674 if (!(req2 = talloc(talloc_tos(), struct smb_request))) {
1675 smb_panic("could not allocate smb_request");
1677 init_smb_request(req2, (uint8 *)inbuf2,0);
1679 /* process the request */
1680 switch_message(smb_com2, req2, new_size);
1683 * We don't accept deferred operations in chained requests.
1685 SMB_ASSERT(req2->outbuf != NULL);
1686 outsize2 = smb_len(req2->outbuf)+4;
1689 * Move away the new command output so that caller_output fits in,
1690 * copy in the caller_output saved above.
1693 SMB_ASSERT(outsize_padded >= smb_wct);
1696 * "ofs" is the space we need for caller_output. Equal to
1697 * caller_outputlen plus the padding.
1700 ofs = outsize_padded - smb_wct;
1703 * "to_move" is the amount of bytes the secondary routine gave us
1706 to_move = outsize2 - smb_wct;
1708 if (to_move + ofs + smb_wct + chain_size > max_send) {
1709 smb_panic("replies too large -- would have to cut");
1713 * In the "new" API "outbuf" is allocated via reply_outbuf, just for
1714 * the first request in the chain. So we have to re-allocate it. In
1715 * the "old" API the only outbuf ever used is the global OutBuffer
1716 * which is always large enough.
1719 outbuf = TALLOC_REALLOC_ARRAY(NULL, outbuf, char,
1720 to_move + ofs + smb_wct);
1721 if (outbuf == NULL) {
1722 smb_panic("could not realloc outbuf");
1725 req->outbuf = (uint8 *)outbuf;
1727 memmove(outbuf + smb_wct + ofs, req2->outbuf + smb_wct, to_move);
1728 memcpy(outbuf + smb_wct, caller_output, caller_outputlen);
1731 * copy the new reply header over the old one but preserve the smb_com
1734 memmove(outbuf, req2->outbuf, smb_wct);
1735 SCVAL(outbuf, smb_com, smb_com1);
1738 * We've just copied in the whole "wct" area from the secondary
1739 * function. Fix up the chaining: com2 and the offset need to be
1743 SCVAL(outbuf, smb_vwv0, smb_com2);
1744 SSVAL(outbuf, smb_vwv1, chain_size + smb_wct - 4);
1746 if (outsize_padded > outsize) {
1749 * Due to padding we have some uninitialized bytes after the
1753 memset(outbuf + outsize, 0, outsize_padded - outsize);
1756 smb_setlen(outbuf, outsize2 + chain_size - 4);
1759 * restore the saved data, being careful not to overwrite any data
1760 * from the reply header
1762 memcpy(inbuf2,inbuf_saved,smb_wct);
1764 SAFE_FREE(caller_output);
1770 /****************************************************************************
1771 Setup the needed select timeout in milliseconds.
1772 ****************************************************************************/
1774 static int setup_select_timeout(void)
1778 select_timeout = SMBD_SELECT_TIMEOUT*1000;
1780 if (print_notify_messages_pending()) {
1781 select_timeout = MIN(select_timeout, 1000);
1784 return select_timeout;
1787 /****************************************************************************
1788 Check if services need reloading.
1789 ****************************************************************************/
1791 void check_reload(time_t t)
1793 static pid_t mypid = 0;
1794 static time_t last_smb_conf_reload_time = 0;
1795 static time_t last_printer_reload_time = 0;
1796 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1798 if(last_smb_conf_reload_time == 0) {
1799 last_smb_conf_reload_time = t;
1800 /* Our printing subsystem might not be ready at smbd start up.
1801 Then no printer is available till the first printers check
1802 is performed. A lower initial interval circumvents this. */
1803 if ( printcap_cache_time > 60 )
1804 last_printer_reload_time = t - printcap_cache_time + 60;
1806 last_printer_reload_time = t;
1809 if (mypid != getpid()) { /* First time or fork happened meanwhile */
1810 /* randomize over 60 second the printcap reload to avoid all
1811 * process hitting cupsd at the same time */
1812 int time_range = 60;
1814 last_printer_reload_time += random() % time_range;
1818 if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
1819 reload_services(True);
1820 reload_after_sighup = False;
1821 last_smb_conf_reload_time = t;
1824 /* 'printcap cache time = 0' disable the feature */
1826 if ( printcap_cache_time != 0 )
1828 /* see if it's time to reload or if the clock has been set back */
1830 if ( (t >= last_printer_reload_time+printcap_cache_time)
1831 || (t-last_printer_reload_time < 0) )
1833 DEBUG( 3,( "Printcap cache time expired.\n"));
1835 last_printer_reload_time = t;
1840 /****************************************************************************
1841 Process any timeout housekeeping. Return False if the caller should exit.
1842 ****************************************************************************/
1844 static bool timeout_processing(int *select_timeout,
1845 time_t *last_timeout_processing_time)
1849 if (*get_srv_read_error() == SMB_READ_EOF) {
1850 DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
1854 if (*get_srv_read_error() == SMB_READ_ERROR) {
1855 DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",
1860 if (*get_srv_read_error() == SMB_READ_BAD_SIG) {
1861 DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));
1865 *last_timeout_processing_time = t = time(NULL);
1867 /* become root again if waiting */
1868 change_to_root_user();
1870 /* check if we need to reload services */
1873 if(global_machine_password_needs_changing &&
1874 /* for ADS we need to do a regular ADS password change, not a domain
1876 lp_security() == SEC_DOMAIN) {
1878 unsigned char trust_passwd_hash[16];
1882 * We're in domain level security, and the code that
1883 * read the machine password flagged that the machine
1884 * password needs changing.
1888 * First, open the machine password file with an exclusive lock.
1891 if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) {
1892 DEBUG(0,("process: unable to lock the machine account password for \
1893 machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
1897 if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
1898 DEBUG(0,("process: unable to read the machine account password for \
1899 machine %s in domain %s.\n", global_myname(), lp_workgroup()));
1900 secrets_lock_trust_account_password(lp_workgroup(), False);
1905 * Make sure someone else hasn't already done this.
1908 if(t < lct + lp_machine_password_timeout()) {
1909 global_machine_password_needs_changing = False;
1910 secrets_lock_trust_account_password(lp_workgroup(), False);
1914 /* always just contact the PDC here */
1916 change_trust_account_password( lp_workgroup(), NULL);
1917 global_machine_password_needs_changing = False;
1918 secrets_lock_trust_account_password(lp_workgroup(), False);
1921 /* update printer queue caches if necessary */
1923 update_monitored_printq_cache();
1926 * Now we are root, check if the log files need pruning.
1927 * Force a log file check.
1929 force_check_log_size();
1932 /* Send any queued printer notify message to interested smbd's. */
1934 print_notify_send_messages(smbd_messaging_context(), 0);
1937 * Modify the select timeout depending upon
1938 * what we have remaining in our queues.
1941 *select_timeout = setup_select_timeout();
1946 /****************************************************************************
1947 Process commands from the client
1948 ****************************************************************************/
1950 void smbd_process(void)
1952 time_t last_timeout_processing_time = time(NULL);
1953 unsigned int num_smbs = 0;
1954 size_t unread_bytes = 0;
1956 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
1959 int select_timeout = setup_select_timeout();
1963 TALLOC_CTX *frame = talloc_stackframe();
1967 /* Did someone ask for immediate checks on things like blocking locks ? */
1968 if (select_timeout == 0) {
1969 if(!timeout_processing(&select_timeout,
1970 &last_timeout_processing_time))
1972 num_smbs = 0; /* Reset smb counter. */
1975 run_events(smbd_event_context(), 0, NULL, NULL);
1977 while (!receive_message_or_smb(NULL, &inbuf, &inbuf_len,
1978 select_timeout, &unread_bytes)) {
1979 if(!timeout_processing(&select_timeout,
1980 &last_timeout_processing_time))
1982 num_smbs = 0; /* Reset smb counter. */
1987 * Ensure we do timeout processing if the SMB we just got was
1988 * only an echo request. This allows us to set the select
1989 * timeout in 'receive_message_or_smb()' to any value we like
1990 * without worrying that the client will send echo requests
1991 * faster than the select timeout, thus starving out the
1992 * essential processing (change notify, blocking locks) that
1993 * the timeout code does. JRA.
1995 num_echos = smb_echo_count;
1997 process_smb(inbuf, inbuf_len, unread_bytes);
2001 if (smb_echo_count != num_echos) {
2002 if(!timeout_processing( &select_timeout, &last_timeout_processing_time))
2004 num_smbs = 0; /* Reset smb counter. */
2010 * If we are getting smb requests in a constant stream
2011 * with no echos, make sure we attempt timeout processing
2012 * every select_timeout milliseconds - but only check for this
2013 * every 200 smb requests.
2016 if ((num_smbs % 200) == 0) {
2017 time_t new_check_time = time(NULL);
2018 if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
2019 if(!timeout_processing(
2021 &last_timeout_processing_time))
2023 num_smbs = 0; /* Reset smb counter. */
2024 last_timeout_processing_time = new_check_time; /* Reset time. */
2028 /* The timeout_processing function isn't run nearly
2029 often enough to implement 'max log size' without
2030 overrunning the size of the file by many megabytes.
2031 This is especially true if we are running at debug
2032 level 10. Checking every 50 SMBs is a nice
2033 tradeoff of performance vs log file size overrun. */
2035 if ((num_smbs % 50) == 0 && need_to_check_log_size()) {
2036 change_to_root_user();