2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "smbd/globals.h"
24 extern bool global_machine_password_needs_changing;
26 static void construct_reply_common(struct smb_request *req, const char *inbuf,
29 /* Accessor function for smb_read_error for smbd functions. */
31 /****************************************************************************
33 ****************************************************************************/
35 bool srv_send_smb(int fd, char *buffer,
36 bool do_signing, uint32_t seqnum,
38 struct smb_perfcount_data *pcd)
43 char *buf_out = buffer;
46 /* Sign the outgoing packet if required. */
47 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
51 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
52 if (!NT_STATUS_IS_OK(status)) {
53 DEBUG(0, ("send_smb: SMB encryption failed "
54 "on outgoing packet! Error %s\n",
60 len = smb_len(buf_out) + 4;
62 ret = write_data(fd,buf_out+nwritten,len - nwritten);
64 DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
65 (int)len,(int)ret, strerror(errno) ));
66 srv_free_enc_buffer(buf_out);
70 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
71 srv_free_enc_buffer(buf_out);
73 SMB_PERFCOUNT_END(pcd);
77 /*******************************************************************
78 Setup the word count and byte count for a smb message.
79 ********************************************************************/
81 int srv_set_message(char *buf,
86 if (zero && (num_words || num_bytes)) {
87 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
89 SCVAL(buf,smb_wct,num_words);
90 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
91 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
92 return (smb_size + num_words*2 + num_bytes);
95 static bool valid_smb_header(const uint8_t *inbuf)
97 if (is_encrypted_packet(inbuf)) {
101 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
102 * but it just looks weird to call strncmp for this one.
104 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
107 /* Socket functions for smbd packet processing. */
109 static bool valid_packet_size(size_t len)
112 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
113 * of header. Don't print the error if this fits.... JRA.
116 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
117 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
118 (unsigned long)len));
124 static NTSTATUS read_packet_remainder(int fd, char *buffer,
125 unsigned int timeout, ssize_t len)
131 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
134 /****************************************************************************
135 Attempt a zerocopy writeX read. We know here that len > smb_size-4
136 ****************************************************************************/
139 * Unfortunately, earlier versions of smbclient/libsmbclient
140 * don't send this "standard" writeX header. I've fixed this
141 * for 3.2 but we'll use the old method with earlier versions.
142 * Windows and CIFSFS at least use this standard size. Not
146 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
147 (2*14) + /* word count (including bcc) */ \
150 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
151 const char lenbuf[4],
152 int fd, char **buffer,
153 unsigned int timeout,
157 /* Size of a WRITEX call (+4 byte len). */
158 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
159 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
163 memcpy(writeX_header, lenbuf, 4);
165 status = read_fd_with_timeout(
166 fd, writeX_header + 4,
167 STANDARD_WRITE_AND_X_HEADER_SIZE,
168 STANDARD_WRITE_AND_X_HEADER_SIZE,
171 if (!NT_STATUS_IS_OK(status)) {
176 * Ok - now try and see if this is a possible
180 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
182 * If the data offset is beyond what
183 * we've read, drain the extra bytes.
185 uint16_t doff = SVAL(writeX_header,smb_vwv11);
188 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
189 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
190 if (drain_socket(smbd_server_fd(), drain) != drain) {
191 smb_panic("receive_smb_raw_talloc_partial_read:"
192 " failed to drain pending bytes");
195 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
198 /* Spoof down the length and null out the bcc. */
199 set_message_bcc(writeX_header, 0);
200 newlen = smb_len(writeX_header);
202 /* Copy the header we've written. */
204 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
206 sizeof(writeX_header));
208 if (*buffer == NULL) {
209 DEBUG(0, ("Could not allocate inbuf of length %d\n",
210 (int)sizeof(writeX_header)));
211 return NT_STATUS_NO_MEMORY;
214 /* Work out the remaining bytes. */
215 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
216 *len_ret = newlen + 4;
220 if (!valid_packet_size(len)) {
221 return NT_STATUS_INVALID_PARAMETER;
225 * Not a valid writeX call. Just do the standard
229 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
231 if (*buffer == NULL) {
232 DEBUG(0, ("Could not allocate inbuf of length %d\n",
234 return NT_STATUS_NO_MEMORY;
237 /* Copy in what we already read. */
240 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
241 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
244 status = read_packet_remainder(
245 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
248 if (!NT_STATUS_IS_OK(status)) {
249 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
259 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
260 char **buffer, unsigned int timeout,
261 size_t *p_unread, size_t *plen)
265 int min_recv_size = lp_min_receive_file_size();
270 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
271 if (!NT_STATUS_IS_OK(status)) {
272 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
276 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
277 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
278 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
279 !srv_is_signing_active(smbd_server_conn)) {
281 return receive_smb_raw_talloc_partial_read(
282 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
285 if (!valid_packet_size(len)) {
286 return NT_STATUS_INVALID_PARAMETER;
290 * The +4 here can't wrap, we've checked the length above already.
293 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
295 if (*buffer == NULL) {
296 DEBUG(0, ("Could not allocate inbuf of length %d\n",
298 return NT_STATUS_NO_MEMORY;
301 memcpy(*buffer, lenbuf, sizeof(lenbuf));
303 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
304 if (!NT_STATUS_IS_OK(status)) {
312 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
313 char **buffer, unsigned int timeout,
314 size_t *p_unread, bool *p_encrypted,
321 *p_encrypted = false;
323 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
325 if (!NT_STATUS_IS_OK(status)) {
329 if (is_encrypted_packet((uint8_t *)*buffer)) {
330 status = srv_decrypt_buffer(*buffer);
331 if (!NT_STATUS_IS_OK(status)) {
332 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
333 "incoming packet! Error %s\n",
334 nt_errstr(status) ));
340 /* Check the incoming SMB signature. */
341 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum)) {
342 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
343 "incoming packet!\n"));
344 return NT_STATUS_INVALID_NETWORK_RESPONSE;
352 * Initialize a struct smb_request from an inbuf
355 void init_smb_request(struct smb_request *req,
360 struct smbd_server_connection *sconn = smbd_server_conn;
361 size_t req_size = smb_len(inbuf) + 4;
362 /* Ensure we have at least smb_size bytes. */
363 if (req_size < smb_size) {
364 DEBUG(0,("init_smb_request: invalid request size %u\n",
365 (unsigned int)req_size ));
366 exit_server_cleanly("Invalid SMB request");
368 req->cmd = CVAL(inbuf, smb_com);
369 req->flags2 = SVAL(inbuf, smb_flg2);
370 req->smbpid = SVAL(inbuf, smb_pid);
371 req->mid = SVAL(inbuf, smb_mid);
373 req->vuid = SVAL(inbuf, smb_uid);
374 req->tid = SVAL(inbuf, smb_tid);
375 req->wct = CVAL(inbuf, smb_wct);
376 req->vwv = (uint16_t *)(inbuf+smb_vwv);
377 req->buflen = smb_buflen(inbuf);
378 req->buf = (const uint8_t *)smb_buf(inbuf);
379 req->unread_bytes = unread_bytes;
380 req->encrypted = encrypted;
381 req->conn = conn_find(sconn,req->tid);
382 req->sconn = smbd_server_conn;
383 req->chain_fsp = NULL;
384 req->chain_outbuf = NULL;
386 smb_init_perfcount_data(&req->pcd);
388 /* Ensure we have at least wct words and 2 bytes of bcc. */
389 if (smb_size + req->wct*2 > req_size) {
390 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
391 (unsigned int)req->wct,
392 (unsigned int)req_size));
393 exit_server_cleanly("Invalid SMB request");
395 /* Ensure bcc is correct. */
396 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
397 DEBUG(0,("init_smb_request: invalid bcc number %u "
398 "(wct = %u, size %u)\n",
399 (unsigned int)req->buflen,
400 (unsigned int)req->wct,
401 (unsigned int)req_size));
402 exit_server_cleanly("Invalid SMB request");
408 static void process_smb(struct smbd_server_connection *conn,
409 uint8_t *inbuf, size_t nread, size_t unread_bytes,
410 uint32_t seqnum, bool encrypted,
411 struct smb_perfcount_data *deferred_pcd);
413 static void smbd_deferred_open_timer(struct event_context *ev,
414 struct timed_event *te,
415 struct timeval _tval,
418 struct pending_message_list *msg = talloc_get_type(private_data,
419 struct pending_message_list);
420 TALLOC_CTX *mem_ctx = talloc_tos();
421 uint16_t mid = SVAL(msg->buf.data,smb_mid);
424 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
427 exit_server("smbd_deferred_open_timer: talloc failed\n");
431 /* We leave this message on the queue so the open code can
432 know this is a retry. */
433 DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
434 (unsigned int)mid ));
436 /* Mark the message as processed so this is not
437 * re-processed in error. */
438 msg->processed = true;
440 process_smb(smbd_server_conn, inbuf,
442 msg->seqnum, msg->encrypted, &msg->pcd);
444 /* If it's still there and was processed, remove it. */
445 msg = get_open_deferred_message(mid);
446 if (msg && msg->processed) {
447 remove_deferred_open_smb_message(mid);
451 /****************************************************************************
452 Function to push a message onto the tail of a linked list of smb messages ready
454 ****************************************************************************/
456 static bool push_queued_message(struct smb_request *req,
457 struct timeval request_time,
458 struct timeval end_time,
459 char *private_data, size_t private_len)
461 int msg_len = smb_len(req->inbuf) + 4;
462 struct pending_message_list *msg;
464 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
467 DEBUG(0,("push_message: malloc fail (1)\n"));
471 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
472 if(msg->buf.data == NULL) {
473 DEBUG(0,("push_message: malloc fail (2)\n"));
478 msg->request_time = request_time;
479 msg->seqnum = req->seqnum;
480 msg->encrypted = req->encrypted;
481 msg->processed = false;
482 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
485 msg->private_data = data_blob_talloc(msg, private_data,
487 if (msg->private_data.data == NULL) {
488 DEBUG(0,("push_message: malloc fail (3)\n"));
494 msg->te = event_add_timed(smbd_event_context(),
497 smbd_deferred_open_timer,
500 DEBUG(0,("push_message: event_add_timed failed\n"));
505 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
507 DEBUG(10,("push_message: pushed message length %u on "
508 "deferred_open_queue\n", (unsigned int)msg_len));
513 /****************************************************************************
514 Function to delete a sharing violation open message by mid.
515 ****************************************************************************/
517 void remove_deferred_open_smb_message(uint16 mid)
519 struct pending_message_list *pml;
521 for (pml = deferred_open_queue; pml; pml = pml->next) {
522 if (mid == SVAL(pml->buf.data,smb_mid)) {
523 DEBUG(10,("remove_deferred_open_smb_message: "
524 "deleting mid %u len %u\n",
526 (unsigned int)pml->buf.length ));
527 DLIST_REMOVE(deferred_open_queue, pml);
534 /****************************************************************************
535 Move a sharing violation open retry message to the front of the list and
536 schedule it for immediate processing.
537 ****************************************************************************/
539 void schedule_deferred_open_smb_message(uint16 mid)
541 struct pending_message_list *pml;
544 for (pml = deferred_open_queue; pml; pml = pml->next) {
545 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
547 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
548 (unsigned int)msg_mid ));
550 if (mid == msg_mid) {
551 struct timed_event *te;
553 if (pml->processed) {
554 /* A processed message should not be
556 DEBUG(0,("schedule_deferred_open_smb_message: LOGIC ERROR "
557 "message mid %u was already processed\n",
562 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
565 te = event_add_timed(smbd_event_context(),
568 smbd_deferred_open_timer,
571 DEBUG(10,("schedule_deferred_open_smb_message: "
572 "event_add_timed() failed, skipping mid %u\n",
576 TALLOC_FREE(pml->te);
578 DLIST_PROMOTE(deferred_open_queue, pml);
583 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
587 /****************************************************************************
588 Return true if this mid is on the deferred queue and was not yet processed.
589 ****************************************************************************/
591 bool open_was_deferred(uint16 mid)
593 struct pending_message_list *pml;
595 for (pml = deferred_open_queue; pml; pml = pml->next) {
596 if (SVAL(pml->buf.data,smb_mid) == mid && !pml->processed) {
603 /****************************************************************************
604 Return the message queued by this mid.
605 ****************************************************************************/
607 struct pending_message_list *get_open_deferred_message(uint16 mid)
609 struct pending_message_list *pml;
611 for (pml = deferred_open_queue; pml; pml = pml->next) {
612 if (SVAL(pml->buf.data,smb_mid) == mid) {
619 /****************************************************************************
620 Function to push a deferred open smb message onto a linked list of local smb
621 messages ready for processing.
622 ****************************************************************************/
624 bool push_deferred_smb_message(struct smb_request *req,
625 struct timeval request_time,
626 struct timeval timeout,
627 char *private_data, size_t priv_len)
629 struct timeval end_time;
631 if (req->unread_bytes) {
632 DEBUG(0,("push_deferred_smb_message: logic error ! "
633 "unread_bytes = %u\n",
634 (unsigned int)req->unread_bytes ));
635 smb_panic("push_deferred_smb_message: "
636 "logic error unread_bytes != 0" );
639 end_time = timeval_sum(&request_time, &timeout);
641 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
642 "timeout time [%u.%06u]\n",
643 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
644 (unsigned int)end_time.tv_sec,
645 (unsigned int)end_time.tv_usec));
647 return push_queued_message(req, request_time, end_time,
648 private_data, priv_len);
652 struct timed_event *te;
653 struct timeval interval;
655 bool (*handler)(const struct timeval *now, void *private_data);
659 static void smbd_idle_event_handler(struct event_context *ctx,
660 struct timed_event *te,
664 struct idle_event *event =
665 talloc_get_type_abort(private_data, struct idle_event);
667 TALLOC_FREE(event->te);
669 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
670 event->name, event->te));
672 if (!event->handler(&now, event->private_data)) {
673 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
674 event->name, event->te));
675 /* Don't repeat, delete ourselves */
680 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
681 event->name, event->te));
683 event->te = event_add_timed(ctx, event,
684 timeval_sum(&now, &event->interval),
685 smbd_idle_event_handler, event);
687 /* We can't do much but fail here. */
688 SMB_ASSERT(event->te != NULL);
691 struct idle_event *event_add_idle(struct event_context *event_ctx,
693 struct timeval interval,
695 bool (*handler)(const struct timeval *now,
699 struct idle_event *result;
700 struct timeval now = timeval_current();
702 result = TALLOC_P(mem_ctx, struct idle_event);
703 if (result == NULL) {
704 DEBUG(0, ("talloc failed\n"));
708 result->interval = interval;
709 result->handler = handler;
710 result->private_data = private_data;
712 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
713 DEBUG(0, ("talloc failed\n"));
718 result->te = event_add_timed(event_ctx, result,
719 timeval_sum(&now, &interval),
720 smbd_idle_event_handler, result);
721 if (result->te == NULL) {
722 DEBUG(0, ("event_add_timed failed\n"));
727 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
731 static void smbd_sig_term_handler(struct tevent_context *ev,
732 struct tevent_signal *se,
738 exit_server_cleanly("termination signal");
741 void smbd_setup_sig_term_handler(void)
743 struct tevent_signal *se;
745 se = tevent_add_signal(smbd_event_context(),
746 smbd_event_context(),
748 smbd_sig_term_handler,
751 exit_server("failed to setup SIGTERM handler");
755 static void smbd_sig_hup_handler(struct tevent_context *ev,
756 struct tevent_signal *se,
762 change_to_root_user();
763 DEBUG(1,("Reloading services after SIGHUP\n"));
764 reload_services(False);
767 void smbd_setup_sig_hup_handler(void)
769 struct tevent_signal *se;
771 se = tevent_add_signal(smbd_event_context(),
772 smbd_event_context(),
774 smbd_sig_hup_handler,
777 exit_server("failed to setup SIGHUP handler");
781 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
788 to.tv_sec = SMBD_SELECT_TIMEOUT;
792 * Setup the select fd sets.
799 * Are there any timed events waiting ? If so, ensure we don't
800 * select for longer than it would take to wait for them.
807 event_add_to_select_args(smbd_event_context(), &now,
808 &r_fds, &w_fds, &to, &maxfd);
811 /* Process a signal and timed events now... */
812 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
813 return NT_STATUS_RETRY;
818 START_PROFILE(smbd_idle);
820 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
823 END_PROFILE(smbd_idle);
827 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
828 return NT_STATUS_RETRY;
833 /* something is wrong. Maybe the socket is dead? */
834 return map_nt_error_from_unix(errno);
837 /* Did we timeout ? */
839 return NT_STATUS_RETRY;
842 /* should not be reached */
843 return NT_STATUS_INTERNAL_ERROR;
847 * Only allow 5 outstanding trans requests. We're allocating memory, so
851 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
854 for (; list != NULL; list = list->next) {
856 if (list->mid == mid) {
857 return NT_STATUS_INVALID_PARAMETER;
863 return NT_STATUS_INSUFFICIENT_RESOURCES;
870 These flags determine some of the permissions required to do an operation
872 Note that I don't set NEED_WRITE on some write operations because they
873 are used by some brain-dead clients when printing, and I don't want to
874 force write permissions on print services.
876 #define AS_USER (1<<0)
877 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
878 #define TIME_INIT (1<<2)
879 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
880 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
881 #define DO_CHDIR (1<<6)
884 define a list of possible SMB messages and their corresponding
885 functions. Any message that has a NULL function is unimplemented -
886 please feel free to contribute implementations!
888 static const struct smb_message_struct {
890 void (*fn)(struct smb_request *req);
892 } smb_messages[256] = {
894 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
895 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
896 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
897 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
898 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
899 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
900 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
901 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
902 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
903 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
904 /* 0x0a */ { "SMBread",reply_read,AS_USER},
905 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
906 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
907 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
908 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
909 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
910 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
911 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
912 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
913 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
914 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
915 /* 0x15 */ { NULL, NULL, 0 },
916 /* 0x16 */ { NULL, NULL, 0 },
917 /* 0x17 */ { NULL, NULL, 0 },
918 /* 0x18 */ { NULL, NULL, 0 },
919 /* 0x19 */ { NULL, NULL, 0 },
920 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
921 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
922 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
923 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
924 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
925 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
926 /* 0x20 */ { "SMBwritec", NULL,0},
927 /* 0x21 */ { NULL, NULL, 0 },
928 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
929 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
930 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
931 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
932 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
933 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
934 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
935 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
936 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
937 /* 0x2b */ { "SMBecho",reply_echo,0},
938 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
939 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
940 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
941 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
942 /* 0x30 */ { NULL, NULL, 0 },
943 /* 0x31 */ { NULL, NULL, 0 },
944 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
945 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
946 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
947 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
948 /* 0x36 */ { NULL, NULL, 0 },
949 /* 0x37 */ { NULL, NULL, 0 },
950 /* 0x38 */ { NULL, NULL, 0 },
951 /* 0x39 */ { NULL, NULL, 0 },
952 /* 0x3a */ { NULL, NULL, 0 },
953 /* 0x3b */ { NULL, NULL, 0 },
954 /* 0x3c */ { NULL, NULL, 0 },
955 /* 0x3d */ { NULL, NULL, 0 },
956 /* 0x3e */ { NULL, NULL, 0 },
957 /* 0x3f */ { NULL, NULL, 0 },
958 /* 0x40 */ { NULL, NULL, 0 },
959 /* 0x41 */ { NULL, NULL, 0 },
960 /* 0x42 */ { NULL, NULL, 0 },
961 /* 0x43 */ { NULL, NULL, 0 },
962 /* 0x44 */ { NULL, NULL, 0 },
963 /* 0x45 */ { NULL, NULL, 0 },
964 /* 0x46 */ { NULL, NULL, 0 },
965 /* 0x47 */ { NULL, NULL, 0 },
966 /* 0x48 */ { NULL, NULL, 0 },
967 /* 0x49 */ { NULL, NULL, 0 },
968 /* 0x4a */ { NULL, NULL, 0 },
969 /* 0x4b */ { NULL, NULL, 0 },
970 /* 0x4c */ { NULL, NULL, 0 },
971 /* 0x4d */ { NULL, NULL, 0 },
972 /* 0x4e */ { NULL, NULL, 0 },
973 /* 0x4f */ { NULL, NULL, 0 },
974 /* 0x50 */ { NULL, NULL, 0 },
975 /* 0x51 */ { NULL, NULL, 0 },
976 /* 0x52 */ { NULL, NULL, 0 },
977 /* 0x53 */ { NULL, NULL, 0 },
978 /* 0x54 */ { NULL, NULL, 0 },
979 /* 0x55 */ { NULL, NULL, 0 },
980 /* 0x56 */ { NULL, NULL, 0 },
981 /* 0x57 */ { NULL, NULL, 0 },
982 /* 0x58 */ { NULL, NULL, 0 },
983 /* 0x59 */ { NULL, NULL, 0 },
984 /* 0x5a */ { NULL, NULL, 0 },
985 /* 0x5b */ { NULL, NULL, 0 },
986 /* 0x5c */ { NULL, NULL, 0 },
987 /* 0x5d */ { NULL, NULL, 0 },
988 /* 0x5e */ { NULL, NULL, 0 },
989 /* 0x5f */ { NULL, NULL, 0 },
990 /* 0x60 */ { NULL, NULL, 0 },
991 /* 0x61 */ { NULL, NULL, 0 },
992 /* 0x62 */ { NULL, NULL, 0 },
993 /* 0x63 */ { NULL, NULL, 0 },
994 /* 0x64 */ { NULL, NULL, 0 },
995 /* 0x65 */ { NULL, NULL, 0 },
996 /* 0x66 */ { NULL, NULL, 0 },
997 /* 0x67 */ { NULL, NULL, 0 },
998 /* 0x68 */ { NULL, NULL, 0 },
999 /* 0x69 */ { NULL, NULL, 0 },
1000 /* 0x6a */ { NULL, NULL, 0 },
1001 /* 0x6b */ { NULL, NULL, 0 },
1002 /* 0x6c */ { NULL, NULL, 0 },
1003 /* 0x6d */ { NULL, NULL, 0 },
1004 /* 0x6e */ { NULL, NULL, 0 },
1005 /* 0x6f */ { NULL, NULL, 0 },
1006 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1007 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1008 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1009 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1010 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1011 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1012 /* 0x76 */ { NULL, NULL, 0 },
1013 /* 0x77 */ { NULL, NULL, 0 },
1014 /* 0x78 */ { NULL, NULL, 0 },
1015 /* 0x79 */ { NULL, NULL, 0 },
1016 /* 0x7a */ { NULL, NULL, 0 },
1017 /* 0x7b */ { NULL, NULL, 0 },
1018 /* 0x7c */ { NULL, NULL, 0 },
1019 /* 0x7d */ { NULL, NULL, 0 },
1020 /* 0x7e */ { NULL, NULL, 0 },
1021 /* 0x7f */ { NULL, NULL, 0 },
1022 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1023 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1024 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1025 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1026 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1027 /* 0x85 */ { NULL, NULL, 0 },
1028 /* 0x86 */ { NULL, NULL, 0 },
1029 /* 0x87 */ { NULL, NULL, 0 },
1030 /* 0x88 */ { NULL, NULL, 0 },
1031 /* 0x89 */ { NULL, NULL, 0 },
1032 /* 0x8a */ { NULL, NULL, 0 },
1033 /* 0x8b */ { NULL, NULL, 0 },
1034 /* 0x8c */ { NULL, NULL, 0 },
1035 /* 0x8d */ { NULL, NULL, 0 },
1036 /* 0x8e */ { NULL, NULL, 0 },
1037 /* 0x8f */ { NULL, NULL, 0 },
1038 /* 0x90 */ { NULL, NULL, 0 },
1039 /* 0x91 */ { NULL, NULL, 0 },
1040 /* 0x92 */ { NULL, NULL, 0 },
1041 /* 0x93 */ { NULL, NULL, 0 },
1042 /* 0x94 */ { NULL, NULL, 0 },
1043 /* 0x95 */ { NULL, NULL, 0 },
1044 /* 0x96 */ { NULL, NULL, 0 },
1045 /* 0x97 */ { NULL, NULL, 0 },
1046 /* 0x98 */ { NULL, NULL, 0 },
1047 /* 0x99 */ { NULL, NULL, 0 },
1048 /* 0x9a */ { NULL, NULL, 0 },
1049 /* 0x9b */ { NULL, NULL, 0 },
1050 /* 0x9c */ { NULL, NULL, 0 },
1051 /* 0x9d */ { NULL, NULL, 0 },
1052 /* 0x9e */ { NULL, NULL, 0 },
1053 /* 0x9f */ { NULL, NULL, 0 },
1054 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1055 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1056 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1057 /* 0xa3 */ { NULL, NULL, 0 },
1058 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1059 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1060 /* 0xa6 */ { NULL, NULL, 0 },
1061 /* 0xa7 */ { NULL, NULL, 0 },
1062 /* 0xa8 */ { NULL, NULL, 0 },
1063 /* 0xa9 */ { NULL, NULL, 0 },
1064 /* 0xaa */ { NULL, NULL, 0 },
1065 /* 0xab */ { NULL, NULL, 0 },
1066 /* 0xac */ { NULL, NULL, 0 },
1067 /* 0xad */ { NULL, NULL, 0 },
1068 /* 0xae */ { NULL, NULL, 0 },
1069 /* 0xaf */ { NULL, NULL, 0 },
1070 /* 0xb0 */ { NULL, NULL, 0 },
1071 /* 0xb1 */ { NULL, NULL, 0 },
1072 /* 0xb2 */ { NULL, NULL, 0 },
1073 /* 0xb3 */ { NULL, NULL, 0 },
1074 /* 0xb4 */ { NULL, NULL, 0 },
1075 /* 0xb5 */ { NULL, NULL, 0 },
1076 /* 0xb6 */ { NULL, NULL, 0 },
1077 /* 0xb7 */ { NULL, NULL, 0 },
1078 /* 0xb8 */ { NULL, NULL, 0 },
1079 /* 0xb9 */ { NULL, NULL, 0 },
1080 /* 0xba */ { NULL, NULL, 0 },
1081 /* 0xbb */ { NULL, NULL, 0 },
1082 /* 0xbc */ { NULL, NULL, 0 },
1083 /* 0xbd */ { NULL, NULL, 0 },
1084 /* 0xbe */ { NULL, NULL, 0 },
1085 /* 0xbf */ { NULL, NULL, 0 },
1086 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1087 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1088 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1089 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1090 /* 0xc4 */ { NULL, NULL, 0 },
1091 /* 0xc5 */ { NULL, NULL, 0 },
1092 /* 0xc6 */ { NULL, NULL, 0 },
1093 /* 0xc7 */ { NULL, NULL, 0 },
1094 /* 0xc8 */ { NULL, NULL, 0 },
1095 /* 0xc9 */ { NULL, NULL, 0 },
1096 /* 0xca */ { NULL, NULL, 0 },
1097 /* 0xcb */ { NULL, NULL, 0 },
1098 /* 0xcc */ { NULL, NULL, 0 },
1099 /* 0xcd */ { NULL, NULL, 0 },
1100 /* 0xce */ { NULL, NULL, 0 },
1101 /* 0xcf */ { NULL, NULL, 0 },
1102 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1103 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1104 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1105 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1106 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1107 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1108 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1109 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1110 /* 0xd8 */ { NULL, NULL, 0 },
1111 /* 0xd9 */ { NULL, NULL, 0 },
1112 /* 0xda */ { NULL, NULL, 0 },
1113 /* 0xdb */ { NULL, NULL, 0 },
1114 /* 0xdc */ { NULL, NULL, 0 },
1115 /* 0xdd */ { NULL, NULL, 0 },
1116 /* 0xde */ { NULL, NULL, 0 },
1117 /* 0xdf */ { NULL, NULL, 0 },
1118 /* 0xe0 */ { NULL, NULL, 0 },
1119 /* 0xe1 */ { NULL, NULL, 0 },
1120 /* 0xe2 */ { NULL, NULL, 0 },
1121 /* 0xe3 */ { NULL, NULL, 0 },
1122 /* 0xe4 */ { NULL, NULL, 0 },
1123 /* 0xe5 */ { NULL, NULL, 0 },
1124 /* 0xe6 */ { NULL, NULL, 0 },
1125 /* 0xe7 */ { NULL, NULL, 0 },
1126 /* 0xe8 */ { NULL, NULL, 0 },
1127 /* 0xe9 */ { NULL, NULL, 0 },
1128 /* 0xea */ { NULL, NULL, 0 },
1129 /* 0xeb */ { NULL, NULL, 0 },
1130 /* 0xec */ { NULL, NULL, 0 },
1131 /* 0xed */ { NULL, NULL, 0 },
1132 /* 0xee */ { NULL, NULL, 0 },
1133 /* 0xef */ { NULL, NULL, 0 },
1134 /* 0xf0 */ { NULL, NULL, 0 },
1135 /* 0xf1 */ { NULL, NULL, 0 },
1136 /* 0xf2 */ { NULL, NULL, 0 },
1137 /* 0xf3 */ { NULL, NULL, 0 },
1138 /* 0xf4 */ { NULL, NULL, 0 },
1139 /* 0xf5 */ { NULL, NULL, 0 },
1140 /* 0xf6 */ { NULL, NULL, 0 },
1141 /* 0xf7 */ { NULL, NULL, 0 },
1142 /* 0xf8 */ { NULL, NULL, 0 },
1143 /* 0xf9 */ { NULL, NULL, 0 },
1144 /* 0xfa */ { NULL, NULL, 0 },
1145 /* 0xfb */ { NULL, NULL, 0 },
1146 /* 0xfc */ { NULL, NULL, 0 },
1147 /* 0xfd */ { NULL, NULL, 0 },
1148 /* 0xfe */ { NULL, NULL, 0 },
1149 /* 0xff */ { NULL, NULL, 0 }
1153 /*******************************************************************
1154 allocate and initialize a reply packet
1155 ********************************************************************/
1157 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1158 const char *inbuf, char **outbuf, uint8_t num_words,
1162 * Protect against integer wrap
1164 if ((num_bytes > 0xffffff)
1165 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1167 if (asprintf(&msg, "num_bytes too large: %u",
1168 (unsigned)num_bytes) == -1) {
1169 msg = CONST_DISCARD(char *, "num_bytes too large");
1174 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1175 smb_size + num_words*2 + num_bytes);
1176 if (*outbuf == NULL) {
1180 construct_reply_common(req, inbuf, *outbuf);
1181 srv_set_message(*outbuf, num_words, num_bytes, false);
1183 * Zero out the word area, the caller has to take care of the bcc area
1186 if (num_words != 0) {
1187 memset(*outbuf + smb_vwv0, 0, num_words*2);
1193 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1196 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1198 smb_panic("could not allocate output buffer\n");
1200 req->outbuf = (uint8_t *)outbuf;
1204 /*******************************************************************
1205 Dump a packet to a file.
1206 ********************************************************************/
1208 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1212 if (DEBUGLEVEL < 50) {
1216 if (len < 4) len = smb_len(data)+4;
1217 for (i=1;i<100;i++) {
1218 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1219 type ? "req" : "resp") == -1) {
1222 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1223 if (fd != -1 || errno != EEXIST) break;
1226 ssize_t ret = write(fd, data, len);
1228 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1230 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1235 /****************************************************************************
1236 Prepare everything for calling the actual request function, and potentially
1237 call the request function via the "new" interface.
1239 Return False if the "legacy" function needs to be called, everything is
1242 Return True if we're done.
1244 I know this API sucks, but it is the one with the least code change I could
1246 ****************************************************************************/
1248 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1252 connection_struct *conn = NULL;
1253 struct smbd_server_connection *sconn = smbd_server_conn;
1257 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1258 * so subtract 4 from it. */
1259 if (!valid_smb_header(req->inbuf)
1260 || (size < (smb_size - 4))) {
1261 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1262 smb_len(req->inbuf)));
1263 exit_server_cleanly("Non-SMB packet");
1266 if (smb_messages[type].fn == NULL) {
1267 DEBUG(0,("Unknown message type %d!\n",type));
1268 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1269 reply_unknown_new(req, type);
1273 flags = smb_messages[type].flags;
1275 /* In share mode security we must ignore the vuid. */
1276 session_tag = (lp_security() == SEC_SHARE)
1277 ? UID_FIELD_INVALID : req->vuid;
1280 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1281 (int)sys_getpid(), (unsigned long)conn));
1283 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1285 /* Ensure this value is replaced in the incoming packet. */
1286 SSVAL(req->inbuf,smb_uid,session_tag);
1289 * Ensure the correct username is in current_user_info. This is a
1290 * really ugly bugfix for problems with multiple session_setup_and_X's
1291 * being done and allowing %U and %G substitutions to work correctly.
1292 * There is a reason this code is done here, don't move it unless you
1293 * know what you're doing... :-).
1297 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1298 user_struct *vuser = NULL;
1300 sconn->smb1.sessions.last_session_tag = session_tag;
1301 if(session_tag != UID_FIELD_INVALID) {
1302 vuser = get_valid_user_struct(sconn, session_tag);
1304 set_current_user_info(
1305 vuser->server_info->sanitized_username,
1306 vuser->server_info->unix_name,
1307 pdb_get_domain(vuser->server_info
1313 /* Does this call need to be run as the connected user? */
1314 if (flags & AS_USER) {
1316 /* Does this call need a valid tree connection? */
1319 * Amazingly, the error code depends on the command
1322 if (type == SMBntcreateX) {
1323 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1325 reply_doserror(req, ERRSRV, ERRinvnid);
1330 if (!change_to_user(conn,session_tag)) {
1331 DEBUG(0, ("Error: Could not change to user. Removing "
1332 "deferred open, mid=%d.\n", req->mid));
1333 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1337 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1339 /* Does it need write permission? */
1340 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1341 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1345 /* IPC services are limited */
1346 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1347 reply_doserror(req, ERRSRV,ERRaccess);
1351 /* This call needs to be run as root */
1352 change_to_root_user();
1355 /* load service specific parameters */
1357 if (req->encrypted) {
1358 conn->encrypted_tid = true;
1359 /* encrypted required from now on. */
1360 conn->encrypt_level = Required;
1361 } else if (ENCRYPTION_REQUIRED(conn)) {
1362 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1363 exit_server_cleanly("encryption required "
1369 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1370 (flags & (AS_USER|DO_CHDIR)
1372 reply_doserror(req, ERRSRV, ERRaccess);
1375 conn->num_smb_operations++;
1378 /* does this protocol need to be run as guest? */
1379 if ((flags & AS_GUEST)
1380 && (!change_to_guest() ||
1381 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1382 lp_hostsdeny(-1)))) {
1383 reply_doserror(req, ERRSRV, ERRaccess);
1387 smb_messages[type].fn(req);
1391 /****************************************************************************
1392 Construct a reply to the incoming packet.
1393 ****************************************************************************/
1395 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1396 uint32_t seqnum, bool encrypted,
1397 struct smb_perfcount_data *deferred_pcd)
1399 connection_struct *conn;
1400 struct smb_request *req;
1402 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1403 smb_panic("could not allocate smb_request");
1406 init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1407 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1408 req->seqnum = seqnum;
1410 /* we popped this message off the queue - keep original perf data */
1412 req->pcd = *deferred_pcd;
1414 SMB_PERFCOUNT_START(&req->pcd);
1415 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1416 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1419 conn = switch_message(req->cmd, req, size);
1421 if (req->unread_bytes) {
1422 /* writeX failed. drain socket. */
1423 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1424 req->unread_bytes) {
1425 smb_panic("failed to drain pending bytes");
1427 req->unread_bytes = 0;
1435 if (req->outbuf == NULL) {
1439 if (CVAL(req->outbuf,0) == 0) {
1440 show_msg((char *)req->outbuf);
1443 if (!srv_send_smb(smbd_server_fd(),
1444 (char *)req->outbuf,
1445 true, req->seqnum+1,
1446 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1448 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1456 /****************************************************************************
1457 Process an smb from the client
1458 ****************************************************************************/
1459 static void process_smb(struct smbd_server_connection *conn,
1460 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1461 uint32_t seqnum, bool encrypted,
1462 struct smb_perfcount_data *deferred_pcd)
1464 int msg_type = CVAL(inbuf,0);
1466 DO_PROFILE_INC(smb_count);
1468 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1470 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1472 (unsigned int)unread_bytes ));
1474 if (msg_type != 0) {
1476 * NetBIOS session request, keepalive, etc.
1478 reply_special((char *)inbuf);
1482 if (smbd_server_conn->allow_smb2) {
1483 if (smbd_is_smb2_header(inbuf, nread)) {
1484 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1487 smbd_server_conn->allow_smb2 = false;
1490 show_msg((char *)inbuf);
1492 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1496 conn->smb1.num_requests++;
1498 /* The timeout_processing function isn't run nearly
1499 often enough to implement 'max log size' without
1500 overrunning the size of the file by many megabytes.
1501 This is especially true if we are running at debug
1502 level 10. Checking every 50 SMBs is a nice
1503 tradeoff of performance vs log file size overrun. */
1505 if ((conn->smb1.num_requests % 50) == 0 &&
1506 need_to_check_log_size()) {
1507 change_to_root_user();
1512 /****************************************************************************
1513 Return a string containing the function name of a SMB command.
1514 ****************************************************************************/
1516 const char *smb_fn_name(int type)
1518 const char *unknown_name = "SMBunknown";
1520 if (smb_messages[type].name == NULL)
1521 return(unknown_name);
1523 return(smb_messages[type].name);
1526 /****************************************************************************
1527 Helper functions for contruct_reply.
1528 ****************************************************************************/
1530 void add_to_common_flags2(uint32 v)
1535 void remove_from_common_flags2(uint32 v)
1537 common_flags2 &= ~v;
1540 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1543 srv_set_message(outbuf,0,0,false);
1545 SCVAL(outbuf, smb_com, req->cmd);
1546 SIVAL(outbuf,smb_rcls,0);
1547 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1548 SSVAL(outbuf,smb_flg2,
1549 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1551 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1553 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1554 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1555 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1556 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1559 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1561 construct_reply_common(req, (char *)req->inbuf, outbuf);
1565 * How many bytes have we already accumulated up to the current wct field
1569 size_t req_wct_ofs(struct smb_request *req)
1573 if (req->chain_outbuf == NULL) {
1576 buf_size = talloc_get_size(req->chain_outbuf);
1577 if ((buf_size % 4) != 0) {
1578 buf_size += (4 - (buf_size % 4));
1580 return buf_size - 4;
1584 * Hack around reply_nterror & friends not being aware of chained requests,
1585 * generating illegal (i.e. wct==0) chain replies.
1588 static void fixup_chain_error_packet(struct smb_request *req)
1590 uint8_t *outbuf = req->outbuf;
1592 reply_outbuf(req, 2, 0);
1593 memcpy(req->outbuf, outbuf, smb_wct);
1594 TALLOC_FREE(outbuf);
1595 SCVAL(req->outbuf, smb_vwv0, 0xff);
1598 /****************************************************************************
1599 Construct a chained reply and add it to the already made reply
1600 ****************************************************************************/
1602 void chain_reply(struct smb_request *req)
1604 size_t smblen = smb_len(req->inbuf);
1605 size_t already_used, length_needed;
1607 uint32_t chain_offset; /* uint32_t to avoid overflow */
1614 if (IVAL(req->outbuf, smb_rcls) != 0) {
1615 fixup_chain_error_packet(req);
1619 * Any of the AndX requests and replies have at least a wct of
1620 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1621 * beginning of the SMB header to the next wct field.
1623 * None of the AndX requests put anything valuable in vwv[0] and [1],
1624 * so we can overwrite it here to form the chain.
1627 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1632 * Here we assume that this is the end of the chain. For that we need
1633 * to set "next command" to 0xff and the offset to 0. If we later find
1634 * more commands in the chain, this will be overwritten again.
1637 SCVAL(req->outbuf, smb_vwv0, 0xff);
1638 SCVAL(req->outbuf, smb_vwv0+1, 0);
1639 SSVAL(req->outbuf, smb_vwv1, 0);
1641 if (req->chain_outbuf == NULL) {
1643 * In req->chain_outbuf we collect all the replies. Start the
1644 * chain by copying in the first reply.
1646 * We do the realloc because later on we depend on
1647 * talloc_get_size to determine the length of
1648 * chain_outbuf. The reply_xxx routines might have
1649 * over-allocated (reply_pipe_read_and_X used to be such an
1652 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1653 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1654 if (req->chain_outbuf == NULL) {
1660 * Update smb headers where subsequent chained commands
1661 * may have updated them.
1663 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1664 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1666 if (!smb_splice_chain(&req->chain_outbuf,
1667 CVAL(req->outbuf, smb_com),
1668 CVAL(req->outbuf, smb_wct),
1669 (uint16_t *)(req->outbuf + smb_vwv),
1670 0, smb_buflen(req->outbuf),
1671 (uint8_t *)smb_buf(req->outbuf))) {
1674 TALLOC_FREE(req->outbuf);
1678 * We use the old request's vwv field to grab the next chained command
1679 * and offset into the chained fields.
1682 chain_cmd = CVAL(req->vwv+0, 0);
1683 chain_offset = SVAL(req->vwv+1, 0);
1685 if (chain_cmd == 0xff) {
1687 * End of chain, no more requests from the client. So ship the
1690 smb_setlen((char *)(req->chain_outbuf),
1691 talloc_get_size(req->chain_outbuf) - 4);
1693 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1694 true, req->seqnum+1,
1695 IS_CONN_ENCRYPTED(req->conn)
1698 exit_server_cleanly("chain_reply: srv_send_smb "
1701 TALLOC_FREE(req->chain_outbuf);
1706 /* add a new perfcounter for this element of chain */
1707 SMB_PERFCOUNT_ADD(&req->pcd);
1708 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1709 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1712 * Check if the client tries to fool us. The request so far uses the
1713 * space to the end of the byte buffer in the request just
1714 * processed. The chain_offset can't point into that area. If that was
1715 * the case, we could end up with an endless processing of the chain,
1716 * we would always handle the same request.
1719 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1720 if (chain_offset < already_used) {
1725 * Next check: Make sure the chain offset does not point beyond the
1726 * overall smb request length.
1729 length_needed = chain_offset+1; /* wct */
1730 if (length_needed > smblen) {
1735 * Now comes the pointer magic. Goal here is to set up req->vwv and
1736 * req->buf correctly again to be able to call the subsequent
1737 * switch_message(). The chain offset (the former vwv[1]) points at
1738 * the new wct field.
1741 wct = CVAL(smb_base(req->inbuf), chain_offset);
1744 * Next consistency check: Make the new vwv array fits in the overall
1748 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1749 if (length_needed > smblen) {
1752 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1755 * Now grab the new byte buffer....
1758 buflen = SVAL(vwv+wct, 0);
1761 * .. and check that it fits.
1764 length_needed += buflen;
1765 if (length_needed > smblen) {
1768 buf = (uint8_t *)(vwv+wct+1);
1770 req->cmd = chain_cmd;
1773 req->buflen = buflen;
1776 switch_message(chain_cmd, req, smblen);
1778 if (req->outbuf == NULL) {
1780 * This happens if the chained command has suspended itself or
1781 * if it has called srv_send_smb() itself.
1787 * We end up here if the chained command was not itself chained or
1788 * suspended, but for example a close() command. We now need to splice
1789 * the chained commands' outbuf into the already built up chain_outbuf
1790 * and ship the result.
1796 * We end up here if there's any error in the chain syntax. Report a
1797 * DOS error, just like Windows does.
1799 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1800 fixup_chain_error_packet(req);
1804 * This scary statement intends to set the
1805 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
1806 * to the value req->outbuf carries
1808 SSVAL(req->chain_outbuf, smb_flg2,
1809 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1810 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1813 * Transfer the error codes from the subrequest to the main one
1815 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1816 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
1818 if (!smb_splice_chain(&req->chain_outbuf,
1819 CVAL(req->outbuf, smb_com),
1820 CVAL(req->outbuf, smb_wct),
1821 (uint16_t *)(req->outbuf + smb_vwv),
1822 0, smb_buflen(req->outbuf),
1823 (uint8_t *)smb_buf(req->outbuf))) {
1824 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1826 TALLOC_FREE(req->outbuf);
1828 smb_setlen((char *)(req->chain_outbuf),
1829 talloc_get_size(req->chain_outbuf) - 4);
1831 show_msg((char *)(req->chain_outbuf));
1833 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1834 true, req->seqnum+1,
1835 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1837 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1839 TALLOC_FREE(req->chain_outbuf);
1843 /****************************************************************************
1844 Check if services need reloading.
1845 ****************************************************************************/
1847 void check_reload(time_t t)
1849 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1851 if(last_smb_conf_reload_time == 0) {
1852 last_smb_conf_reload_time = t;
1853 /* Our printing subsystem might not be ready at smbd start up.
1854 Then no printer is available till the first printers check
1855 is performed. A lower initial interval circumvents this. */
1856 if ( printcap_cache_time > 60 )
1857 last_printer_reload_time = t - printcap_cache_time + 60;
1859 last_printer_reload_time = t;
1862 if (mypid != getpid()) { /* First time or fork happened meanwhile */
1863 /* randomize over 60 second the printcap reload to avoid all
1864 * process hitting cupsd at the same time */
1865 int time_range = 60;
1867 last_printer_reload_time += random() % time_range;
1871 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1872 reload_services(True);
1873 last_smb_conf_reload_time = t;
1876 /* 'printcap cache time = 0' disable the feature */
1878 if ( printcap_cache_time != 0 )
1880 /* see if it's time to reload or if the clock has been set back */
1882 if ( (t >= last_printer_reload_time+printcap_cache_time)
1883 || (t-last_printer_reload_time < 0) )
1885 DEBUG( 3,( "Printcap cache time expired.\n"));
1887 last_printer_reload_time = t;
1892 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1894 /* TODO: make write nonblocking */
1897 static void smbd_server_connection_read_handler(struct smbd_server_connection *conn)
1899 uint8_t *inbuf = NULL;
1900 size_t inbuf_len = 0;
1901 size_t unread_bytes = 0;
1902 bool encrypted = false;
1903 TALLOC_CTX *mem_ctx = talloc_tos();
1907 /* TODO: make this completely nonblocking */
1909 status = receive_smb_talloc(mem_ctx, smbd_server_fd(),
1910 (char **)(void *)&inbuf,
1914 &inbuf_len, &seqnum);
1915 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1918 if (NT_STATUS_IS_ERR(status)) {
1919 exit_server_cleanly("failed to receive smb request");
1921 if (!NT_STATUS_IS_OK(status)) {
1926 process_smb(conn, inbuf, inbuf_len, unread_bytes,
1927 seqnum, encrypted, NULL);
1930 static void smbd_server_connection_handler(struct event_context *ev,
1931 struct fd_event *fde,
1935 struct smbd_server_connection *conn = talloc_get_type(private_data,
1936 struct smbd_server_connection);
1938 if (flags & EVENT_FD_WRITE) {
1939 smbd_server_connection_write_handler(conn);
1940 } else if (flags & EVENT_FD_READ) {
1941 smbd_server_connection_read_handler(conn);
1946 /****************************************************************************
1947 received when we should release a specific IP
1948 ****************************************************************************/
1949 static void release_ip(const char *ip, void *priv)
1951 char addr[INET6_ADDRSTRLEN];
1954 client_socket_addr(get_client_fd(),addr,sizeof(addr));
1956 if (strncmp("::ffff:", addr, 7) == 0) {
1960 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
1961 /* we can't afford to do a clean exit - that involves
1962 database writes, which would potentially mean we
1963 are still running after the failover has finished -
1964 we have to get rid of this process ID straight
1966 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
1968 /* note we must exit with non-zero status so the unclean handler gets
1969 called in the parent, so that the brl database is tickled */
1974 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
1975 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
1977 release_ip((char *)data->data, NULL);
1980 #ifdef CLUSTER_SUPPORT
1981 static int client_get_tcp_info(struct sockaddr_storage *server,
1982 struct sockaddr_storage *client)
1985 if (server_fd == -1) {
1988 length = sizeof(*server);
1989 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
1992 length = sizeof(*client);
1993 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2001 * Send keepalive packets to our client
2003 static bool keepalive_fn(const struct timeval *now, void *private_data)
2005 if (!send_keepalive(smbd_server_fd())) {
2006 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2013 * Do the recurring check if we're idle
2015 static bool deadtime_fn(const struct timeval *now, void *private_data)
2017 struct smbd_server_connection *sconn = smbd_server_conn;
2018 if ((conn_num_open(sconn) == 0)
2019 || (conn_idle_all(sconn, now->tv_sec))) {
2020 DEBUG( 2, ( "Closing idle connection\n" ) );
2021 messaging_send(smbd_messaging_context(), procid_self(),
2022 MSG_SHUTDOWN, &data_blob_null);
2030 * Do the recurring log file and smb.conf reload checks.
2033 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2035 change_to_root_user();
2037 /* update printer queue caches if necessary */
2038 update_monitored_printq_cache();
2040 /* check if we need to reload services */
2041 check_reload(time(NULL));
2043 /* Change machine password if neccessary. */
2044 attempt_machine_password_change();
2047 * Force a log file check.
2049 force_check_log_size();
2054 /****************************************************************************
2055 Process commands from the client
2056 ****************************************************************************/
2058 void smbd_process(void)
2060 TALLOC_CTX *frame = talloc_stackframe();
2061 char remaddr[INET6_ADDRSTRLEN];
2063 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2064 lp_security() != SEC_SHARE) {
2065 smbd_server_conn->allow_smb2 = true;
2068 /* Ensure child is set to blocking mode */
2069 set_blocking(smbd_server_fd(),True);
2071 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2072 set_socket_options(smbd_server_fd(), lp_socket_options());
2074 /* this is needed so that we get decent entries
2075 in smbstatus for port 445 connects */
2076 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2080 reload_services(true);
2083 * Before the first packet, check the global hosts allow/ hosts deny
2084 * parameters before doing any parsing of packets passed to us by the
2085 * client. This prevents attacks on our parsing code from hosts not in
2086 * the hosts allow list.
2089 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2090 lp_hostsdeny(-1))) {
2091 char addr[INET6_ADDRSTRLEN];
2094 * send a negative session response "not listening on calling
2097 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2098 DEBUG( 1, ("Connection denied from %s\n",
2099 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2100 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2102 exit_server_cleanly("connection denied");
2109 smb_perfcount_init();
2111 if (!init_account_policy()) {
2112 exit_server("Could not open account policy tdb.\n");
2115 if (*lp_rootdir()) {
2116 if (chroot(lp_rootdir()) != 0) {
2117 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2118 exit_server("Failed to chroot()");
2120 if (chdir("/") == -1) {
2121 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2122 exit_server("Failed to chroot()");
2124 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2127 if (!srv_init_signing(smbd_server_conn)) {
2128 exit_server("Failed to init smb_signing");
2132 if (!init_oplocks(smbd_messaging_context()))
2133 exit_server("Failed to init oplocks");
2135 /* Setup aio signal handler. */
2136 initialize_async_io_handler();
2138 /* register our message handlers */
2139 messaging_register(smbd_messaging_context(), NULL,
2140 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2141 messaging_register(smbd_messaging_context(), NULL,
2142 MSG_SMB_RELEASE_IP, msg_release_ip);
2143 messaging_register(smbd_messaging_context(), NULL,
2144 MSG_SMB_CLOSE_FILE, msg_close_file);
2147 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2148 * MSGs to all child processes
2150 messaging_deregister(smbd_messaging_context(),
2152 messaging_register(smbd_messaging_context(), NULL,
2153 MSG_DEBUG, debug_message);
2155 if ((lp_keepalive() != 0)
2156 && !(event_add_idle(smbd_event_context(), NULL,
2157 timeval_set(lp_keepalive(), 0),
2158 "keepalive", keepalive_fn,
2160 DEBUG(0, ("Could not add keepalive event\n"));
2164 if (!(event_add_idle(smbd_event_context(), NULL,
2165 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2166 "deadtime", deadtime_fn, NULL))) {
2167 DEBUG(0, ("Could not add deadtime event\n"));
2171 if (!(event_add_idle(smbd_event_context(), NULL,
2172 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2173 "housekeeping", housekeeping_fn, NULL))) {
2174 DEBUG(0, ("Could not add housekeeping event\n"));
2178 #ifdef CLUSTER_SUPPORT
2180 if (lp_clustering()) {
2182 * We need to tell ctdb about our client's TCP
2183 * connection, so that for failover ctdbd can send
2184 * tickle acks, triggering a reconnection by the
2188 struct sockaddr_storage srv, clnt;
2190 if (client_get_tcp_info(&srv, &clnt) == 0) {
2194 status = ctdbd_register_ips(
2195 messaging_ctdbd_connection(),
2196 &srv, &clnt, release_ip, NULL);
2198 if (!NT_STATUS_IS_OK(status)) {
2199 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2200 nt_errstr(status)));
2204 DEBUG(0,("Unable to get tcp info for "
2205 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2212 smbd_server_conn->nbt.got_session = false;
2214 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2216 smbd_server_conn->smb1.sessions.done_sesssetup = false;
2217 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
2218 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
2219 /* users from session setup */
2220 smbd_server_conn->smb1.sessions.session_userlist = NULL;
2221 /* workgroup from session setup. */
2222 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
2223 /* this holds info on user ids that are already validated for this VC */
2224 smbd_server_conn->smb1.sessions.validated_users = NULL;
2225 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
2226 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
2227 #ifdef HAVE_NETGROUP
2228 smbd_server_conn->smb1.sessions.my_yp_domain = NULL;
2231 conn_init(smbd_server_conn);
2232 if (!init_dptrs(smbd_server_conn)) {
2233 exit_server("init_dptrs() failed");
2236 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
2240 smbd_server_connection_handler,
2242 if (!smbd_server_conn->smb1.fde) {
2243 exit_server("failed to create smbd_server_connection fde");
2251 frame = talloc_stackframe_pool(8192);
2255 status = smbd_server_connection_loop_once(smbd_server_conn);
2256 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2257 !NT_STATUS_IS_OK(status)) {
2258 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2259 " exiting\n", nt_errstr(status)));
2266 exit_server_cleanly(NULL);
2269 bool req_is_in_chain(struct smb_request *req)
2271 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2273 * We're right now handling a subsequent request, so we must
2279 if (!is_andx_req(req->cmd)) {
2285 * Okay, an illegal request, but definitely not chained :-)
2290 return (CVAL(req->vwv+0, 0) != 0xFF);