s3:smbd: readd START_PROFILE(smbd_idle)/END_PROFILE(smbd_idle)
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blob5e26826d6a96e573bf30df707b22d90e396c5665
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 "../lib/tsocket/tsocket.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "librpc/gen_ndr/netlogon.h"
27 #include "../lib/async_req/async_sock.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/select.h"
30 #include "printing/queue_process.h"
31 #include "system/select.h"
32 #include "passdb.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "smbprofile.h"
36 #include "rpc_server/spoolss/srv_spoolss_nt.h"
37 #include "libsmb/libsmb.h"
38 #include "../lib/util/tevent_ntstatus.h"
39 #include "../libcli/security/dom_sid.h"
40 #include "../libcli/security/security_token.h"
41 #include "lib/id_cache.h"
42 #include "serverid.h"
44 extern bool global_machine_password_needs_changing;
46 /* Internal message queue for deferred opens. */
47 struct pending_message_list {
48 struct pending_message_list *next, *prev;
49 struct timeval request_time; /* When was this first issued? */
50 struct smbd_server_connection *sconn;
51 struct timed_event *te;
52 struct smb_perfcount_data pcd;
53 uint32_t seqnum;
54 bool encrypted;
55 bool processed;
56 DATA_BLOB buf;
57 DATA_BLOB private_data;
60 static void construct_reply_common(struct smb_request *req, const char *inbuf,
61 char *outbuf);
62 static struct pending_message_list *get_deferred_open_message_smb(
63 struct smbd_server_connection *sconn, uint64_t mid);
64 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf);
66 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
68 bool ok;
70 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
71 return true;
74 sconn->smb1.echo_handler.ref_count++;
76 if (sconn->smb1.echo_handler.ref_count > 1) {
77 return true;
80 DEBUG(10,("pid[%d] wait for socket lock\n", (int)getpid()));
82 do {
83 ok = fcntl_lock(
84 sconn->smb1.echo_handler.socket_lock_fd,
85 F_SETLKW, 0, 0, F_WRLCK);
86 } while (!ok && (errno == EINTR));
88 if (!ok) {
89 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
90 return false;
93 DEBUG(10,("pid[%d] got for socket lock\n", (int)getpid()));
95 return true;
98 void smbd_lock_socket(struct smbd_server_connection *sconn)
100 if (!smbd_lock_socket_internal(sconn)) {
101 exit_server_cleanly("failed to lock socket");
105 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
107 bool ok;
109 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
110 return true;
113 sconn->smb1.echo_handler.ref_count--;
115 if (sconn->smb1.echo_handler.ref_count > 0) {
116 return true;
119 do {
120 ok = fcntl_lock(
121 sconn->smb1.echo_handler.socket_lock_fd,
122 F_SETLKW, 0, 0, F_UNLCK);
123 } while (!ok && (errno == EINTR));
125 if (!ok) {
126 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
127 return false;
130 DEBUG(10,("pid[%d] unlocked socket\n", (int)getpid()));
132 return true;
135 void smbd_unlock_socket(struct smbd_server_connection *sconn)
137 if (!smbd_unlock_socket_internal(sconn)) {
138 exit_server_cleanly("failed to unlock socket");
142 /* Accessor function for smb_read_error for smbd functions. */
144 /****************************************************************************
145 Send an smb to a fd.
146 ****************************************************************************/
148 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
149 bool do_signing, uint32_t seqnum,
150 bool do_encrypt,
151 struct smb_perfcount_data *pcd)
153 size_t len = 0;
154 size_t nwritten=0;
155 ssize_t ret;
156 char *buf_out = buffer;
158 smbd_lock_socket(sconn);
160 if (do_signing) {
161 /* Sign the outgoing packet if required. */
162 srv_calculate_sign_mac(sconn, buf_out, seqnum);
165 if (do_encrypt) {
166 NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
167 if (!NT_STATUS_IS_OK(status)) {
168 DEBUG(0, ("send_smb: SMB encryption failed "
169 "on outgoing packet! Error %s\n",
170 nt_errstr(status) ));
171 goto out;
175 len = smb_len(buf_out) + 4;
177 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
178 if (ret <= 0) {
180 char addr[INET6_ADDRSTRLEN];
182 * Try and give an error message saying what
183 * client failed.
185 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
186 (int)getpid(), (int)len,
187 get_peer_addr(sconn->sock, addr, sizeof(addr)),
188 (int)ret, strerror(errno) ));
190 srv_free_enc_buffer(sconn, buf_out);
191 goto out;
194 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
195 srv_free_enc_buffer(sconn, buf_out);
196 out:
197 SMB_PERFCOUNT_END(pcd);
199 smbd_unlock_socket(sconn);
200 return true;
203 /*******************************************************************
204 Setup the word count and byte count for a smb message.
205 ********************************************************************/
207 int srv_set_message(char *buf,
208 int num_words,
209 int num_bytes,
210 bool zero)
212 if (zero && (num_words || num_bytes)) {
213 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
215 SCVAL(buf,smb_wct,num_words);
216 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
217 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
218 return (smb_size + num_words*2 + num_bytes);
221 static bool valid_smb_header(struct smbd_server_connection *sconn,
222 const uint8_t *inbuf)
224 if (is_encrypted_packet(sconn, inbuf)) {
225 return true;
228 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
229 * but it just looks weird to call strncmp for this one.
231 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
234 /* Socket functions for smbd packet processing. */
236 static bool valid_packet_size(size_t len)
239 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
240 * of header. Don't print the error if this fits.... JRA.
243 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
244 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
245 (unsigned long)len));
246 return false;
248 return true;
251 static NTSTATUS read_packet_remainder(int fd, char *buffer,
252 unsigned int timeout, ssize_t len)
254 NTSTATUS status;
256 if (len <= 0) {
257 return NT_STATUS_OK;
260 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
261 if (!NT_STATUS_IS_OK(status)) {
262 char addr[INET6_ADDRSTRLEN];
263 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
264 "error = %s.\n",
265 get_peer_addr(fd, addr, sizeof(addr)),
266 nt_errstr(status)));
268 return status;
271 /****************************************************************************
272 Attempt a zerocopy writeX read. We know here that len > smb_size-4
273 ****************************************************************************/
276 * Unfortunately, earlier versions of smbclient/libsmbclient
277 * don't send this "standard" writeX header. I've fixed this
278 * for 3.2 but we'll use the old method with earlier versions.
279 * Windows and CIFSFS at least use this standard size. Not
280 * sure about MacOSX.
283 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
284 (2*14) + /* word count (including bcc) */ \
285 1 /* pad byte */)
287 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
288 const char lenbuf[4],
289 struct smbd_server_connection *sconn,
290 int sock,
291 char **buffer,
292 unsigned int timeout,
293 size_t *p_unread,
294 size_t *len_ret)
296 /* Size of a WRITEX call (+4 byte len). */
297 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
298 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
299 ssize_t toread;
300 NTSTATUS status;
302 memcpy(writeX_header, lenbuf, 4);
304 status = read_fd_with_timeout(
305 sock, writeX_header + 4,
306 STANDARD_WRITE_AND_X_HEADER_SIZE,
307 STANDARD_WRITE_AND_X_HEADER_SIZE,
308 timeout, NULL);
310 if (!NT_STATUS_IS_OK(status)) {
311 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
312 "error = %s.\n",
313 tsocket_address_string(sconn->remote_address,
314 talloc_tos()),
315 nt_errstr(status)));
316 return status;
320 * Ok - now try and see if this is a possible
321 * valid writeX call.
324 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
326 * If the data offset is beyond what
327 * we've read, drain the extra bytes.
329 uint16_t doff = SVAL(writeX_header,smb_vwv11);
330 ssize_t newlen;
332 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
333 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
334 if (drain_socket(sock, drain) != drain) {
335 smb_panic("receive_smb_raw_talloc_partial_read:"
336 " failed to drain pending bytes");
338 } else {
339 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
342 /* Spoof down the length and null out the bcc. */
343 set_message_bcc(writeX_header, 0);
344 newlen = smb_len(writeX_header);
346 /* Copy the header we've written. */
348 *buffer = (char *)talloc_memdup(mem_ctx,
349 writeX_header,
350 sizeof(writeX_header));
352 if (*buffer == NULL) {
353 DEBUG(0, ("Could not allocate inbuf of length %d\n",
354 (int)sizeof(writeX_header)));
355 return NT_STATUS_NO_MEMORY;
358 /* Work out the remaining bytes. */
359 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
360 *len_ret = newlen + 4;
361 return NT_STATUS_OK;
364 if (!valid_packet_size(len)) {
365 return NT_STATUS_INVALID_PARAMETER;
369 * Not a valid writeX call. Just do the standard
370 * talloc and return.
373 *buffer = talloc_array(mem_ctx, char, len+4);
375 if (*buffer == NULL) {
376 DEBUG(0, ("Could not allocate inbuf of length %d\n",
377 (int)len+4));
378 return NT_STATUS_NO_MEMORY;
381 /* Copy in what we already read. */
382 memcpy(*buffer,
383 writeX_header,
384 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
385 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
387 if(toread > 0) {
388 status = read_packet_remainder(
389 sock,
390 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
391 timeout, toread);
393 if (!NT_STATUS_IS_OK(status)) {
394 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
395 nt_errstr(status)));
396 return status;
400 *len_ret = len + 4;
401 return NT_STATUS_OK;
404 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
405 struct smbd_server_connection *sconn,
406 int sock,
407 char **buffer, unsigned int timeout,
408 size_t *p_unread, size_t *plen)
410 char lenbuf[4];
411 size_t len;
412 int min_recv_size = lp_min_receive_file_size();
413 NTSTATUS status;
415 *p_unread = 0;
417 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
418 &len);
419 if (!NT_STATUS_IS_OK(status)) {
420 return status;
423 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
424 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
425 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
426 !srv_is_signing_active(sconn) &&
427 sconn->smb1.echo_handler.trusted_fde == NULL) {
429 return receive_smb_raw_talloc_partial_read(
430 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
431 p_unread, plen);
434 if (!valid_packet_size(len)) {
435 return NT_STATUS_INVALID_PARAMETER;
439 * The +4 here can't wrap, we've checked the length above already.
442 *buffer = talloc_array(mem_ctx, char, len+4);
444 if (*buffer == NULL) {
445 DEBUG(0, ("Could not allocate inbuf of length %d\n",
446 (int)len+4));
447 return NT_STATUS_NO_MEMORY;
450 memcpy(*buffer, lenbuf, sizeof(lenbuf));
452 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
453 if (!NT_STATUS_IS_OK(status)) {
454 return status;
457 *plen = len + 4;
458 return NT_STATUS_OK;
461 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
462 struct smbd_server_connection *sconn,
463 int sock,
464 char **buffer, unsigned int timeout,
465 size_t *p_unread, bool *p_encrypted,
466 size_t *p_len,
467 uint32_t *seqnum,
468 bool trusted_channel)
470 size_t len = 0;
471 NTSTATUS status;
473 *p_encrypted = false;
475 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
476 p_unread, &len);
477 if (!NT_STATUS_IS_OK(status)) {
478 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
479 ("receive_smb_raw_talloc failed for client %s "
480 "read error = %s.\n",
481 tsocket_address_string(sconn->remote_address,
482 talloc_tos()),
483 nt_errstr(status)) );
484 return status;
487 if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
488 status = srv_decrypt_buffer(sconn, *buffer);
489 if (!NT_STATUS_IS_OK(status)) {
490 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
491 "incoming packet! Error %s\n",
492 nt_errstr(status) ));
493 return status;
495 *p_encrypted = true;
498 /* Check the incoming SMB signature. */
499 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
500 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
501 "incoming packet!\n"));
502 return NT_STATUS_INVALID_NETWORK_RESPONSE;
505 *p_len = len;
506 return NT_STATUS_OK;
510 * Initialize a struct smb_request from an inbuf
513 static bool init_smb_request(struct smb_request *req,
514 struct smbd_server_connection *sconn,
515 const uint8 *inbuf,
516 size_t unread_bytes, bool encrypted,
517 uint32_t seqnum)
519 size_t req_size = smb_len(inbuf) + 4;
520 /* Ensure we have at least smb_size bytes. */
521 if (req_size < smb_size) {
522 DEBUG(0,("init_smb_request: invalid request size %u\n",
523 (unsigned int)req_size ));
524 return false;
526 req->cmd = CVAL(inbuf, smb_com);
527 req->flags2 = SVAL(inbuf, smb_flg2);
528 req->smbpid = SVAL(inbuf, smb_pid);
529 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
530 req->seqnum = seqnum;
531 req->vuid = SVAL(inbuf, smb_uid);
532 req->tid = SVAL(inbuf, smb_tid);
533 req->wct = CVAL(inbuf, smb_wct);
534 req->vwv = (const uint16_t *)(inbuf+smb_vwv);
535 req->buflen = smb_buflen(inbuf);
536 req->buf = (const uint8_t *)smb_buf_const(inbuf);
537 req->unread_bytes = unread_bytes;
538 req->encrypted = encrypted;
539 req->sconn = sconn;
540 req->conn = conn_find(sconn,req->tid);
541 req->chain_fsp = NULL;
542 req->smb2req = NULL;
543 req->priv_paths = NULL;
544 req->chain = NULL;
545 smb_init_perfcount_data(&req->pcd);
547 /* Ensure we have at least wct words and 2 bytes of bcc. */
548 if (smb_size + req->wct*2 > req_size) {
549 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
550 (unsigned int)req->wct,
551 (unsigned int)req_size));
552 return false;
554 /* Ensure bcc is correct. */
555 if (((const uint8_t *)smb_buf_const(inbuf)) + req->buflen > inbuf + req_size) {
556 DEBUG(0,("init_smb_request: invalid bcc number %u "
557 "(wct = %u, size %u)\n",
558 (unsigned int)req->buflen,
559 (unsigned int)req->wct,
560 (unsigned int)req_size));
561 return false;
564 req->outbuf = NULL;
565 return true;
568 static void process_smb(struct smbd_server_connection *conn,
569 uint8_t *inbuf, size_t nread, size_t unread_bytes,
570 uint32_t seqnum, bool encrypted,
571 struct smb_perfcount_data *deferred_pcd);
573 static void smbd_deferred_open_timer(struct event_context *ev,
574 struct timed_event *te,
575 struct timeval _tval,
576 void *private_data)
578 struct pending_message_list *msg = talloc_get_type(private_data,
579 struct pending_message_list);
580 struct smbd_server_connection *sconn = msg->sconn;
581 TALLOC_CTX *mem_ctx = talloc_tos();
582 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
583 uint8_t *inbuf;
585 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
586 msg->buf.length);
587 if (inbuf == NULL) {
588 exit_server("smbd_deferred_open_timer: talloc failed\n");
589 return;
592 /* We leave this message on the queue so the open code can
593 know this is a retry. */
594 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
595 (unsigned long long)mid ));
597 /* Mark the message as processed so this is not
598 * re-processed in error. */
599 msg->processed = true;
601 process_smb(sconn, inbuf,
602 msg->buf.length, 0,
603 msg->seqnum, msg->encrypted, &msg->pcd);
605 /* If it's still there and was processed, remove it. */
606 msg = get_deferred_open_message_smb(sconn, mid);
607 if (msg && msg->processed) {
608 remove_deferred_open_message_smb(sconn, mid);
612 /****************************************************************************
613 Function to push a message onto the tail of a linked list of smb messages ready
614 for processing.
615 ****************************************************************************/
617 static bool push_queued_message(struct smb_request *req,
618 struct timeval request_time,
619 struct timeval end_time,
620 char *private_data, size_t private_len)
622 int msg_len = smb_len(req->inbuf) + 4;
623 struct pending_message_list *msg;
625 msg = talloc_zero(NULL, struct pending_message_list);
627 if(msg == NULL) {
628 DEBUG(0,("push_message: malloc fail (1)\n"));
629 return False;
631 msg->sconn = req->sconn;
633 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
634 if(msg->buf.data == NULL) {
635 DEBUG(0,("push_message: malloc fail (2)\n"));
636 TALLOC_FREE(msg);
637 return False;
640 msg->request_time = request_time;
641 msg->seqnum = req->seqnum;
642 msg->encrypted = req->encrypted;
643 msg->processed = false;
644 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
646 if (private_data) {
647 msg->private_data = data_blob_talloc(msg, private_data,
648 private_len);
649 if (msg->private_data.data == NULL) {
650 DEBUG(0,("push_message: malloc fail (3)\n"));
651 TALLOC_FREE(msg);
652 return False;
656 msg->te = tevent_add_timer(msg->sconn->ev_ctx,
657 msg,
658 end_time,
659 smbd_deferred_open_timer,
660 msg);
661 if (!msg->te) {
662 DEBUG(0,("push_message: event_add_timed failed\n"));
663 TALLOC_FREE(msg);
664 return false;
667 DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
668 struct pending_message_list *);
670 DEBUG(10,("push_message: pushed message length %u on "
671 "deferred_open_queue\n", (unsigned int)msg_len));
673 return True;
676 /****************************************************************************
677 Function to delete a sharing violation open message by mid.
678 ****************************************************************************/
680 void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
681 uint64_t mid)
683 struct pending_message_list *pml;
685 if (sconn->using_smb2) {
686 remove_deferred_open_message_smb2(sconn, mid);
687 return;
690 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
691 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
692 DEBUG(10,("remove_deferred_open_message_smb: "
693 "deleting mid %llu len %u\n",
694 (unsigned long long)mid,
695 (unsigned int)pml->buf.length ));
696 DLIST_REMOVE(sconn->deferred_open_queue, pml);
697 TALLOC_FREE(pml);
698 return;
703 /****************************************************************************
704 Move a sharing violation open retry message to the front of the list and
705 schedule it for immediate processing.
706 ****************************************************************************/
708 void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
709 uint64_t mid)
711 struct pending_message_list *pml;
712 int i = 0;
714 if (sconn->using_smb2) {
715 schedule_deferred_open_message_smb2(sconn, mid);
716 return;
719 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
720 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
722 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
723 "msg_mid = %llu\n",
724 i++,
725 (unsigned long long)msg_mid ));
727 if (mid == msg_mid) {
728 struct timed_event *te;
730 if (pml->processed) {
731 /* A processed message should not be
732 * rescheduled. */
733 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
734 "message mid %llu was already processed\n",
735 (unsigned long long)msg_mid ));
736 continue;
739 DEBUG(10,("schedule_deferred_open_message_smb: "
740 "scheduling mid %llu\n",
741 (unsigned long long)mid ));
743 te = tevent_add_timer(pml->sconn->ev_ctx,
744 pml,
745 timeval_zero(),
746 smbd_deferred_open_timer,
747 pml);
748 if (!te) {
749 DEBUG(10,("schedule_deferred_open_message_smb: "
750 "event_add_timed() failed, "
751 "skipping mid %llu\n",
752 (unsigned long long)msg_mid ));
755 TALLOC_FREE(pml->te);
756 pml->te = te;
757 DLIST_PROMOTE(sconn->deferred_open_queue, pml);
758 return;
762 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
763 "find message mid %llu\n",
764 (unsigned long long)mid ));
767 /****************************************************************************
768 Return true if this mid is on the deferred queue and was not yet processed.
769 ****************************************************************************/
771 bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
773 struct pending_message_list *pml;
775 if (sconn->using_smb2) {
776 return open_was_deferred_smb2(sconn, mid);
779 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
780 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
781 return True;
784 return False;
787 /****************************************************************************
788 Return the message queued by this mid.
789 ****************************************************************************/
791 static struct pending_message_list *get_deferred_open_message_smb(
792 struct smbd_server_connection *sconn, uint64_t mid)
794 struct pending_message_list *pml;
796 for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
797 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
798 return pml;
801 return NULL;
804 /****************************************************************************
805 Get the state data queued by this mid.
806 ****************************************************************************/
808 bool get_deferred_open_message_state(struct smb_request *smbreq,
809 struct timeval *p_request_time,
810 void **pp_state)
812 struct pending_message_list *pml;
814 if (smbreq->sconn->using_smb2) {
815 return get_deferred_open_message_state_smb2(smbreq->smb2req,
816 p_request_time,
817 pp_state);
820 pml = get_deferred_open_message_smb(smbreq->sconn, smbreq->mid);
821 if (!pml) {
822 return false;
824 if (p_request_time) {
825 *p_request_time = pml->request_time;
827 if (pp_state) {
828 *pp_state = (void *)pml->private_data.data;
830 return true;
833 /****************************************************************************
834 Function to push a deferred open smb message onto a linked list of local smb
835 messages ready for processing.
836 ****************************************************************************/
838 bool push_deferred_open_message_smb(struct smb_request *req,
839 struct timeval request_time,
840 struct timeval timeout,
841 struct file_id id,
842 char *private_data, size_t priv_len)
844 struct timeval end_time;
846 if (req->smb2req) {
847 return push_deferred_open_message_smb2(req->smb2req,
848 request_time,
849 timeout,
851 private_data,
852 priv_len);
855 if (req->unread_bytes) {
856 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
857 "unread_bytes = %u\n",
858 (unsigned int)req->unread_bytes ));
859 smb_panic("push_deferred_open_message_smb: "
860 "logic error unread_bytes != 0" );
863 end_time = timeval_sum(&request_time, &timeout);
865 DEBUG(10,("push_deferred_open_message_smb: pushing message "
866 "len %u mid %llu timeout time [%u.%06u]\n",
867 (unsigned int) smb_len(req->inbuf)+4,
868 (unsigned long long)req->mid,
869 (unsigned int)end_time.tv_sec,
870 (unsigned int)end_time.tv_usec));
872 return push_queued_message(req, request_time, end_time,
873 private_data, priv_len);
876 static void smbd_sig_term_handler(struct tevent_context *ev,
877 struct tevent_signal *se,
878 int signum,
879 int count,
880 void *siginfo,
881 void *private_data)
883 exit_server_cleanly("termination signal");
886 void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
888 struct tevent_signal *se;
890 se = tevent_add_signal(sconn->ev_ctx,
891 sconn,
892 SIGTERM, 0,
893 smbd_sig_term_handler,
894 sconn);
895 if (!se) {
896 exit_server("failed to setup SIGTERM handler");
900 static void smbd_sig_hup_handler(struct tevent_context *ev,
901 struct tevent_signal *se,
902 int signum,
903 int count,
904 void *siginfo,
905 void *private_data)
907 struct smbd_server_connection *sconn =
908 talloc_get_type_abort(private_data,
909 struct smbd_server_connection);
911 change_to_root_user();
912 DEBUG(1,("Reloading services after SIGHUP\n"));
913 reload_services(sconn, conn_snum_used, false);
916 void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
918 struct tevent_signal *se;
920 se = tevent_add_signal(sconn->ev_ctx,
921 sconn,
922 SIGHUP, 0,
923 smbd_sig_hup_handler,
924 sconn);
925 if (!se) {
926 exit_server("failed to setup SIGHUP handler");
930 static void smbd_conf_updated(struct messaging_context *msg,
931 void *private_data,
932 uint32_t msg_type,
933 struct server_id server_id,
934 DATA_BLOB *data)
936 struct smbd_server_connection *sconn =
937 talloc_get_type_abort(private_data,
938 struct smbd_server_connection);
940 DEBUG(10,("smbd_conf_updated: Got message saying smb.conf was "
941 "updated. Reloading.\n"));
942 change_to_root_user();
943 reload_services(sconn, conn_snum_used, false);
947 * Only allow 5 outstanding trans requests. We're allocating memory, so
948 * prevent a DoS.
951 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
953 int count = 0;
954 for (; list != NULL; list = list->next) {
956 if (list->mid == mid) {
957 return NT_STATUS_INVALID_PARAMETER;
960 count += 1;
962 if (count > 5) {
963 return NT_STATUS_INSUFFICIENT_RESOURCES;
966 return NT_STATUS_OK;
970 These flags determine some of the permissions required to do an operation
972 Note that I don't set NEED_WRITE on some write operations because they
973 are used by some brain-dead clients when printing, and I don't want to
974 force write permissions on print services.
976 #define AS_USER (1<<0)
977 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
978 #define TIME_INIT (1<<2)
979 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
980 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
981 #define DO_CHDIR (1<<6)
984 define a list of possible SMB messages and their corresponding
985 functions. Any message that has a NULL function is unimplemented -
986 please feel free to contribute implementations!
988 static const struct smb_message_struct {
989 const char *name;
990 void (*fn)(struct smb_request *req);
991 int flags;
992 } smb_messages[256] = {
994 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
995 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
996 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
997 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
998 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
999 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1000 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1001 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1002 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1003 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1004 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1005 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1006 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1007 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1008 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1009 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1010 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1011 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1012 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1013 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1014 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1015 /* 0x15 */ { NULL, NULL, 0 },
1016 /* 0x16 */ { NULL, NULL, 0 },
1017 /* 0x17 */ { NULL, NULL, 0 },
1018 /* 0x18 */ { NULL, NULL, 0 },
1019 /* 0x19 */ { NULL, NULL, 0 },
1020 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1021 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1022 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1023 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1024 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1025 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1026 /* 0x20 */ { "SMBwritec", NULL,0},
1027 /* 0x21 */ { NULL, NULL, 0 },
1028 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1029 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1030 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1031 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1032 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1033 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1034 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1035 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1036 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1037 /* 0x2b */ { "SMBecho",reply_echo,0},
1038 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1039 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1040 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1041 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1042 /* 0x30 */ { NULL, NULL, 0 },
1043 /* 0x31 */ { NULL, NULL, 0 },
1044 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1045 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1046 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1047 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1048 /* 0x36 */ { NULL, NULL, 0 },
1049 /* 0x37 */ { NULL, NULL, 0 },
1050 /* 0x38 */ { NULL, NULL, 0 },
1051 /* 0x39 */ { NULL, NULL, 0 },
1052 /* 0x3a */ { NULL, NULL, 0 },
1053 /* 0x3b */ { NULL, NULL, 0 },
1054 /* 0x3c */ { NULL, NULL, 0 },
1055 /* 0x3d */ { NULL, NULL, 0 },
1056 /* 0x3e */ { NULL, NULL, 0 },
1057 /* 0x3f */ { NULL, NULL, 0 },
1058 /* 0x40 */ { NULL, NULL, 0 },
1059 /* 0x41 */ { NULL, NULL, 0 },
1060 /* 0x42 */ { NULL, NULL, 0 },
1061 /* 0x43 */ { NULL, NULL, 0 },
1062 /* 0x44 */ { NULL, NULL, 0 },
1063 /* 0x45 */ { NULL, NULL, 0 },
1064 /* 0x46 */ { NULL, NULL, 0 },
1065 /* 0x47 */ { NULL, NULL, 0 },
1066 /* 0x48 */ { NULL, NULL, 0 },
1067 /* 0x49 */ { NULL, NULL, 0 },
1068 /* 0x4a */ { NULL, NULL, 0 },
1069 /* 0x4b */ { NULL, NULL, 0 },
1070 /* 0x4c */ { NULL, NULL, 0 },
1071 /* 0x4d */ { NULL, NULL, 0 },
1072 /* 0x4e */ { NULL, NULL, 0 },
1073 /* 0x4f */ { NULL, NULL, 0 },
1074 /* 0x50 */ { NULL, NULL, 0 },
1075 /* 0x51 */ { NULL, NULL, 0 },
1076 /* 0x52 */ { NULL, NULL, 0 },
1077 /* 0x53 */ { NULL, NULL, 0 },
1078 /* 0x54 */ { NULL, NULL, 0 },
1079 /* 0x55 */ { NULL, NULL, 0 },
1080 /* 0x56 */ { NULL, NULL, 0 },
1081 /* 0x57 */ { NULL, NULL, 0 },
1082 /* 0x58 */ { NULL, NULL, 0 },
1083 /* 0x59 */ { NULL, NULL, 0 },
1084 /* 0x5a */ { NULL, NULL, 0 },
1085 /* 0x5b */ { NULL, NULL, 0 },
1086 /* 0x5c */ { NULL, NULL, 0 },
1087 /* 0x5d */ { NULL, NULL, 0 },
1088 /* 0x5e */ { NULL, NULL, 0 },
1089 /* 0x5f */ { NULL, NULL, 0 },
1090 /* 0x60 */ { NULL, NULL, 0 },
1091 /* 0x61 */ { NULL, NULL, 0 },
1092 /* 0x62 */ { NULL, NULL, 0 },
1093 /* 0x63 */ { NULL, NULL, 0 },
1094 /* 0x64 */ { NULL, NULL, 0 },
1095 /* 0x65 */ { NULL, NULL, 0 },
1096 /* 0x66 */ { NULL, NULL, 0 },
1097 /* 0x67 */ { NULL, NULL, 0 },
1098 /* 0x68 */ { NULL, NULL, 0 },
1099 /* 0x69 */ { NULL, NULL, 0 },
1100 /* 0x6a */ { NULL, NULL, 0 },
1101 /* 0x6b */ { NULL, NULL, 0 },
1102 /* 0x6c */ { NULL, NULL, 0 },
1103 /* 0x6d */ { NULL, NULL, 0 },
1104 /* 0x6e */ { NULL, NULL, 0 },
1105 /* 0x6f */ { NULL, NULL, 0 },
1106 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1107 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1108 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1109 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1110 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1111 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1112 /* 0x76 */ { NULL, NULL, 0 },
1113 /* 0x77 */ { NULL, NULL, 0 },
1114 /* 0x78 */ { NULL, NULL, 0 },
1115 /* 0x79 */ { NULL, NULL, 0 },
1116 /* 0x7a */ { NULL, NULL, 0 },
1117 /* 0x7b */ { NULL, NULL, 0 },
1118 /* 0x7c */ { NULL, NULL, 0 },
1119 /* 0x7d */ { NULL, NULL, 0 },
1120 /* 0x7e */ { NULL, NULL, 0 },
1121 /* 0x7f */ { NULL, NULL, 0 },
1122 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1123 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1124 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1125 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1126 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1127 /* 0x85 */ { NULL, NULL, 0 },
1128 /* 0x86 */ { NULL, NULL, 0 },
1129 /* 0x87 */ { NULL, NULL, 0 },
1130 /* 0x88 */ { NULL, NULL, 0 },
1131 /* 0x89 */ { NULL, NULL, 0 },
1132 /* 0x8a */ { NULL, NULL, 0 },
1133 /* 0x8b */ { NULL, NULL, 0 },
1134 /* 0x8c */ { NULL, NULL, 0 },
1135 /* 0x8d */ { NULL, NULL, 0 },
1136 /* 0x8e */ { NULL, NULL, 0 },
1137 /* 0x8f */ { NULL, NULL, 0 },
1138 /* 0x90 */ { NULL, NULL, 0 },
1139 /* 0x91 */ { NULL, NULL, 0 },
1140 /* 0x92 */ { NULL, NULL, 0 },
1141 /* 0x93 */ { NULL, NULL, 0 },
1142 /* 0x94 */ { NULL, NULL, 0 },
1143 /* 0x95 */ { NULL, NULL, 0 },
1144 /* 0x96 */ { NULL, NULL, 0 },
1145 /* 0x97 */ { NULL, NULL, 0 },
1146 /* 0x98 */ { NULL, NULL, 0 },
1147 /* 0x99 */ { NULL, NULL, 0 },
1148 /* 0x9a */ { NULL, NULL, 0 },
1149 /* 0x9b */ { NULL, NULL, 0 },
1150 /* 0x9c */ { NULL, NULL, 0 },
1151 /* 0x9d */ { NULL, NULL, 0 },
1152 /* 0x9e */ { NULL, NULL, 0 },
1153 /* 0x9f */ { NULL, NULL, 0 },
1154 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1155 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1156 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1157 /* 0xa3 */ { NULL, NULL, 0 },
1158 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1159 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1160 /* 0xa6 */ { NULL, NULL, 0 },
1161 /* 0xa7 */ { NULL, NULL, 0 },
1162 /* 0xa8 */ { NULL, NULL, 0 },
1163 /* 0xa9 */ { NULL, NULL, 0 },
1164 /* 0xaa */ { NULL, NULL, 0 },
1165 /* 0xab */ { NULL, NULL, 0 },
1166 /* 0xac */ { NULL, NULL, 0 },
1167 /* 0xad */ { NULL, NULL, 0 },
1168 /* 0xae */ { NULL, NULL, 0 },
1169 /* 0xaf */ { NULL, NULL, 0 },
1170 /* 0xb0 */ { NULL, NULL, 0 },
1171 /* 0xb1 */ { NULL, NULL, 0 },
1172 /* 0xb2 */ { NULL, NULL, 0 },
1173 /* 0xb3 */ { NULL, NULL, 0 },
1174 /* 0xb4 */ { NULL, NULL, 0 },
1175 /* 0xb5 */ { NULL, NULL, 0 },
1176 /* 0xb6 */ { NULL, NULL, 0 },
1177 /* 0xb7 */ { NULL, NULL, 0 },
1178 /* 0xb8 */ { NULL, NULL, 0 },
1179 /* 0xb9 */ { NULL, NULL, 0 },
1180 /* 0xba */ { NULL, NULL, 0 },
1181 /* 0xbb */ { NULL, NULL, 0 },
1182 /* 0xbc */ { NULL, NULL, 0 },
1183 /* 0xbd */ { NULL, NULL, 0 },
1184 /* 0xbe */ { NULL, NULL, 0 },
1185 /* 0xbf */ { NULL, NULL, 0 },
1186 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1187 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1188 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1189 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1190 /* 0xc4 */ { NULL, NULL, 0 },
1191 /* 0xc5 */ { NULL, NULL, 0 },
1192 /* 0xc6 */ { NULL, NULL, 0 },
1193 /* 0xc7 */ { NULL, NULL, 0 },
1194 /* 0xc8 */ { NULL, NULL, 0 },
1195 /* 0xc9 */ { NULL, NULL, 0 },
1196 /* 0xca */ { NULL, NULL, 0 },
1197 /* 0xcb */ { NULL, NULL, 0 },
1198 /* 0xcc */ { NULL, NULL, 0 },
1199 /* 0xcd */ { NULL, NULL, 0 },
1200 /* 0xce */ { NULL, NULL, 0 },
1201 /* 0xcf */ { NULL, NULL, 0 },
1202 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1203 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1204 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1205 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1206 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1207 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1208 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1209 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1210 /* 0xd8 */ { NULL, NULL, 0 },
1211 /* 0xd9 */ { NULL, NULL, 0 },
1212 /* 0xda */ { NULL, NULL, 0 },
1213 /* 0xdb */ { NULL, NULL, 0 },
1214 /* 0xdc */ { NULL, NULL, 0 },
1215 /* 0xdd */ { NULL, NULL, 0 },
1216 /* 0xde */ { NULL, NULL, 0 },
1217 /* 0xdf */ { NULL, NULL, 0 },
1218 /* 0xe0 */ { NULL, NULL, 0 },
1219 /* 0xe1 */ { NULL, NULL, 0 },
1220 /* 0xe2 */ { NULL, NULL, 0 },
1221 /* 0xe3 */ { NULL, NULL, 0 },
1222 /* 0xe4 */ { NULL, NULL, 0 },
1223 /* 0xe5 */ { NULL, NULL, 0 },
1224 /* 0xe6 */ { NULL, NULL, 0 },
1225 /* 0xe7 */ { NULL, NULL, 0 },
1226 /* 0xe8 */ { NULL, NULL, 0 },
1227 /* 0xe9 */ { NULL, NULL, 0 },
1228 /* 0xea */ { NULL, NULL, 0 },
1229 /* 0xeb */ { NULL, NULL, 0 },
1230 /* 0xec */ { NULL, NULL, 0 },
1231 /* 0xed */ { NULL, NULL, 0 },
1232 /* 0xee */ { NULL, NULL, 0 },
1233 /* 0xef */ { NULL, NULL, 0 },
1234 /* 0xf0 */ { NULL, NULL, 0 },
1235 /* 0xf1 */ { NULL, NULL, 0 },
1236 /* 0xf2 */ { NULL, NULL, 0 },
1237 /* 0xf3 */ { NULL, NULL, 0 },
1238 /* 0xf4 */ { NULL, NULL, 0 },
1239 /* 0xf5 */ { NULL, NULL, 0 },
1240 /* 0xf6 */ { NULL, NULL, 0 },
1241 /* 0xf7 */ { NULL, NULL, 0 },
1242 /* 0xf8 */ { NULL, NULL, 0 },
1243 /* 0xf9 */ { NULL, NULL, 0 },
1244 /* 0xfa */ { NULL, NULL, 0 },
1245 /* 0xfb */ { NULL, NULL, 0 },
1246 /* 0xfc */ { NULL, NULL, 0 },
1247 /* 0xfd */ { NULL, NULL, 0 },
1248 /* 0xfe */ { NULL, NULL, 0 },
1249 /* 0xff */ { NULL, NULL, 0 }
1253 /*******************************************************************
1254 allocate and initialize a reply packet
1255 ********************************************************************/
1257 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1258 const char *inbuf, char **outbuf, uint8_t num_words,
1259 uint32_t num_bytes)
1262 * Protect against integer wrap
1264 if ((num_bytes > 0xffffff)
1265 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1266 char *msg;
1267 if (asprintf(&msg, "num_bytes too large: %u",
1268 (unsigned)num_bytes) == -1) {
1269 msg = discard_const_p(char, "num_bytes too large");
1271 smb_panic(msg);
1274 *outbuf = talloc_array(mem_ctx, char,
1275 smb_size + num_words*2 + num_bytes);
1276 if (*outbuf == NULL) {
1277 return false;
1280 construct_reply_common(req, inbuf, *outbuf);
1281 srv_set_message(*outbuf, num_words, num_bytes, false);
1283 * Zero out the word area, the caller has to take care of the bcc area
1284 * himself
1286 if (num_words != 0) {
1287 memset(*outbuf + smb_vwv0, 0, num_words*2);
1290 return true;
1293 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1295 char *outbuf;
1296 if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
1297 num_bytes)) {
1298 smb_panic("could not allocate output buffer\n");
1300 req->outbuf = (uint8_t *)outbuf;
1304 /*******************************************************************
1305 Dump a packet to a file.
1306 ********************************************************************/
1308 static void smb_dump(const char *name, int type, const char *data)
1310 size_t len;
1311 int fd, i;
1312 char *fname = NULL;
1313 if (DEBUGLEVEL < 50) {
1314 return;
1317 len = smb_len_tcp(data)+4;
1318 for (i=1;i<100;i++) {
1319 fname = talloc_asprintf(talloc_tos(),
1320 "/tmp/%s.%d.%s",
1321 name,
1323 type ? "req" : "resp");
1324 if (fname == NULL) {
1325 return;
1327 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1328 if (fd != -1 || errno != EEXIST) break;
1329 TALLOC_FREE(fname);
1331 if (fd != -1) {
1332 ssize_t ret = write(fd, data, len);
1333 if (ret != len)
1334 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1335 close(fd);
1336 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1338 TALLOC_FREE(fname);
1341 /****************************************************************************
1342 Prepare everything for calling the actual request function, and potentially
1343 call the request function via the "new" interface.
1345 Return False if the "legacy" function needs to be called, everything is
1346 prepared.
1348 Return True if we're done.
1350 I know this API sucks, but it is the one with the least code change I could
1351 find.
1352 ****************************************************************************/
1354 static connection_struct *switch_message(uint8 type, struct smb_request *req)
1356 int flags;
1357 uint64_t session_tag;
1358 connection_struct *conn = NULL;
1359 struct smbd_server_connection *sconn = req->sconn;
1361 errno = 0;
1363 if (smb_messages[type].fn == NULL) {
1364 DEBUG(0,("Unknown message type %d!\n",type));
1365 smb_dump("Unknown", 1, (const char *)req->inbuf);
1366 reply_unknown_new(req, type);
1367 return NULL;
1370 flags = smb_messages[type].flags;
1372 /* In share mode security we must ignore the vuid. */
1373 session_tag = req->vuid;
1374 conn = req->conn;
1376 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1377 (int)getpid(), (unsigned long)conn));
1379 smb_dump(smb_fn_name(type), 1, (const char *)req->inbuf);
1381 /* Ensure this value is replaced in the incoming packet. */
1382 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_uid,session_tag);
1385 * Ensure the correct username is in current_user_info. This is a
1386 * really ugly bugfix for problems with multiple session_setup_and_X's
1387 * being done and allowing %U and %G substitutions to work correctly.
1388 * There is a reason this code is done here, don't move it unless you
1389 * know what you're doing... :-).
1390 * JRA.
1393 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1394 struct user_struct *vuser = NULL;
1396 sconn->smb1.sessions.last_session_tag = session_tag;
1397 if(session_tag != UID_FIELD_INVALID) {
1398 vuser = get_valid_user_struct(sconn, session_tag);
1399 if (vuser) {
1400 set_current_user_info(
1401 vuser->session_info->unix_info->sanitized_username,
1402 vuser->session_info->unix_info->unix_name,
1403 vuser->session_info->info->domain_name);
1408 /* Does this call need to be run as the connected user? */
1409 if (flags & AS_USER) {
1411 /* Does this call need a valid tree connection? */
1412 if (!conn) {
1414 * Amazingly, the error code depends on the command
1415 * (from Samba4).
1417 if (type == SMBntcreateX) {
1418 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1419 } else {
1420 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1422 return NULL;
1425 if (!change_to_user(conn,session_tag)) {
1426 DEBUG(0, ("Error: Could not change to user. Removing "
1427 "deferred open, mid=%llu.\n",
1428 (unsigned long long)req->mid));
1429 reply_force_doserror(req, ERRSRV, ERRbaduid);
1430 return conn;
1433 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1435 /* Does it need write permission? */
1436 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1437 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1438 return conn;
1441 /* IPC services are limited */
1442 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1443 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1444 return conn;
1446 } else {
1447 /* This call needs to be run as root */
1448 change_to_root_user();
1451 /* load service specific parameters */
1452 if (conn) {
1453 if (req->encrypted) {
1454 conn->encrypted_tid = true;
1455 /* encrypted required from now on. */
1456 conn->encrypt_level = Required;
1457 } else if (ENCRYPTION_REQUIRED(conn)) {
1458 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1459 exit_server_cleanly("encryption required "
1460 "on connection");
1461 return conn;
1465 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1466 (flags & (AS_USER|DO_CHDIR)
1467 ?True:False))) {
1468 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1469 return conn;
1471 conn->num_smb_operations++;
1475 * Does this protocol need to be run as guest? (Only archane
1476 * messenger service requests have this...)
1478 if (flags & AS_GUEST) {
1479 char *raddr;
1480 bool ok;
1482 if (!change_to_guest()) {
1483 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1484 return conn;
1487 raddr = tsocket_address_inet_addr_string(sconn->remote_address,
1488 talloc_tos());
1489 if (raddr == NULL) {
1490 reply_nterror(req, NT_STATUS_NO_MEMORY);
1491 return conn;
1495 * Haven't we checked this in smbd_process already???
1498 ok = allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1499 sconn->remote_hostname, raddr);
1500 TALLOC_FREE(raddr);
1502 if (!ok) {
1503 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1504 return conn;
1508 smb_messages[type].fn(req);
1509 return req->conn;
1512 /****************************************************************************
1513 Construct a reply to the incoming packet.
1514 ****************************************************************************/
1516 static void construct_reply(struct smbd_server_connection *sconn,
1517 char *inbuf, int size, size_t unread_bytes,
1518 uint32_t seqnum, bool encrypted,
1519 struct smb_perfcount_data *deferred_pcd)
1521 connection_struct *conn;
1522 struct smb_request *req;
1524 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1525 smb_panic("could not allocate smb_request");
1528 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1529 encrypted, seqnum)) {
1530 exit_server_cleanly("Invalid SMB request");
1533 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1535 /* we popped this message off the queue - keep original perf data */
1536 if (deferred_pcd)
1537 req->pcd = *deferred_pcd;
1538 else {
1539 SMB_PERFCOUNT_START(&req->pcd);
1540 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1541 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1544 conn = switch_message(req->cmd, req);
1546 if (req->outbuf == NULL) {
1547 return;
1550 if (CVAL(req->outbuf,0) == 0) {
1551 show_msg((char *)req->outbuf);
1554 if (!srv_send_smb(req->sconn,
1555 (char *)req->outbuf,
1556 true, req->seqnum+1,
1557 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1558 &req->pcd)) {
1559 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1562 TALLOC_FREE(req);
1564 return;
1567 static void construct_reply_chain(struct smbd_server_connection *sconn,
1568 char *inbuf, int size, uint32_t seqnum,
1569 bool encrypted,
1570 struct smb_perfcount_data *deferred_pcd)
1572 struct smb_request **reqs = NULL;
1573 struct smb_request *req;
1574 unsigned num_reqs;
1575 bool ok;
1577 ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, sconn, encrypted,
1578 seqnum, &reqs, &num_reqs);
1579 if (!ok) {
1580 char errbuf[smb_size];
1581 error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
1582 __LINE__, __FILE__);
1583 if (!srv_send_smb(sconn, errbuf, true, seqnum, encrypted,
1584 NULL)) {
1585 exit_server_cleanly("construct_reply_chain: "
1586 "srv_send_smb failed.");
1588 return;
1591 req = reqs[0];
1592 req->inbuf = (uint8_t *)talloc_move(reqs, &inbuf);
1594 req->conn = switch_message(req->cmd, req);
1596 if (req->outbuf == NULL) {
1598 * Request has suspended itself, will come
1599 * back here.
1601 return;
1603 smb_request_done(req);
1607 * To be called from an async SMB handler that is potentially chained
1608 * when it is finished for shipping.
1611 void smb_request_done(struct smb_request *req)
1613 struct smb_request **reqs = NULL;
1614 struct smb_request *first_req;
1615 size_t i, num_reqs, next_index;
1616 NTSTATUS status;
1618 if (req->chain == NULL) {
1619 first_req = req;
1620 goto shipit;
1623 reqs = req->chain;
1624 num_reqs = talloc_array_length(reqs);
1626 for (i=0; i<num_reqs; i++) {
1627 if (reqs[i] == req) {
1628 break;
1631 if (i == num_reqs) {
1633 * Invalid chain, should not happen
1635 status = NT_STATUS_INTERNAL_ERROR;
1636 goto error;
1638 next_index = i+1;
1640 while ((next_index < num_reqs) && (IVAL(req->outbuf, smb_rcls) == 0)) {
1641 struct smb_request *next = reqs[next_index];
1643 next->vuid = SVAL(req->outbuf, smb_uid);
1644 next->tid = SVAL(req->outbuf, smb_tid);
1645 next->conn = conn_find(req->sconn, req->tid);
1646 next->chain_fsp = req->chain_fsp;
1647 next->inbuf = (uint8_t *)req->inbuf;
1649 req = next;
1650 req->conn = switch_message(req->cmd, req);
1652 if (req->outbuf == NULL) {
1654 * Request has suspended itself, will come
1655 * back here.
1657 return;
1659 next_index += 1;
1662 first_req = reqs[0];
1664 for (i=1; i<next_index; i++) {
1665 bool ok;
1667 ok = smb_splice_chain(&first_req->outbuf, reqs[i]->outbuf);
1668 if (!ok) {
1669 status = NT_STATUS_INTERNAL_ERROR;
1670 goto error;
1674 SSVAL(first_req->outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1675 SSVAL(first_req->outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1678 * This scary statement intends to set the
1679 * FLAGS2_32_BIT_ERROR_CODES flg2 field in first_req->outbuf
1680 * to the value last_req->outbuf carries
1682 SSVAL(first_req->outbuf, smb_flg2,
1683 (SVAL(first_req->outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
1684 |(SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
1687 * Transfer the error codes from the subrequest to the main one
1689 SSVAL(first_req->outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
1690 SSVAL(first_req->outbuf, smb_err, SVAL(req->outbuf, smb_err));
1692 _smb_setlen_large(
1693 first_req->outbuf, talloc_get_size(first_req->outbuf) - 4);
1695 shipit:
1696 if (!srv_send_smb(first_req->sconn,
1697 (char *)first_req->outbuf,
1698 true, first_req->seqnum+1,
1699 IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
1700 &first_req->pcd)) {
1701 exit_server_cleanly("construct_reply_chain: srv_send_smb "
1702 "failed.");
1704 TALLOC_FREE(req); /* non-chained case */
1705 TALLOC_FREE(reqs); /* chained case */
1706 return;
1708 error:
1710 char errbuf[smb_size];
1711 error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
1712 if (!srv_send_smb(req->sconn, errbuf, true,
1713 req->seqnum+1, req->encrypted,
1714 NULL)) {
1715 exit_server_cleanly("construct_reply_chain: "
1716 "srv_send_smb failed.");
1719 TALLOC_FREE(req); /* non-chained case */
1720 TALLOC_FREE(reqs); /* chained case */
1723 /****************************************************************************
1724 Process an smb from the client
1725 ****************************************************************************/
1726 static void process_smb(struct smbd_server_connection *sconn,
1727 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1728 uint32_t seqnum, bool encrypted,
1729 struct smb_perfcount_data *deferred_pcd)
1731 int msg_type = CVAL(inbuf,0);
1733 DO_PROFILE_INC(smb_count);
1735 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1736 smb_len(inbuf) ) );
1737 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1738 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1740 if (msg_type != NBSSmessage) {
1742 * NetBIOS session request, keepalive, etc.
1744 reply_special(sconn, (char *)inbuf, nread);
1745 goto done;
1748 if (sconn->using_smb2) {
1749 /* At this point we're not really using smb2,
1750 * we make the decision here.. */
1751 if (smbd_is_smb2_header(inbuf, nread)) {
1752 smbd_smb2_first_negprot(sconn, inbuf, nread);
1753 return;
1754 } else if (nread >= smb_size && valid_smb_header(sconn, inbuf)
1755 && CVAL(inbuf, smb_com) != 0x72) {
1756 /* This is a non-negprot SMB1 packet.
1757 Disable SMB2 from now on. */
1758 sconn->using_smb2 = false;
1762 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1763 * so subtract 4 from it. */
1764 if ((nread < (smb_size - 4)) || !valid_smb_header(sconn, inbuf)) {
1765 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1766 smb_len(inbuf)));
1768 /* special magic for immediate exit */
1769 if ((nread == 9) &&
1770 (IVAL(inbuf, 4) == 0x74697865) &&
1771 lp_parm_bool(-1, "smbd", "suicide mode", false)) {
1772 uint8_t exitcode = CVAL(inbuf, 8);
1773 DEBUG(1, ("Exiting immediately with code %d\n",
1774 (int)exitcode));
1775 exit(exitcode);
1778 exit_server_cleanly("Non-SMB packet");
1781 show_msg((char *)inbuf);
1783 if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
1784 construct_reply_chain(sconn, (char *)inbuf, nread,
1785 seqnum, encrypted, deferred_pcd);
1786 } else {
1787 construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
1788 seqnum, encrypted, deferred_pcd);
1791 sconn->trans_num++;
1793 done:
1794 sconn->num_requests++;
1796 /* The timeout_processing function isn't run nearly
1797 often enough to implement 'max log size' without
1798 overrunning the size of the file by many megabytes.
1799 This is especially true if we are running at debug
1800 level 10. Checking every 50 SMBs is a nice
1801 tradeoff of performance vs log file size overrun. */
1803 if ((sconn->num_requests % 50) == 0 &&
1804 need_to_check_log_size()) {
1805 change_to_root_user();
1806 check_log_size();
1810 /****************************************************************************
1811 Return a string containing the function name of a SMB command.
1812 ****************************************************************************/
1814 const char *smb_fn_name(int type)
1816 const char *unknown_name = "SMBunknown";
1818 if (smb_messages[type].name == NULL)
1819 return(unknown_name);
1821 return(smb_messages[type].name);
1824 /****************************************************************************
1825 Helper functions for contruct_reply.
1826 ****************************************************************************/
1828 void add_to_common_flags2(uint32 v)
1830 common_flags2 |= v;
1833 void remove_from_common_flags2(uint32 v)
1835 common_flags2 &= ~v;
1838 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1839 char *outbuf)
1841 uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
1842 uint16_t out_flags2 = common_flags2;
1844 out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
1845 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
1846 out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
1848 srv_set_message(outbuf,0,0,false);
1850 SCVAL(outbuf, smb_com, req->cmd);
1851 SIVAL(outbuf,smb_rcls,0);
1852 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1853 SSVAL(outbuf,smb_flg2, out_flags2);
1854 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1855 memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
1857 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1858 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1859 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1860 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1863 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1865 construct_reply_common(req, (const char *)req->inbuf, outbuf);
1869 * @brief Find the smb_cmd offset of the last command pushed
1870 * @param[in] buf The buffer we're building up
1871 * @retval Where can we put our next andx cmd?
1873 * While chaining requests, the "next" request we're looking at needs to put
1874 * its SMB_Command before the data the previous request already built up added
1875 * to the chain. Find the offset to the place where we have to put our cmd.
1878 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1880 uint8_t cmd;
1881 size_t ofs;
1883 cmd = CVAL(buf, smb_com);
1885 if (!is_andx_req(cmd)) {
1886 return false;
1889 ofs = smb_vwv0;
1891 while (CVAL(buf, ofs) != 0xff) {
1893 if (!is_andx_req(CVAL(buf, ofs))) {
1894 return false;
1898 * ofs is from start of smb header, so add the 4 length
1899 * bytes. The next cmd is right after the wct field.
1901 ofs = SVAL(buf, ofs+2) + 4 + 1;
1903 if (ofs+4 >= talloc_get_size(buf)) {
1904 return false;
1908 *pofs = ofs;
1909 return true;
1913 * @brief Do the smb chaining at a buffer level
1914 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1915 * @param[in] andx_buf Buffer to be appended
1918 static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf)
1920 uint8_t smb_command = CVAL(andx_buf, smb_com);
1921 uint8_t wct = CVAL(andx_buf, smb_wct);
1922 const uint16_t *vwv = (const uint16_t *)(andx_buf + smb_vwv);
1923 uint32_t num_bytes = smb_buflen(andx_buf);
1924 const uint8_t *bytes = (const uint8_t *)smb_buf_const(andx_buf);
1926 uint8_t *outbuf;
1927 size_t old_size, new_size;
1928 size_t ofs;
1929 size_t chain_padding = 0;
1930 size_t andx_cmd_ofs;
1933 old_size = talloc_get_size(*poutbuf);
1935 if ((old_size % 4) != 0) {
1937 * Align the wct field of subsequent requests to a 4-byte
1938 * boundary
1940 chain_padding = 4 - (old_size % 4);
1944 * After the old request comes the new wct field (1 byte), the vwv's
1945 * and the num_bytes field.
1948 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1949 new_size += num_bytes;
1951 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1952 DEBUG(1, ("smb_splice_chain: %u bytes won't fit\n",
1953 (unsigned)new_size));
1954 return false;
1957 outbuf = talloc_realloc(NULL, *poutbuf, uint8_t, new_size);
1958 if (outbuf == NULL) {
1959 DEBUG(0, ("talloc failed\n"));
1960 return false;
1962 *poutbuf = outbuf;
1964 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1965 DEBUG(1, ("invalid command chain\n"));
1966 *poutbuf = talloc_realloc(NULL, *poutbuf, uint8_t, old_size);
1967 return false;
1970 if (chain_padding != 0) {
1971 memset(outbuf + old_size, 0, chain_padding);
1972 old_size += chain_padding;
1975 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1976 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1978 ofs = old_size;
1981 * Push the chained request:
1983 * wct field
1986 SCVAL(outbuf, ofs, wct);
1987 ofs += 1;
1990 * vwv array
1993 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1996 * HACK ALERT
1998 * Read&X has an offset into its data buffer at
1999 * vwv[6]. reply_read_andx has no idea anymore that it's
2000 * running from within a chain, so we have to fix up the
2001 * offset here.
2003 * Although it looks disgusting at this place, I want to keep
2004 * it here. The alternative would be to push knowledge about
2005 * the andx chain down into read&x again.
2008 if (smb_command == SMBreadX) {
2009 uint8_t *bytes_addr;
2011 if (wct < 7) {
2013 * Invalid read&x response
2015 return false;
2018 bytes_addr = outbuf + ofs /* vwv start */
2019 + sizeof(uint16_t) * wct /* vwv array */
2020 + sizeof(uint16_t); /* bcc */
2022 SSVAL(outbuf + ofs, 6 * sizeof(uint16_t),
2023 bytes_addr - outbuf - 4);
2026 ofs += sizeof(uint16_t) * wct;
2029 * bcc (byte count)
2032 SSVAL(outbuf, ofs, num_bytes);
2033 ofs += sizeof(uint16_t);
2036 * The bytes field
2039 memcpy(outbuf + ofs, bytes, num_bytes);
2041 return true;
2044 bool smb1_is_chain(const uint8_t *buf)
2046 uint8_t cmd, wct, andx_cmd;
2048 cmd = CVAL(buf, smb_com);
2049 if (!is_andx_req(cmd)) {
2050 return false;
2052 wct = CVAL(buf, smb_wct);
2053 if (wct < 2) {
2054 return false;
2056 andx_cmd = CVAL(buf, smb_vwv);
2057 return (andx_cmd != 0xFF);
2060 bool smb1_walk_chain(const uint8_t *buf,
2061 bool (*fn)(uint8_t cmd,
2062 uint8_t wct, const uint16_t *vwv,
2063 uint16_t num_bytes, const uint8_t *bytes,
2064 void *private_data),
2065 void *private_data)
2067 size_t smblen = smb_len(buf);
2068 const char *smb_buf = smb_base(buf);
2069 uint8_t cmd, chain_cmd;
2070 uint8_t wct;
2071 const uint16_t *vwv;
2072 uint16_t num_bytes;
2073 const uint8_t *bytes;
2075 cmd = CVAL(buf, smb_com);
2076 wct = CVAL(buf, smb_wct);
2077 vwv = (const uint16_t *)(buf + smb_vwv);
2078 num_bytes = smb_buflen(buf);
2079 bytes = (uint8_t *)smb_buf_const(buf);
2081 if (!fn(cmd, wct, vwv, num_bytes, bytes, private_data)) {
2082 return false;
2085 if (!is_andx_req(cmd)) {
2086 return true;
2088 if (wct < 2) {
2089 return false;
2092 chain_cmd = CVAL(vwv, 0);
2094 while (chain_cmd != 0xff) {
2095 uint32_t chain_offset; /* uint32_t to avoid overflow */
2096 size_t length_needed;
2097 ptrdiff_t vwv_offset;
2099 chain_offset = SVAL(vwv+1, 0);
2102 * Check if the client tries to fool us. The chain
2103 * offset needs to point beyond the current request in
2104 * the chain, it needs to strictly grow. Otherwise we
2105 * might be tricked into an endless loop always
2106 * processing the same request over and over again. We
2107 * used to assume that vwv and the byte buffer array
2108 * in a chain are always attached, but OS/2 the
2109 * Write&X/Read&X chain puts the Read&X vwv array
2110 * right behind the Write&X vwv chain. The Write&X bcc
2111 * array is put behind the Read&X vwv array. So now we
2112 * check whether the chain offset points strictly
2113 * behind the previous vwv array. req->buf points
2114 * right after the vwv array of the previous
2115 * request. See
2116 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for
2117 * more information.
2120 vwv_offset = ((const char *)vwv - smb_buf);
2121 if (chain_offset <= vwv_offset) {
2122 return false;
2126 * Next check: Make sure the chain offset does not
2127 * point beyond the overall smb request length.
2130 length_needed = chain_offset+1; /* wct */
2131 if (length_needed > smblen) {
2132 return false;
2136 * Now comes the pointer magic. Goal here is to set up
2137 * vwv and buf correctly again. The chain offset (the
2138 * former vwv[1]) points at the new wct field.
2141 wct = CVAL(smb_buf, chain_offset);
2143 if (is_andx_req(chain_cmd) && (wct < 2)) {
2144 return false;
2148 * Next consistency check: Make the new vwv array fits
2149 * in the overall smb request.
2152 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2153 if (length_needed > smblen) {
2154 return false;
2156 vwv = (const uint16_t *)(smb_buf + chain_offset + 1);
2159 * Now grab the new byte buffer....
2162 num_bytes = SVAL(vwv+wct, 0);
2165 * .. and check that it fits.
2168 length_needed += num_bytes;
2169 if (length_needed > smblen) {
2170 return false;
2172 bytes = (const uint8_t *)(vwv+wct+1);
2174 if (!fn(chain_cmd, wct, vwv, num_bytes, bytes, private_data)) {
2175 return false;
2178 if (!is_andx_req(chain_cmd)) {
2179 return true;
2181 chain_cmd = CVAL(vwv, 0);
2183 return true;
2186 static bool smb1_chain_length_cb(uint8_t cmd,
2187 uint8_t wct, const uint16_t *vwv,
2188 uint16_t num_bytes, const uint8_t *bytes,
2189 void *private_data)
2191 unsigned *count = (unsigned *)private_data;
2192 *count += 1;
2193 return true;
2196 unsigned smb1_chain_length(const uint8_t *buf)
2198 unsigned count = 0;
2200 if (!smb1_walk_chain(buf, smb1_chain_length_cb, &count)) {
2201 return 0;
2203 return count;
2206 struct smb1_parse_chain_state {
2207 TALLOC_CTX *mem_ctx;
2208 const uint8_t *buf;
2209 struct smbd_server_connection *sconn;
2210 bool encrypted;
2211 uint32_t seqnum;
2213 struct smb_request **reqs;
2214 unsigned num_reqs;
2217 static bool smb1_parse_chain_cb(uint8_t cmd,
2218 uint8_t wct, const uint16_t *vwv,
2219 uint16_t num_bytes, const uint8_t *bytes,
2220 void *private_data)
2222 struct smb1_parse_chain_state *state =
2223 (struct smb1_parse_chain_state *)private_data;
2224 struct smb_request **reqs;
2225 struct smb_request *req;
2226 bool ok;
2228 reqs = talloc_realloc(state->mem_ctx, state->reqs,
2229 struct smb_request *, state->num_reqs+1);
2230 if (reqs == NULL) {
2231 return false;
2233 state->reqs = reqs;
2235 req = talloc(reqs, struct smb_request);
2236 if (req == NULL) {
2237 return false;
2240 ok = init_smb_request(req, state->sconn, state->buf, 0,
2241 state->encrypted, state->seqnum);
2242 if (!ok) {
2243 return false;
2245 req->cmd = cmd;
2246 req->wct = wct;
2247 req->vwv = vwv;
2248 req->buflen = num_bytes;
2249 req->buf = bytes;
2251 reqs[state->num_reqs] = req;
2252 state->num_reqs += 1;
2253 return true;
2256 bool smb1_parse_chain(TALLOC_CTX *mem_ctx, const uint8_t *buf,
2257 struct smbd_server_connection *sconn,
2258 bool encrypted, uint32_t seqnum,
2259 struct smb_request ***reqs, unsigned *num_reqs)
2261 struct smb1_parse_chain_state state;
2262 unsigned i;
2264 state.mem_ctx = mem_ctx;
2265 state.buf = buf;
2266 state.sconn = sconn;
2267 state.encrypted = encrypted;
2268 state.seqnum = seqnum;
2269 state.reqs = NULL;
2270 state.num_reqs = 0;
2272 if (!smb1_walk_chain(buf, smb1_parse_chain_cb, &state)) {
2273 TALLOC_FREE(state.reqs);
2274 return false;
2276 for (i=0; i<state.num_reqs; i++) {
2277 state.reqs[i]->chain = state.reqs;
2279 *reqs = state.reqs;
2280 *num_reqs = state.num_reqs;
2281 return true;
2284 /****************************************************************************
2285 Check if services need reloading.
2286 ****************************************************************************/
2288 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2291 if (last_smb_conf_reload_time == 0) {
2292 last_smb_conf_reload_time = t;
2295 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2296 reload_services(sconn, conn_snum_used, true);
2297 last_smb_conf_reload_time = t;
2301 static bool fd_is_readable(int fd)
2303 int ret, revents;
2305 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2307 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2311 static void smbd_server_connection_write_handler(
2312 struct smbd_server_connection *sconn)
2314 /* TODO: make write nonblocking */
2317 static void smbd_server_connection_read_handler(
2318 struct smbd_server_connection *sconn, int fd)
2320 uint8_t *inbuf = NULL;
2321 size_t inbuf_len = 0;
2322 size_t unread_bytes = 0;
2323 bool encrypted = false;
2324 TALLOC_CTX *mem_ctx = talloc_tos();
2325 NTSTATUS status;
2326 uint32_t seqnum;
2328 bool from_client;
2330 if (lp_async_smb_echo_handler()
2331 && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
2333 * This is the super-ugly hack to prefer the packets
2334 * forwarded by the echo handler over the ones by the
2335 * client directly
2337 fd = sconn->smb1.echo_handler.trusted_fd;
2340 from_client = (sconn->sock == fd);
2342 if (from_client) {
2343 smbd_lock_socket(sconn);
2345 if (!fd_is_readable(fd)) {
2346 DEBUG(10,("the echo listener was faster\n"));
2347 smbd_unlock_socket(sconn);
2348 return;
2352 /* TODO: make this completely nonblocking */
2353 status = receive_smb_talloc(mem_ctx, sconn, fd,
2354 (char **)(void *)&inbuf,
2355 0, /* timeout */
2356 &unread_bytes,
2357 &encrypted,
2358 &inbuf_len, &seqnum,
2359 false /* trusted channel */);
2361 if (from_client) {
2362 smbd_unlock_socket(sconn);
2365 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2366 goto process;
2368 if (NT_STATUS_IS_ERR(status)) {
2369 exit_server_cleanly("failed to receive smb request");
2371 if (!NT_STATUS_IS_OK(status)) {
2372 return;
2375 process:
2376 process_smb(sconn, inbuf, inbuf_len, unread_bytes,
2377 seqnum, encrypted, NULL);
2380 static void smbd_server_connection_handler(struct event_context *ev,
2381 struct fd_event *fde,
2382 uint16_t flags,
2383 void *private_data)
2385 struct smbd_server_connection *conn = talloc_get_type(private_data,
2386 struct smbd_server_connection);
2388 if (flags & EVENT_FD_WRITE) {
2389 smbd_server_connection_write_handler(conn);
2390 return;
2392 if (flags & EVENT_FD_READ) {
2393 smbd_server_connection_read_handler(conn, conn->sock);
2394 return;
2398 static void smbd_server_echo_handler(struct event_context *ev,
2399 struct fd_event *fde,
2400 uint16_t flags,
2401 void *private_data)
2403 struct smbd_server_connection *conn = talloc_get_type(private_data,
2404 struct smbd_server_connection);
2406 if (flags & EVENT_FD_WRITE) {
2407 smbd_server_connection_write_handler(conn);
2408 return;
2410 if (flags & EVENT_FD_READ) {
2411 smbd_server_connection_read_handler(
2412 conn, conn->smb1.echo_handler.trusted_fd);
2413 return;
2417 #ifdef CLUSTER_SUPPORT
2418 /****************************************************************************
2419 received when we should release a specific IP
2420 ****************************************************************************/
2421 static void release_ip(const char *ip, void *priv)
2423 const char *addr = (const char *)priv;
2424 const char *p = addr;
2426 if (strncmp("::ffff:", addr, 7) == 0) {
2427 p = addr + 7;
2430 DEBUG(10, ("Got release IP message for %s, "
2431 "our address is %s\n", ip, p));
2433 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2434 /* we can't afford to do a clean exit - that involves
2435 database writes, which would potentially mean we
2436 are still running after the failover has finished -
2437 we have to get rid of this process ID straight
2438 away */
2439 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2440 ip));
2441 /* note we must exit with non-zero status so the unclean handler gets
2442 called in the parent, so that the brl database is tickled */
2443 _exit(1);
2447 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2448 struct sockaddr_storage *client)
2450 socklen_t length;
2451 length = sizeof(*server);
2452 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2453 return -1;
2455 length = sizeof(*client);
2456 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2457 return -1;
2459 return 0;
2461 #endif
2464 * Send keepalive packets to our client
2466 static bool keepalive_fn(const struct timeval *now, void *private_data)
2468 struct smbd_server_connection *sconn = talloc_get_type_abort(
2469 private_data, struct smbd_server_connection);
2470 bool ret;
2472 if (sconn->using_smb2) {
2473 /* Don't do keepalives on an SMB2 connection. */
2474 return false;
2477 smbd_lock_socket(sconn);
2478 ret = send_keepalive(sconn->sock);
2479 smbd_unlock_socket(sconn);
2481 if (!ret) {
2482 char addr[INET6_ADDRSTRLEN];
2484 * Try and give an error message saying what
2485 * client failed.
2487 DEBUG(0, ("send_keepalive failed for client %s. "
2488 "Error %s - exiting\n",
2489 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2490 strerror(errno)));
2491 return False;
2493 return True;
2497 * Do the recurring check if we're idle
2499 static bool deadtime_fn(const struct timeval *now, void *private_data)
2501 struct smbd_server_connection *sconn =
2502 (struct smbd_server_connection *)private_data;
2504 if ((conn_num_open(sconn) == 0)
2505 || (conn_idle_all(sconn, now->tv_sec))) {
2506 DEBUG( 2, ( "Closing idle connection\n" ) );
2507 messaging_send(sconn->msg_ctx,
2508 messaging_server_id(sconn->msg_ctx),
2509 MSG_SHUTDOWN, &data_blob_null);
2510 return False;
2513 return True;
2517 * Do the recurring log file and smb.conf reload checks.
2520 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2522 struct smbd_server_connection *sconn = talloc_get_type_abort(
2523 private_data, struct smbd_server_connection);
2525 DEBUG(5, ("housekeeping\n"));
2527 change_to_root_user();
2529 /* update printer queue caches if necessary */
2530 update_monitored_printq_cache(sconn->msg_ctx);
2532 /* check if we need to reload services */
2533 check_reload(sconn, time_mono(NULL));
2535 /* Change machine password if neccessary. */
2536 attempt_machine_password_change();
2539 * Force a log file check.
2541 force_check_log_size();
2542 check_log_size();
2543 return true;
2547 * Read an smb packet in the echo handler child, giving the parent
2548 * smbd one second to react once the socket becomes readable.
2551 struct smbd_echo_read_state {
2552 struct tevent_context *ev;
2553 struct smbd_server_connection *sconn;
2555 char *buf;
2556 size_t buflen;
2557 uint32_t seqnum;
2560 static void smbd_echo_read_readable(struct tevent_req *subreq);
2561 static void smbd_echo_read_waited(struct tevent_req *subreq);
2563 static struct tevent_req *smbd_echo_read_send(
2564 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2565 struct smbd_server_connection *sconn)
2567 struct tevent_req *req, *subreq;
2568 struct smbd_echo_read_state *state;
2570 req = tevent_req_create(mem_ctx, &state,
2571 struct smbd_echo_read_state);
2572 if (req == NULL) {
2573 return NULL;
2575 state->ev = ev;
2576 state->sconn = sconn;
2578 subreq = wait_for_read_send(state, ev, sconn->sock);
2579 if (tevent_req_nomem(subreq, req)) {
2580 return tevent_req_post(req, ev);
2582 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2583 return req;
2586 static void smbd_echo_read_readable(struct tevent_req *subreq)
2588 struct tevent_req *req = tevent_req_callback_data(
2589 subreq, struct tevent_req);
2590 struct smbd_echo_read_state *state = tevent_req_data(
2591 req, struct smbd_echo_read_state);
2592 bool ok;
2593 int err;
2595 ok = wait_for_read_recv(subreq, &err);
2596 TALLOC_FREE(subreq);
2597 if (!ok) {
2598 tevent_req_nterror(req, map_nt_error_from_unix(err));
2599 return;
2603 * Give the parent smbd one second to step in
2606 subreq = tevent_wakeup_send(
2607 state, state->ev, timeval_current_ofs(1, 0));
2608 if (tevent_req_nomem(subreq, req)) {
2609 return;
2611 tevent_req_set_callback(subreq, smbd_echo_read_waited, req);
2614 static void smbd_echo_read_waited(struct tevent_req *subreq)
2616 struct tevent_req *req = tevent_req_callback_data(
2617 subreq, struct tevent_req);
2618 struct smbd_echo_read_state *state = tevent_req_data(
2619 req, struct smbd_echo_read_state);
2620 struct smbd_server_connection *sconn = state->sconn;
2621 bool ok;
2622 NTSTATUS status;
2623 size_t unread = 0;
2624 bool encrypted;
2626 ok = tevent_wakeup_recv(subreq);
2627 TALLOC_FREE(subreq);
2628 if (!ok) {
2629 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2630 return;
2633 ok = smbd_lock_socket_internal(sconn);
2634 if (!ok) {
2635 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2636 DEBUG(0, ("%s: failed to lock socket\n", __location__));
2637 return;
2640 if (!fd_is_readable(sconn->sock)) {
2641 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2642 (int)getpid()));
2644 ok = smbd_unlock_socket_internal(sconn);
2645 if (!ok) {
2646 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2647 DEBUG(1, ("%s: failed to unlock socket\n",
2648 __location__));
2649 return;
2652 subreq = wait_for_read_send(state, state->ev, sconn->sock);
2653 if (tevent_req_nomem(subreq, req)) {
2654 return;
2656 tevent_req_set_callback(subreq, smbd_echo_read_readable, req);
2657 return;
2660 status = receive_smb_talloc(state, sconn, sconn->sock, &state->buf,
2661 0 /* timeout */,
2662 &unread,
2663 &encrypted,
2664 &state->buflen,
2665 &state->seqnum,
2666 false /* trusted_channel*/);
2668 if (tevent_req_nterror(req, status)) {
2669 tevent_req_nterror(req, status);
2670 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2671 (int)getpid(), nt_errstr(status)));
2672 return;
2675 ok = smbd_unlock_socket_internal(sconn);
2676 if (!ok) {
2677 tevent_req_nterror(req, map_nt_error_from_unix(errno));
2678 DEBUG(1, ("%s: failed to unlock socket\n", __location__));
2679 return;
2681 tevent_req_done(req);
2684 static NTSTATUS smbd_echo_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2685 char **pbuf, size_t *pbuflen, uint32_t *pseqnum)
2687 struct smbd_echo_read_state *state = tevent_req_data(
2688 req, struct smbd_echo_read_state);
2689 NTSTATUS status;
2691 if (tevent_req_is_nterror(req, &status)) {
2692 return status;
2694 *pbuf = talloc_move(mem_ctx, &state->buf);
2695 *pbuflen = state->buflen;
2696 *pseqnum = state->seqnum;
2697 return NT_STATUS_OK;
2700 struct smbd_echo_state {
2701 struct tevent_context *ev;
2702 struct iovec *pending;
2703 struct smbd_server_connection *sconn;
2704 int parent_pipe;
2706 struct tevent_fd *parent_fde;
2708 struct tevent_req *write_req;
2711 static void smbd_echo_writer_done(struct tevent_req *req);
2713 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2715 int num_pending;
2717 if (state->write_req != NULL) {
2718 return;
2721 num_pending = talloc_array_length(state->pending);
2722 if (num_pending == 0) {
2723 return;
2726 state->write_req = writev_send(state, state->ev, NULL,
2727 state->parent_pipe, false,
2728 state->pending, num_pending);
2729 if (state->write_req == NULL) {
2730 DEBUG(1, ("writev_send failed\n"));
2731 exit(1);
2734 talloc_steal(state->write_req, state->pending);
2735 state->pending = NULL;
2737 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2738 state);
2741 static void smbd_echo_writer_done(struct tevent_req *req)
2743 struct smbd_echo_state *state = tevent_req_callback_data(
2744 req, struct smbd_echo_state);
2745 ssize_t written;
2746 int err;
2748 written = writev_recv(req, &err);
2749 TALLOC_FREE(req);
2750 state->write_req = NULL;
2751 if (written == -1) {
2752 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2753 exit(1);
2755 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)getpid()));
2756 smbd_echo_activate_writer(state);
2759 static bool smbd_echo_reply(struct smbd_echo_state *state,
2760 uint8_t *inbuf, size_t inbuf_len,
2761 uint32_t seqnum)
2763 struct smb_request req;
2764 uint16_t num_replies;
2765 char *outbuf;
2766 bool ok;
2768 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == NBSSkeepalive)) {
2769 DEBUG(10, ("Got netbios keepalive\n"));
2771 * Just swallow it
2773 return true;
2776 if (inbuf_len < smb_size) {
2777 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2778 return false;
2780 if (!valid_smb_header(state->sconn, inbuf)) {
2781 DEBUG(10, ("Got invalid SMB header\n"));
2782 return false;
2785 if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
2786 seqnum)) {
2787 return false;
2789 req.inbuf = inbuf;
2791 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2792 smb_messages[req.cmd].name
2793 ? smb_messages[req.cmd].name : "unknown"));
2795 if (req.cmd != SMBecho) {
2796 return false;
2798 if (req.wct < 1) {
2799 return false;
2802 num_replies = SVAL(req.vwv+0, 0);
2803 if (num_replies != 1) {
2804 /* Not a Windows "Hey, you're still there?" request */
2805 return false;
2808 if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
2809 1, req.buflen)) {
2810 DEBUG(10, ("create_outbuf failed\n"));
2811 return false;
2813 req.outbuf = (uint8_t *)outbuf;
2815 SSVAL(req.outbuf, smb_vwv0, num_replies);
2817 if (req.buflen > 0) {
2818 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2821 ok = srv_send_smb(req.sconn,
2822 (char *)outbuf,
2823 true, seqnum+1,
2824 false, &req.pcd);
2825 TALLOC_FREE(outbuf);
2826 if (!ok) {
2827 exit(1);
2830 return true;
2833 static void smbd_echo_exit(struct tevent_context *ev,
2834 struct tevent_fd *fde, uint16_t flags,
2835 void *private_data)
2837 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2838 exit(0);
2841 static void smbd_echo_got_packet(struct tevent_req *req);
2843 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2844 int parent_pipe)
2846 struct smbd_echo_state *state;
2847 struct tevent_req *read_req;
2849 state = talloc_zero(sconn, struct smbd_echo_state);
2850 if (state == NULL) {
2851 DEBUG(1, ("talloc failed\n"));
2852 return;
2854 state->sconn = sconn;
2855 state->parent_pipe = parent_pipe;
2856 state->ev = s3_tevent_context_init(state);
2857 if (state->ev == NULL) {
2858 DEBUG(1, ("tevent_context_init failed\n"));
2859 TALLOC_FREE(state);
2860 return;
2862 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2863 TEVENT_FD_READ, smbd_echo_exit,
2864 state);
2865 if (state->parent_fde == NULL) {
2866 DEBUG(1, ("tevent_add_fd failed\n"));
2867 TALLOC_FREE(state);
2868 return;
2871 read_req = smbd_echo_read_send(state, state->ev, sconn);
2872 if (read_req == NULL) {
2873 DEBUG(1, ("smbd_echo_read_send failed\n"));
2874 TALLOC_FREE(state);
2875 return;
2877 tevent_req_set_callback(read_req, smbd_echo_got_packet, state);
2879 while (true) {
2880 if (tevent_loop_once(state->ev) == -1) {
2881 DEBUG(1, ("tevent_loop_once failed: %s\n",
2882 strerror(errno)));
2883 break;
2886 TALLOC_FREE(state);
2889 static void smbd_echo_got_packet(struct tevent_req *req)
2891 struct smbd_echo_state *state = tevent_req_callback_data(
2892 req, struct smbd_echo_state);
2893 NTSTATUS status;
2894 char *buf = NULL;
2895 size_t buflen = 0;
2896 uint32_t seqnum = 0;
2897 bool reply;
2899 status = smbd_echo_read_recv(req, state, &buf, &buflen, &seqnum);
2900 TALLOC_FREE(req);
2901 if (!NT_STATUS_IS_OK(status)) {
2902 DEBUG(1, ("smbd_echo_read_recv returned %s\n",
2903 nt_errstr(status)));
2904 exit(1);
2907 reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
2908 if (!reply) {
2909 size_t num_pending;
2910 struct iovec *tmp;
2911 struct iovec *iov;
2913 num_pending = talloc_array_length(state->pending);
2914 tmp = talloc_realloc(state, state->pending, struct iovec,
2915 num_pending+1);
2916 if (tmp == NULL) {
2917 DEBUG(1, ("talloc_realloc failed\n"));
2918 exit(1);
2920 state->pending = tmp;
2922 if (buflen >= smb_size) {
2924 * place the seqnum in the packet so that the main process
2925 * can reply with signing
2927 SIVAL(buf, smb_ss_field, seqnum);
2928 SIVAL(buf, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2931 iov = &state->pending[num_pending];
2932 iov->iov_base = buf;
2933 iov->iov_len = buflen;
2935 DEBUG(10,("echo_handler[%d]: forward to main\n",
2936 (int)getpid()));
2937 smbd_echo_activate_writer(state);
2940 req = smbd_echo_read_send(state, state->ev, state->sconn);
2941 if (req == NULL) {
2942 DEBUG(1, ("smbd_echo_read_send failed\n"));
2943 exit(1);
2945 tevent_req_set_callback(req, smbd_echo_got_packet, state);
2950 * Handle SMBecho requests in a forked child process
2952 bool fork_echo_handler(struct smbd_server_connection *sconn)
2954 int listener_pipe[2];
2955 int res;
2956 pid_t child;
2958 res = pipe(listener_pipe);
2959 if (res == -1) {
2960 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2961 return false;
2963 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2964 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2965 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2966 goto fail;
2969 child = fork();
2970 if (child == 0) {
2971 NTSTATUS status;
2973 close(listener_pipe[0]);
2974 set_blocking(listener_pipe[1], false);
2976 status = reinit_after_fork(sconn->msg_ctx,
2977 sconn->ev_ctx,
2978 false);
2979 if (!NT_STATUS_IS_OK(status)) {
2980 DEBUG(1, ("reinit_after_fork failed: %s\n",
2981 nt_errstr(status)));
2982 exit(1);
2984 smbd_echo_loop(sconn, listener_pipe[1]);
2985 exit(0);
2987 close(listener_pipe[1]);
2988 listener_pipe[1] = -1;
2989 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2991 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)getpid(), child));
2994 * Without smb signing this is the same as the normal smbd
2995 * listener. This needs to change once signing comes in.
2997 sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
2998 sconn,
2999 sconn->smb1.echo_handler.trusted_fd,
3000 TEVENT_FD_READ,
3001 smbd_server_echo_handler,
3002 sconn);
3003 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
3004 DEBUG(1, ("event_add_fd failed\n"));
3005 goto fail;
3008 return true;
3010 fail:
3011 if (listener_pipe[0] != -1) {
3012 close(listener_pipe[0]);
3014 if (listener_pipe[1] != -1) {
3015 close(listener_pipe[1]);
3017 sconn->smb1.echo_handler.trusted_fd = -1;
3018 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
3019 close(sconn->smb1.echo_handler.socket_lock_fd);
3021 sconn->smb1.echo_handler.trusted_fd = -1;
3022 sconn->smb1.echo_handler.socket_lock_fd = -1;
3023 return false;
3026 #if CLUSTER_SUPPORT
3028 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
3029 struct sockaddr_storage *srv,
3030 struct sockaddr_storage *clnt)
3032 struct ctdbd_connection *cconn;
3033 char tmp_addr[INET6_ADDRSTRLEN];
3034 char *addr;
3036 cconn = messaging_ctdbd_connection();
3037 if (cconn == NULL) {
3038 return NT_STATUS_NO_MEMORY;
3041 if (client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr)) == NULL) {
3042 return NT_STATUS_NO_MEMORY;
3044 addr = talloc_strdup(cconn, tmp_addr);
3045 if (addr == NULL) {
3046 return NT_STATUS_NO_MEMORY;
3048 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
3051 #endif
3053 static bool uid_in_use(const struct user_struct *user, uid_t uid)
3055 while (user) {
3056 if (user->session_info &&
3057 (user->session_info->unix_token->uid == uid)) {
3058 return true;
3060 user = user->next;
3062 return false;
3065 static bool gid_in_use(const struct user_struct *user, gid_t gid)
3067 while (user) {
3068 if (user->session_info != NULL) {
3069 int i;
3070 struct security_unix_token *utok;
3072 utok = user->session_info->unix_token;
3073 if (utok->gid == gid) {
3074 return true;
3076 for(i=0; i<utok->ngroups; i++) {
3077 if (utok->groups[i] == gid) {
3078 return true;
3082 user = user->next;
3084 return false;
3087 static bool sid_in_use(const struct user_struct *user,
3088 const struct dom_sid *psid)
3090 while (user) {
3091 struct security_token *tok;
3093 if (user->session_info == NULL) {
3094 continue;
3096 tok = user->session_info->security_token;
3097 if (tok == NULL) {
3099 * Not sure session_info->security_token can
3100 * ever be NULL. This check might be not
3101 * necessary.
3103 continue;
3105 if (security_token_has_sid(tok, psid)) {
3106 return true;
3108 user = user->next;
3110 return false;
3113 static bool id_in_use(const struct user_struct *user,
3114 const struct id_cache_ref *id)
3116 switch(id->type) {
3117 case UID:
3118 return uid_in_use(user, id->id.uid);
3119 case GID:
3120 return gid_in_use(user, id->id.gid);
3121 case SID:
3122 return sid_in_use(user, &id->id.sid);
3123 default:
3124 break;
3126 return false;
3129 static void smbd_id_cache_kill(struct messaging_context *msg_ctx,
3130 void *private_data,
3131 uint32_t msg_type,
3132 struct server_id server_id,
3133 DATA_BLOB* data)
3135 const char *msg = (data && data->data)
3136 ? (const char *)data->data : "<NULL>";
3137 struct id_cache_ref id;
3138 struct smbd_server_connection *sconn =
3139 talloc_get_type_abort(private_data,
3140 struct smbd_server_connection);
3142 if (!id_cache_ref_parse(msg, &id)) {
3143 DEBUG(0, ("Invalid ?ID: %s\n", msg));
3144 return;
3147 if (id_in_use(sconn->users, &id)) {
3148 exit_server_cleanly(msg);
3150 id_cache_delete_from_cache(&id);
3153 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
3154 enum protocol_types protocol)
3156 set_Protocol(protocol);
3157 conn->protocol = protocol;
3159 return NT_STATUS_OK;
3162 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
3163 void *private_data)
3165 switch (point) {
3166 case TEVENT_TRACE_BEFORE_WAIT:
3167 START_PROFILE(smbd_idle);
3168 break;
3169 case TEVENT_TRACE_AFTER_WAIT:
3170 END_PROFILE(smbd_idle);
3171 break;
3175 /****************************************************************************
3176 Process commands from the client
3177 ****************************************************************************/
3179 void smbd_process(struct tevent_context *ev_ctx,
3180 struct messaging_context *msg_ctx,
3181 int sock_fd,
3182 bool interactive)
3184 TALLOC_CTX *frame = talloc_stackframe();
3185 struct smbXsrv_connection *conn;
3186 struct smbd_server_connection *sconn;
3187 struct sockaddr_storage ss;
3188 struct sockaddr *sa = NULL;
3189 socklen_t sa_socklen;
3190 struct tsocket_address *local_address = NULL;
3191 struct tsocket_address *remote_address = NULL;
3192 const char *locaddr = NULL;
3193 const char *remaddr = NULL;
3194 char *rhost;
3195 int ret;
3197 conn = talloc_zero(ev_ctx, struct smbXsrv_connection);
3198 if (conn == NULL) {
3199 DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
3200 exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
3203 conn->ev_ctx = ev_ctx;
3204 conn->msg_ctx = msg_ctx;
3206 sconn = talloc_zero(conn, struct smbd_server_connection);
3207 if (!sconn) {
3208 exit_server("failed to create smbd_server_connection");
3211 conn->sconn = sconn;
3212 sconn->conn = conn;
3215 * TODO: remove this...:-)
3217 global_smbXsrv_connection = conn;
3219 sconn->ev_ctx = ev_ctx;
3220 sconn->msg_ctx = msg_ctx;
3221 sconn->sock = sock_fd;
3222 sconn->smb1.echo_handler.trusted_fd = -1;
3223 sconn->smb1.echo_handler.socket_lock_fd = -1;
3225 if (!interactive) {
3226 smbd_setup_sig_term_handler(sconn);
3227 smbd_setup_sig_hup_handler(sconn);
3229 if (!serverid_register(messaging_server_id(msg_ctx),
3230 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
3231 |FLAG_MSG_DBWRAP
3232 |FLAG_MSG_PRINT_GENERAL)) {
3233 exit_server_cleanly("Could not register myself in "
3234 "serverid.tdb");
3238 if (lp_srv_maxprotocol() >= PROTOCOL_SMB2_02) {
3240 * We're not making the decision here,
3241 * we're just allowing the client
3242 * to decide between SMB1 and SMB2
3243 * with the first negprot
3244 * packet.
3246 sconn->using_smb2 = true;
3249 /* Ensure child is set to blocking mode */
3250 set_blocking(sconn->sock,True);
3252 set_socket_options(sconn->sock, "SO_KEEPALIVE");
3253 set_socket_options(sconn->sock, lp_socket_options());
3255 sa = (struct sockaddr *)(void *)&ss;
3256 sa_socklen = sizeof(ss);
3257 ret = getpeername(sconn->sock, sa, &sa_socklen);
3258 if (ret != 0) {
3259 int level = (errno == ENOTCONN)?2:0;
3260 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
3261 exit_server_cleanly("getpeername() failed.\n");
3263 ret = tsocket_address_bsd_from_sockaddr(sconn,
3264 sa, sa_socklen,
3265 &remote_address);
3266 if (ret != 0) {
3267 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3268 __location__, strerror(errno)));
3269 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3272 sa = (struct sockaddr *)(void *)&ss;
3273 sa_socklen = sizeof(ss);
3274 ret = getsockname(sconn->sock, sa, &sa_socklen);
3275 if (ret != 0) {
3276 int level = (errno == ENOTCONN)?2:0;
3277 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
3278 exit_server_cleanly("getsockname() failed.\n");
3280 ret = tsocket_address_bsd_from_sockaddr(sconn,
3281 sa, sa_socklen,
3282 &local_address);
3283 if (ret != 0) {
3284 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
3285 __location__, strerror(errno)));
3286 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
3289 sconn->local_address = local_address;
3290 sconn->remote_address = remote_address;
3292 if (tsocket_address_is_inet(local_address, "ip")) {
3293 locaddr = tsocket_address_inet_addr_string(
3294 sconn->local_address,
3295 talloc_tos());
3296 if (locaddr == NULL) {
3297 DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
3298 __location__, strerror(errno)));
3299 exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
3301 } else {
3302 locaddr = "0.0.0.0";
3305 if (tsocket_address_is_inet(remote_address, "ip")) {
3306 remaddr = tsocket_address_inet_addr_string(
3307 sconn->remote_address,
3308 talloc_tos());
3309 if (remaddr == NULL) {
3310 DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
3311 __location__, strerror(errno)));
3312 exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
3314 } else {
3315 remaddr = "0.0.0.0";
3318 /* this is needed so that we get decent entries
3319 in smbstatus for port 445 connects */
3320 set_remote_machine_name(remaddr, false);
3321 reload_services(sconn, conn_snum_used, true);
3324 * Before the first packet, check the global hosts allow/ hosts deny
3325 * parameters before doing any parsing of packets passed to us by the
3326 * client. This prevents attacks on our parsing code from hosts not in
3327 * the hosts allow list.
3330 ret = get_remote_hostname(remote_address,
3331 &rhost,
3332 talloc_tos());
3333 if (ret < 0) {
3334 DEBUG(0,("%s: get_remote_hostname failed - %s\n",
3335 __location__, strerror(errno)));
3336 exit_server_cleanly("get_remote_hostname failed.\n");
3338 if (strequal(rhost, "UNKNOWN")) {
3339 rhost = talloc_strdup(talloc_tos(), remaddr);
3341 sconn->remote_hostname = talloc_move(sconn, &rhost);
3343 sub_set_socket_ids(remaddr,
3344 sconn->remote_hostname,
3345 locaddr);
3347 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3348 sconn->remote_hostname,
3349 remaddr)) {
3351 * send a negative session response "not listening on calling
3352 * name"
3354 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3355 DEBUG( 1, ("Connection denied from %s to %s\n",
3356 tsocket_address_string(remote_address, talloc_tos()),
3357 tsocket_address_string(local_address, talloc_tos())));
3358 (void)srv_send_smb(sconn,(char *)buf, false,
3359 0, false, NULL);
3360 exit_server_cleanly("connection denied");
3363 DEBUG(10, ("Connection allowed from %s to %s\n",
3364 tsocket_address_string(remote_address, talloc_tos()),
3365 tsocket_address_string(local_address, talloc_tos())));
3367 if (lp_preload_modules()) {
3368 smb_load_modules(lp_preload_modules());
3371 smb_perfcount_init();
3373 if (!init_account_policy()) {
3374 exit_server("Could not open account policy tdb.\n");
3377 if (*lp_rootdir()) {
3378 if (chroot(lp_rootdir()) != 0) {
3379 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3380 exit_server("Failed to chroot()");
3382 if (chdir("/") == -1) {
3383 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3384 exit_server("Failed to chroot()");
3386 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3389 if (!srv_init_signing(sconn)) {
3390 exit_server("Failed to init smb_signing");
3393 if (!file_init(sconn)) {
3394 exit_server("file_init() failed");
3397 /* Setup oplocks */
3398 if (!init_oplocks(sconn))
3399 exit_server("Failed to init oplocks");
3401 /* register our message handlers */
3402 messaging_register(sconn->msg_ctx, sconn,
3403 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3404 messaging_register(sconn->msg_ctx, sconn,
3405 MSG_SMB_CLOSE_FILE, msg_close_file);
3406 messaging_register(sconn->msg_ctx, sconn,
3407 MSG_SMB_FILE_RENAME, msg_file_was_renamed);
3409 id_cache_register_msgs(sconn->msg_ctx);
3410 messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL);
3411 messaging_register(sconn->msg_ctx, sconn,
3412 ID_CACHE_KILL, smbd_id_cache_kill);
3414 messaging_deregister(sconn->msg_ctx,
3415 MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
3416 messaging_register(sconn->msg_ctx, sconn,
3417 MSG_SMB_CONF_UPDATED, smbd_conf_updated);
3420 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3421 * MSGs to all child processes
3423 messaging_deregister(sconn->msg_ctx,
3424 MSG_DEBUG, NULL);
3425 messaging_register(sconn->msg_ctx, NULL,
3426 MSG_DEBUG, debug_message);
3428 if ((lp_keepalive() != 0)
3429 && !(event_add_idle(ev_ctx, NULL,
3430 timeval_set(lp_keepalive(), 0),
3431 "keepalive", keepalive_fn,
3432 sconn))) {
3433 DEBUG(0, ("Could not add keepalive event\n"));
3434 exit(1);
3437 if (!(event_add_idle(ev_ctx, NULL,
3438 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3439 "deadtime", deadtime_fn, sconn))) {
3440 DEBUG(0, ("Could not add deadtime event\n"));
3441 exit(1);
3444 if (!(event_add_idle(ev_ctx, NULL,
3445 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3446 "housekeeping", housekeeping_fn, sconn))) {
3447 DEBUG(0, ("Could not add housekeeping event\n"));
3448 exit(1);
3451 #ifdef CLUSTER_SUPPORT
3453 if (lp_clustering()) {
3455 * We need to tell ctdb about our client's TCP
3456 * connection, so that for failover ctdbd can send
3457 * tickle acks, triggering a reconnection by the
3458 * client.
3461 struct sockaddr_storage srv, clnt;
3463 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3464 NTSTATUS status;
3465 status = smbd_register_ips(sconn, &srv, &clnt);
3466 if (!NT_STATUS_IS_OK(status)) {
3467 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3468 nt_errstr(status)));
3470 } else
3472 DEBUG(0,("Unable to get tcp info for "
3473 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3474 strerror(errno)));
3478 #endif
3480 sconn->nbt.got_session = false;
3482 sconn->smb1.negprot.max_recv = MIN(lp_max_xmit(),BUFFER_SIZE);
3484 sconn->smb1.sessions.done_sesssetup = false;
3485 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3486 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3487 /* this holds info on user ids that are already validated for this VC */
3488 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3490 conn_init(sconn);
3491 if (!init_dptrs(sconn)) {
3492 exit_server("init_dptrs() failed");
3495 sconn->smb1.fde = event_add_fd(ev_ctx,
3496 sconn,
3497 sconn->sock,
3498 EVENT_FD_READ,
3499 smbd_server_connection_handler,
3500 sconn);
3501 if (!sconn->smb1.fde) {
3502 exit_server("failed to create smbd_server_connection fde");
3505 sconn->conn->local_address = sconn->local_address;
3506 sconn->conn->remote_address = sconn->remote_address;
3507 sconn->conn->remote_hostname = sconn->remote_hostname;
3508 sconn->conn->protocol = PROTOCOL_NONE;
3510 TALLOC_FREE(frame);
3512 tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, NULL);
3514 while (True) {
3515 frame = talloc_stackframe_pool(8192);
3517 errno = 0;
3518 if (tevent_loop_once(ev_ctx) == -1) {
3519 if (errno != EINTR) {
3520 DEBUG(3, ("tevent_loop_once failed: %s,"
3521 " exiting\n", strerror(errno) ));
3522 break;
3526 TALLOC_FREE(frame);
3529 exit_server_cleanly(NULL);
3532 bool req_is_in_chain(struct smb_request *req)
3534 if (req->vwv != (const uint16_t *)(req->inbuf+smb_vwv)) {
3536 * We're right now handling a subsequent request, so we must
3537 * be in a chain
3539 return true;
3542 if (!is_andx_req(req->cmd)) {
3543 return false;
3546 if (req->wct < 2) {
3548 * Okay, an illegal request, but definitely not chained :-)
3550 return false;
3553 return (CVAL(req->vwv+0, 0) != 0xFF);