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_socket_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_socket_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->chain_fsp = NULL;
383 req->chain_outbuf = NULL;
384 smb_init_perfcount_data(&req->pcd);
386 /* Ensure we have at least wct words and 2 bytes of bcc. */
387 if (smb_size + req->wct*2 > req_size) {
388 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
389 (unsigned int)req->wct,
390 (unsigned int)req_size));
391 exit_server_cleanly("Invalid SMB request");
393 /* Ensure bcc is correct. */
394 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
395 DEBUG(0,("init_smb_request: invalid bcc number %u "
396 "(wct = %u, size %u)\n",
397 (unsigned int)req->buflen,
398 (unsigned int)req->wct,
399 (unsigned int)req_size));
400 exit_server_cleanly("Invalid SMB request");
406 static void process_smb(struct smbd_server_connection *conn,
407 uint8_t *inbuf, size_t nread, size_t unread_bytes,
408 uint32_t seqnum, bool encrypted,
409 struct smb_perfcount_data *deferred_pcd);
411 static void smbd_deferred_open_timer(struct event_context *ev,
412 struct timed_event *te,
413 struct timeval _tval,
416 struct pending_message_list *msg = talloc_get_type(private_data,
417 struct pending_message_list);
418 TALLOC_CTX *mem_ctx = talloc_tos();
421 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
424 exit_server("smbd_deferred_open_timer: talloc failed\n");
428 /* We leave this message on the queue so the open code can
429 know this is a retry. */
430 DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
431 (unsigned int)SVAL(msg->buf.data,smb_mid)));
433 process_smb(smbd_server_conn, inbuf,
435 msg->seqnum, msg->encrypted, &msg->pcd);
438 /****************************************************************************
439 Function to push a message onto the tail of a linked list of smb messages ready
441 ****************************************************************************/
443 static bool push_queued_message(struct smb_request *req,
444 struct timeval request_time,
445 struct timeval end_time,
446 char *private_data, size_t private_len)
448 int msg_len = smb_len(req->inbuf) + 4;
449 struct pending_message_list *msg;
451 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
454 DEBUG(0,("push_message: malloc fail (1)\n"));
458 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
459 if(msg->buf.data == NULL) {
460 DEBUG(0,("push_message: malloc fail (2)\n"));
465 msg->request_time = request_time;
466 msg->seqnum = req->seqnum;
467 msg->encrypted = req->encrypted;
468 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
471 msg->private_data = data_blob_talloc(msg, private_data,
473 if (msg->private_data.data == NULL) {
474 DEBUG(0,("push_message: malloc fail (3)\n"));
480 msg->te = event_add_timed(smbd_event_context(),
483 smbd_deferred_open_timer,
486 DEBUG(0,("push_message: event_add_timed failed\n"));
491 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
493 DEBUG(10,("push_message: pushed message length %u on "
494 "deferred_open_queue\n", (unsigned int)msg_len));
499 /****************************************************************************
500 Function to delete a sharing violation open message by mid.
501 ****************************************************************************/
503 void remove_deferred_open_smb_message(uint16 mid)
505 struct pending_message_list *pml;
507 for (pml = deferred_open_queue; pml; pml = pml->next) {
508 if (mid == SVAL(pml->buf.data,smb_mid)) {
509 DEBUG(10,("remove_sharing_violation_open_smb_message: "
510 "deleting mid %u len %u\n",
512 (unsigned int)pml->buf.length ));
513 DLIST_REMOVE(deferred_open_queue, pml);
520 /****************************************************************************
521 Move a sharing violation open retry message to the front of the list and
522 schedule it for immediate processing.
523 ****************************************************************************/
525 void schedule_deferred_open_smb_message(uint16 mid)
527 struct pending_message_list *pml;
530 for (pml = deferred_open_queue; pml; pml = pml->next) {
531 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
533 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
534 (unsigned int)msg_mid ));
536 if (mid == msg_mid) {
537 struct timed_event *te;
539 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
542 te = event_add_timed(smbd_event_context(),
545 smbd_deferred_open_timer,
548 DEBUG(10,("schedule_deferred_open_smb_message: "
549 "event_add_timed() failed, skipping mid %u\n",
553 TALLOC_FREE(pml->te);
555 DLIST_PROMOTE(deferred_open_queue, pml);
560 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
564 /****************************************************************************
565 Return true if this mid is on the deferred queue.
566 ****************************************************************************/
568 bool open_was_deferred(uint16 mid)
570 struct pending_message_list *pml;
572 for (pml = deferred_open_queue; pml; pml = pml->next) {
573 if (SVAL(pml->buf.data,smb_mid) == mid) {
580 /****************************************************************************
581 Return the message queued by this mid.
582 ****************************************************************************/
584 struct pending_message_list *get_open_deferred_message(uint16 mid)
586 struct pending_message_list *pml;
588 for (pml = deferred_open_queue; pml; pml = pml->next) {
589 if (SVAL(pml->buf.data,smb_mid) == mid) {
596 /****************************************************************************
597 Function to push a deferred open smb message onto a linked list of local smb
598 messages ready for processing.
599 ****************************************************************************/
601 bool push_deferred_smb_message(struct smb_request *req,
602 struct timeval request_time,
603 struct timeval timeout,
604 char *private_data, size_t priv_len)
606 struct timeval end_time;
608 if (req->unread_bytes) {
609 DEBUG(0,("push_deferred_smb_message: logic error ! "
610 "unread_bytes = %u\n",
611 (unsigned int)req->unread_bytes ));
612 smb_panic("push_deferred_smb_message: "
613 "logic error unread_bytes != 0" );
616 end_time = timeval_sum(&request_time, &timeout);
618 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
619 "timeout time [%u.%06u]\n",
620 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
621 (unsigned int)end_time.tv_sec,
622 (unsigned int)end_time.tv_usec));
624 return push_queued_message(req, request_time, end_time,
625 private_data, priv_len);
629 struct timed_event *te;
630 struct timeval interval;
632 bool (*handler)(const struct timeval *now, void *private_data);
636 static void smbd_idle_event_handler(struct event_context *ctx,
637 struct timed_event *te,
641 struct idle_event *event =
642 talloc_get_type_abort(private_data, struct idle_event);
644 TALLOC_FREE(event->te);
646 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
647 event->name, event->te));
649 if (!event->handler(&now, event->private_data)) {
650 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
651 event->name, event->te));
652 /* Don't repeat, delete ourselves */
657 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
658 event->name, event->te));
660 event->te = event_add_timed(ctx, event,
661 timeval_sum(&now, &event->interval),
662 smbd_idle_event_handler, event);
664 /* We can't do much but fail here. */
665 SMB_ASSERT(event->te != NULL);
668 struct idle_event *event_add_idle(struct event_context *event_ctx,
670 struct timeval interval,
672 bool (*handler)(const struct timeval *now,
676 struct idle_event *result;
677 struct timeval now = timeval_current();
679 result = TALLOC_P(mem_ctx, struct idle_event);
680 if (result == NULL) {
681 DEBUG(0, ("talloc failed\n"));
685 result->interval = interval;
686 result->handler = handler;
687 result->private_data = private_data;
689 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
690 DEBUG(0, ("talloc failed\n"));
695 result->te = event_add_timed(event_ctx, result,
696 timeval_sum(&now, &interval),
697 smbd_idle_event_handler, result);
698 if (result->te == NULL) {
699 DEBUG(0, ("event_add_timed failed\n"));
704 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
708 static void smbd_sig_term_handler(struct tevent_context *ev,
709 struct tevent_signal *se,
715 exit_server_cleanly("termination signal");
718 void smbd_setup_sig_term_handler(void)
720 struct tevent_signal *se;
722 se = tevent_add_signal(smbd_event_context(),
723 smbd_event_context(),
725 smbd_sig_term_handler,
728 exit_server("failed to setup SIGTERM handler");
732 static void smbd_sig_hup_handler(struct tevent_context *ev,
733 struct tevent_signal *se,
739 change_to_root_user();
740 DEBUG(1,("Reloading services after SIGHUP\n"));
741 reload_services(False);
744 void smbd_setup_sig_hup_handler(void)
746 struct tevent_signal *se;
748 se = tevent_add_signal(smbd_event_context(),
749 smbd_event_context(),
751 smbd_sig_hup_handler,
754 exit_server("failed to setup SIGHUP handler");
758 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
765 to.tv_sec = SMBD_SELECT_TIMEOUT;
769 * Setup the select fd sets.
776 * Are there any timed events waiting ? If so, ensure we don't
777 * select for longer than it would take to wait for them.
784 event_add_to_select_args(smbd_event_context(), &now,
785 &r_fds, &w_fds, &to, &maxfd);
788 /* Process a signal and timed events now... */
789 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
790 return NT_STATUS_RETRY;
795 START_PROFILE(smbd_idle);
797 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
800 END_PROFILE(smbd_idle);
804 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
805 return NT_STATUS_RETRY;
810 /* something is wrong. Maybe the socket is dead? */
811 return map_nt_error_from_unix(errno);
814 /* Did we timeout ? */
816 return NT_STATUS_RETRY;
819 /* should not be reached */
820 return NT_STATUS_INTERNAL_ERROR;
824 * Only allow 5 outstanding trans requests. We're allocating memory, so
828 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
831 for (; list != NULL; list = list->next) {
833 if (list->mid == mid) {
834 return NT_STATUS_INVALID_PARAMETER;
840 return NT_STATUS_INSUFFICIENT_RESOURCES;
847 These flags determine some of the permissions required to do an operation
849 Note that I don't set NEED_WRITE on some write operations because they
850 are used by some brain-dead clients when printing, and I don't want to
851 force write permissions on print services.
853 #define AS_USER (1<<0)
854 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
855 #define TIME_INIT (1<<2)
856 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
857 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
858 #define DO_CHDIR (1<<6)
861 define a list of possible SMB messages and their corresponding
862 functions. Any message that has a NULL function is unimplemented -
863 please feel free to contribute implementations!
865 static const struct smb_message_struct {
867 void (*fn)(struct smb_request *req);
869 } smb_messages[256] = {
871 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
872 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
873 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
874 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
875 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
876 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
877 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
878 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
879 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
880 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
881 /* 0x0a */ { "SMBread",reply_read,AS_USER},
882 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
883 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
884 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
885 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
886 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
887 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
888 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
889 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
890 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
891 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
892 /* 0x15 */ { NULL, NULL, 0 },
893 /* 0x16 */ { NULL, NULL, 0 },
894 /* 0x17 */ { NULL, NULL, 0 },
895 /* 0x18 */ { NULL, NULL, 0 },
896 /* 0x19 */ { NULL, NULL, 0 },
897 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
898 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
899 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
900 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
901 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
902 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
903 /* 0x20 */ { "SMBwritec", NULL,0},
904 /* 0x21 */ { NULL, NULL, 0 },
905 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
906 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
907 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
908 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
909 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
910 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
911 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
912 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
913 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
914 /* 0x2b */ { "SMBecho",reply_echo,0},
915 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
916 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
917 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
918 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
919 /* 0x30 */ { NULL, NULL, 0 },
920 /* 0x31 */ { NULL, NULL, 0 },
921 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
922 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
923 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
924 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
925 /* 0x36 */ { NULL, NULL, 0 },
926 /* 0x37 */ { NULL, NULL, 0 },
927 /* 0x38 */ { NULL, NULL, 0 },
928 /* 0x39 */ { NULL, NULL, 0 },
929 /* 0x3a */ { NULL, NULL, 0 },
930 /* 0x3b */ { NULL, NULL, 0 },
931 /* 0x3c */ { NULL, NULL, 0 },
932 /* 0x3d */ { NULL, NULL, 0 },
933 /* 0x3e */ { NULL, NULL, 0 },
934 /* 0x3f */ { NULL, NULL, 0 },
935 /* 0x40 */ { NULL, NULL, 0 },
936 /* 0x41 */ { NULL, NULL, 0 },
937 /* 0x42 */ { NULL, NULL, 0 },
938 /* 0x43 */ { NULL, NULL, 0 },
939 /* 0x44 */ { NULL, NULL, 0 },
940 /* 0x45 */ { NULL, NULL, 0 },
941 /* 0x46 */ { NULL, NULL, 0 },
942 /* 0x47 */ { NULL, NULL, 0 },
943 /* 0x48 */ { NULL, NULL, 0 },
944 /* 0x49 */ { NULL, NULL, 0 },
945 /* 0x4a */ { NULL, NULL, 0 },
946 /* 0x4b */ { NULL, NULL, 0 },
947 /* 0x4c */ { NULL, NULL, 0 },
948 /* 0x4d */ { NULL, NULL, 0 },
949 /* 0x4e */ { NULL, NULL, 0 },
950 /* 0x4f */ { NULL, NULL, 0 },
951 /* 0x50 */ { NULL, NULL, 0 },
952 /* 0x51 */ { NULL, NULL, 0 },
953 /* 0x52 */ { NULL, NULL, 0 },
954 /* 0x53 */ { NULL, NULL, 0 },
955 /* 0x54 */ { NULL, NULL, 0 },
956 /* 0x55 */ { NULL, NULL, 0 },
957 /* 0x56 */ { NULL, NULL, 0 },
958 /* 0x57 */ { NULL, NULL, 0 },
959 /* 0x58 */ { NULL, NULL, 0 },
960 /* 0x59 */ { NULL, NULL, 0 },
961 /* 0x5a */ { NULL, NULL, 0 },
962 /* 0x5b */ { NULL, NULL, 0 },
963 /* 0x5c */ { NULL, NULL, 0 },
964 /* 0x5d */ { NULL, NULL, 0 },
965 /* 0x5e */ { NULL, NULL, 0 },
966 /* 0x5f */ { NULL, NULL, 0 },
967 /* 0x60 */ { NULL, NULL, 0 },
968 /* 0x61 */ { NULL, NULL, 0 },
969 /* 0x62 */ { NULL, NULL, 0 },
970 /* 0x63 */ { NULL, NULL, 0 },
971 /* 0x64 */ { NULL, NULL, 0 },
972 /* 0x65 */ { NULL, NULL, 0 },
973 /* 0x66 */ { NULL, NULL, 0 },
974 /* 0x67 */ { NULL, NULL, 0 },
975 /* 0x68 */ { NULL, NULL, 0 },
976 /* 0x69 */ { NULL, NULL, 0 },
977 /* 0x6a */ { NULL, NULL, 0 },
978 /* 0x6b */ { NULL, NULL, 0 },
979 /* 0x6c */ { NULL, NULL, 0 },
980 /* 0x6d */ { NULL, NULL, 0 },
981 /* 0x6e */ { NULL, NULL, 0 },
982 /* 0x6f */ { NULL, NULL, 0 },
983 /* 0x70 */ { "SMBtcon",reply_tcon,0},
984 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
985 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
986 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
987 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
988 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
989 /* 0x76 */ { NULL, NULL, 0 },
990 /* 0x77 */ { NULL, NULL, 0 },
991 /* 0x78 */ { NULL, NULL, 0 },
992 /* 0x79 */ { NULL, NULL, 0 },
993 /* 0x7a */ { NULL, NULL, 0 },
994 /* 0x7b */ { NULL, NULL, 0 },
995 /* 0x7c */ { NULL, NULL, 0 },
996 /* 0x7d */ { NULL, NULL, 0 },
997 /* 0x7e */ { NULL, NULL, 0 },
998 /* 0x7f */ { NULL, NULL, 0 },
999 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1000 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1001 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1002 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1003 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1004 /* 0x85 */ { NULL, NULL, 0 },
1005 /* 0x86 */ { NULL, NULL, 0 },
1006 /* 0x87 */ { NULL, NULL, 0 },
1007 /* 0x88 */ { NULL, NULL, 0 },
1008 /* 0x89 */ { NULL, NULL, 0 },
1009 /* 0x8a */ { NULL, NULL, 0 },
1010 /* 0x8b */ { NULL, NULL, 0 },
1011 /* 0x8c */ { NULL, NULL, 0 },
1012 /* 0x8d */ { NULL, NULL, 0 },
1013 /* 0x8e */ { NULL, NULL, 0 },
1014 /* 0x8f */ { NULL, NULL, 0 },
1015 /* 0x90 */ { NULL, NULL, 0 },
1016 /* 0x91 */ { NULL, NULL, 0 },
1017 /* 0x92 */ { NULL, NULL, 0 },
1018 /* 0x93 */ { NULL, NULL, 0 },
1019 /* 0x94 */ { NULL, NULL, 0 },
1020 /* 0x95 */ { NULL, NULL, 0 },
1021 /* 0x96 */ { NULL, NULL, 0 },
1022 /* 0x97 */ { NULL, NULL, 0 },
1023 /* 0x98 */ { NULL, NULL, 0 },
1024 /* 0x99 */ { NULL, NULL, 0 },
1025 /* 0x9a */ { NULL, NULL, 0 },
1026 /* 0x9b */ { NULL, NULL, 0 },
1027 /* 0x9c */ { NULL, NULL, 0 },
1028 /* 0x9d */ { NULL, NULL, 0 },
1029 /* 0x9e */ { NULL, NULL, 0 },
1030 /* 0x9f */ { NULL, NULL, 0 },
1031 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1032 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1033 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1034 /* 0xa3 */ { NULL, NULL, 0 },
1035 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1036 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1037 /* 0xa6 */ { NULL, NULL, 0 },
1038 /* 0xa7 */ { NULL, NULL, 0 },
1039 /* 0xa8 */ { NULL, NULL, 0 },
1040 /* 0xa9 */ { NULL, NULL, 0 },
1041 /* 0xaa */ { NULL, NULL, 0 },
1042 /* 0xab */ { NULL, NULL, 0 },
1043 /* 0xac */ { NULL, NULL, 0 },
1044 /* 0xad */ { NULL, NULL, 0 },
1045 /* 0xae */ { NULL, NULL, 0 },
1046 /* 0xaf */ { NULL, NULL, 0 },
1047 /* 0xb0 */ { NULL, NULL, 0 },
1048 /* 0xb1 */ { NULL, NULL, 0 },
1049 /* 0xb2 */ { NULL, NULL, 0 },
1050 /* 0xb3 */ { NULL, NULL, 0 },
1051 /* 0xb4 */ { NULL, NULL, 0 },
1052 /* 0xb5 */ { NULL, NULL, 0 },
1053 /* 0xb6 */ { NULL, NULL, 0 },
1054 /* 0xb7 */ { NULL, NULL, 0 },
1055 /* 0xb8 */ { NULL, NULL, 0 },
1056 /* 0xb9 */ { NULL, NULL, 0 },
1057 /* 0xba */ { NULL, NULL, 0 },
1058 /* 0xbb */ { NULL, NULL, 0 },
1059 /* 0xbc */ { NULL, NULL, 0 },
1060 /* 0xbd */ { NULL, NULL, 0 },
1061 /* 0xbe */ { NULL, NULL, 0 },
1062 /* 0xbf */ { NULL, NULL, 0 },
1063 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1064 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1065 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1066 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1067 /* 0xc4 */ { NULL, NULL, 0 },
1068 /* 0xc5 */ { NULL, NULL, 0 },
1069 /* 0xc6 */ { NULL, NULL, 0 },
1070 /* 0xc7 */ { NULL, NULL, 0 },
1071 /* 0xc8 */ { NULL, NULL, 0 },
1072 /* 0xc9 */ { NULL, NULL, 0 },
1073 /* 0xca */ { NULL, NULL, 0 },
1074 /* 0xcb */ { NULL, NULL, 0 },
1075 /* 0xcc */ { NULL, NULL, 0 },
1076 /* 0xcd */ { NULL, NULL, 0 },
1077 /* 0xce */ { NULL, NULL, 0 },
1078 /* 0xcf */ { NULL, NULL, 0 },
1079 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1080 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1081 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1082 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1083 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1084 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1085 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1086 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1087 /* 0xd8 */ { NULL, NULL, 0 },
1088 /* 0xd9 */ { NULL, NULL, 0 },
1089 /* 0xda */ { NULL, NULL, 0 },
1090 /* 0xdb */ { NULL, NULL, 0 },
1091 /* 0xdc */ { NULL, NULL, 0 },
1092 /* 0xdd */ { NULL, NULL, 0 },
1093 /* 0xde */ { NULL, NULL, 0 },
1094 /* 0xdf */ { NULL, NULL, 0 },
1095 /* 0xe0 */ { NULL, NULL, 0 },
1096 /* 0xe1 */ { NULL, NULL, 0 },
1097 /* 0xe2 */ { NULL, NULL, 0 },
1098 /* 0xe3 */ { NULL, NULL, 0 },
1099 /* 0xe4 */ { NULL, NULL, 0 },
1100 /* 0xe5 */ { NULL, NULL, 0 },
1101 /* 0xe6 */ { NULL, NULL, 0 },
1102 /* 0xe7 */ { NULL, NULL, 0 },
1103 /* 0xe8 */ { NULL, NULL, 0 },
1104 /* 0xe9 */ { NULL, NULL, 0 },
1105 /* 0xea */ { NULL, NULL, 0 },
1106 /* 0xeb */ { NULL, NULL, 0 },
1107 /* 0xec */ { NULL, NULL, 0 },
1108 /* 0xed */ { NULL, NULL, 0 },
1109 /* 0xee */ { NULL, NULL, 0 },
1110 /* 0xef */ { NULL, NULL, 0 },
1111 /* 0xf0 */ { NULL, NULL, 0 },
1112 /* 0xf1 */ { NULL, NULL, 0 },
1113 /* 0xf2 */ { NULL, NULL, 0 },
1114 /* 0xf3 */ { NULL, NULL, 0 },
1115 /* 0xf4 */ { NULL, NULL, 0 },
1116 /* 0xf5 */ { NULL, NULL, 0 },
1117 /* 0xf6 */ { NULL, NULL, 0 },
1118 /* 0xf7 */ { NULL, NULL, 0 },
1119 /* 0xf8 */ { NULL, NULL, 0 },
1120 /* 0xf9 */ { NULL, NULL, 0 },
1121 /* 0xfa */ { NULL, NULL, 0 },
1122 /* 0xfb */ { NULL, NULL, 0 },
1123 /* 0xfc */ { NULL, NULL, 0 },
1124 /* 0xfd */ { NULL, NULL, 0 },
1125 /* 0xfe */ { NULL, NULL, 0 },
1126 /* 0xff */ { NULL, NULL, 0 }
1130 /*******************************************************************
1131 allocate and initialize a reply packet
1132 ********************************************************************/
1134 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1135 const char *inbuf, char **outbuf, uint8_t num_words,
1139 * Protect against integer wrap
1141 if ((num_bytes > 0xffffff)
1142 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1144 if (asprintf(&msg, "num_bytes too large: %u",
1145 (unsigned)num_bytes) == -1) {
1146 msg = CONST_DISCARD(char *, "num_bytes too large");
1151 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1152 smb_size + num_words*2 + num_bytes);
1153 if (*outbuf == NULL) {
1157 construct_reply_common(req, inbuf, *outbuf);
1158 srv_set_message(*outbuf, num_words, num_bytes, false);
1160 * Zero out the word area, the caller has to take care of the bcc area
1163 if (num_words != 0) {
1164 memset(*outbuf + smb_vwv0, 0, num_words*2);
1170 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1173 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1175 smb_panic("could not allocate output buffer\n");
1177 req->outbuf = (uint8_t *)outbuf;
1181 /*******************************************************************
1182 Dump a packet to a file.
1183 ********************************************************************/
1185 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1189 if (DEBUGLEVEL < 50) {
1193 if (len < 4) len = smb_len(data)+4;
1194 for (i=1;i<100;i++) {
1195 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1196 type ? "req" : "resp") == -1) {
1199 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1200 if (fd != -1 || errno != EEXIST) break;
1203 ssize_t ret = write(fd, data, len);
1205 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1207 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1212 /****************************************************************************
1213 Prepare everything for calling the actual request function, and potentially
1214 call the request function via the "new" interface.
1216 Return False if the "legacy" function needs to be called, everything is
1219 Return True if we're done.
1221 I know this API sucks, but it is the one with the least code change I could
1223 ****************************************************************************/
1225 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1229 connection_struct *conn = NULL;
1230 struct smbd_server_connection *sconn = smbd_server_conn;
1234 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1235 * so subtract 4 from it. */
1236 if (!valid_smb_header(req->inbuf)
1237 || (size < (smb_size - 4))) {
1238 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1239 smb_len(req->inbuf)));
1240 exit_server_cleanly("Non-SMB packet");
1243 if (smb_messages[type].fn == NULL) {
1244 DEBUG(0,("Unknown message type %d!\n",type));
1245 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1246 reply_unknown_new(req, type);
1250 flags = smb_messages[type].flags;
1252 /* In share mode security we must ignore the vuid. */
1253 session_tag = (lp_security() == SEC_SHARE)
1254 ? UID_FIELD_INVALID : req->vuid;
1257 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1258 (int)sys_getpid(), (unsigned long)conn));
1260 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1262 /* Ensure this value is replaced in the incoming packet. */
1263 SSVAL(req->inbuf,smb_uid,session_tag);
1266 * Ensure the correct username is in current_user_info. This is a
1267 * really ugly bugfix for problems with multiple session_setup_and_X's
1268 * being done and allowing %U and %G substitutions to work correctly.
1269 * There is a reason this code is done here, don't move it unless you
1270 * know what you're doing... :-).
1274 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1275 user_struct *vuser = NULL;
1277 sconn->smb1.sessions.last_session_tag = session_tag;
1278 if(session_tag != UID_FIELD_INVALID) {
1279 vuser = get_valid_user_struct(sconn, session_tag);
1281 set_current_user_info(
1282 vuser->server_info->sanitized_username,
1283 vuser->server_info->unix_name,
1284 pdb_get_domain(vuser->server_info
1289 /* Does this call need to be run as the connected user? */
1290 if (flags & AS_USER) {
1292 /* Does this call need a valid tree connection? */
1295 * Amazingly, the error code depends on the command
1298 if (type == SMBntcreateX) {
1299 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1301 reply_doserror(req, ERRSRV, ERRinvnid);
1306 if (conn->force_recheck_perm) {
1309 const char *service = NULL;
1310 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1311 conn->force_recheck_perm = false;
1312 DEBUG(5, ("switch_message: rechecking permission for connection %x\n",
1313 (unsigned int)conn));
1315 service = lp_servicename(old);
1316 conn->read_only = False;
1317 if (lp_snum_ok(old) && am_usershare(old)) {
1318 iService = load_usershare_service(service);
1319 if (iService < 0 || old != iService) {
1320 /* non-exist service */
1321 DEBUG(5, ("switch_message: deleting connection %x\n",
1322 (unsigned int)conn));
1323 DEBUG(5, ("snum %d, sname %s\n",
1324 old, service ? service : "NULL"));
1325 delete_share_security(service);
1326 set_current_service(NULL, 0, True);
1327 close_cnum(smbd_server_conn, conn, conn->vuid);
1328 lp_killservice(old);
1329 reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME);
1334 * Don't have to reauthentication here, but
1335 * need to check share permissions.....
1336 * the vuid cache is a problem..
1339 if (!change_to_root_user()) {
1340 smb_panic("cann't change to root user!\n");
1343 if (!change_to_user_force_recheck(conn, session_tag,
1345 reply_nterror(req, status);
1346 remove_deferred_open_smb_message(req->mid);
1351 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1352 if (!change_to_user_force_recheck(conn, session_tag,
1354 reply_nterror(req, status);
1355 remove_deferred_open_smb_message(req->mid);
1360 if (!change_to_user(conn,session_tag)) {
1361 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1362 remove_deferred_open_smb_message(req->mid);
1367 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1369 /* Does it need write permission? */
1370 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1371 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1375 /* IPC services are limited */
1376 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1377 reply_doserror(req, ERRSRV,ERRaccess);
1381 /* This call needs to be run as root */
1382 change_to_root_user();
1385 /* load service specific parameters */
1387 if (req->encrypted) {
1388 conn->encrypted_tid = true;
1389 /* encrypted required from now on. */
1390 conn->encrypt_level = Required;
1391 } else if (ENCRYPTION_REQUIRED(conn)) {
1392 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1393 exit_server_cleanly("encryption required "
1399 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1400 (flags & (AS_USER|DO_CHDIR)
1402 reply_doserror(req, ERRSRV, ERRaccess);
1405 conn->num_smb_operations++;
1408 /* does this protocol need to be run as guest? */
1409 if ((flags & AS_GUEST)
1410 && (!change_to_guest() ||
1411 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1412 lp_hostsdeny(-1)))) {
1413 reply_doserror(req, ERRSRV, ERRaccess);
1417 smb_messages[type].fn(req);
1421 /****************************************************************************
1422 Construct a reply to the incoming packet.
1423 ****************************************************************************/
1425 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1426 uint32_t seqnum, bool encrypted,
1427 struct smb_perfcount_data *deferred_pcd)
1429 connection_struct *conn;
1430 struct smb_request *req;
1432 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1433 smb_panic("could not allocate smb_request");
1436 init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1437 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1438 req->seqnum = seqnum;
1440 /* we popped this message off the queue - keep original perf data */
1442 req->pcd = *deferred_pcd;
1444 SMB_PERFCOUNT_START(&req->pcd);
1445 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1446 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1449 conn = switch_message(req->cmd, req, size);
1451 if (req->unread_bytes) {
1452 /* writeX failed. drain socket. */
1453 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1454 req->unread_bytes) {
1455 smb_panic("failed to drain pending bytes");
1457 req->unread_bytes = 0;
1460 if (req->outbuf == NULL) {
1464 if (CVAL(req->outbuf,0) == 0) {
1465 show_msg((char *)req->outbuf);
1468 if (!srv_send_smb(smbd_server_fd(),
1469 (char *)req->outbuf,
1470 true, req->seqnum+1,
1471 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1473 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1481 /****************************************************************************
1482 Process an smb from the client
1483 ****************************************************************************/
1484 static void process_smb(struct smbd_server_connection *conn,
1485 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1486 uint32_t seqnum, bool encrypted,
1487 struct smb_perfcount_data *deferred_pcd)
1489 int msg_type = CVAL(inbuf,0);
1491 DO_PROFILE_INC(smb_count);
1493 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1495 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1497 (unsigned int)unread_bytes ));
1499 if (msg_type != 0) {
1501 * NetBIOS session request, keepalive, etc.
1503 reply_special((char *)inbuf);
1507 if (smbd_server_conn->allow_smb2) {
1508 if (smbd_is_smb2_header(inbuf, nread)) {
1509 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1512 smbd_server_conn->allow_smb2 = false;
1515 show_msg((char *)inbuf);
1517 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1521 conn->smb1.num_requests++;
1523 /* The timeout_processing function isn't run nearly
1524 often enough to implement 'max log size' without
1525 overrunning the size of the file by many megabytes.
1526 This is especially true if we are running at debug
1527 level 10. Checking every 50 SMBs is a nice
1528 tradeoff of performance vs log file size overrun. */
1530 if ((conn->smb1.num_requests % 50) == 0 &&
1531 need_to_check_log_size()) {
1532 change_to_root_user();
1537 /****************************************************************************
1538 Return a string containing the function name of a SMB command.
1539 ****************************************************************************/
1541 const char *smb_fn_name(int type)
1543 const char *unknown_name = "SMBunknown";
1545 if (smb_messages[type].name == NULL)
1546 return(unknown_name);
1548 return(smb_messages[type].name);
1551 /****************************************************************************
1552 Helper functions for contruct_reply.
1553 ****************************************************************************/
1555 void add_to_common_flags2(uint32 v)
1560 void remove_from_common_flags2(uint32 v)
1562 common_flags2 &= ~v;
1565 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1568 srv_set_message(outbuf,0,0,false);
1570 SCVAL(outbuf, smb_com, req->cmd);
1571 SIVAL(outbuf,smb_rcls,0);
1572 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1573 SSVAL(outbuf,smb_flg2,
1574 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1576 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1578 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1579 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1580 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1581 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1584 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1586 construct_reply_common(req, (char *)req->inbuf, outbuf);
1590 * How many bytes have we already accumulated up to the current wct field
1594 size_t req_wct_ofs(struct smb_request *req)
1598 if (req->chain_outbuf == NULL) {
1601 buf_size = talloc_get_size(req->chain_outbuf);
1602 if ((buf_size % 4) != 0) {
1603 buf_size += (4 - (buf_size % 4));
1605 return buf_size - 4;
1609 * Hack around reply_nterror & friends not being aware of chained requests,
1610 * generating illegal (i.e. wct==0) chain replies.
1613 static void fixup_chain_error_packet(struct smb_request *req)
1615 uint8_t *outbuf = req->outbuf;
1617 reply_outbuf(req, 2, 0);
1618 memcpy(req->outbuf, outbuf, smb_wct);
1619 TALLOC_FREE(outbuf);
1620 SCVAL(req->outbuf, smb_vwv0, 0xff);
1623 /****************************************************************************
1624 Construct a chained reply and add it to the already made reply
1625 ****************************************************************************/
1627 void chain_reply(struct smb_request *req)
1629 size_t smblen = smb_len(req->inbuf);
1630 size_t already_used, length_needed;
1632 uint32_t chain_offset; /* uint32_t to avoid overflow */
1639 if (IVAL(req->outbuf, smb_rcls) != 0) {
1640 fixup_chain_error_packet(req);
1644 * Any of the AndX requests and replies have at least a wct of
1645 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1646 * beginning of the SMB header to the next wct field.
1648 * None of the AndX requests put anything valuable in vwv[0] and [1],
1649 * so we can overwrite it here to form the chain.
1652 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1657 * Here we assume that this is the end of the chain. For that we need
1658 * to set "next command" to 0xff and the offset to 0. If we later find
1659 * more commands in the chain, this will be overwritten again.
1662 SCVAL(req->outbuf, smb_vwv0, 0xff);
1663 SCVAL(req->outbuf, smb_vwv0+1, 0);
1664 SSVAL(req->outbuf, smb_vwv1, 0);
1666 if (req->chain_outbuf == NULL) {
1668 * In req->chain_outbuf we collect all the replies. Start the
1669 * chain by copying in the first reply.
1671 * We do the realloc because later on we depend on
1672 * talloc_get_size to determine the length of
1673 * chain_outbuf. The reply_xxx routines might have
1674 * over-allocated (reply_pipe_read_and_X used to be such an
1677 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1678 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1679 if (req->chain_outbuf == NULL) {
1685 * Update smb headers where subsequent chained commands
1686 * may have updated them.
1688 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1689 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1691 if (!smb_splice_chain(&req->chain_outbuf,
1692 CVAL(req->outbuf, smb_com),
1693 CVAL(req->outbuf, smb_wct),
1694 (uint16_t *)(req->outbuf + smb_vwv),
1695 0, smb_buflen(req->outbuf),
1696 (uint8_t *)smb_buf(req->outbuf))) {
1699 TALLOC_FREE(req->outbuf);
1703 * We use the old request's vwv field to grab the next chained command
1704 * and offset into the chained fields.
1707 chain_cmd = CVAL(req->vwv+0, 0);
1708 chain_offset = SVAL(req->vwv+1, 0);
1710 if (chain_cmd == 0xff) {
1712 * End of chain, no more requests from the client. So ship the
1715 smb_setlen((char *)(req->chain_outbuf),
1716 talloc_get_size(req->chain_outbuf) - 4);
1718 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1719 true, req->seqnum+1,
1720 IS_CONN_ENCRYPTED(req->conn)
1723 exit_server_cleanly("chain_reply: srv_send_smb "
1731 /* add a new perfcounter for this element of chain */
1732 SMB_PERFCOUNT_ADD(&req->pcd);
1733 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1734 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1737 * Check if the client tries to fool us. The request so far uses the
1738 * space to the end of the byte buffer in the request just
1739 * processed. The chain_offset can't point into that area. If that was
1740 * the case, we could end up with an endless processing of the chain,
1741 * we would always handle the same request.
1744 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1745 if (chain_offset < already_used) {
1750 * Next check: Make sure the chain offset does not point beyond the
1751 * overall smb request length.
1754 length_needed = chain_offset+1; /* wct */
1755 if (length_needed > smblen) {
1760 * Now comes the pointer magic. Goal here is to set up req->vwv and
1761 * req->buf correctly again to be able to call the subsequent
1762 * switch_message(). The chain offset (the former vwv[1]) points at
1763 * the new wct field.
1766 wct = CVAL(smb_base(req->inbuf), chain_offset);
1769 * Next consistency check: Make the new vwv array fits in the overall
1773 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1774 if (length_needed > smblen) {
1777 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1780 * Now grab the new byte buffer....
1783 buflen = SVAL(vwv+wct, 0);
1786 * .. and check that it fits.
1789 length_needed += buflen;
1790 if (length_needed > smblen) {
1793 buf = (uint8_t *)(vwv+wct+1);
1795 req->cmd = chain_cmd;
1798 req->buflen = buflen;
1801 switch_message(chain_cmd, req, smblen);
1803 if (req->outbuf == NULL) {
1805 * This happens if the chained command has suspended itself or
1806 * if it has called srv_send_smb() itself.
1812 * We end up here if the chained command was not itself chained or
1813 * suspended, but for example a close() command. We now need to splice
1814 * the chained commands' outbuf into the already built up chain_outbuf
1815 * and ship the result.
1821 * We end up here if there's any error in the chain syntax. Report a
1822 * DOS error, just like Windows does.
1824 reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1825 fixup_chain_error_packet(req);
1828 if (!smb_splice_chain(&req->chain_outbuf,
1829 CVAL(req->outbuf, smb_com),
1830 CVAL(req->outbuf, smb_wct),
1831 (uint16_t *)(req->outbuf + smb_vwv),
1832 0, smb_buflen(req->outbuf),
1833 (uint8_t *)smb_buf(req->outbuf))) {
1834 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1836 TALLOC_FREE(req->outbuf);
1838 smb_setlen((char *)(req->chain_outbuf),
1839 talloc_get_size(req->chain_outbuf) - 4);
1841 show_msg((char *)(req->chain_outbuf));
1843 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1844 true, req->seqnum+1,
1845 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1847 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1852 /****************************************************************************
1853 Check if services need reloading.
1854 ****************************************************************************/
1856 void check_reload(time_t t)
1858 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1860 if(last_smb_conf_reload_time == 0) {
1861 last_smb_conf_reload_time = t;
1862 /* Our printing subsystem might not be ready at smbd start up.
1863 Then no printer is available till the first printers check
1864 is performed. A lower initial interval circumvents this. */
1865 if ( printcap_cache_time > 60 )
1866 last_printer_reload_time = t - printcap_cache_time + 60;
1868 last_printer_reload_time = t;
1871 if (mypid != getpid()) { /* First time or fork happened meanwhile */
1872 /* randomize over 60 second the printcap reload to avoid all
1873 * process hitting cupsd at the same time */
1874 int time_range = 60;
1876 last_printer_reload_time += random() % time_range;
1880 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1881 reload_services(True);
1882 last_smb_conf_reload_time = t;
1885 /* 'printcap cache time = 0' disable the feature */
1887 if ( printcap_cache_time != 0 )
1889 /* see if it's time to reload or if the clock has been set back */
1891 if ( (t >= last_printer_reload_time+printcap_cache_time)
1892 || (t-last_printer_reload_time < 0) )
1894 DEBUG( 3,( "Printcap cache time expired.\n"));
1896 last_printer_reload_time = t;
1901 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1903 /* TODO: make write nonblocking */
1906 static void smbd_server_connection_read_handler(struct smbd_server_connection *conn)
1908 uint8_t *inbuf = NULL;
1909 size_t inbuf_len = 0;
1910 size_t unread_bytes = 0;
1911 bool encrypted = false;
1912 TALLOC_CTX *mem_ctx = talloc_tos();
1916 /* TODO: make this completely nonblocking */
1918 status = receive_smb_talloc(mem_ctx, smbd_server_fd(),
1919 (char **)(void *)&inbuf,
1923 &inbuf_len, &seqnum);
1924 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1927 if (NT_STATUS_IS_ERR(status)) {
1928 exit_server_cleanly("failed to receive smb request");
1930 if (!NT_STATUS_IS_OK(status)) {
1935 process_smb(conn, inbuf, inbuf_len, unread_bytes,
1936 seqnum, encrypted, NULL);
1939 static void smbd_server_connection_handler(struct event_context *ev,
1940 struct fd_event *fde,
1944 struct smbd_server_connection *conn = talloc_get_type(private_data,
1945 struct smbd_server_connection);
1947 if (flags & EVENT_FD_WRITE) {
1948 smbd_server_connection_write_handler(conn);
1949 } else if (flags & EVENT_FD_READ) {
1950 smbd_server_connection_read_handler(conn);
1955 /****************************************************************************
1956 received when we should release a specific IP
1957 ****************************************************************************/
1958 static void release_ip(const char *ip, void *priv)
1960 char addr[INET6_ADDRSTRLEN];
1963 client_socket_addr(get_client_fd(),addr,sizeof(addr));
1965 if (strncmp("::ffff:", addr, 7) == 0) {
1969 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
1970 /* we can't afford to do a clean exit - that involves
1971 database writes, which would potentially mean we
1972 are still running after the failover has finished -
1973 we have to get rid of this process ID straight
1975 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
1977 /* note we must exit with non-zero status so the unclean handler gets
1978 called in the parent, so that the brl database is tickled */
1983 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
1984 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
1986 release_ip((char *)data->data, NULL);
1989 #ifdef CLUSTER_SUPPORT
1990 static int client_get_tcp_info(struct sockaddr_storage *server,
1991 struct sockaddr_storage *client)
1994 if (server_fd == -1) {
1997 length = sizeof(*server);
1998 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2001 length = sizeof(*client);
2002 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2010 * Send keepalive packets to our client
2012 static bool keepalive_fn(const struct timeval *now, void *private_data)
2014 if (!send_keepalive(smbd_server_fd())) {
2015 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2022 * Do the recurring check if we're idle
2024 static bool deadtime_fn(const struct timeval *now, void *private_data)
2026 struct smbd_server_connection *sconn = smbd_server_conn;
2027 if ((conn_num_open(sconn) == 0)
2028 || (conn_idle_all(sconn, now->tv_sec))) {
2029 DEBUG( 2, ( "Closing idle connection\n" ) );
2030 messaging_send(smbd_messaging_context(), procid_self(),
2031 MSG_SHUTDOWN, &data_blob_null);
2039 * Do the recurring log file and smb.conf reload checks.
2042 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2044 change_to_root_user();
2046 /* update printer queue caches if necessary */
2047 update_monitored_printq_cache();
2049 /* check if we need to reload services */
2050 check_reload(time(NULL));
2052 /* Change machine password if neccessary. */
2053 attempt_machine_password_change();
2056 * Force a log file check.
2058 force_check_log_size();
2063 /****************************************************************************
2064 Process commands from the client
2065 ****************************************************************************/
2067 void smbd_process(void)
2069 TALLOC_CTX *frame = talloc_stackframe();
2070 char remaddr[INET6_ADDRSTRLEN];
2072 smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
2073 if (!smbd_server_conn) {
2074 exit_server("failed to create smbd_server_connection");
2077 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2078 lp_security() != SEC_SHARE) {
2079 smbd_server_conn->allow_smb2 = true;
2082 /* Ensure child is set to blocking mode */
2083 set_blocking(smbd_server_fd(),True);
2085 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2086 set_socket_options(smbd_server_fd(), lp_socket_options());
2088 /* this is needed so that we get decent entries
2089 in smbstatus for port 445 connects */
2090 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2094 reload_services(true);
2097 * Before the first packet, check the global hosts allow/ hosts deny
2098 * parameters before doing any parsing of packets passed to us by the
2099 * client. This prevents attacks on our parsing code from hosts not in
2100 * the hosts allow list.
2103 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2104 lp_hostsdeny(-1))) {
2105 char addr[INET6_ADDRSTRLEN];
2108 * send a negative session response "not listening on calling
2111 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2112 DEBUG( 1, ("Connection denied from %s\n",
2113 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2114 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2116 exit_server_cleanly("connection denied");
2123 smb_perfcount_init();
2125 if (!init_account_policy()) {
2126 exit_server("Could not open account policy tdb.\n");
2129 if (*lp_rootdir()) {
2130 if (chroot(lp_rootdir()) != 0) {
2131 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2132 exit_server("Failed to chroot()");
2134 if (chdir("/") == -1) {
2135 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2136 exit_server("Failed to chroot()");
2138 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2141 if (!srv_init_signing(smbd_server_conn)) {
2142 exit_server("Failed to init smb_signing");
2146 if (!init_oplocks(smbd_messaging_context()))
2147 exit_server("Failed to init oplocks");
2149 /* Setup aio signal handler. */
2150 initialize_async_io_handler();
2152 /* register our message handlers */
2153 messaging_register(smbd_messaging_context(), NULL,
2154 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2155 messaging_register(smbd_messaging_context(), NULL,
2156 MSG_SMB_RELEASE_IP, msg_release_ip);
2157 messaging_register(smbd_messaging_context(), NULL,
2158 MSG_SMB_CLOSE_FILE, msg_close_file);
2161 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2162 * MSGs to all child processes
2164 messaging_deregister(smbd_messaging_context(),
2166 messaging_register(smbd_messaging_context(), NULL,
2167 MSG_DEBUG, debug_message);
2169 if ((lp_keepalive() != 0)
2170 && !(event_add_idle(smbd_event_context(), NULL,
2171 timeval_set(lp_keepalive(), 0),
2172 "keepalive", keepalive_fn,
2174 DEBUG(0, ("Could not add keepalive event\n"));
2178 if (!(event_add_idle(smbd_event_context(), NULL,
2179 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2180 "deadtime", deadtime_fn, NULL))) {
2181 DEBUG(0, ("Could not add deadtime event\n"));
2185 if (!(event_add_idle(smbd_event_context(), NULL,
2186 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2187 "housekeeping", housekeeping_fn, NULL))) {
2188 DEBUG(0, ("Could not add housekeeping event\n"));
2192 #ifdef CLUSTER_SUPPORT
2194 if (lp_clustering()) {
2196 * We need to tell ctdb about our client's TCP
2197 * connection, so that for failover ctdbd can send
2198 * tickle acks, triggering a reconnection by the
2202 struct sockaddr_storage srv, clnt;
2204 if (client_get_tcp_info(&srv, &clnt) == 0) {
2208 status = ctdbd_register_ips(
2209 messaging_ctdbd_connection(),
2210 &srv, &clnt, release_ip, NULL);
2212 if (!NT_STATUS_IS_OK(status)) {
2213 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2214 nt_errstr(status)));
2218 DEBUG(0,("Unable to get tcp info for "
2219 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2226 smbd_server_conn->nbt.got_session = false;
2228 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2230 smbd_server_conn->smb1.sessions.done_sesssetup = false;
2231 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
2232 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
2233 /* users from session setup */
2234 smbd_server_conn->smb1.sessions.session_userlist = NULL;
2235 /* workgroup from session setup. */
2236 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
2237 /* this holds info on user ids that are already validated for this VC */
2238 smbd_server_conn->smb1.sessions.validated_users = NULL;
2239 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
2240 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
2241 #ifdef HAVE_NETGROUP
2242 smbd_server_conn->smb1.sessions.my_yp_domain = NULL;
2245 conn_init(smbd_server_conn);
2247 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
2251 smbd_server_connection_handler,
2253 if (!smbd_server_conn->smb1.fde) {
2254 exit_server("failed to create smbd_server_connection fde");
2262 frame = talloc_stackframe_pool(8192);
2266 status = smbd_server_connection_loop_once(smbd_server_conn);
2267 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2268 !NT_STATUS_IS_OK(status)) {
2269 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2270 " exiting\n", nt_errstr(status)));
2277 exit_server_cleanly(NULL);
2280 bool req_is_in_chain(struct smb_request *req)
2282 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2284 * We're right now handling a subsequent request, so we must
2290 if (!is_andx_req(req->cmd)) {
2296 * Okay, an illegal request, but definitely not chained :-)
2301 return (CVAL(req->vwv+0, 0) != 0xFF);