s3:smbd: don't use recvfile if the echo handler is active
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blob5b8b42d5bfa0548b03c6a43435a540a713cc30d1
1 /*
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/>.
21 #include "includes.h"
22 #include "smbd/globals.h"
23 #include "../librpc/gen_ndr/srv_dfs.h"
24 #include "../librpc/gen_ndr/srv_dssetup.h"
25 #include "../librpc/gen_ndr/srv_echo.h"
26 #include "../librpc/gen_ndr/srv_eventlog.h"
27 #include "../librpc/gen_ndr/srv_initshutdown.h"
28 #include "../librpc/gen_ndr/srv_lsa.h"
29 #include "../librpc/gen_ndr/srv_netlogon.h"
30 #include "../librpc/gen_ndr/srv_ntsvcs.h"
31 #include "../librpc/gen_ndr/srv_samr.h"
32 #include "../librpc/gen_ndr/srv_spoolss.h"
33 #include "../librpc/gen_ndr/srv_srvsvc.h"
34 #include "../librpc/gen_ndr/srv_svcctl.h"
35 #include "../librpc/gen_ndr/srv_winreg.h"
36 #include "../librpc/gen_ndr/srv_wkssvc.h"
38 extern bool global_machine_password_needs_changing;
40 static void construct_reply_common(struct smb_request *req, const char *inbuf,
41 char *outbuf);
43 bool smbd_lock_socket(struct smbd_server_connection *sconn)
45 return true;
48 bool smbd_unlock_socket(struct smbd_server_connection *sconn)
50 return true;
53 /* Accessor function for smb_read_error for smbd functions. */
55 /****************************************************************************
56 Send an smb to a fd.
57 ****************************************************************************/
59 bool srv_send_smb(int fd, char *buffer,
60 bool do_signing, uint32_t seqnum,
61 bool do_encrypt,
62 struct smb_perfcount_data *pcd)
64 size_t len = 0;
65 size_t nwritten=0;
66 ssize_t ret;
67 char *buf_out = buffer;
68 bool ok;
70 ok = smbd_lock_socket(smbd_server_conn);
71 if (!ok) {
72 exit_server_cleanly("failed to lock socket");
75 if (do_signing) {
76 /* Sign the outgoing packet if required. */
77 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
80 if (do_encrypt) {
81 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
82 if (!NT_STATUS_IS_OK(status)) {
83 DEBUG(0, ("send_smb: SMB encryption failed "
84 "on outgoing packet! Error %s\n",
85 nt_errstr(status) ));
86 goto out;
90 len = smb_len(buf_out) + 4;
92 ret = write_data(fd,buf_out+nwritten,len - nwritten);
93 if (ret <= 0) {
94 DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
95 (int)len,(int)ret, strerror(errno) ));
96 srv_free_enc_buffer(buf_out);
97 goto out;
100 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
101 srv_free_enc_buffer(buf_out);
102 out:
103 SMB_PERFCOUNT_END(pcd);
105 ok = smbd_unlock_socket(smbd_server_conn);
106 if (!ok) {
107 exit_server_cleanly("failed to unlock socket");
110 return true;
113 /*******************************************************************
114 Setup the word count and byte count for a smb message.
115 ********************************************************************/
117 int srv_set_message(char *buf,
118 int num_words,
119 int num_bytes,
120 bool zero)
122 if (zero && (num_words || num_bytes)) {
123 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
125 SCVAL(buf,smb_wct,num_words);
126 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
127 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
128 return (smb_size + num_words*2 + num_bytes);
131 static bool valid_smb_header(const uint8_t *inbuf)
133 if (is_encrypted_packet(inbuf)) {
134 return true;
137 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
138 * but it just looks weird to call strncmp for this one.
140 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
143 /* Socket functions for smbd packet processing. */
145 static bool valid_packet_size(size_t len)
148 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
149 * of header. Don't print the error if this fits.... JRA.
152 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
153 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
154 (unsigned long)len));
155 return false;
157 return true;
160 static NTSTATUS read_packet_remainder(int fd, char *buffer,
161 unsigned int timeout, ssize_t len)
163 if (len <= 0) {
164 return NT_STATUS_OK;
167 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
170 /****************************************************************************
171 Attempt a zerocopy writeX read. We know here that len > smb_size-4
172 ****************************************************************************/
175 * Unfortunately, earlier versions of smbclient/libsmbclient
176 * don't send this "standard" writeX header. I've fixed this
177 * for 3.2 but we'll use the old method with earlier versions.
178 * Windows and CIFSFS at least use this standard size. Not
179 * sure about MacOSX.
182 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
183 (2*14) + /* word count (including bcc) */ \
184 1 /* pad byte */)
186 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
187 const char lenbuf[4],
188 int fd, char **buffer,
189 unsigned int timeout,
190 size_t *p_unread,
191 size_t *len_ret)
193 /* Size of a WRITEX call (+4 byte len). */
194 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
195 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
196 ssize_t toread;
197 NTSTATUS status;
199 memcpy(writeX_header, lenbuf, 4);
201 status = read_fd_with_timeout(
202 fd, writeX_header + 4,
203 STANDARD_WRITE_AND_X_HEADER_SIZE,
204 STANDARD_WRITE_AND_X_HEADER_SIZE,
205 timeout, NULL);
207 if (!NT_STATUS_IS_OK(status)) {
208 return status;
212 * Ok - now try and see if this is a possible
213 * valid writeX call.
216 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
218 * If the data offset is beyond what
219 * we've read, drain the extra bytes.
221 uint16_t doff = SVAL(writeX_header,smb_vwv11);
222 ssize_t newlen;
224 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
225 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
226 if (drain_socket(smbd_server_fd(), drain) != drain) {
227 smb_panic("receive_smb_raw_talloc_partial_read:"
228 " failed to drain pending bytes");
230 } else {
231 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
234 /* Spoof down the length and null out the bcc. */
235 set_message_bcc(writeX_header, 0);
236 newlen = smb_len(writeX_header);
238 /* Copy the header we've written. */
240 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
241 writeX_header,
242 sizeof(writeX_header));
244 if (*buffer == NULL) {
245 DEBUG(0, ("Could not allocate inbuf of length %d\n",
246 (int)sizeof(writeX_header)));
247 return NT_STATUS_NO_MEMORY;
250 /* Work out the remaining bytes. */
251 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
252 *len_ret = newlen + 4;
253 return NT_STATUS_OK;
256 if (!valid_packet_size(len)) {
257 return NT_STATUS_INVALID_PARAMETER;
261 * Not a valid writeX call. Just do the standard
262 * talloc and return.
265 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
267 if (*buffer == NULL) {
268 DEBUG(0, ("Could not allocate inbuf of length %d\n",
269 (int)len+4));
270 return NT_STATUS_NO_MEMORY;
273 /* Copy in what we already read. */
274 memcpy(*buffer,
275 writeX_header,
276 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
277 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
279 if(toread > 0) {
280 status = read_packet_remainder(
281 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
282 timeout, toread);
284 if (!NT_STATUS_IS_OK(status)) {
285 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
286 nt_errstr(status)));
287 return status;
291 *len_ret = len + 4;
292 return NT_STATUS_OK;
295 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
296 char **buffer, unsigned int timeout,
297 size_t *p_unread, size_t *plen)
299 char lenbuf[4];
300 size_t len;
301 int min_recv_size = lp_min_receive_file_size();
302 NTSTATUS status;
304 *p_unread = 0;
306 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
307 if (!NT_STATUS_IS_OK(status)) {
308 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
309 return status;
312 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
313 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
314 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
315 !srv_is_signing_active(smbd_server_conn) &&
316 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
318 return receive_smb_raw_talloc_partial_read(
319 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
322 if (!valid_packet_size(len)) {
323 return NT_STATUS_INVALID_PARAMETER;
327 * The +4 here can't wrap, we've checked the length above already.
330 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
332 if (*buffer == NULL) {
333 DEBUG(0, ("Could not allocate inbuf of length %d\n",
334 (int)len+4));
335 return NT_STATUS_NO_MEMORY;
338 memcpy(*buffer, lenbuf, sizeof(lenbuf));
340 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
341 if (!NT_STATUS_IS_OK(status)) {
342 return status;
345 *plen = len + 4;
346 return NT_STATUS_OK;
349 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
350 char **buffer, unsigned int timeout,
351 size_t *p_unread, bool *p_encrypted,
352 size_t *p_len,
353 uint32_t *seqnum,
354 bool trusted_channel)
356 size_t len = 0;
357 NTSTATUS status;
359 *p_encrypted = false;
361 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
362 p_unread, &len);
363 if (!NT_STATUS_IS_OK(status)) {
364 return status;
367 if (is_encrypted_packet((uint8_t *)*buffer)) {
368 status = srv_decrypt_buffer(*buffer);
369 if (!NT_STATUS_IS_OK(status)) {
370 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
371 "incoming packet! Error %s\n",
372 nt_errstr(status) ));
373 return status;
375 *p_encrypted = true;
378 /* Check the incoming SMB signature. */
379 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
380 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
381 "incoming packet!\n"));
382 return NT_STATUS_INVALID_NETWORK_RESPONSE;
385 *p_len = len;
386 return NT_STATUS_OK;
390 * Initialize a struct smb_request from an inbuf
393 static bool init_smb_request(struct smb_request *req, const uint8 *inbuf,
394 size_t unread_bytes, bool encrypted,
395 uint32_t seqnum)
397 struct smbd_server_connection *sconn = smbd_server_conn;
398 size_t req_size = smb_len(inbuf) + 4;
399 /* Ensure we have at least smb_size bytes. */
400 if (req_size < smb_size) {
401 DEBUG(0,("init_smb_request: invalid request size %u\n",
402 (unsigned int)req_size ));
403 return false;
405 req->cmd = CVAL(inbuf, smb_com);
406 req->flags2 = SVAL(inbuf, smb_flg2);
407 req->smbpid = SVAL(inbuf, smb_pid);
408 req->mid = SVAL(inbuf, smb_mid);
409 req->seqnum = seqnum;
410 req->vuid = SVAL(inbuf, smb_uid);
411 req->tid = SVAL(inbuf, smb_tid);
412 req->wct = CVAL(inbuf, smb_wct);
413 req->vwv = (uint16_t *)(inbuf+smb_vwv);
414 req->buflen = smb_buflen(inbuf);
415 req->buf = (const uint8_t *)smb_buf(inbuf);
416 req->unread_bytes = unread_bytes;
417 req->encrypted = encrypted;
418 req->conn = conn_find(sconn,req->tid);
419 req->chain_fsp = NULL;
420 req->chain_outbuf = NULL;
421 req->done = false;
422 smb_init_perfcount_data(&req->pcd);
424 /* Ensure we have at least wct words and 2 bytes of bcc. */
425 if (smb_size + req->wct*2 > req_size) {
426 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
427 (unsigned int)req->wct,
428 (unsigned int)req_size));
429 return false;
431 /* Ensure bcc is correct. */
432 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
433 DEBUG(0,("init_smb_request: invalid bcc number %u "
434 "(wct = %u, size %u)\n",
435 (unsigned int)req->buflen,
436 (unsigned int)req->wct,
437 (unsigned int)req_size));
438 return false;
441 req->outbuf = NULL;
442 return true;
445 static void process_smb(struct smbd_server_connection *conn,
446 uint8_t *inbuf, size_t nread, size_t unread_bytes,
447 uint32_t seqnum, bool encrypted,
448 struct smb_perfcount_data *deferred_pcd);
450 static void smbd_deferred_open_timer(struct event_context *ev,
451 struct timed_event *te,
452 struct timeval _tval,
453 void *private_data)
455 struct pending_message_list *msg = talloc_get_type(private_data,
456 struct pending_message_list);
457 TALLOC_CTX *mem_ctx = talloc_tos();
458 uint16_t mid = SVAL(msg->buf.data,smb_mid);
459 uint8_t *inbuf;
461 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
462 msg->buf.length);
463 if (inbuf == NULL) {
464 exit_server("smbd_deferred_open_timer: talloc failed\n");
465 return;
468 /* We leave this message on the queue so the open code can
469 know this is a retry. */
470 DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
471 (unsigned int)mid ));
473 /* Mark the message as processed so this is not
474 * re-processed in error. */
475 msg->processed = true;
477 process_smb(smbd_server_conn, inbuf,
478 msg->buf.length, 0,
479 msg->seqnum, msg->encrypted, &msg->pcd);
481 /* If it's still there and was processed, remove it. */
482 msg = get_open_deferred_message(mid);
483 if (msg && msg->processed) {
484 remove_deferred_open_smb_message(mid);
488 /****************************************************************************
489 Function to push a message onto the tail of a linked list of smb messages ready
490 for processing.
491 ****************************************************************************/
493 static bool push_queued_message(struct smb_request *req,
494 struct timeval request_time,
495 struct timeval end_time,
496 char *private_data, size_t private_len)
498 int msg_len = smb_len(req->inbuf) + 4;
499 struct pending_message_list *msg;
501 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
503 if(msg == NULL) {
504 DEBUG(0,("push_message: malloc fail (1)\n"));
505 return False;
508 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
509 if(msg->buf.data == NULL) {
510 DEBUG(0,("push_message: malloc fail (2)\n"));
511 TALLOC_FREE(msg);
512 return False;
515 msg->request_time = request_time;
516 msg->seqnum = req->seqnum;
517 msg->encrypted = req->encrypted;
518 msg->processed = false;
519 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
521 if (private_data) {
522 msg->private_data = data_blob_talloc(msg, private_data,
523 private_len);
524 if (msg->private_data.data == NULL) {
525 DEBUG(0,("push_message: malloc fail (3)\n"));
526 TALLOC_FREE(msg);
527 return False;
531 msg->te = event_add_timed(smbd_event_context(),
532 msg,
533 end_time,
534 smbd_deferred_open_timer,
535 msg);
536 if (!msg->te) {
537 DEBUG(0,("push_message: event_add_timed failed\n"));
538 TALLOC_FREE(msg);
539 return false;
542 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
544 DEBUG(10,("push_message: pushed message length %u on "
545 "deferred_open_queue\n", (unsigned int)msg_len));
547 return True;
550 /****************************************************************************
551 Function to delete a sharing violation open message by mid.
552 ****************************************************************************/
554 void remove_deferred_open_smb_message(uint16 mid)
556 struct pending_message_list *pml;
558 for (pml = deferred_open_queue; pml; pml = pml->next) {
559 if (mid == SVAL(pml->buf.data,smb_mid)) {
560 DEBUG(10,("remove_deferred_open_smb_message: "
561 "deleting mid %u len %u\n",
562 (unsigned int)mid,
563 (unsigned int)pml->buf.length ));
564 DLIST_REMOVE(deferred_open_queue, pml);
565 TALLOC_FREE(pml);
566 return;
571 /****************************************************************************
572 Move a sharing violation open retry message to the front of the list and
573 schedule it for immediate processing.
574 ****************************************************************************/
576 void schedule_deferred_open_smb_message(uint16 mid)
578 struct pending_message_list *pml;
579 int i = 0;
581 for (pml = deferred_open_queue; pml; pml = pml->next) {
582 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
584 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
585 (unsigned int)msg_mid ));
587 if (mid == msg_mid) {
588 struct timed_event *te;
590 if (pml->processed) {
591 /* A processed message should not be
592 * rescheduled. */
593 DEBUG(0,("schedule_deferred_open_smb_message: LOGIC ERROR "
594 "message mid %u was already processed\n",
595 msg_mid ));
596 continue;
599 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
600 mid ));
602 te = event_add_timed(smbd_event_context(),
603 pml,
604 timeval_zero(),
605 smbd_deferred_open_timer,
606 pml);
607 if (!te) {
608 DEBUG(10,("schedule_deferred_open_smb_message: "
609 "event_add_timed() failed, skipping mid %u\n",
610 mid ));
613 TALLOC_FREE(pml->te);
614 pml->te = te;
615 DLIST_PROMOTE(deferred_open_queue, pml);
616 return;
620 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
621 mid ));
624 /****************************************************************************
625 Return true if this mid is on the deferred queue and was not yet processed.
626 ****************************************************************************/
628 bool open_was_deferred(uint16 mid)
630 struct pending_message_list *pml;
632 for (pml = deferred_open_queue; pml; pml = pml->next) {
633 if (SVAL(pml->buf.data,smb_mid) == mid && !pml->processed) {
634 return True;
637 return False;
640 /****************************************************************************
641 Return the message queued by this mid.
642 ****************************************************************************/
644 struct pending_message_list *get_open_deferred_message(uint16 mid)
646 struct pending_message_list *pml;
648 for (pml = deferred_open_queue; pml; pml = pml->next) {
649 if (SVAL(pml->buf.data,smb_mid) == mid) {
650 return pml;
653 return NULL;
656 /****************************************************************************
657 Function to push a deferred open smb message onto a linked list of local smb
658 messages ready for processing.
659 ****************************************************************************/
661 bool push_deferred_smb_message(struct smb_request *req,
662 struct timeval request_time,
663 struct timeval timeout,
664 char *private_data, size_t priv_len)
666 struct timeval end_time;
668 if (req->unread_bytes) {
669 DEBUG(0,("push_deferred_smb_message: logic error ! "
670 "unread_bytes = %u\n",
671 (unsigned int)req->unread_bytes ));
672 smb_panic("push_deferred_smb_message: "
673 "logic error unread_bytes != 0" );
676 end_time = timeval_sum(&request_time, &timeout);
678 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
679 "timeout time [%u.%06u]\n",
680 (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
681 (unsigned int)end_time.tv_sec,
682 (unsigned int)end_time.tv_usec));
684 return push_queued_message(req, request_time, end_time,
685 private_data, priv_len);
688 struct idle_event {
689 struct timed_event *te;
690 struct timeval interval;
691 char *name;
692 bool (*handler)(const struct timeval *now, void *private_data);
693 void *private_data;
696 static void smbd_idle_event_handler(struct event_context *ctx,
697 struct timed_event *te,
698 struct timeval now,
699 void *private_data)
701 struct idle_event *event =
702 talloc_get_type_abort(private_data, struct idle_event);
704 TALLOC_FREE(event->te);
706 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
707 event->name, event->te));
709 if (!event->handler(&now, event->private_data)) {
710 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
711 event->name, event->te));
712 /* Don't repeat, delete ourselves */
713 TALLOC_FREE(event);
714 return;
717 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
718 event->name, event->te));
720 event->te = event_add_timed(ctx, event,
721 timeval_sum(&now, &event->interval),
722 smbd_idle_event_handler, event);
724 /* We can't do much but fail here. */
725 SMB_ASSERT(event->te != NULL);
728 struct idle_event *event_add_idle(struct event_context *event_ctx,
729 TALLOC_CTX *mem_ctx,
730 struct timeval interval,
731 const char *name,
732 bool (*handler)(const struct timeval *now,
733 void *private_data),
734 void *private_data)
736 struct idle_event *result;
737 struct timeval now = timeval_current();
739 result = TALLOC_P(mem_ctx, struct idle_event);
740 if (result == NULL) {
741 DEBUG(0, ("talloc failed\n"));
742 return NULL;
745 result->interval = interval;
746 result->handler = handler;
747 result->private_data = private_data;
749 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
750 DEBUG(0, ("talloc failed\n"));
751 TALLOC_FREE(result);
752 return NULL;
755 result->te = event_add_timed(event_ctx, result,
756 timeval_sum(&now, &interval),
757 smbd_idle_event_handler, result);
758 if (result->te == NULL) {
759 DEBUG(0, ("event_add_timed failed\n"));
760 TALLOC_FREE(result);
761 return NULL;
764 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
765 return result;
768 static void smbd_sig_term_handler(struct tevent_context *ev,
769 struct tevent_signal *se,
770 int signum,
771 int count,
772 void *siginfo,
773 void *private_data)
775 exit_server_cleanly("termination signal");
778 void smbd_setup_sig_term_handler(void)
780 struct tevent_signal *se;
782 se = tevent_add_signal(smbd_event_context(),
783 smbd_event_context(),
784 SIGTERM, 0,
785 smbd_sig_term_handler,
786 NULL);
787 if (!se) {
788 exit_server("failed to setup SIGTERM handler");
792 static void smbd_sig_hup_handler(struct tevent_context *ev,
793 struct tevent_signal *se,
794 int signum,
795 int count,
796 void *siginfo,
797 void *private_data)
799 change_to_root_user();
800 DEBUG(1,("Reloading services after SIGHUP\n"));
801 reload_services(False);
804 void smbd_setup_sig_hup_handler(void)
806 struct tevent_signal *se;
808 se = tevent_add_signal(smbd_event_context(),
809 smbd_event_context(),
810 SIGHUP, 0,
811 smbd_sig_hup_handler,
812 NULL);
813 if (!se) {
814 exit_server("failed to setup SIGHUP handler");
818 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
820 fd_set r_fds, w_fds;
821 int selrtn;
822 struct timeval to;
823 int maxfd = 0;
825 to.tv_sec = SMBD_SELECT_TIMEOUT;
826 to.tv_usec = 0;
829 * Setup the select fd sets.
832 FD_ZERO(&r_fds);
833 FD_ZERO(&w_fds);
836 * Are there any timed events waiting ? If so, ensure we don't
837 * select for longer than it would take to wait for them.
841 struct timeval now;
842 GetTimeOfDay(&now);
844 event_add_to_select_args(smbd_event_context(), &now,
845 &r_fds, &w_fds, &to, &maxfd);
848 /* Process a signal and timed events now... */
849 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
850 return NT_STATUS_RETRY;
854 int sav;
855 START_PROFILE(smbd_idle);
857 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
858 sav = errno;
860 END_PROFILE(smbd_idle);
861 errno = sav;
864 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
865 return NT_STATUS_RETRY;
868 /* Check if error */
869 if (selrtn == -1) {
870 /* something is wrong. Maybe the socket is dead? */
871 return map_nt_error_from_unix(errno);
874 /* Did we timeout ? */
875 if (selrtn == 0) {
876 return NT_STATUS_RETRY;
879 /* should not be reached */
880 return NT_STATUS_INTERNAL_ERROR;
884 * Only allow 5 outstanding trans requests. We're allocating memory, so
885 * prevent a DoS.
888 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
890 int count = 0;
891 for (; list != NULL; list = list->next) {
893 if (list->mid == mid) {
894 return NT_STATUS_INVALID_PARAMETER;
897 count += 1;
899 if (count > 5) {
900 return NT_STATUS_INSUFFICIENT_RESOURCES;
903 return NT_STATUS_OK;
907 These flags determine some of the permissions required to do an operation
909 Note that I don't set NEED_WRITE on some write operations because they
910 are used by some brain-dead clients when printing, and I don't want to
911 force write permissions on print services.
913 #define AS_USER (1<<0)
914 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
915 #define TIME_INIT (1<<2)
916 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
917 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
918 #define DO_CHDIR (1<<6)
921 define a list of possible SMB messages and their corresponding
922 functions. Any message that has a NULL function is unimplemented -
923 please feel free to contribute implementations!
925 static const struct smb_message_struct {
926 const char *name;
927 void (*fn)(struct smb_request *req);
928 int flags;
929 } smb_messages[256] = {
931 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
932 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
933 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
934 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
935 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
936 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
937 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
938 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
939 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
940 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
941 /* 0x0a */ { "SMBread",reply_read,AS_USER},
942 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
943 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
944 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
945 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
946 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
947 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
948 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
949 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
950 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
951 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
952 /* 0x15 */ { NULL, NULL, 0 },
953 /* 0x16 */ { NULL, NULL, 0 },
954 /* 0x17 */ { NULL, NULL, 0 },
955 /* 0x18 */ { NULL, NULL, 0 },
956 /* 0x19 */ { NULL, NULL, 0 },
957 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
958 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
959 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
960 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
961 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
962 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
963 /* 0x20 */ { "SMBwritec", NULL,0},
964 /* 0x21 */ { NULL, NULL, 0 },
965 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
966 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
967 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
968 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
969 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
970 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
971 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
972 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
973 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
974 /* 0x2b */ { "SMBecho",reply_echo,0},
975 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
976 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
977 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
978 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
979 /* 0x30 */ { NULL, NULL, 0 },
980 /* 0x31 */ { NULL, NULL, 0 },
981 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
982 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
983 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
984 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
985 /* 0x36 */ { NULL, NULL, 0 },
986 /* 0x37 */ { NULL, NULL, 0 },
987 /* 0x38 */ { NULL, NULL, 0 },
988 /* 0x39 */ { NULL, NULL, 0 },
989 /* 0x3a */ { NULL, NULL, 0 },
990 /* 0x3b */ { NULL, NULL, 0 },
991 /* 0x3c */ { NULL, NULL, 0 },
992 /* 0x3d */ { NULL, NULL, 0 },
993 /* 0x3e */ { NULL, NULL, 0 },
994 /* 0x3f */ { NULL, NULL, 0 },
995 /* 0x40 */ { NULL, NULL, 0 },
996 /* 0x41 */ { NULL, NULL, 0 },
997 /* 0x42 */ { NULL, NULL, 0 },
998 /* 0x43 */ { NULL, NULL, 0 },
999 /* 0x44 */ { NULL, NULL, 0 },
1000 /* 0x45 */ { NULL, NULL, 0 },
1001 /* 0x46 */ { NULL, NULL, 0 },
1002 /* 0x47 */ { NULL, NULL, 0 },
1003 /* 0x48 */ { NULL, NULL, 0 },
1004 /* 0x49 */ { NULL, NULL, 0 },
1005 /* 0x4a */ { NULL, NULL, 0 },
1006 /* 0x4b */ { NULL, NULL, 0 },
1007 /* 0x4c */ { NULL, NULL, 0 },
1008 /* 0x4d */ { NULL, NULL, 0 },
1009 /* 0x4e */ { NULL, NULL, 0 },
1010 /* 0x4f */ { NULL, NULL, 0 },
1011 /* 0x50 */ { NULL, NULL, 0 },
1012 /* 0x51 */ { NULL, NULL, 0 },
1013 /* 0x52 */ { NULL, NULL, 0 },
1014 /* 0x53 */ { NULL, NULL, 0 },
1015 /* 0x54 */ { NULL, NULL, 0 },
1016 /* 0x55 */ { NULL, NULL, 0 },
1017 /* 0x56 */ { NULL, NULL, 0 },
1018 /* 0x57 */ { NULL, NULL, 0 },
1019 /* 0x58 */ { NULL, NULL, 0 },
1020 /* 0x59 */ { NULL, NULL, 0 },
1021 /* 0x5a */ { NULL, NULL, 0 },
1022 /* 0x5b */ { NULL, NULL, 0 },
1023 /* 0x5c */ { NULL, NULL, 0 },
1024 /* 0x5d */ { NULL, NULL, 0 },
1025 /* 0x5e */ { NULL, NULL, 0 },
1026 /* 0x5f */ { NULL, NULL, 0 },
1027 /* 0x60 */ { NULL, NULL, 0 },
1028 /* 0x61 */ { NULL, NULL, 0 },
1029 /* 0x62 */ { NULL, NULL, 0 },
1030 /* 0x63 */ { NULL, NULL, 0 },
1031 /* 0x64 */ { NULL, NULL, 0 },
1032 /* 0x65 */ { NULL, NULL, 0 },
1033 /* 0x66 */ { NULL, NULL, 0 },
1034 /* 0x67 */ { NULL, NULL, 0 },
1035 /* 0x68 */ { NULL, NULL, 0 },
1036 /* 0x69 */ { NULL, NULL, 0 },
1037 /* 0x6a */ { NULL, NULL, 0 },
1038 /* 0x6b */ { NULL, NULL, 0 },
1039 /* 0x6c */ { NULL, NULL, 0 },
1040 /* 0x6d */ { NULL, NULL, 0 },
1041 /* 0x6e */ { NULL, NULL, 0 },
1042 /* 0x6f */ { NULL, NULL, 0 },
1043 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1044 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1045 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1046 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1047 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1048 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1049 /* 0x76 */ { NULL, NULL, 0 },
1050 /* 0x77 */ { NULL, NULL, 0 },
1051 /* 0x78 */ { NULL, NULL, 0 },
1052 /* 0x79 */ { NULL, NULL, 0 },
1053 /* 0x7a */ { NULL, NULL, 0 },
1054 /* 0x7b */ { NULL, NULL, 0 },
1055 /* 0x7c */ { NULL, NULL, 0 },
1056 /* 0x7d */ { NULL, NULL, 0 },
1057 /* 0x7e */ { NULL, NULL, 0 },
1058 /* 0x7f */ { NULL, NULL, 0 },
1059 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1060 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1061 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1062 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1063 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1064 /* 0x85 */ { NULL, NULL, 0 },
1065 /* 0x86 */ { NULL, NULL, 0 },
1066 /* 0x87 */ { NULL, NULL, 0 },
1067 /* 0x88 */ { NULL, NULL, 0 },
1068 /* 0x89 */ { NULL, NULL, 0 },
1069 /* 0x8a */ { NULL, NULL, 0 },
1070 /* 0x8b */ { NULL, NULL, 0 },
1071 /* 0x8c */ { NULL, NULL, 0 },
1072 /* 0x8d */ { NULL, NULL, 0 },
1073 /* 0x8e */ { NULL, NULL, 0 },
1074 /* 0x8f */ { NULL, NULL, 0 },
1075 /* 0x90 */ { NULL, NULL, 0 },
1076 /* 0x91 */ { NULL, NULL, 0 },
1077 /* 0x92 */ { NULL, NULL, 0 },
1078 /* 0x93 */ { NULL, NULL, 0 },
1079 /* 0x94 */ { NULL, NULL, 0 },
1080 /* 0x95 */ { NULL, NULL, 0 },
1081 /* 0x96 */ { NULL, NULL, 0 },
1082 /* 0x97 */ { NULL, NULL, 0 },
1083 /* 0x98 */ { NULL, NULL, 0 },
1084 /* 0x99 */ { NULL, NULL, 0 },
1085 /* 0x9a */ { NULL, NULL, 0 },
1086 /* 0x9b */ { NULL, NULL, 0 },
1087 /* 0x9c */ { NULL, NULL, 0 },
1088 /* 0x9d */ { NULL, NULL, 0 },
1089 /* 0x9e */ { NULL, NULL, 0 },
1090 /* 0x9f */ { NULL, NULL, 0 },
1091 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1092 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1093 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1094 /* 0xa3 */ { NULL, NULL, 0 },
1095 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1096 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1097 /* 0xa6 */ { NULL, NULL, 0 },
1098 /* 0xa7 */ { NULL, NULL, 0 },
1099 /* 0xa8 */ { NULL, NULL, 0 },
1100 /* 0xa9 */ { NULL, NULL, 0 },
1101 /* 0xaa */ { NULL, NULL, 0 },
1102 /* 0xab */ { NULL, NULL, 0 },
1103 /* 0xac */ { NULL, NULL, 0 },
1104 /* 0xad */ { NULL, NULL, 0 },
1105 /* 0xae */ { NULL, NULL, 0 },
1106 /* 0xaf */ { NULL, NULL, 0 },
1107 /* 0xb0 */ { NULL, NULL, 0 },
1108 /* 0xb1 */ { NULL, NULL, 0 },
1109 /* 0xb2 */ { NULL, NULL, 0 },
1110 /* 0xb3 */ { NULL, NULL, 0 },
1111 /* 0xb4 */ { NULL, NULL, 0 },
1112 /* 0xb5 */ { NULL, NULL, 0 },
1113 /* 0xb6 */ { NULL, NULL, 0 },
1114 /* 0xb7 */ { NULL, NULL, 0 },
1115 /* 0xb8 */ { NULL, NULL, 0 },
1116 /* 0xb9 */ { NULL, NULL, 0 },
1117 /* 0xba */ { NULL, NULL, 0 },
1118 /* 0xbb */ { NULL, NULL, 0 },
1119 /* 0xbc */ { NULL, NULL, 0 },
1120 /* 0xbd */ { NULL, NULL, 0 },
1121 /* 0xbe */ { NULL, NULL, 0 },
1122 /* 0xbf */ { NULL, NULL, 0 },
1123 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1124 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1125 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1126 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1127 /* 0xc4 */ { NULL, NULL, 0 },
1128 /* 0xc5 */ { NULL, NULL, 0 },
1129 /* 0xc6 */ { NULL, NULL, 0 },
1130 /* 0xc7 */ { NULL, NULL, 0 },
1131 /* 0xc8 */ { NULL, NULL, 0 },
1132 /* 0xc9 */ { NULL, NULL, 0 },
1133 /* 0xca */ { NULL, NULL, 0 },
1134 /* 0xcb */ { NULL, NULL, 0 },
1135 /* 0xcc */ { NULL, NULL, 0 },
1136 /* 0xcd */ { NULL, NULL, 0 },
1137 /* 0xce */ { NULL, NULL, 0 },
1138 /* 0xcf */ { NULL, NULL, 0 },
1139 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1140 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1141 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1142 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1143 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1144 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1145 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1146 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1147 /* 0xd8 */ { NULL, NULL, 0 },
1148 /* 0xd9 */ { NULL, NULL, 0 },
1149 /* 0xda */ { NULL, NULL, 0 },
1150 /* 0xdb */ { NULL, NULL, 0 },
1151 /* 0xdc */ { NULL, NULL, 0 },
1152 /* 0xdd */ { NULL, NULL, 0 },
1153 /* 0xde */ { NULL, NULL, 0 },
1154 /* 0xdf */ { NULL, NULL, 0 },
1155 /* 0xe0 */ { NULL, NULL, 0 },
1156 /* 0xe1 */ { NULL, NULL, 0 },
1157 /* 0xe2 */ { NULL, NULL, 0 },
1158 /* 0xe3 */ { NULL, NULL, 0 },
1159 /* 0xe4 */ { NULL, NULL, 0 },
1160 /* 0xe5 */ { NULL, NULL, 0 },
1161 /* 0xe6 */ { NULL, NULL, 0 },
1162 /* 0xe7 */ { NULL, NULL, 0 },
1163 /* 0xe8 */ { NULL, NULL, 0 },
1164 /* 0xe9 */ { NULL, NULL, 0 },
1165 /* 0xea */ { NULL, NULL, 0 },
1166 /* 0xeb */ { NULL, NULL, 0 },
1167 /* 0xec */ { NULL, NULL, 0 },
1168 /* 0xed */ { NULL, NULL, 0 },
1169 /* 0xee */ { NULL, NULL, 0 },
1170 /* 0xef */ { NULL, NULL, 0 },
1171 /* 0xf0 */ { NULL, NULL, 0 },
1172 /* 0xf1 */ { NULL, NULL, 0 },
1173 /* 0xf2 */ { NULL, NULL, 0 },
1174 /* 0xf3 */ { NULL, NULL, 0 },
1175 /* 0xf4 */ { NULL, NULL, 0 },
1176 /* 0xf5 */ { NULL, NULL, 0 },
1177 /* 0xf6 */ { NULL, NULL, 0 },
1178 /* 0xf7 */ { NULL, NULL, 0 },
1179 /* 0xf8 */ { NULL, NULL, 0 },
1180 /* 0xf9 */ { NULL, NULL, 0 },
1181 /* 0xfa */ { NULL, NULL, 0 },
1182 /* 0xfb */ { NULL, NULL, 0 },
1183 /* 0xfc */ { NULL, NULL, 0 },
1184 /* 0xfd */ { NULL, NULL, 0 },
1185 /* 0xfe */ { NULL, NULL, 0 },
1186 /* 0xff */ { NULL, NULL, 0 }
1190 /*******************************************************************
1191 allocate and initialize a reply packet
1192 ********************************************************************/
1194 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1195 const char *inbuf, char **outbuf, uint8_t num_words,
1196 uint32_t num_bytes)
1199 * Protect against integer wrap
1201 if ((num_bytes > 0xffffff)
1202 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1203 char *msg;
1204 if (asprintf(&msg, "num_bytes too large: %u",
1205 (unsigned)num_bytes) == -1) {
1206 msg = CONST_DISCARD(char *, "num_bytes too large");
1208 smb_panic(msg);
1211 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1212 smb_size + num_words*2 + num_bytes);
1213 if (*outbuf == NULL) {
1214 return false;
1217 construct_reply_common(req, inbuf, *outbuf);
1218 srv_set_message(*outbuf, num_words, num_bytes, false);
1220 * Zero out the word area, the caller has to take care of the bcc area
1221 * himself
1223 if (num_words != 0) {
1224 memset(*outbuf + smb_vwv0, 0, num_words*2);
1227 return true;
1230 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1232 char *outbuf;
1233 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1234 num_bytes)) {
1235 smb_panic("could not allocate output buffer\n");
1237 req->outbuf = (uint8_t *)outbuf;
1241 /*******************************************************************
1242 Dump a packet to a file.
1243 ********************************************************************/
1245 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1247 int fd, i;
1248 char *fname = NULL;
1249 if (DEBUGLEVEL < 50) {
1250 return;
1253 if (len < 4) len = smb_len(data)+4;
1254 for (i=1;i<100;i++) {
1255 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1256 type ? "req" : "resp") == -1) {
1257 return;
1259 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1260 if (fd != -1 || errno != EEXIST) break;
1262 if (fd != -1) {
1263 ssize_t ret = write(fd, data, len);
1264 if (ret != len)
1265 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1266 close(fd);
1267 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1269 SAFE_FREE(fname);
1272 /****************************************************************************
1273 Prepare everything for calling the actual request function, and potentially
1274 call the request function via the "new" interface.
1276 Return False if the "legacy" function needs to be called, everything is
1277 prepared.
1279 Return True if we're done.
1281 I know this API sucks, but it is the one with the least code change I could
1282 find.
1283 ****************************************************************************/
1285 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1287 int flags;
1288 uint16 session_tag;
1289 connection_struct *conn = NULL;
1290 struct smbd_server_connection *sconn = smbd_server_conn;
1292 errno = 0;
1294 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1295 * so subtract 4 from it. */
1296 if (!valid_smb_header(req->inbuf)
1297 || (size < (smb_size - 4))) {
1298 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1299 smb_len(req->inbuf)));
1300 exit_server_cleanly("Non-SMB packet");
1303 if (smb_messages[type].fn == NULL) {
1304 DEBUG(0,("Unknown message type %d!\n",type));
1305 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1306 reply_unknown_new(req, type);
1307 return NULL;
1310 flags = smb_messages[type].flags;
1312 /* In share mode security we must ignore the vuid. */
1313 session_tag = (lp_security() == SEC_SHARE)
1314 ? UID_FIELD_INVALID : req->vuid;
1315 conn = req->conn;
1317 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1318 (int)sys_getpid(), (unsigned long)conn));
1320 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1322 /* Ensure this value is replaced in the incoming packet. */
1323 SSVAL(req->inbuf,smb_uid,session_tag);
1326 * Ensure the correct username is in current_user_info. This is a
1327 * really ugly bugfix for problems with multiple session_setup_and_X's
1328 * being done and allowing %U and %G substitutions to work correctly.
1329 * There is a reason this code is done here, don't move it unless you
1330 * know what you're doing... :-).
1331 * JRA.
1334 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1335 user_struct *vuser = NULL;
1337 sconn->smb1.sessions.last_session_tag = session_tag;
1338 if(session_tag != UID_FIELD_INVALID) {
1339 vuser = get_valid_user_struct(sconn, session_tag);
1340 if (vuser) {
1341 set_current_user_info(
1342 vuser->server_info->sanitized_username,
1343 vuser->server_info->unix_name,
1344 pdb_get_domain(vuser->server_info
1345 ->sam_account));
1350 /* Does this call need to be run as the connected user? */
1351 if (flags & AS_USER) {
1353 /* Does this call need a valid tree connection? */
1354 if (!conn) {
1356 * Amazingly, the error code depends on the command
1357 * (from Samba4).
1359 if (type == SMBntcreateX) {
1360 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1361 } else {
1362 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1364 return NULL;
1367 if (!change_to_user(conn,session_tag)) {
1368 DEBUG(0, ("Error: Could not change to user. Removing "
1369 "deferred open, mid=%d.\n", req->mid));
1370 reply_force_doserror(req, ERRSRV, ERRbaduid);
1371 return conn;
1374 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1376 /* Does it need write permission? */
1377 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1378 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1379 return conn;
1382 /* IPC services are limited */
1383 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1384 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1385 return conn;
1387 } else {
1388 /* This call needs to be run as root */
1389 change_to_root_user();
1392 /* load service specific parameters */
1393 if (conn) {
1394 if (req->encrypted) {
1395 conn->encrypted_tid = true;
1396 /* encrypted required from now on. */
1397 conn->encrypt_level = Required;
1398 } else if (ENCRYPTION_REQUIRED(conn)) {
1399 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1400 exit_server_cleanly("encryption required "
1401 "on connection");
1402 return conn;
1406 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1407 (flags & (AS_USER|DO_CHDIR)
1408 ?True:False))) {
1409 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1410 return conn;
1412 conn->num_smb_operations++;
1415 /* does this protocol need to be run as guest? */
1416 if ((flags & AS_GUEST)
1417 && (!change_to_guest() ||
1418 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1419 lp_hostsdeny(-1)))) {
1420 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1421 return conn;
1424 smb_messages[type].fn(req);
1425 return req->conn;
1428 /****************************************************************************
1429 Construct a reply to the incoming packet.
1430 ****************************************************************************/
1432 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1433 uint32_t seqnum, bool encrypted,
1434 struct smb_perfcount_data *deferred_pcd)
1436 connection_struct *conn;
1437 struct smb_request *req;
1439 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1440 smb_panic("could not allocate smb_request");
1443 if (!init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted,
1444 seqnum)) {
1445 exit_server_cleanly("Invalid SMB request");
1448 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1450 /* we popped this message off the queue - keep original perf data */
1451 if (deferred_pcd)
1452 req->pcd = *deferred_pcd;
1453 else {
1454 SMB_PERFCOUNT_START(&req->pcd);
1455 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1456 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1459 conn = switch_message(req->cmd, req, size);
1461 if (req->unread_bytes) {
1462 /* writeX failed. drain socket. */
1463 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1464 req->unread_bytes) {
1465 smb_panic("failed to drain pending bytes");
1467 req->unread_bytes = 0;
1470 if (req->done) {
1471 TALLOC_FREE(req);
1472 return;
1475 if (req->outbuf == NULL) {
1476 return;
1479 if (CVAL(req->outbuf,0) == 0) {
1480 show_msg((char *)req->outbuf);
1483 if (!srv_send_smb(smbd_server_fd(),
1484 (char *)req->outbuf,
1485 true, req->seqnum+1,
1486 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1487 &req->pcd)) {
1488 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1491 TALLOC_FREE(req);
1493 return;
1496 /****************************************************************************
1497 Process an smb from the client
1498 ****************************************************************************/
1499 static void process_smb(struct smbd_server_connection *conn,
1500 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1501 uint32_t seqnum, bool encrypted,
1502 struct smb_perfcount_data *deferred_pcd)
1504 int msg_type = CVAL(inbuf,0);
1506 DO_PROFILE_INC(smb_count);
1508 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1509 smb_len(inbuf) ) );
1510 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1511 (int)nread,
1512 (unsigned int)unread_bytes ));
1514 if (msg_type != 0) {
1516 * NetBIOS session request, keepalive, etc.
1518 reply_special((char *)inbuf);
1519 goto done;
1522 if (smbd_server_conn->allow_smb2) {
1523 if (smbd_is_smb2_header(inbuf, nread)) {
1524 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1525 return;
1527 smbd_server_conn->allow_smb2 = false;
1530 show_msg((char *)inbuf);
1532 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1533 trans_num++;
1535 done:
1536 conn->smb1.num_requests++;
1538 /* The timeout_processing function isn't run nearly
1539 often enough to implement 'max log size' without
1540 overrunning the size of the file by many megabytes.
1541 This is especially true if we are running at debug
1542 level 10. Checking every 50 SMBs is a nice
1543 tradeoff of performance vs log file size overrun. */
1545 if ((conn->smb1.num_requests % 50) == 0 &&
1546 need_to_check_log_size()) {
1547 change_to_root_user();
1548 check_log_size();
1552 /****************************************************************************
1553 Return a string containing the function name of a SMB command.
1554 ****************************************************************************/
1556 const char *smb_fn_name(int type)
1558 const char *unknown_name = "SMBunknown";
1560 if (smb_messages[type].name == NULL)
1561 return(unknown_name);
1563 return(smb_messages[type].name);
1566 /****************************************************************************
1567 Helper functions for contruct_reply.
1568 ****************************************************************************/
1570 void add_to_common_flags2(uint32 v)
1572 common_flags2 |= v;
1575 void remove_from_common_flags2(uint32 v)
1577 common_flags2 &= ~v;
1580 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1581 char *outbuf)
1583 srv_set_message(outbuf,0,0,false);
1585 SCVAL(outbuf, smb_com, req->cmd);
1586 SIVAL(outbuf,smb_rcls,0);
1587 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1588 SSVAL(outbuf,smb_flg2,
1589 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1590 common_flags2);
1591 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1593 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1594 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1595 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1596 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1599 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1601 construct_reply_common(req, (char *)req->inbuf, outbuf);
1605 * How many bytes have we already accumulated up to the current wct field
1606 * offset?
1609 size_t req_wct_ofs(struct smb_request *req)
1611 size_t buf_size;
1613 if (req->chain_outbuf == NULL) {
1614 return smb_wct - 4;
1616 buf_size = talloc_get_size(req->chain_outbuf);
1617 if ((buf_size % 4) != 0) {
1618 buf_size += (4 - (buf_size % 4));
1620 return buf_size - 4;
1624 * Hack around reply_nterror & friends not being aware of chained requests,
1625 * generating illegal (i.e. wct==0) chain replies.
1628 static void fixup_chain_error_packet(struct smb_request *req)
1630 uint8_t *outbuf = req->outbuf;
1631 req->outbuf = NULL;
1632 reply_outbuf(req, 2, 0);
1633 memcpy(req->outbuf, outbuf, smb_wct);
1634 TALLOC_FREE(outbuf);
1635 SCVAL(req->outbuf, smb_vwv0, 0xff);
1639 * @brief Find the smb_cmd offset of the last command pushed
1640 * @param[in] buf The buffer we're building up
1641 * @retval Where can we put our next andx cmd?
1643 * While chaining requests, the "next" request we're looking at needs to put
1644 * its SMB_Command before the data the previous request already built up added
1645 * to the chain. Find the offset to the place where we have to put our cmd.
1648 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1650 uint8_t cmd;
1651 size_t ofs;
1653 cmd = CVAL(buf, smb_com);
1655 SMB_ASSERT(is_andx_req(cmd));
1657 ofs = smb_vwv0;
1659 while (CVAL(buf, ofs) != 0xff) {
1661 if (!is_andx_req(CVAL(buf, ofs))) {
1662 return false;
1666 * ofs is from start of smb header, so add the 4 length
1667 * bytes. The next cmd is right after the wct field.
1669 ofs = SVAL(buf, ofs+2) + 4 + 1;
1671 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1674 *pofs = ofs;
1675 return true;
1679 * @brief Do the smb chaining at a buffer level
1680 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1681 * @param[in] smb_command The command that we want to issue
1682 * @param[in] wct How many words?
1683 * @param[in] vwv The words, already in network order
1684 * @param[in] bytes_alignment How shall we align "bytes"?
1685 * @param[in] num_bytes How many bytes?
1686 * @param[in] bytes The data the request ships
1688 * smb_splice_chain() adds the vwv and bytes to the request already present in
1689 * *poutbuf.
1692 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1693 uint8_t wct, const uint16_t *vwv,
1694 size_t bytes_alignment,
1695 uint32_t num_bytes, const uint8_t *bytes)
1697 uint8_t *outbuf;
1698 size_t old_size, new_size;
1699 size_t ofs;
1700 size_t chain_padding = 0;
1701 size_t bytes_padding = 0;
1702 bool first_request;
1704 old_size = talloc_get_size(*poutbuf);
1707 * old_size == smb_wct means we're pushing the first request in for
1708 * libsmb/
1711 first_request = (old_size == smb_wct);
1713 if (!first_request && ((old_size % 4) != 0)) {
1715 * Align the wct field of subsequent requests to a 4-byte
1716 * boundary
1718 chain_padding = 4 - (old_size % 4);
1722 * After the old request comes the new wct field (1 byte), the vwv's
1723 * and the num_bytes field. After at we might need to align the bytes
1724 * given to us to "bytes_alignment", increasing the num_bytes value.
1727 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1729 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1730 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1733 new_size += bytes_padding + num_bytes;
1735 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1736 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1737 (unsigned)new_size));
1738 return false;
1741 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1742 if (outbuf == NULL) {
1743 DEBUG(0, ("talloc failed\n"));
1744 return false;
1746 *poutbuf = outbuf;
1748 if (first_request) {
1749 SCVAL(outbuf, smb_com, smb_command);
1750 } else {
1751 size_t andx_cmd_ofs;
1753 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1754 DEBUG(1, ("invalid command chain\n"));
1755 *poutbuf = TALLOC_REALLOC_ARRAY(
1756 NULL, *poutbuf, uint8_t, old_size);
1757 return false;
1760 if (chain_padding != 0) {
1761 memset(outbuf + old_size, 0, chain_padding);
1762 old_size += chain_padding;
1765 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1766 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1769 ofs = old_size;
1772 * Push the chained request:
1774 * wct field
1777 SCVAL(outbuf, ofs, wct);
1778 ofs += 1;
1781 * vwv array
1784 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1785 ofs += sizeof(uint16_t) * wct;
1788 * bcc (byte count)
1791 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1792 ofs += sizeof(uint16_t);
1795 * padding
1798 if (bytes_padding != 0) {
1799 memset(outbuf + ofs, 0, bytes_padding);
1800 ofs += bytes_padding;
1804 * The bytes field
1807 memcpy(outbuf + ofs, bytes, num_bytes);
1809 return true;
1812 /****************************************************************************
1813 Construct a chained reply and add it to the already made reply
1814 ****************************************************************************/
1816 void chain_reply(struct smb_request *req)
1818 size_t smblen = smb_len(req->inbuf);
1819 size_t already_used, length_needed;
1820 uint8_t chain_cmd;
1821 uint32_t chain_offset; /* uint32_t to avoid overflow */
1823 uint8_t wct;
1824 uint16_t *vwv;
1825 uint16_t buflen;
1826 uint8_t *buf;
1828 if (IVAL(req->outbuf, smb_rcls) != 0) {
1829 fixup_chain_error_packet(req);
1833 * Any of the AndX requests and replies have at least a wct of
1834 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1835 * beginning of the SMB header to the next wct field.
1837 * None of the AndX requests put anything valuable in vwv[0] and [1],
1838 * so we can overwrite it here to form the chain.
1841 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1842 if (req->chain_outbuf == NULL) {
1843 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1844 req, req->outbuf, uint8_t,
1845 smb_len(req->outbuf) + 4);
1846 if (req->chain_outbuf == NULL) {
1847 smb_panic("talloc failed");
1850 req->outbuf = NULL;
1851 goto error;
1855 * Here we assume that this is the end of the chain. For that we need
1856 * to set "next command" to 0xff and the offset to 0. If we later find
1857 * more commands in the chain, this will be overwritten again.
1860 SCVAL(req->outbuf, smb_vwv0, 0xff);
1861 SCVAL(req->outbuf, smb_vwv0+1, 0);
1862 SSVAL(req->outbuf, smb_vwv1, 0);
1864 if (req->chain_outbuf == NULL) {
1866 * In req->chain_outbuf we collect all the replies. Start the
1867 * chain by copying in the first reply.
1869 * We do the realloc because later on we depend on
1870 * talloc_get_size to determine the length of
1871 * chain_outbuf. The reply_xxx routines might have
1872 * over-allocated (reply_pipe_read_and_X used to be such an
1873 * example).
1875 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1876 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1877 if (req->chain_outbuf == NULL) {
1878 smb_panic("talloc failed");
1880 req->outbuf = NULL;
1881 } else {
1883 * Update smb headers where subsequent chained commands
1884 * may have updated them.
1886 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1887 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1889 if (!smb_splice_chain(&req->chain_outbuf,
1890 CVAL(req->outbuf, smb_com),
1891 CVAL(req->outbuf, smb_wct),
1892 (uint16_t *)(req->outbuf + smb_vwv),
1893 0, smb_buflen(req->outbuf),
1894 (uint8_t *)smb_buf(req->outbuf))) {
1895 goto error;
1897 TALLOC_FREE(req->outbuf);
1901 * We use the old request's vwv field to grab the next chained command
1902 * and offset into the chained fields.
1905 chain_cmd = CVAL(req->vwv+0, 0);
1906 chain_offset = SVAL(req->vwv+1, 0);
1908 if (chain_cmd == 0xff) {
1910 * End of chain, no more requests from the client. So ship the
1911 * replies.
1913 smb_setlen((char *)(req->chain_outbuf),
1914 talloc_get_size(req->chain_outbuf) - 4);
1916 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1917 true, req->seqnum+1,
1918 IS_CONN_ENCRYPTED(req->conn)
1919 ||req->encrypted,
1920 &req->pcd)) {
1921 exit_server_cleanly("chain_reply: srv_send_smb "
1922 "failed.");
1924 TALLOC_FREE(req->chain_outbuf);
1925 req->done = true;
1926 return;
1929 /* add a new perfcounter for this element of chain */
1930 SMB_PERFCOUNT_ADD(&req->pcd);
1931 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1932 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1935 * Check if the client tries to fool us. The request so far uses the
1936 * space to the end of the byte buffer in the request just
1937 * processed. The chain_offset can't point into that area. If that was
1938 * the case, we could end up with an endless processing of the chain,
1939 * we would always handle the same request.
1942 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1943 if (chain_offset < already_used) {
1944 goto error;
1948 * Next check: Make sure the chain offset does not point beyond the
1949 * overall smb request length.
1952 length_needed = chain_offset+1; /* wct */
1953 if (length_needed > smblen) {
1954 goto error;
1958 * Now comes the pointer magic. Goal here is to set up req->vwv and
1959 * req->buf correctly again to be able to call the subsequent
1960 * switch_message(). The chain offset (the former vwv[1]) points at
1961 * the new wct field.
1964 wct = CVAL(smb_base(req->inbuf), chain_offset);
1967 * Next consistency check: Make the new vwv array fits in the overall
1968 * smb request.
1971 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1972 if (length_needed > smblen) {
1973 goto error;
1975 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1978 * Now grab the new byte buffer....
1981 buflen = SVAL(vwv+wct, 0);
1984 * .. and check that it fits.
1987 length_needed += buflen;
1988 if (length_needed > smblen) {
1989 goto error;
1991 buf = (uint8_t *)(vwv+wct+1);
1993 req->cmd = chain_cmd;
1994 req->wct = wct;
1995 req->vwv = vwv;
1996 req->buflen = buflen;
1997 req->buf = buf;
1999 switch_message(chain_cmd, req, smblen);
2001 if (req->outbuf == NULL) {
2003 * This happens if the chained command has suspended itself or
2004 * if it has called srv_send_smb() itself.
2006 return;
2010 * We end up here if the chained command was not itself chained or
2011 * suspended, but for example a close() command. We now need to splice
2012 * the chained commands' outbuf into the already built up chain_outbuf
2013 * and ship the result.
2015 goto done;
2017 error:
2019 * We end up here if there's any error in the chain syntax. Report a
2020 * DOS error, just like Windows does.
2022 reply_force_doserror(req, ERRSRV, ERRerror);
2023 fixup_chain_error_packet(req);
2025 done:
2027 * This scary statement intends to set the
2028 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2029 * to the value req->outbuf carries
2031 SSVAL(req->chain_outbuf, smb_flg2,
2032 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2033 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2036 * Transfer the error codes from the subrequest to the main one
2038 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2039 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2041 if (!smb_splice_chain(&req->chain_outbuf,
2042 CVAL(req->outbuf, smb_com),
2043 CVAL(req->outbuf, smb_wct),
2044 (uint16_t *)(req->outbuf + smb_vwv),
2045 0, smb_buflen(req->outbuf),
2046 (uint8_t *)smb_buf(req->outbuf))) {
2047 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2049 TALLOC_FREE(req->outbuf);
2051 smb_setlen((char *)(req->chain_outbuf),
2052 talloc_get_size(req->chain_outbuf) - 4);
2054 show_msg((char *)(req->chain_outbuf));
2056 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2057 true, req->seqnum+1,
2058 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2059 &req->pcd)) {
2060 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2062 TALLOC_FREE(req->chain_outbuf);
2063 req->done = true;
2066 /****************************************************************************
2067 Check if services need reloading.
2068 ****************************************************************************/
2070 void check_reload(time_t t)
2072 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2074 if(last_smb_conf_reload_time == 0) {
2075 last_smb_conf_reload_time = t;
2076 /* Our printing subsystem might not be ready at smbd start up.
2077 Then no printer is available till the first printers check
2078 is performed. A lower initial interval circumvents this. */
2079 if ( printcap_cache_time > 60 )
2080 last_printer_reload_time = t - printcap_cache_time + 60;
2081 else
2082 last_printer_reload_time = t;
2085 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2086 /* randomize over 60 second the printcap reload to avoid all
2087 * process hitting cupsd at the same time */
2088 int time_range = 60;
2090 last_printer_reload_time += random() % time_range;
2091 mypid = getpid();
2094 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2095 reload_services(True);
2096 last_smb_conf_reload_time = t;
2099 /* 'printcap cache time = 0' disable the feature */
2101 if ( printcap_cache_time != 0 )
2103 /* see if it's time to reload or if the clock has been set back */
2105 if ( (t >= last_printer_reload_time+printcap_cache_time)
2106 || (t-last_printer_reload_time < 0) )
2108 DEBUG( 3,( "Printcap cache time expired.\n"));
2109 reload_printers();
2110 last_printer_reload_time = t;
2115 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2117 /* TODO: make write nonblocking */
2120 static void smbd_server_connection_read_handler(struct smbd_server_connection *conn)
2122 uint8_t *inbuf = NULL;
2123 size_t inbuf_len = 0;
2124 size_t unread_bytes = 0;
2125 bool encrypted = false;
2126 TALLOC_CTX *mem_ctx = talloc_tos();
2127 NTSTATUS status;
2128 uint32_t seqnum;
2130 bool ok;
2132 ok = smbd_lock_socket(conn);
2133 if (!ok) {
2134 exit_server_cleanly("failed to lock socket");
2137 /* TODO: make this completely nonblocking */
2138 status = receive_smb_talloc(mem_ctx, smbd_server_fd(),
2139 (char **)(void *)&inbuf,
2140 0, /* timeout */
2141 &unread_bytes,
2142 &encrypted,
2143 &inbuf_len, &seqnum,
2144 false /* trusted channel */);
2145 ok = smbd_unlock_socket(conn);
2146 if (!ok) {
2147 exit_server_cleanly("failed to unlock");
2150 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2151 goto process;
2153 if (NT_STATUS_IS_ERR(status)) {
2154 exit_server_cleanly("failed to receive smb request");
2156 if (!NT_STATUS_IS_OK(status)) {
2157 return;
2160 process:
2161 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2162 seqnum, encrypted, NULL);
2165 static void smbd_server_connection_handler(struct event_context *ev,
2166 struct fd_event *fde,
2167 uint16_t flags,
2168 void *private_data)
2170 struct smbd_server_connection *conn = talloc_get_type(private_data,
2171 struct smbd_server_connection);
2173 if (flags & EVENT_FD_WRITE) {
2174 smbd_server_connection_write_handler(conn);
2175 } else if (flags & EVENT_FD_READ) {
2176 smbd_server_connection_read_handler(conn);
2181 /****************************************************************************
2182 received when we should release a specific IP
2183 ****************************************************************************/
2184 static void release_ip(const char *ip, void *priv)
2186 char addr[INET6_ADDRSTRLEN];
2187 char *p = addr;
2189 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2191 if (strncmp("::ffff:", addr, 7) == 0) {
2192 p = addr + 7;
2195 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2196 /* we can't afford to do a clean exit - that involves
2197 database writes, which would potentially mean we
2198 are still running after the failover has finished -
2199 we have to get rid of this process ID straight
2200 away */
2201 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2202 ip));
2203 /* note we must exit with non-zero status so the unclean handler gets
2204 called in the parent, so that the brl database is tickled */
2205 _exit(1);
2209 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2210 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2212 release_ip((char *)data->data, NULL);
2215 #ifdef CLUSTER_SUPPORT
2216 static int client_get_tcp_info(struct sockaddr_storage *server,
2217 struct sockaddr_storage *client)
2219 socklen_t length;
2220 if (server_fd == -1) {
2221 return -1;
2223 length = sizeof(*server);
2224 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2225 return -1;
2227 length = sizeof(*client);
2228 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2229 return -1;
2231 return 0;
2233 #endif
2236 * Send keepalive packets to our client
2238 static bool keepalive_fn(const struct timeval *now, void *private_data)
2240 bool ok;
2241 bool ret;
2243 ok = smbd_lock_socket(smbd_server_conn);
2244 if (!ok) {
2245 exit_server_cleanly("failed to lock socket");
2248 ret = send_keepalive(smbd_server_fd());
2250 ok = smbd_unlock_socket(smbd_server_conn);
2251 if (!ok) {
2252 exit_server_cleanly("failed to unlock socket");
2255 if (!ret) {
2256 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2257 return False;
2259 return True;
2263 * Do the recurring check if we're idle
2265 static bool deadtime_fn(const struct timeval *now, void *private_data)
2267 struct smbd_server_connection *sconn = smbd_server_conn;
2268 if ((conn_num_open(sconn) == 0)
2269 || (conn_idle_all(sconn, now->tv_sec))) {
2270 DEBUG( 2, ( "Closing idle connection\n" ) );
2271 messaging_send(smbd_messaging_context(), procid_self(),
2272 MSG_SHUTDOWN, &data_blob_null);
2273 return False;
2276 return True;
2280 * Do the recurring log file and smb.conf reload checks.
2283 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2285 change_to_root_user();
2287 /* update printer queue caches if necessary */
2288 update_monitored_printq_cache();
2290 /* check if we need to reload services */
2291 check_reload(time(NULL));
2293 /* Change machine password if neccessary. */
2294 attempt_machine_password_change();
2297 * Force a log file check.
2299 force_check_log_size();
2300 check_log_size();
2301 return true;
2304 /****************************************************************************
2305 Process commands from the client
2306 ****************************************************************************/
2308 void smbd_process(void)
2310 TALLOC_CTX *frame = talloc_stackframe();
2311 char remaddr[INET6_ADDRSTRLEN];
2313 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2314 lp_security() != SEC_SHARE) {
2315 smbd_server_conn->allow_smb2 = true;
2318 /* Ensure child is set to blocking mode */
2319 set_blocking(smbd_server_fd(),True);
2321 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2322 set_socket_options(smbd_server_fd(), lp_socket_options());
2324 /* this is needed so that we get decent entries
2325 in smbstatus for port 445 connects */
2326 set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2327 remaddr,
2328 sizeof(remaddr)),
2329 false);
2330 reload_services(true);
2333 * Before the first packet, check the global hosts allow/ hosts deny
2334 * parameters before doing any parsing of packets passed to us by the
2335 * client. This prevents attacks on our parsing code from hosts not in
2336 * the hosts allow list.
2339 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2340 lp_hostsdeny(-1))) {
2341 char addr[INET6_ADDRSTRLEN];
2344 * send a negative session response "not listening on calling
2345 * name"
2347 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2348 DEBUG( 1, ("Connection denied from %s\n",
2349 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2350 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2351 0, false, NULL);
2352 exit_server_cleanly("connection denied");
2355 static_init_rpc;
2357 init_modules();
2359 smb_perfcount_init();
2361 if (!init_account_policy()) {
2362 exit_server("Could not open account policy tdb.\n");
2365 if (*lp_rootdir()) {
2366 if (chroot(lp_rootdir()) != 0) {
2367 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2368 exit_server("Failed to chroot()");
2370 if (chdir("/") == -1) {
2371 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2372 exit_server("Failed to chroot()");
2374 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2377 if (!srv_init_signing(smbd_server_conn)) {
2378 exit_server("Failed to init smb_signing");
2381 /* Setup oplocks */
2382 if (!init_oplocks(smbd_messaging_context()))
2383 exit_server("Failed to init oplocks");
2385 /* Setup aio signal handler. */
2386 initialize_async_io_handler();
2388 /* register our message handlers */
2389 messaging_register(smbd_messaging_context(), NULL,
2390 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2391 messaging_register(smbd_messaging_context(), NULL,
2392 MSG_SMB_RELEASE_IP, msg_release_ip);
2393 messaging_register(smbd_messaging_context(), NULL,
2394 MSG_SMB_CLOSE_FILE, msg_close_file);
2397 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2398 * MSGs to all child processes
2400 messaging_deregister(smbd_messaging_context(),
2401 MSG_DEBUG, NULL);
2402 messaging_register(smbd_messaging_context(), NULL,
2403 MSG_DEBUG, debug_message);
2405 if ((lp_keepalive() != 0)
2406 && !(event_add_idle(smbd_event_context(), NULL,
2407 timeval_set(lp_keepalive(), 0),
2408 "keepalive", keepalive_fn,
2409 NULL))) {
2410 DEBUG(0, ("Could not add keepalive event\n"));
2411 exit(1);
2414 if (!(event_add_idle(smbd_event_context(), NULL,
2415 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2416 "deadtime", deadtime_fn, NULL))) {
2417 DEBUG(0, ("Could not add deadtime event\n"));
2418 exit(1);
2421 if (!(event_add_idle(smbd_event_context(), NULL,
2422 timeval_set(SMBD_SELECT_TIMEOUT, 0),
2423 "housekeeping", housekeeping_fn, NULL))) {
2424 DEBUG(0, ("Could not add housekeeping event\n"));
2425 exit(1);
2428 #ifdef CLUSTER_SUPPORT
2430 if (lp_clustering()) {
2432 * We need to tell ctdb about our client's TCP
2433 * connection, so that for failover ctdbd can send
2434 * tickle acks, triggering a reconnection by the
2435 * client.
2438 struct sockaddr_storage srv, clnt;
2440 if (client_get_tcp_info(&srv, &clnt) == 0) {
2442 NTSTATUS status;
2444 status = ctdbd_register_ips(
2445 messaging_ctdbd_connection(),
2446 &srv, &clnt, release_ip, NULL);
2448 if (!NT_STATUS_IS_OK(status)) {
2449 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2450 nt_errstr(status)));
2452 } else
2454 DEBUG(0,("Unable to get tcp info for "
2455 "CTDB_CONTROL_TCP_CLIENT: %s\n",
2456 strerror(errno)));
2460 #endif
2462 smbd_server_conn->nbt.got_session = false;
2464 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2466 smbd_server_conn->smb1.sessions.done_sesssetup = false;
2467 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
2468 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
2469 /* users from session setup */
2470 smbd_server_conn->smb1.sessions.session_userlist = NULL;
2471 /* workgroup from session setup. */
2472 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
2473 /* this holds info on user ids that are already validated for this VC */
2474 smbd_server_conn->smb1.sessions.validated_users = NULL;
2475 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
2476 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
2477 #ifdef HAVE_NETGROUP
2478 smbd_server_conn->smb1.sessions.my_yp_domain = NULL;
2479 #endif
2481 conn_init(smbd_server_conn);
2482 if (!init_dptrs(smbd_server_conn)) {
2483 exit_server("init_dptrs() failed");
2486 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
2487 smbd_server_conn,
2488 smbd_server_fd(),
2489 EVENT_FD_READ,
2490 smbd_server_connection_handler,
2491 smbd_server_conn);
2492 if (!smbd_server_conn->smb1.fde) {
2493 exit_server("failed to create smbd_server_connection fde");
2496 TALLOC_FREE(frame);
2498 while (True) {
2499 NTSTATUS status;
2501 frame = talloc_stackframe_pool(8192);
2503 errno = 0;
2505 status = smbd_server_connection_loop_once(smbd_server_conn);
2506 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2507 !NT_STATUS_IS_OK(status)) {
2508 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2509 " exiting\n", nt_errstr(status)));
2510 break;
2513 TALLOC_FREE(frame);
2516 exit_server_cleanly(NULL);
2519 bool req_is_in_chain(struct smb_request *req)
2521 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2523 * We're right now handling a subsequent request, so we must
2524 * be in a chain
2526 return true;
2529 if (!is_andx_req(req->cmd)) {
2530 return false;
2533 if (req->wct < 2) {
2535 * Okay, an illegal request, but definitely not chained :-)
2537 return false;
2540 return (CVAL(req->vwv+0, 0) != 0xFF);