WHATSNEW: Update changes.
[Samba/gebeck_regimport.git] / source3 / smbd / process.c
blob13fec92ea5621bcda978bc70bbc3d5f8176a2f30
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "smbd/globals.h"
23 #include "../librpc/gen_ndr/srv_dfs.h"
24 #include "../librpc/gen_ndr/srv_dssetup.h"
25 #include "../librpc/gen_ndr/srv_echo.h"
26 #include "../librpc/gen_ndr/srv_eventlog.h"
27 #include "../librpc/gen_ndr/srv_initshutdown.h"
28 #include "../librpc/gen_ndr/srv_lsa.h"
29 #include "../librpc/gen_ndr/srv_netlogon.h"
30 #include "../librpc/gen_ndr/srv_ntsvcs.h"
31 #include "../librpc/gen_ndr/srv_samr.h"
32 #include "../librpc/gen_ndr/srv_spoolss.h"
33 #include "../librpc/gen_ndr/srv_srvsvc.h"
34 #include "../librpc/gen_ndr/srv_svcctl.h"
35 #include "../librpc/gen_ndr/srv_winreg.h"
36 #include "../librpc/gen_ndr/srv_wkssvc.h"
37 #include "librpc/gen_ndr/messaging.h"
39 extern bool global_machine_password_needs_changing;
41 static void construct_reply_common(struct smb_request *req, const char *inbuf,
42 char *outbuf);
43 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
45 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
47 bool ok;
49 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
50 return true;
53 sconn->smb1.echo_handler.ref_count++;
55 if (sconn->smb1.echo_handler.ref_count > 1) {
56 return true;
59 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
61 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
62 SMB_F_SETLKW, 0, 0, F_WRLCK);
63 if (!ok) {
64 return false;
67 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
69 return true;
72 void smbd_lock_socket(struct smbd_server_connection *sconn)
74 if (!smbd_lock_socket_internal(sconn)) {
75 exit_server_cleanly("failed to lock socket");
79 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
81 bool ok;
83 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
84 return true;
87 sconn->smb1.echo_handler.ref_count--;
89 if (sconn->smb1.echo_handler.ref_count > 0) {
90 return true;
93 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
94 SMB_F_SETLKW, 0, 0, F_UNLCK);
95 if (!ok) {
96 return false;
99 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
101 return true;
104 void smbd_unlock_socket(struct smbd_server_connection *sconn)
106 if (!smbd_unlock_socket_internal(sconn)) {
107 exit_server_cleanly("failed to unlock socket");
111 /* Accessor function for smb_read_error for smbd functions. */
113 /****************************************************************************
114 Send an smb to a fd.
115 ****************************************************************************/
117 bool srv_send_smb(int fd, char *buffer,
118 bool do_signing, uint32_t seqnum,
119 bool do_encrypt,
120 struct smb_perfcount_data *pcd)
122 size_t len = 0;
123 size_t nwritten=0;
124 ssize_t ret;
125 char *buf_out = buffer;
127 smbd_lock_socket(smbd_server_conn);
129 if (do_signing) {
130 /* Sign the outgoing packet if required. */
131 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
134 if (do_encrypt) {
135 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
136 if (!NT_STATUS_IS_OK(status)) {
137 DEBUG(0, ("send_smb: SMB encryption failed "
138 "on outgoing packet! Error %s\n",
139 nt_errstr(status) ));
140 goto out;
144 len = smb_len(buf_out) + 4;
146 ret = write_data(fd,buf_out+nwritten,len - nwritten);
147 if (ret <= 0) {
148 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
149 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
150 srv_free_enc_buffer(buf_out);
151 goto out;
154 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
155 srv_free_enc_buffer(buf_out);
156 out:
157 SMB_PERFCOUNT_END(pcd);
159 smbd_unlock_socket(smbd_server_conn);
160 return true;
163 /*******************************************************************
164 Setup the word count and byte count for a smb message.
165 ********************************************************************/
167 int srv_set_message(char *buf,
168 int num_words,
169 int num_bytes,
170 bool zero)
172 if (zero && (num_words || num_bytes)) {
173 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
175 SCVAL(buf,smb_wct,num_words);
176 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
177 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
178 return (smb_size + num_words*2 + num_bytes);
181 static bool valid_smb_header(const uint8_t *inbuf)
183 if (is_encrypted_packet(inbuf)) {
184 return true;
187 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
188 * but it just looks weird to call strncmp for this one.
190 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
193 /* Socket functions for smbd packet processing. */
195 static bool valid_packet_size(size_t len)
198 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
199 * of header. Don't print the error if this fits.... JRA.
202 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
203 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
204 (unsigned long)len));
205 return false;
207 return true;
210 static NTSTATUS read_packet_remainder(int fd, char *buffer,
211 unsigned int timeout, ssize_t len)
213 if (len <= 0) {
214 return NT_STATUS_OK;
217 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
220 /****************************************************************************
221 Attempt a zerocopy writeX read. We know here that len > smb_size-4
222 ****************************************************************************/
225 * Unfortunately, earlier versions of smbclient/libsmbclient
226 * don't send this "standard" writeX header. I've fixed this
227 * for 3.2 but we'll use the old method with earlier versions.
228 * Windows and CIFSFS at least use this standard size. Not
229 * sure about MacOSX.
232 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
233 (2*14) + /* word count (including bcc) */ \
234 1 /* pad byte */)
236 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
237 const char lenbuf[4],
238 int fd, char **buffer,
239 unsigned int timeout,
240 size_t *p_unread,
241 size_t *len_ret)
243 /* Size of a WRITEX call (+4 byte len). */
244 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
245 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
246 ssize_t toread;
247 NTSTATUS status;
249 memcpy(writeX_header, lenbuf, 4);
251 status = read_fd_with_timeout(
252 fd, writeX_header + 4,
253 STANDARD_WRITE_AND_X_HEADER_SIZE,
254 STANDARD_WRITE_AND_X_HEADER_SIZE,
255 timeout, NULL);
257 if (!NT_STATUS_IS_OK(status)) {
258 return status;
262 * Ok - now try and see if this is a possible
263 * valid writeX call.
266 if (is_valid_writeX_buffer(smbd_server_conn,
267 (uint8_t *)writeX_header)) {
269 * If the data offset is beyond what
270 * we've read, drain the extra bytes.
272 uint16_t doff = SVAL(writeX_header,smb_vwv11);
273 ssize_t newlen;
275 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
276 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
277 if (drain_socket(smbd_server_fd(), drain) != drain) {
278 smb_panic("receive_smb_raw_talloc_partial_read:"
279 " failed to drain pending bytes");
281 } else {
282 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
285 /* Spoof down the length and null out the bcc. */
286 set_message_bcc(writeX_header, 0);
287 newlen = smb_len(writeX_header);
289 /* Copy the header we've written. */
291 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
292 writeX_header,
293 sizeof(writeX_header));
295 if (*buffer == NULL) {
296 DEBUG(0, ("Could not allocate inbuf of length %d\n",
297 (int)sizeof(writeX_header)));
298 return NT_STATUS_NO_MEMORY;
301 /* Work out the remaining bytes. */
302 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
303 *len_ret = newlen + 4;
304 return NT_STATUS_OK;
307 if (!valid_packet_size(len)) {
308 return NT_STATUS_INVALID_PARAMETER;
312 * Not a valid writeX call. Just do the standard
313 * talloc and return.
316 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
318 if (*buffer == NULL) {
319 DEBUG(0, ("Could not allocate inbuf of length %d\n",
320 (int)len+4));
321 return NT_STATUS_NO_MEMORY;
324 /* Copy in what we already read. */
325 memcpy(*buffer,
326 writeX_header,
327 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
328 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
330 if(toread > 0) {
331 status = read_packet_remainder(
332 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
333 timeout, toread);
335 if (!NT_STATUS_IS_OK(status)) {
336 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
337 nt_errstr(status)));
338 return status;
342 *len_ret = len + 4;
343 return NT_STATUS_OK;
346 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
347 char **buffer, unsigned int timeout,
348 size_t *p_unread, size_t *plen)
350 char lenbuf[4];
351 size_t len;
352 int min_recv_size = lp_min_receive_file_size();
353 NTSTATUS status;
355 *p_unread = 0;
357 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
358 if (!NT_STATUS_IS_OK(status)) {
359 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
360 return status;
363 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
364 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
365 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
366 !srv_is_signing_active(smbd_server_conn) &&
367 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
369 return receive_smb_raw_talloc_partial_read(
370 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
373 if (!valid_packet_size(len)) {
374 return NT_STATUS_INVALID_PARAMETER;
378 * The +4 here can't wrap, we've checked the length above already.
381 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
383 if (*buffer == NULL) {
384 DEBUG(0, ("Could not allocate inbuf of length %d\n",
385 (int)len+4));
386 return NT_STATUS_NO_MEMORY;
389 memcpy(*buffer, lenbuf, sizeof(lenbuf));
391 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
392 if (!NT_STATUS_IS_OK(status)) {
393 return status;
396 *plen = len + 4;
397 return NT_STATUS_OK;
400 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
401 char **buffer, unsigned int timeout,
402 size_t *p_unread, bool *p_encrypted,
403 size_t *p_len,
404 uint32_t *seqnum,
405 bool trusted_channel)
407 size_t len = 0;
408 NTSTATUS status;
410 *p_encrypted = false;
412 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
413 p_unread, &len);
414 if (!NT_STATUS_IS_OK(status)) {
415 return status;
418 if (is_encrypted_packet((uint8_t *)*buffer)) {
419 status = srv_decrypt_buffer(*buffer);
420 if (!NT_STATUS_IS_OK(status)) {
421 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
422 "incoming packet! Error %s\n",
423 nt_errstr(status) ));
424 return status;
426 *p_encrypted = true;
429 /* Check the incoming SMB signature. */
430 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
431 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
432 "incoming packet!\n"));
433 return NT_STATUS_INVALID_NETWORK_RESPONSE;
436 *p_len = len;
437 return NT_STATUS_OK;
441 * Initialize a struct smb_request from an inbuf
444 static bool init_smb_request(struct smb_request *req,
445 struct smbd_server_connection *sconn,
446 const uint8 *inbuf,
447 size_t unread_bytes, bool encrypted,
448 uint32_t seqnum)
450 size_t req_size = smb_len(inbuf) + 4;
451 /* Ensure we have at least smb_size bytes. */
452 if (req_size < smb_size) {
453 DEBUG(0,("init_smb_request: invalid request size %u\n",
454 (unsigned int)req_size ));
455 return false;
457 req->cmd = CVAL(inbuf, smb_com);
458 req->flags2 = SVAL(inbuf, smb_flg2);
459 req->smbpid = SVAL(inbuf, smb_pid);
460 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
461 req->seqnum = seqnum;
462 req->vuid = SVAL(inbuf, smb_uid);
463 req->tid = SVAL(inbuf, smb_tid);
464 req->wct = CVAL(inbuf, smb_wct);
465 req->vwv = (uint16_t *)(inbuf+smb_vwv);
466 req->buflen = smb_buflen(inbuf);
467 req->buf = (const uint8_t *)smb_buf(inbuf);
468 req->unread_bytes = unread_bytes;
469 req->encrypted = encrypted;
470 req->sconn = sconn;
471 req->conn = conn_find(sconn,req->tid);
472 req->chain_fsp = NULL;
473 req->chain_outbuf = NULL;
474 req->done = false;
475 req->smb2req = NULL;
476 smb_init_perfcount_data(&req->pcd);
478 /* Ensure we have at least wct words and 2 bytes of bcc. */
479 if (smb_size + req->wct*2 > req_size) {
480 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
481 (unsigned int)req->wct,
482 (unsigned int)req_size));
483 return false;
485 /* Ensure bcc is correct. */
486 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
487 DEBUG(0,("init_smb_request: invalid bcc number %u "
488 "(wct = %u, size %u)\n",
489 (unsigned int)req->buflen,
490 (unsigned int)req->wct,
491 (unsigned int)req_size));
492 return false;
495 req->outbuf = NULL;
496 return true;
499 static void process_smb(struct smbd_server_connection *conn,
500 uint8_t *inbuf, size_t nread, size_t unread_bytes,
501 uint32_t seqnum, bool encrypted,
502 struct smb_perfcount_data *deferred_pcd);
504 static void smbd_deferred_open_timer(struct event_context *ev,
505 struct timed_event *te,
506 struct timeval _tval,
507 void *private_data)
509 struct pending_message_list *msg = talloc_get_type(private_data,
510 struct pending_message_list);
511 TALLOC_CTX *mem_ctx = talloc_tos();
512 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
513 uint8_t *inbuf;
515 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
516 msg->buf.length);
517 if (inbuf == NULL) {
518 exit_server("smbd_deferred_open_timer: talloc failed\n");
519 return;
522 /* We leave this message on the queue so the open code can
523 know this is a retry. */
524 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
525 (unsigned long long)mid ));
527 /* Mark the message as processed so this is not
528 * re-processed in error. */
529 msg->processed = true;
531 process_smb(smbd_server_conn, inbuf,
532 msg->buf.length, 0,
533 msg->seqnum, msg->encrypted, &msg->pcd);
535 /* If it's still there and was processed, remove it. */
536 msg = get_deferred_open_message_smb(mid);
537 if (msg && msg->processed) {
538 remove_deferred_open_message_smb(mid);
542 /****************************************************************************
543 Function to push a message onto the tail of a linked list of smb messages ready
544 for processing.
545 ****************************************************************************/
547 static bool push_queued_message(struct smb_request *req,
548 struct timeval request_time,
549 struct timeval end_time,
550 char *private_data, size_t private_len)
552 int msg_len = smb_len(req->inbuf) + 4;
553 struct pending_message_list *msg;
555 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
557 if(msg == NULL) {
558 DEBUG(0,("push_message: malloc fail (1)\n"));
559 return False;
562 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
563 if(msg->buf.data == NULL) {
564 DEBUG(0,("push_message: malloc fail (2)\n"));
565 TALLOC_FREE(msg);
566 return False;
569 msg->request_time = request_time;
570 msg->seqnum = req->seqnum;
571 msg->encrypted = req->encrypted;
572 msg->processed = false;
573 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
575 if (private_data) {
576 msg->private_data = data_blob_talloc(msg, private_data,
577 private_len);
578 if (msg->private_data.data == NULL) {
579 DEBUG(0,("push_message: malloc fail (3)\n"));
580 TALLOC_FREE(msg);
581 return False;
585 msg->te = event_add_timed(smbd_event_context(),
586 msg,
587 end_time,
588 smbd_deferred_open_timer,
589 msg);
590 if (!msg->te) {
591 DEBUG(0,("push_message: event_add_timed failed\n"));
592 TALLOC_FREE(msg);
593 return false;
596 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
598 DEBUG(10,("push_message: pushed message length %u on "
599 "deferred_open_queue\n", (unsigned int)msg_len));
601 return True;
604 /****************************************************************************
605 Function to delete a sharing violation open message by mid.
606 ****************************************************************************/
608 void remove_deferred_open_message_smb(uint64_t mid)
610 struct pending_message_list *pml;
612 if (smbd_server_conn->using_smb2) {
613 remove_deferred_open_message_smb2(smbd_server_conn, mid);
614 return;
617 for (pml = deferred_open_queue; pml; pml = pml->next) {
618 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
619 DEBUG(10,("remove_deferred_open_message_smb: "
620 "deleting mid %llu len %u\n",
621 (unsigned long long)mid,
622 (unsigned int)pml->buf.length ));
623 DLIST_REMOVE(deferred_open_queue, pml);
624 TALLOC_FREE(pml);
625 return;
630 /****************************************************************************
631 Move a sharing violation open retry message to the front of the list and
632 schedule it for immediate processing.
633 ****************************************************************************/
635 void schedule_deferred_open_message_smb(uint64_t mid)
637 struct pending_message_list *pml;
638 int i = 0;
640 if (smbd_server_conn->using_smb2) {
641 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
642 return;
645 for (pml = deferred_open_queue; pml; pml = pml->next) {
646 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
648 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
649 "msg_mid = %llu\n",
650 i++,
651 (unsigned long long)msg_mid ));
653 if (mid == msg_mid) {
654 struct timed_event *te;
656 if (pml->processed) {
657 /* A processed message should not be
658 * rescheduled. */
659 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
660 "message mid %llu was already processed\n",
661 (unsigned long long)msg_mid ));
662 continue;
665 DEBUG(10,("schedule_deferred_open_message_smb: "
666 "scheduling mid %llu\n",
667 (unsigned long long)mid ));
669 te = event_add_timed(smbd_event_context(),
670 pml,
671 timeval_zero(),
672 smbd_deferred_open_timer,
673 pml);
674 if (!te) {
675 DEBUG(10,("schedule_deferred_open_message_smb: "
676 "event_add_timed() failed, "
677 "skipping mid %llu\n",
678 (unsigned long long)msg_mid ));
681 TALLOC_FREE(pml->te);
682 pml->te = te;
683 DLIST_PROMOTE(deferred_open_queue, pml);
684 return;
688 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
689 "find message mid %llu\n",
690 (unsigned long long)mid ));
693 /****************************************************************************
694 Return true if this mid is on the deferred queue and was not yet processed.
695 ****************************************************************************/
697 bool open_was_deferred(uint64_t mid)
699 struct pending_message_list *pml;
701 if (smbd_server_conn->using_smb2) {
702 return open_was_deferred_smb2(smbd_server_conn, mid);
705 for (pml = deferred_open_queue; pml; pml = pml->next) {
706 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
707 return True;
710 return False;
713 /****************************************************************************
714 Return the message queued by this mid.
715 ****************************************************************************/
717 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
719 struct pending_message_list *pml;
721 for (pml = deferred_open_queue; pml; pml = pml->next) {
722 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
723 return pml;
726 return NULL;
729 /****************************************************************************
730 Get the state data queued by this mid.
731 ****************************************************************************/
733 bool get_deferred_open_message_state(struct smb_request *smbreq,
734 struct timeval *p_request_time,
735 void **pp_state)
737 struct pending_message_list *pml;
739 if (smbd_server_conn->using_smb2) {
740 return get_deferred_open_message_state_smb2(smbreq->smb2req,
741 p_request_time,
742 pp_state);
745 pml = get_deferred_open_message_smb(smbreq->mid);
746 if (!pml) {
747 return false;
749 if (p_request_time) {
750 *p_request_time = pml->request_time;
752 if (pp_state) {
753 *pp_state = (void *)pml->private_data.data;
755 return true;
758 /****************************************************************************
759 Function to push a deferred open smb message onto a linked list of local smb
760 messages ready for processing.
761 ****************************************************************************/
763 bool push_deferred_open_message_smb(struct smb_request *req,
764 struct timeval request_time,
765 struct timeval timeout,
766 struct file_id id,
767 char *private_data, size_t priv_len)
769 struct timeval end_time;
771 if (req->smb2req) {
772 return push_deferred_open_message_smb2(req->smb2req,
773 request_time,
774 timeout,
776 private_data,
777 priv_len);
780 if (req->unread_bytes) {
781 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
782 "unread_bytes = %u\n",
783 (unsigned int)req->unread_bytes ));
784 smb_panic("push_deferred_open_message_smb: "
785 "logic error unread_bytes != 0" );
788 end_time = timeval_sum(&request_time, &timeout);
790 DEBUG(10,("push_deferred_open_message_smb: pushing message "
791 "len %u mid %llu timeout time [%u.%06u]\n",
792 (unsigned int) smb_len(req->inbuf)+4,
793 (unsigned long long)req->mid,
794 (unsigned int)end_time.tv_sec,
795 (unsigned int)end_time.tv_usec));
797 return push_queued_message(req, request_time, end_time,
798 private_data, priv_len);
801 struct idle_event {
802 struct timed_event *te;
803 struct timeval interval;
804 char *name;
805 bool (*handler)(const struct timeval *now, void *private_data);
806 void *private_data;
809 static void smbd_idle_event_handler(struct event_context *ctx,
810 struct timed_event *te,
811 struct timeval now,
812 void *private_data)
814 struct idle_event *event =
815 talloc_get_type_abort(private_data, struct idle_event);
817 TALLOC_FREE(event->te);
819 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
820 event->name, event->te));
822 if (!event->handler(&now, event->private_data)) {
823 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
824 event->name, event->te));
825 /* Don't repeat, delete ourselves */
826 TALLOC_FREE(event);
827 return;
830 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
831 event->name, event->te));
833 event->te = event_add_timed(ctx, event,
834 timeval_sum(&now, &event->interval),
835 smbd_idle_event_handler, event);
837 /* We can't do much but fail here. */
838 SMB_ASSERT(event->te != NULL);
841 struct idle_event *event_add_idle(struct event_context *event_ctx,
842 TALLOC_CTX *mem_ctx,
843 struct timeval interval,
844 const char *name,
845 bool (*handler)(const struct timeval *now,
846 void *private_data),
847 void *private_data)
849 struct idle_event *result;
850 struct timeval now = timeval_current();
852 result = TALLOC_P(mem_ctx, struct idle_event);
853 if (result == NULL) {
854 DEBUG(0, ("talloc failed\n"));
855 return NULL;
858 result->interval = interval;
859 result->handler = handler;
860 result->private_data = private_data;
862 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
863 DEBUG(0, ("talloc failed\n"));
864 TALLOC_FREE(result);
865 return NULL;
868 result->te = event_add_timed(event_ctx, result,
869 timeval_sum(&now, &interval),
870 smbd_idle_event_handler, result);
871 if (result->te == NULL) {
872 DEBUG(0, ("event_add_timed failed\n"));
873 TALLOC_FREE(result);
874 return NULL;
877 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
878 return result;
881 static void smbd_sig_term_handler(struct tevent_context *ev,
882 struct tevent_signal *se,
883 int signum,
884 int count,
885 void *siginfo,
886 void *private_data)
888 exit_server_cleanly("termination signal");
891 void smbd_setup_sig_term_handler(void)
893 struct tevent_signal *se;
895 se = tevent_add_signal(smbd_event_context(),
896 smbd_event_context(),
897 SIGTERM, 0,
898 smbd_sig_term_handler,
899 NULL);
900 if (!se) {
901 exit_server("failed to setup SIGTERM handler");
905 static void smbd_sig_hup_handler(struct tevent_context *ev,
906 struct tevent_signal *se,
907 int signum,
908 int count,
909 void *siginfo,
910 void *private_data)
912 change_to_root_user();
913 DEBUG(1,("Reloading services after SIGHUP\n"));
914 reload_services(False);
917 void smbd_setup_sig_hup_handler(void)
919 struct tevent_signal *se;
921 se = tevent_add_signal(smbd_event_context(),
922 smbd_event_context(),
923 SIGHUP, 0,
924 smbd_sig_hup_handler,
925 NULL);
926 if (!se) {
927 exit_server("failed to setup SIGHUP handler");
931 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
933 fd_set r_fds, w_fds;
934 int selrtn;
935 struct timeval to;
936 int maxfd = 0;
938 to.tv_sec = SMBD_SELECT_TIMEOUT;
939 to.tv_usec = 0;
942 * Setup the select fd sets.
945 FD_ZERO(&r_fds);
946 FD_ZERO(&w_fds);
949 * Are there any timed events waiting ? If so, ensure we don't
950 * select for longer than it would take to wait for them.
954 struct timeval now;
955 GetTimeOfDay(&now);
957 event_add_to_select_args(smbd_event_context(), &now,
958 &r_fds, &w_fds, &to, &maxfd);
961 /* Process a signal and timed events now... */
962 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
963 return NT_STATUS_RETRY;
967 int sav;
968 START_PROFILE(smbd_idle);
970 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
971 sav = errno;
973 END_PROFILE(smbd_idle);
974 errno = sav;
977 if ((conn->smb1.echo_handler.trusted_fd != -1)
978 && FD_ISSET(smbd_server_fd(), &r_fds)
979 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
981 * Prefer to read pending requests from the echo handler. To
982 * quote Jeremy (da70f8ab1): This is a hack of monstrous
983 * proportions...
985 FD_CLR(smbd_server_fd(), &r_fds);
988 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
989 return NT_STATUS_RETRY;
992 /* Check if error */
993 if (selrtn == -1) {
994 /* something is wrong. Maybe the socket is dead? */
995 return map_nt_error_from_unix(errno);
998 /* Did we timeout ? */
999 if (selrtn == 0) {
1000 return NT_STATUS_RETRY;
1003 /* should not be reached */
1004 return NT_STATUS_INTERNAL_ERROR;
1008 * Only allow 5 outstanding trans requests. We're allocating memory, so
1009 * prevent a DoS.
1012 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1014 int count = 0;
1015 for (; list != NULL; list = list->next) {
1017 if (list->mid == mid) {
1018 return NT_STATUS_INVALID_PARAMETER;
1021 count += 1;
1023 if (count > 5) {
1024 return NT_STATUS_INSUFFICIENT_RESOURCES;
1027 return NT_STATUS_OK;
1031 These flags determine some of the permissions required to do an operation
1033 Note that I don't set NEED_WRITE on some write operations because they
1034 are used by some brain-dead clients when printing, and I don't want to
1035 force write permissions on print services.
1037 #define AS_USER (1<<0)
1038 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1039 #define TIME_INIT (1<<2)
1040 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1041 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1042 #define DO_CHDIR (1<<6)
1045 define a list of possible SMB messages and their corresponding
1046 functions. Any message that has a NULL function is unimplemented -
1047 please feel free to contribute implementations!
1049 static const struct smb_message_struct {
1050 const char *name;
1051 void (*fn)(struct smb_request *req);
1052 int flags;
1053 } smb_messages[256] = {
1055 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1056 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1057 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1058 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1059 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1060 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1061 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1062 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1063 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1064 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1065 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1066 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1067 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1068 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1069 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1070 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1071 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1072 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1073 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1074 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1075 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1076 /* 0x15 */ { NULL, NULL, 0 },
1077 /* 0x16 */ { NULL, NULL, 0 },
1078 /* 0x17 */ { NULL, NULL, 0 },
1079 /* 0x18 */ { NULL, NULL, 0 },
1080 /* 0x19 */ { NULL, NULL, 0 },
1081 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1082 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1083 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1084 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1085 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1086 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1087 /* 0x20 */ { "SMBwritec", NULL,0},
1088 /* 0x21 */ { NULL, NULL, 0 },
1089 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1090 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1091 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1092 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1093 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1094 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1095 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1096 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1097 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1098 /* 0x2b */ { "SMBecho",reply_echo,0},
1099 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1100 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1101 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1102 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1103 /* 0x30 */ { NULL, NULL, 0 },
1104 /* 0x31 */ { NULL, NULL, 0 },
1105 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1106 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1107 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1108 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1109 /* 0x36 */ { NULL, NULL, 0 },
1110 /* 0x37 */ { NULL, NULL, 0 },
1111 /* 0x38 */ { NULL, NULL, 0 },
1112 /* 0x39 */ { NULL, NULL, 0 },
1113 /* 0x3a */ { NULL, NULL, 0 },
1114 /* 0x3b */ { NULL, NULL, 0 },
1115 /* 0x3c */ { NULL, NULL, 0 },
1116 /* 0x3d */ { NULL, NULL, 0 },
1117 /* 0x3e */ { NULL, NULL, 0 },
1118 /* 0x3f */ { NULL, NULL, 0 },
1119 /* 0x40 */ { NULL, NULL, 0 },
1120 /* 0x41 */ { NULL, NULL, 0 },
1121 /* 0x42 */ { NULL, NULL, 0 },
1122 /* 0x43 */ { NULL, NULL, 0 },
1123 /* 0x44 */ { NULL, NULL, 0 },
1124 /* 0x45 */ { NULL, NULL, 0 },
1125 /* 0x46 */ { NULL, NULL, 0 },
1126 /* 0x47 */ { NULL, NULL, 0 },
1127 /* 0x48 */ { NULL, NULL, 0 },
1128 /* 0x49 */ { NULL, NULL, 0 },
1129 /* 0x4a */ { NULL, NULL, 0 },
1130 /* 0x4b */ { NULL, NULL, 0 },
1131 /* 0x4c */ { NULL, NULL, 0 },
1132 /* 0x4d */ { NULL, NULL, 0 },
1133 /* 0x4e */ { NULL, NULL, 0 },
1134 /* 0x4f */ { NULL, NULL, 0 },
1135 /* 0x50 */ { NULL, NULL, 0 },
1136 /* 0x51 */ { NULL, NULL, 0 },
1137 /* 0x52 */ { NULL, NULL, 0 },
1138 /* 0x53 */ { NULL, NULL, 0 },
1139 /* 0x54 */ { NULL, NULL, 0 },
1140 /* 0x55 */ { NULL, NULL, 0 },
1141 /* 0x56 */ { NULL, NULL, 0 },
1142 /* 0x57 */ { NULL, NULL, 0 },
1143 /* 0x58 */ { NULL, NULL, 0 },
1144 /* 0x59 */ { NULL, NULL, 0 },
1145 /* 0x5a */ { NULL, NULL, 0 },
1146 /* 0x5b */ { NULL, NULL, 0 },
1147 /* 0x5c */ { NULL, NULL, 0 },
1148 /* 0x5d */ { NULL, NULL, 0 },
1149 /* 0x5e */ { NULL, NULL, 0 },
1150 /* 0x5f */ { NULL, NULL, 0 },
1151 /* 0x60 */ { NULL, NULL, 0 },
1152 /* 0x61 */ { NULL, NULL, 0 },
1153 /* 0x62 */ { NULL, NULL, 0 },
1154 /* 0x63 */ { NULL, NULL, 0 },
1155 /* 0x64 */ { NULL, NULL, 0 },
1156 /* 0x65 */ { NULL, NULL, 0 },
1157 /* 0x66 */ { NULL, NULL, 0 },
1158 /* 0x67 */ { NULL, NULL, 0 },
1159 /* 0x68 */ { NULL, NULL, 0 },
1160 /* 0x69 */ { NULL, NULL, 0 },
1161 /* 0x6a */ { NULL, NULL, 0 },
1162 /* 0x6b */ { NULL, NULL, 0 },
1163 /* 0x6c */ { NULL, NULL, 0 },
1164 /* 0x6d */ { NULL, NULL, 0 },
1165 /* 0x6e */ { NULL, NULL, 0 },
1166 /* 0x6f */ { NULL, NULL, 0 },
1167 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1168 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1169 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1170 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1171 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1172 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1173 /* 0x76 */ { NULL, NULL, 0 },
1174 /* 0x77 */ { NULL, NULL, 0 },
1175 /* 0x78 */ { NULL, NULL, 0 },
1176 /* 0x79 */ { NULL, NULL, 0 },
1177 /* 0x7a */ { NULL, NULL, 0 },
1178 /* 0x7b */ { NULL, NULL, 0 },
1179 /* 0x7c */ { NULL, NULL, 0 },
1180 /* 0x7d */ { NULL, NULL, 0 },
1181 /* 0x7e */ { NULL, NULL, 0 },
1182 /* 0x7f */ { NULL, NULL, 0 },
1183 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1184 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1185 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1186 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1187 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1188 /* 0x85 */ { NULL, NULL, 0 },
1189 /* 0x86 */ { NULL, NULL, 0 },
1190 /* 0x87 */ { NULL, NULL, 0 },
1191 /* 0x88 */ { NULL, NULL, 0 },
1192 /* 0x89 */ { NULL, NULL, 0 },
1193 /* 0x8a */ { NULL, NULL, 0 },
1194 /* 0x8b */ { NULL, NULL, 0 },
1195 /* 0x8c */ { NULL, NULL, 0 },
1196 /* 0x8d */ { NULL, NULL, 0 },
1197 /* 0x8e */ { NULL, NULL, 0 },
1198 /* 0x8f */ { NULL, NULL, 0 },
1199 /* 0x90 */ { NULL, NULL, 0 },
1200 /* 0x91 */ { NULL, NULL, 0 },
1201 /* 0x92 */ { NULL, NULL, 0 },
1202 /* 0x93 */ { NULL, NULL, 0 },
1203 /* 0x94 */ { NULL, NULL, 0 },
1204 /* 0x95 */ { NULL, NULL, 0 },
1205 /* 0x96 */ { NULL, NULL, 0 },
1206 /* 0x97 */ { NULL, NULL, 0 },
1207 /* 0x98 */ { NULL, NULL, 0 },
1208 /* 0x99 */ { NULL, NULL, 0 },
1209 /* 0x9a */ { NULL, NULL, 0 },
1210 /* 0x9b */ { NULL, NULL, 0 },
1211 /* 0x9c */ { NULL, NULL, 0 },
1212 /* 0x9d */ { NULL, NULL, 0 },
1213 /* 0x9e */ { NULL, NULL, 0 },
1214 /* 0x9f */ { NULL, NULL, 0 },
1215 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1216 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1217 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1218 /* 0xa3 */ { NULL, NULL, 0 },
1219 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1220 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1221 /* 0xa6 */ { NULL, NULL, 0 },
1222 /* 0xa7 */ { NULL, NULL, 0 },
1223 /* 0xa8 */ { NULL, NULL, 0 },
1224 /* 0xa9 */ { NULL, NULL, 0 },
1225 /* 0xaa */ { NULL, NULL, 0 },
1226 /* 0xab */ { NULL, NULL, 0 },
1227 /* 0xac */ { NULL, NULL, 0 },
1228 /* 0xad */ { NULL, NULL, 0 },
1229 /* 0xae */ { NULL, NULL, 0 },
1230 /* 0xaf */ { NULL, NULL, 0 },
1231 /* 0xb0 */ { NULL, NULL, 0 },
1232 /* 0xb1 */ { NULL, NULL, 0 },
1233 /* 0xb2 */ { NULL, NULL, 0 },
1234 /* 0xb3 */ { NULL, NULL, 0 },
1235 /* 0xb4 */ { NULL, NULL, 0 },
1236 /* 0xb5 */ { NULL, NULL, 0 },
1237 /* 0xb6 */ { NULL, NULL, 0 },
1238 /* 0xb7 */ { NULL, NULL, 0 },
1239 /* 0xb8 */ { NULL, NULL, 0 },
1240 /* 0xb9 */ { NULL, NULL, 0 },
1241 /* 0xba */ { NULL, NULL, 0 },
1242 /* 0xbb */ { NULL, NULL, 0 },
1243 /* 0xbc */ { NULL, NULL, 0 },
1244 /* 0xbd */ { NULL, NULL, 0 },
1245 /* 0xbe */ { NULL, NULL, 0 },
1246 /* 0xbf */ { NULL, NULL, 0 },
1247 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1248 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1249 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1250 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1251 /* 0xc4 */ { NULL, NULL, 0 },
1252 /* 0xc5 */ { NULL, NULL, 0 },
1253 /* 0xc6 */ { NULL, NULL, 0 },
1254 /* 0xc7 */ { NULL, NULL, 0 },
1255 /* 0xc8 */ { NULL, NULL, 0 },
1256 /* 0xc9 */ { NULL, NULL, 0 },
1257 /* 0xca */ { NULL, NULL, 0 },
1258 /* 0xcb */ { NULL, NULL, 0 },
1259 /* 0xcc */ { NULL, NULL, 0 },
1260 /* 0xcd */ { NULL, NULL, 0 },
1261 /* 0xce */ { NULL, NULL, 0 },
1262 /* 0xcf */ { NULL, NULL, 0 },
1263 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1264 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1265 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1266 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1267 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1268 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1269 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1270 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1271 /* 0xd8 */ { NULL, NULL, 0 },
1272 /* 0xd9 */ { NULL, NULL, 0 },
1273 /* 0xda */ { NULL, NULL, 0 },
1274 /* 0xdb */ { NULL, NULL, 0 },
1275 /* 0xdc */ { NULL, NULL, 0 },
1276 /* 0xdd */ { NULL, NULL, 0 },
1277 /* 0xde */ { NULL, NULL, 0 },
1278 /* 0xdf */ { NULL, NULL, 0 },
1279 /* 0xe0 */ { NULL, NULL, 0 },
1280 /* 0xe1 */ { NULL, NULL, 0 },
1281 /* 0xe2 */ { NULL, NULL, 0 },
1282 /* 0xe3 */ { NULL, NULL, 0 },
1283 /* 0xe4 */ { NULL, NULL, 0 },
1284 /* 0xe5 */ { NULL, NULL, 0 },
1285 /* 0xe6 */ { NULL, NULL, 0 },
1286 /* 0xe7 */ { NULL, NULL, 0 },
1287 /* 0xe8 */ { NULL, NULL, 0 },
1288 /* 0xe9 */ { NULL, NULL, 0 },
1289 /* 0xea */ { NULL, NULL, 0 },
1290 /* 0xeb */ { NULL, NULL, 0 },
1291 /* 0xec */ { NULL, NULL, 0 },
1292 /* 0xed */ { NULL, NULL, 0 },
1293 /* 0xee */ { NULL, NULL, 0 },
1294 /* 0xef */ { NULL, NULL, 0 },
1295 /* 0xf0 */ { NULL, NULL, 0 },
1296 /* 0xf1 */ { NULL, NULL, 0 },
1297 /* 0xf2 */ { NULL, NULL, 0 },
1298 /* 0xf3 */ { NULL, NULL, 0 },
1299 /* 0xf4 */ { NULL, NULL, 0 },
1300 /* 0xf5 */ { NULL, NULL, 0 },
1301 /* 0xf6 */ { NULL, NULL, 0 },
1302 /* 0xf7 */ { NULL, NULL, 0 },
1303 /* 0xf8 */ { NULL, NULL, 0 },
1304 /* 0xf9 */ { NULL, NULL, 0 },
1305 /* 0xfa */ { NULL, NULL, 0 },
1306 /* 0xfb */ { NULL, NULL, 0 },
1307 /* 0xfc */ { NULL, NULL, 0 },
1308 /* 0xfd */ { NULL, NULL, 0 },
1309 /* 0xfe */ { NULL, NULL, 0 },
1310 /* 0xff */ { NULL, NULL, 0 }
1314 /*******************************************************************
1315 allocate and initialize a reply packet
1316 ********************************************************************/
1318 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1319 const char *inbuf, char **outbuf, uint8_t num_words,
1320 uint32_t num_bytes)
1323 * Protect against integer wrap
1325 if ((num_bytes > 0xffffff)
1326 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1327 char *msg;
1328 if (asprintf(&msg, "num_bytes too large: %u",
1329 (unsigned)num_bytes) == -1) {
1330 msg = CONST_DISCARD(char *, "num_bytes too large");
1332 smb_panic(msg);
1335 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1336 smb_size + num_words*2 + num_bytes);
1337 if (*outbuf == NULL) {
1338 return false;
1341 construct_reply_common(req, inbuf, *outbuf);
1342 srv_set_message(*outbuf, num_words, num_bytes, false);
1344 * Zero out the word area, the caller has to take care of the bcc area
1345 * himself
1347 if (num_words != 0) {
1348 memset(*outbuf + smb_vwv0, 0, num_words*2);
1351 return true;
1354 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1356 char *outbuf;
1357 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1358 num_bytes)) {
1359 smb_panic("could not allocate output buffer\n");
1361 req->outbuf = (uint8_t *)outbuf;
1365 /*******************************************************************
1366 Dump a packet to a file.
1367 ********************************************************************/
1369 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1371 int fd, i;
1372 char *fname = NULL;
1373 if (DEBUGLEVEL < 50) {
1374 return;
1377 if (len < 4) len = smb_len(data)+4;
1378 for (i=1;i<100;i++) {
1379 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1380 type ? "req" : "resp") == -1) {
1381 return;
1383 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1384 if (fd != -1 || errno != EEXIST) break;
1386 if (fd != -1) {
1387 ssize_t ret = write(fd, data, len);
1388 if (ret != len)
1389 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1390 close(fd);
1391 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1393 SAFE_FREE(fname);
1396 /****************************************************************************
1397 Prepare everything for calling the actual request function, and potentially
1398 call the request function via the "new" interface.
1400 Return False if the "legacy" function needs to be called, everything is
1401 prepared.
1403 Return True if we're done.
1405 I know this API sucks, but it is the one with the least code change I could
1406 find.
1407 ****************************************************************************/
1409 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1411 int flags;
1412 uint16 session_tag;
1413 connection_struct *conn = NULL;
1414 struct smbd_server_connection *sconn = req->sconn;
1416 errno = 0;
1418 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1419 * so subtract 4 from it. */
1420 if (!valid_smb_header(req->inbuf)
1421 || (size < (smb_size - 4))) {
1422 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1423 smb_len(req->inbuf)));
1424 exit_server_cleanly("Non-SMB packet");
1427 if (smb_messages[type].fn == NULL) {
1428 DEBUG(0,("Unknown message type %d!\n",type));
1429 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1430 reply_unknown_new(req, type);
1431 return NULL;
1434 flags = smb_messages[type].flags;
1436 /* In share mode security we must ignore the vuid. */
1437 session_tag = (lp_security() == SEC_SHARE)
1438 ? UID_FIELD_INVALID : req->vuid;
1439 conn = req->conn;
1441 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1442 (int)sys_getpid(), (unsigned long)conn));
1444 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1446 /* Ensure this value is replaced in the incoming packet. */
1447 SSVAL(req->inbuf,smb_uid,session_tag);
1450 * Ensure the correct username is in current_user_info. This is a
1451 * really ugly bugfix for problems with multiple session_setup_and_X's
1452 * being done and allowing %U and %G substitutions to work correctly.
1453 * There is a reason this code is done here, don't move it unless you
1454 * know what you're doing... :-).
1455 * JRA.
1458 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1459 user_struct *vuser = NULL;
1461 sconn->smb1.sessions.last_session_tag = session_tag;
1462 if(session_tag != UID_FIELD_INVALID) {
1463 vuser = get_valid_user_struct(sconn, session_tag);
1464 if (vuser) {
1465 set_current_user_info(
1466 vuser->server_info->sanitized_username,
1467 vuser->server_info->unix_name,
1468 vuser->server_info->info3->base.domain.string);
1473 /* Does this call need to be run as the connected user? */
1474 if (flags & AS_USER) {
1476 /* Does this call need a valid tree connection? */
1477 if (!conn) {
1479 * Amazingly, the error code depends on the command
1480 * (from Samba4).
1482 if (type == SMBntcreateX) {
1483 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1484 } else {
1485 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1487 return NULL;
1490 if (!change_to_user(conn,session_tag)) {
1491 DEBUG(0, ("Error: Could not change to user. Removing "
1492 "deferred open, mid=%llu.\n",
1493 (unsigned long long)req->mid));
1494 reply_force_doserror(req, ERRSRV, ERRbaduid);
1495 return conn;
1498 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1500 /* Does it need write permission? */
1501 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1502 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1503 return conn;
1506 /* IPC services are limited */
1507 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1508 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1509 return conn;
1511 } else {
1512 /* This call needs to be run as root */
1513 change_to_root_user();
1516 /* load service specific parameters */
1517 if (conn) {
1518 if (req->encrypted) {
1519 conn->encrypted_tid = true;
1520 /* encrypted required from now on. */
1521 conn->encrypt_level = Required;
1522 } else if (ENCRYPTION_REQUIRED(conn)) {
1523 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1524 exit_server_cleanly("encryption required "
1525 "on connection");
1526 return conn;
1530 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1531 (flags & (AS_USER|DO_CHDIR)
1532 ?True:False))) {
1533 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1534 return conn;
1536 conn->num_smb_operations++;
1539 /* does this protocol need to be run as guest? */
1540 if ((flags & AS_GUEST)
1541 && (!change_to_guest() ||
1542 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1543 lp_hostsdeny(-1)))) {
1544 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1545 return conn;
1548 smb_messages[type].fn(req);
1549 return req->conn;
1552 /****************************************************************************
1553 Construct a reply to the incoming packet.
1554 ****************************************************************************/
1556 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1557 uint32_t seqnum, bool encrypted,
1558 struct smb_perfcount_data *deferred_pcd)
1560 connection_struct *conn;
1561 struct smb_request *req;
1563 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1564 smb_panic("could not allocate smb_request");
1567 if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1568 unread_bytes, encrypted, seqnum)) {
1569 exit_server_cleanly("Invalid SMB request");
1572 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1574 /* we popped this message off the queue - keep original perf data */
1575 if (deferred_pcd)
1576 req->pcd = *deferred_pcd;
1577 else {
1578 SMB_PERFCOUNT_START(&req->pcd);
1579 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1580 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1583 conn = switch_message(req->cmd, req, size);
1585 if (req->unread_bytes) {
1586 /* writeX failed. drain socket. */
1587 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1588 req->unread_bytes) {
1589 smb_panic("failed to drain pending bytes");
1591 req->unread_bytes = 0;
1594 if (req->done) {
1595 TALLOC_FREE(req);
1596 return;
1599 if (req->outbuf == NULL) {
1600 return;
1603 if (CVAL(req->outbuf,0) == 0) {
1604 show_msg((char *)req->outbuf);
1607 if (!srv_send_smb(smbd_server_fd(),
1608 (char *)req->outbuf,
1609 true, req->seqnum+1,
1610 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1611 &req->pcd)) {
1612 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1615 TALLOC_FREE(req);
1617 return;
1620 /****************************************************************************
1621 Process an smb from the client
1622 ****************************************************************************/
1623 static void process_smb(struct smbd_server_connection *conn,
1624 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1625 uint32_t seqnum, bool encrypted,
1626 struct smb_perfcount_data *deferred_pcd)
1628 int msg_type = CVAL(inbuf,0);
1630 DO_PROFILE_INC(smb_count);
1632 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1633 smb_len(inbuf) ) );
1634 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1635 (int)nread,
1636 (unsigned int)unread_bytes ));
1638 if (msg_type != 0) {
1640 * NetBIOS session request, keepalive, etc.
1642 reply_special(conn, (char *)inbuf);
1643 goto done;
1646 if (smbd_server_conn->using_smb2) {
1647 /* At this point we're not really using smb2,
1648 * we make the decision here.. */
1649 if (smbd_is_smb2_header(inbuf, nread)) {
1650 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1651 return;
1652 } else if (nread >= smb_size && valid_smb_header(inbuf)
1653 && CVAL(inbuf, smb_com) != 0x72) {
1654 /* This is a non-negprot SMB1 packet.
1655 Disable SMB2 from now on. */
1656 smbd_server_conn->using_smb2 = false;
1660 show_msg((char *)inbuf);
1662 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1663 trans_num++;
1665 done:
1666 conn->smb1.num_requests++;
1668 /* The timeout_processing function isn't run nearly
1669 often enough to implement 'max log size' without
1670 overrunning the size of the file by many megabytes.
1671 This is especially true if we are running at debug
1672 level 10. Checking every 50 SMBs is a nice
1673 tradeoff of performance vs log file size overrun. */
1675 if ((conn->smb1.num_requests % 50) == 0 &&
1676 need_to_check_log_size()) {
1677 change_to_root_user();
1678 check_log_size();
1682 /****************************************************************************
1683 Return a string containing the function name of a SMB command.
1684 ****************************************************************************/
1686 const char *smb_fn_name(int type)
1688 const char *unknown_name = "SMBunknown";
1690 if (smb_messages[type].name == NULL)
1691 return(unknown_name);
1693 return(smb_messages[type].name);
1696 /****************************************************************************
1697 Helper functions for contruct_reply.
1698 ****************************************************************************/
1700 void add_to_common_flags2(uint32 v)
1702 common_flags2 |= v;
1705 void remove_from_common_flags2(uint32 v)
1707 common_flags2 &= ~v;
1710 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1711 char *outbuf)
1713 srv_set_message(outbuf,0,0,false);
1715 SCVAL(outbuf, smb_com, req->cmd);
1716 SIVAL(outbuf,smb_rcls,0);
1717 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1718 SSVAL(outbuf,smb_flg2,
1719 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1720 common_flags2);
1721 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1723 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1724 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1725 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1726 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1729 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1731 construct_reply_common(req, (char *)req->inbuf, outbuf);
1735 * How many bytes have we already accumulated up to the current wct field
1736 * offset?
1739 size_t req_wct_ofs(struct smb_request *req)
1741 size_t buf_size;
1743 if (req->chain_outbuf == NULL) {
1744 return smb_wct - 4;
1746 buf_size = talloc_get_size(req->chain_outbuf);
1747 if ((buf_size % 4) != 0) {
1748 buf_size += (4 - (buf_size % 4));
1750 return buf_size - 4;
1754 * Hack around reply_nterror & friends not being aware of chained requests,
1755 * generating illegal (i.e. wct==0) chain replies.
1758 static void fixup_chain_error_packet(struct smb_request *req)
1760 uint8_t *outbuf = req->outbuf;
1761 req->outbuf = NULL;
1762 reply_outbuf(req, 2, 0);
1763 memcpy(req->outbuf, outbuf, smb_wct);
1764 TALLOC_FREE(outbuf);
1765 SCVAL(req->outbuf, smb_vwv0, 0xff);
1769 * @brief Find the smb_cmd offset of the last command pushed
1770 * @param[in] buf The buffer we're building up
1771 * @retval Where can we put our next andx cmd?
1773 * While chaining requests, the "next" request we're looking at needs to put
1774 * its SMB_Command before the data the previous request already built up added
1775 * to the chain. Find the offset to the place where we have to put our cmd.
1778 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1780 uint8_t cmd;
1781 size_t ofs;
1783 cmd = CVAL(buf, smb_com);
1785 SMB_ASSERT(is_andx_req(cmd));
1787 ofs = smb_vwv0;
1789 while (CVAL(buf, ofs) != 0xff) {
1791 if (!is_andx_req(CVAL(buf, ofs))) {
1792 return false;
1796 * ofs is from start of smb header, so add the 4 length
1797 * bytes. The next cmd is right after the wct field.
1799 ofs = SVAL(buf, ofs+2) + 4 + 1;
1801 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1804 *pofs = ofs;
1805 return true;
1809 * @brief Do the smb chaining at a buffer level
1810 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1811 * @param[in] smb_command The command that we want to issue
1812 * @param[in] wct How many words?
1813 * @param[in] vwv The words, already in network order
1814 * @param[in] bytes_alignment How shall we align "bytes"?
1815 * @param[in] num_bytes How many bytes?
1816 * @param[in] bytes The data the request ships
1818 * smb_splice_chain() adds the vwv and bytes to the request already present in
1819 * *poutbuf.
1822 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1823 uint8_t wct, const uint16_t *vwv,
1824 size_t bytes_alignment,
1825 uint32_t num_bytes, const uint8_t *bytes)
1827 uint8_t *outbuf;
1828 size_t old_size, new_size;
1829 size_t ofs;
1830 size_t chain_padding = 0;
1831 size_t bytes_padding = 0;
1832 bool first_request;
1834 old_size = talloc_get_size(*poutbuf);
1837 * old_size == smb_wct means we're pushing the first request in for
1838 * libsmb/
1841 first_request = (old_size == smb_wct);
1843 if (!first_request && ((old_size % 4) != 0)) {
1845 * Align the wct field of subsequent requests to a 4-byte
1846 * boundary
1848 chain_padding = 4 - (old_size % 4);
1852 * After the old request comes the new wct field (1 byte), the vwv's
1853 * and the num_bytes field. After at we might need to align the bytes
1854 * given to us to "bytes_alignment", increasing the num_bytes value.
1857 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1859 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1860 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1863 new_size += bytes_padding + num_bytes;
1865 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1866 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1867 (unsigned)new_size));
1868 return false;
1871 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1872 if (outbuf == NULL) {
1873 DEBUG(0, ("talloc failed\n"));
1874 return false;
1876 *poutbuf = outbuf;
1878 if (first_request) {
1879 SCVAL(outbuf, smb_com, smb_command);
1880 } else {
1881 size_t andx_cmd_ofs;
1883 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1884 DEBUG(1, ("invalid command chain\n"));
1885 *poutbuf = TALLOC_REALLOC_ARRAY(
1886 NULL, *poutbuf, uint8_t, old_size);
1887 return false;
1890 if (chain_padding != 0) {
1891 memset(outbuf + old_size, 0, chain_padding);
1892 old_size += chain_padding;
1895 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1896 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1899 ofs = old_size;
1902 * Push the chained request:
1904 * wct field
1907 SCVAL(outbuf, ofs, wct);
1908 ofs += 1;
1911 * vwv array
1914 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1915 ofs += sizeof(uint16_t) * wct;
1918 * bcc (byte count)
1921 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1922 ofs += sizeof(uint16_t);
1925 * padding
1928 if (bytes_padding != 0) {
1929 memset(outbuf + ofs, 0, bytes_padding);
1930 ofs += bytes_padding;
1934 * The bytes field
1937 memcpy(outbuf + ofs, bytes, num_bytes);
1939 return true;
1942 /****************************************************************************
1943 Construct a chained reply and add it to the already made reply
1944 ****************************************************************************/
1946 void chain_reply(struct smb_request *req)
1948 size_t smblen = smb_len(req->inbuf);
1949 size_t already_used, length_needed;
1950 uint8_t chain_cmd;
1951 uint32_t chain_offset; /* uint32_t to avoid overflow */
1953 uint8_t wct;
1954 uint16_t *vwv;
1955 uint16_t buflen;
1956 uint8_t *buf;
1958 if (IVAL(req->outbuf, smb_rcls) != 0) {
1959 fixup_chain_error_packet(req);
1963 * Any of the AndX requests and replies have at least a wct of
1964 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1965 * beginning of the SMB header to the next wct field.
1967 * None of the AndX requests put anything valuable in vwv[0] and [1],
1968 * so we can overwrite it here to form the chain.
1971 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1972 if (req->chain_outbuf == NULL) {
1973 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1974 req, req->outbuf, uint8_t,
1975 smb_len(req->outbuf) + 4);
1976 if (req->chain_outbuf == NULL) {
1977 smb_panic("talloc failed");
1980 req->outbuf = NULL;
1981 goto error;
1985 * Here we assume that this is the end of the chain. For that we need
1986 * to set "next command" to 0xff and the offset to 0. If we later find
1987 * more commands in the chain, this will be overwritten again.
1990 SCVAL(req->outbuf, smb_vwv0, 0xff);
1991 SCVAL(req->outbuf, smb_vwv0+1, 0);
1992 SSVAL(req->outbuf, smb_vwv1, 0);
1994 if (req->chain_outbuf == NULL) {
1996 * In req->chain_outbuf we collect all the replies. Start the
1997 * chain by copying in the first reply.
1999 * We do the realloc because later on we depend on
2000 * talloc_get_size to determine the length of
2001 * chain_outbuf. The reply_xxx routines might have
2002 * over-allocated (reply_pipe_read_and_X used to be such an
2003 * example).
2005 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2006 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2007 if (req->chain_outbuf == NULL) {
2008 smb_panic("talloc failed");
2010 req->outbuf = NULL;
2011 } else {
2013 * Update smb headers where subsequent chained commands
2014 * may have updated them.
2016 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2017 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2019 if (!smb_splice_chain(&req->chain_outbuf,
2020 CVAL(req->outbuf, smb_com),
2021 CVAL(req->outbuf, smb_wct),
2022 (uint16_t *)(req->outbuf + smb_vwv),
2023 0, smb_buflen(req->outbuf),
2024 (uint8_t *)smb_buf(req->outbuf))) {
2025 goto error;
2027 TALLOC_FREE(req->outbuf);
2031 * We use the old request's vwv field to grab the next chained command
2032 * and offset into the chained fields.
2035 chain_cmd = CVAL(req->vwv+0, 0);
2036 chain_offset = SVAL(req->vwv+1, 0);
2038 if (chain_cmd == 0xff) {
2040 * End of chain, no more requests from the client. So ship the
2041 * replies.
2043 smb_setlen((char *)(req->chain_outbuf),
2044 talloc_get_size(req->chain_outbuf) - 4);
2046 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2047 true, req->seqnum+1,
2048 IS_CONN_ENCRYPTED(req->conn)
2049 ||req->encrypted,
2050 &req->pcd)) {
2051 exit_server_cleanly("chain_reply: srv_send_smb "
2052 "failed.");
2054 TALLOC_FREE(req->chain_outbuf);
2055 req->done = true;
2056 return;
2059 /* add a new perfcounter for this element of chain */
2060 SMB_PERFCOUNT_ADD(&req->pcd);
2061 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2062 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2065 * Check if the client tries to fool us. The request so far uses the
2066 * space to the end of the byte buffer in the request just
2067 * processed. The chain_offset can't point into that area. If that was
2068 * the case, we could end up with an endless processing of the chain,
2069 * we would always handle the same request.
2072 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2073 if (chain_offset < already_used) {
2074 goto error;
2078 * Next check: Make sure the chain offset does not point beyond the
2079 * overall smb request length.
2082 length_needed = chain_offset+1; /* wct */
2083 if (length_needed > smblen) {
2084 goto error;
2088 * Now comes the pointer magic. Goal here is to set up req->vwv and
2089 * req->buf correctly again to be able to call the subsequent
2090 * switch_message(). The chain offset (the former vwv[1]) points at
2091 * the new wct field.
2094 wct = CVAL(smb_base(req->inbuf), chain_offset);
2097 * Next consistency check: Make the new vwv array fits in the overall
2098 * smb request.
2101 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2102 if (length_needed > smblen) {
2103 goto error;
2105 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2108 * Now grab the new byte buffer....
2111 buflen = SVAL(vwv+wct, 0);
2114 * .. and check that it fits.
2117 length_needed += buflen;
2118 if (length_needed > smblen) {
2119 goto error;
2121 buf = (uint8_t *)(vwv+wct+1);
2123 req->cmd = chain_cmd;
2124 req->wct = wct;
2125 req->vwv = vwv;
2126 req->buflen = buflen;
2127 req->buf = buf;
2129 switch_message(chain_cmd, req, smblen);
2131 if (req->outbuf == NULL) {
2133 * This happens if the chained command has suspended itself or
2134 * if it has called srv_send_smb() itself.
2136 return;
2140 * We end up here if the chained command was not itself chained or
2141 * suspended, but for example a close() command. We now need to splice
2142 * the chained commands' outbuf into the already built up chain_outbuf
2143 * and ship the result.
2145 goto done;
2147 error:
2149 * We end up here if there's any error in the chain syntax. Report a
2150 * DOS error, just like Windows does.
2152 reply_force_doserror(req, ERRSRV, ERRerror);
2153 fixup_chain_error_packet(req);
2155 done:
2157 * This scary statement intends to set the
2158 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2159 * to the value req->outbuf carries
2161 SSVAL(req->chain_outbuf, smb_flg2,
2162 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2163 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2166 * Transfer the error codes from the subrequest to the main one
2168 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2169 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2171 if (!smb_splice_chain(&req->chain_outbuf,
2172 CVAL(req->outbuf, smb_com),
2173 CVAL(req->outbuf, smb_wct),
2174 (uint16_t *)(req->outbuf + smb_vwv),
2175 0, smb_buflen(req->outbuf),
2176 (uint8_t *)smb_buf(req->outbuf))) {
2177 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2179 TALLOC_FREE(req->outbuf);
2181 smb_setlen((char *)(req->chain_outbuf),
2182 talloc_get_size(req->chain_outbuf) - 4);
2184 show_msg((char *)(req->chain_outbuf));
2186 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2187 true, req->seqnum+1,
2188 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2189 &req->pcd)) {
2190 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2192 TALLOC_FREE(req->chain_outbuf);
2193 req->done = true;
2196 /****************************************************************************
2197 Check if services need reloading.
2198 ****************************************************************************/
2200 void check_reload(time_t t)
2202 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2204 if(last_smb_conf_reload_time == 0) {
2205 last_smb_conf_reload_time = t;
2206 /* Our printing subsystem might not be ready at smbd start up.
2207 Then no printer is available till the first printers check
2208 is performed. A lower initial interval circumvents this. */
2209 if ( printcap_cache_time > 60 )
2210 last_printer_reload_time = t - printcap_cache_time + 60;
2211 else
2212 last_printer_reload_time = t;
2215 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2216 /* randomize over 60 second the printcap reload to avoid all
2217 * process hitting cupsd at the same time */
2218 int time_range = 60;
2220 last_printer_reload_time += random() % time_range;
2221 mypid = getpid();
2224 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2225 reload_services(True);
2226 last_smb_conf_reload_time = t;
2229 /* 'printcap cache time = 0' disable the feature */
2231 if ( printcap_cache_time != 0 )
2233 /* see if it's time to reload or if the clock has been set back */
2235 if ( (t >= last_printer_reload_time+printcap_cache_time)
2236 || (t-last_printer_reload_time < 0) )
2238 DEBUG( 3,( "Printcap cache time expired.\n"));
2239 reload_printers();
2240 last_printer_reload_time = t;
2245 static bool fd_is_readable(int fd)
2247 fd_set fds;
2248 struct timeval timeout = {0, };
2249 int ret;
2251 FD_ZERO(&fds);
2252 FD_SET(fd, &fds);
2254 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2255 if (ret == -1) {
2256 return false;
2258 return FD_ISSET(fd, &fds);
2261 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2263 /* TODO: make write nonblocking */
2266 static void smbd_server_connection_read_handler(
2267 struct smbd_server_connection *conn, int fd)
2269 uint8_t *inbuf = NULL;
2270 size_t inbuf_len = 0;
2271 size_t unread_bytes = 0;
2272 bool encrypted = false;
2273 TALLOC_CTX *mem_ctx = talloc_tos();
2274 NTSTATUS status;
2275 uint32_t seqnum;
2277 bool from_client = (smbd_server_fd() == fd)?true:false;
2279 if (from_client) {
2280 smbd_lock_socket(conn);
2282 if (!fd_is_readable(smbd_server_fd())) {
2283 DEBUG(10,("the echo listener was faster\n"));
2284 smbd_unlock_socket(conn);
2285 return;
2288 /* TODO: make this completely nonblocking */
2289 status = receive_smb_talloc(mem_ctx, fd,
2290 (char **)(void *)&inbuf,
2291 0, /* timeout */
2292 &unread_bytes,
2293 &encrypted,
2294 &inbuf_len, &seqnum,
2295 false /* trusted channel */);
2296 smbd_unlock_socket(conn);
2297 } else {
2298 /* TODO: make this completely nonblocking */
2299 status = receive_smb_talloc(mem_ctx, fd,
2300 (char **)(void *)&inbuf,
2301 0, /* timeout */
2302 &unread_bytes,
2303 &encrypted,
2304 &inbuf_len, &seqnum,
2305 true /* trusted channel */);
2308 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2309 goto process;
2311 if (NT_STATUS_IS_ERR(status)) {
2312 exit_server_cleanly("failed to receive smb request");
2314 if (!NT_STATUS_IS_OK(status)) {
2315 return;
2318 process:
2319 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2320 seqnum, encrypted, NULL);
2323 static void smbd_server_connection_handler(struct event_context *ev,
2324 struct fd_event *fde,
2325 uint16_t flags,
2326 void *private_data)
2328 struct smbd_server_connection *conn = talloc_get_type(private_data,
2329 struct smbd_server_connection);
2331 if (flags & EVENT_FD_WRITE) {
2332 smbd_server_connection_write_handler(conn);
2333 } else if (flags & EVENT_FD_READ) {
2334 smbd_server_connection_read_handler(conn, smbd_server_fd());
2338 static void smbd_server_echo_handler(struct event_context *ev,
2339 struct fd_event *fde,
2340 uint16_t flags,
2341 void *private_data)
2343 struct smbd_server_connection *conn = talloc_get_type(private_data,
2344 struct smbd_server_connection);
2346 if (flags & EVENT_FD_WRITE) {
2347 smbd_server_connection_write_handler(conn);
2348 } else if (flags & EVENT_FD_READ) {
2349 smbd_server_connection_read_handler(
2350 conn, conn->smb1.echo_handler.trusted_fd);
2354 /****************************************************************************
2355 received when we should release a specific IP
2356 ****************************************************************************/
2357 static void release_ip(const char *ip, void *priv)
2359 char addr[INET6_ADDRSTRLEN];
2360 char *p = addr;
2362 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2364 if (strncmp("::ffff:", addr, 7) == 0) {
2365 p = addr + 7;
2368 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2369 /* we can't afford to do a clean exit - that involves
2370 database writes, which would potentially mean we
2371 are still running after the failover has finished -
2372 we have to get rid of this process ID straight
2373 away */
2374 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2375 ip));
2376 /* note we must exit with non-zero status so the unclean handler gets
2377 called in the parent, so that the brl database is tickled */
2378 _exit(1);
2382 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2383 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2385 release_ip((char *)data->data, NULL);
2388 #ifdef CLUSTER_SUPPORT
2389 static int client_get_tcp_info(struct sockaddr_storage *server,
2390 struct sockaddr_storage *client)
2392 socklen_t length;
2393 if (server_fd == -1) {
2394 return -1;
2396 length = sizeof(*server);
2397 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2398 return -1;
2400 length = sizeof(*client);
2401 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2402 return -1;
2404 return 0;
2406 #endif
2409 * Send keepalive packets to our client
2411 static bool keepalive_fn(const struct timeval *now, void *private_data)
2413 struct smbd_server_connection *sconn = smbd_server_conn;
2414 bool ret;
2416 if (sconn->using_smb2) {
2417 /* Don't do keepalives on an SMB2 connection. */
2418 return false;
2421 smbd_lock_socket(smbd_server_conn);
2422 ret = send_keepalive(smbd_server_fd());
2423 smbd_unlock_socket(smbd_server_conn);
2425 if (!ret) {
2426 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2427 return False;
2429 return True;
2433 * Do the recurring check if we're idle
2435 static bool deadtime_fn(const struct timeval *now, void *private_data)
2437 struct smbd_server_connection *sconn = smbd_server_conn;
2439 if (sconn->using_smb2) {
2440 /* TODO: implement real idle check */
2441 if (sconn->smb2.sessions.list) {
2442 return true;
2444 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2445 messaging_send(smbd_messaging_context(), procid_self(),
2446 MSG_SHUTDOWN, &data_blob_null);
2447 return false;
2450 if ((conn_num_open(sconn) == 0)
2451 || (conn_idle_all(sconn, now->tv_sec))) {
2452 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2453 messaging_send(smbd_messaging_context(), procid_self(),
2454 MSG_SHUTDOWN, &data_blob_null);
2455 return False;
2458 return True;
2462 * Do the recurring log file and smb.conf reload checks.
2465 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2467 change_to_root_user();
2469 /* update printer queue caches if necessary */
2470 update_monitored_printq_cache();
2472 /* check if we need to reload services */
2473 check_reload(time(NULL));
2475 /* Change machine password if neccessary. */
2476 attempt_machine_password_change();
2479 * Force a log file check.
2481 force_check_log_size();
2482 check_log_size();
2483 return true;
2486 static int create_unlink_tmp(const char *dir)
2488 char *fname;
2489 int fd;
2491 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2492 if (fname == NULL) {
2493 errno = ENOMEM;
2494 return -1;
2496 fd = mkstemp(fname);
2497 if (fd == -1) {
2498 TALLOC_FREE(fname);
2499 return -1;
2501 if (unlink(fname) == -1) {
2502 int sys_errno = errno;
2503 close(fd);
2504 TALLOC_FREE(fname);
2505 errno = sys_errno;
2506 return -1;
2508 TALLOC_FREE(fname);
2509 return fd;
2512 struct smbd_echo_state {
2513 struct tevent_context *ev;
2514 struct iovec *pending;
2515 struct smbd_server_connection *sconn;
2516 int parent_pipe;
2518 struct tevent_fd *parent_fde;
2520 struct tevent_fd *read_fde;
2521 struct tevent_req *write_req;
2524 static void smbd_echo_writer_done(struct tevent_req *req);
2526 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2528 int num_pending;
2530 if (state->write_req != NULL) {
2531 return;
2534 num_pending = talloc_array_length(state->pending);
2535 if (num_pending == 0) {
2536 return;
2539 state->write_req = writev_send(state, state->ev, NULL,
2540 state->parent_pipe, false,
2541 state->pending, num_pending);
2542 if (state->write_req == NULL) {
2543 DEBUG(1, ("writev_send failed\n"));
2544 exit(1);
2547 talloc_steal(state->write_req, state->pending);
2548 state->pending = NULL;
2550 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2551 state);
2554 static void smbd_echo_writer_done(struct tevent_req *req)
2556 struct smbd_echo_state *state = tevent_req_callback_data(
2557 req, struct smbd_echo_state);
2558 ssize_t written;
2559 int err;
2561 written = writev_recv(req, &err);
2562 TALLOC_FREE(req);
2563 state->write_req = NULL;
2564 if (written == -1) {
2565 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2566 exit(1);
2568 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2569 smbd_echo_activate_writer(state);
2572 static bool smbd_echo_reply(int fd,
2573 uint8_t *inbuf, size_t inbuf_len,
2574 uint32_t seqnum)
2576 struct smb_request req;
2577 uint16_t num_replies;
2578 size_t out_len;
2579 char *outbuf;
2580 bool ok;
2582 if (inbuf_len < smb_size) {
2583 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2584 return false;
2586 if (!valid_smb_header(inbuf)) {
2587 DEBUG(10, ("Got invalid SMB header\n"));
2588 return false;
2591 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2592 seqnum)) {
2593 return false;
2595 req.inbuf = inbuf;
2597 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2598 smb_messages[req.cmd].name
2599 ? smb_messages[req.cmd].name : "unknown"));
2601 if (req.cmd != SMBecho) {
2602 return false;
2604 if (req.wct < 1) {
2605 return false;
2608 num_replies = SVAL(req.vwv+0, 0);
2609 if (num_replies != 1) {
2610 /* Not a Windows "Hey, you're still there?" request */
2611 return false;
2614 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2615 1, req.buflen)) {
2616 DEBUG(10, ("create_outbuf failed\n"));
2617 return false;
2619 req.outbuf = (uint8_t *)outbuf;
2621 SSVAL(req.outbuf, smb_vwv0, num_replies);
2623 if (req.buflen > 0) {
2624 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2627 out_len = smb_len(req.outbuf) + 4;
2629 ok = srv_send_smb(smbd_server_fd(),
2630 (char *)outbuf,
2631 true, seqnum+1,
2632 false, &req.pcd);
2633 TALLOC_FREE(outbuf);
2634 if (!ok) {
2635 exit(1);
2638 return true;
2641 static void smbd_echo_exit(struct tevent_context *ev,
2642 struct tevent_fd *fde, uint16_t flags,
2643 void *private_data)
2645 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2646 exit(0);
2649 static void smbd_echo_reader(struct tevent_context *ev,
2650 struct tevent_fd *fde, uint16_t flags,
2651 void *private_data)
2653 struct smbd_echo_state *state = talloc_get_type_abort(
2654 private_data, struct smbd_echo_state);
2655 struct smbd_server_connection *sconn = state->sconn;
2656 size_t unread, num_pending;
2657 NTSTATUS status;
2658 struct iovec *tmp;
2659 uint32_t seqnum = 0;
2660 bool reply;
2661 bool ok;
2662 bool encrypted = false;
2664 ok = smbd_lock_socket_internal(sconn);
2665 if (!ok) {
2666 DEBUG(0, ("%s: failed to lock socket\n",
2667 __location__));
2668 exit(1);
2671 if (!fd_is_readable(smbd_server_fd())) {
2672 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2673 (int)sys_getpid()));
2674 ok = smbd_unlock_socket_internal(sconn);
2675 if (!ok) {
2676 DEBUG(1, ("%s: failed to unlock socket in\n",
2677 __location__));
2678 exit(1);
2680 return;
2683 num_pending = talloc_array_length(state->pending);
2684 tmp = talloc_realloc(state, state->pending, struct iovec,
2685 num_pending+1);
2686 if (tmp == NULL) {
2687 DEBUG(1, ("talloc_realloc failed\n"));
2688 exit(1);
2690 state->pending = tmp;
2692 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2694 status = receive_smb_talloc(state->pending, smbd_server_fd(),
2695 (char **)(void *)&state->pending[num_pending].iov_base,
2696 0 /* timeout */,
2697 &unread,
2698 &encrypted,
2699 &state->pending[num_pending].iov_len,
2700 &seqnum,
2701 false /* trusted_channel*/);
2702 if (!NT_STATUS_IS_OK(status)) {
2703 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2704 (int)sys_getpid(), nt_errstr(status)));
2705 exit(1);
2708 ok = smbd_unlock_socket_internal(sconn);
2709 if (!ok) {
2710 DEBUG(1, ("%s: failed to unlock socket in\n",
2711 __location__));
2712 exit(1);
2716 * place the seqnum in the packet so that the main process can reply
2717 * with signing
2719 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2720 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2722 reply = smbd_echo_reply(smbd_server_fd(),
2723 (uint8_t *)state->pending[num_pending].iov_base,
2724 state->pending[num_pending].iov_len,
2725 seqnum);
2726 if (reply) {
2727 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2728 /* no check, shrinking by some bytes does not fail */
2729 state->pending = talloc_realloc(state, state->pending,
2730 struct iovec,
2731 num_pending);
2732 } else {
2733 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2734 smbd_echo_activate_writer(state);
2738 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2739 int parent_pipe)
2741 struct smbd_echo_state *state;
2743 state = talloc_zero(sconn, struct smbd_echo_state);
2744 if (state == NULL) {
2745 DEBUG(1, ("talloc failed\n"));
2746 return;
2748 state->sconn = sconn;
2749 state->parent_pipe = parent_pipe;
2750 state->ev = s3_tevent_context_init(state);
2751 if (state->ev == NULL) {
2752 DEBUG(1, ("tevent_context_init failed\n"));
2753 TALLOC_FREE(state);
2754 return;
2756 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2757 TEVENT_FD_READ, smbd_echo_exit,
2758 state);
2759 if (state->parent_fde == NULL) {
2760 DEBUG(1, ("tevent_add_fd failed\n"));
2761 TALLOC_FREE(state);
2762 return;
2764 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2765 TEVENT_FD_READ, smbd_echo_reader,
2766 state);
2767 if (state->read_fde == NULL) {
2768 DEBUG(1, ("tevent_add_fd failed\n"));
2769 TALLOC_FREE(state);
2770 return;
2773 while (true) {
2774 if (tevent_loop_once(state->ev) == -1) {
2775 DEBUG(1, ("tevent_loop_once failed: %s\n",
2776 strerror(errno)));
2777 break;
2780 TALLOC_FREE(state);
2784 * Handle SMBecho requests in a forked child process
2786 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2788 int listener_pipe[2];
2789 int res;
2790 pid_t child;
2792 res = pipe(listener_pipe);
2793 if (res == -1) {
2794 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2795 return false;
2797 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2798 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2799 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2800 goto fail;
2803 child = sys_fork();
2804 if (child == 0) {
2805 NTSTATUS status;
2807 close(listener_pipe[0]);
2809 status = reinit_after_fork(smbd_messaging_context(),
2810 smbd_event_context(),
2811 procid_self(), false);
2812 if (!NT_STATUS_IS_OK(status)) {
2813 DEBUG(1, ("reinit_after_fork failed: %s\n",
2814 nt_errstr(status)));
2815 exit(1);
2817 smbd_echo_loop(sconn, listener_pipe[1]);
2818 exit(0);
2820 close(listener_pipe[1]);
2821 listener_pipe[1] = -1;
2822 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2824 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2827 * Without smb signing this is the same as the normal smbd
2828 * listener. This needs to change once signing comes in.
2830 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2831 sconn,
2832 sconn->smb1.echo_handler.trusted_fd,
2833 EVENT_FD_READ,
2834 smbd_server_echo_handler,
2835 sconn);
2836 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2837 DEBUG(1, ("event_add_fd failed\n"));
2838 goto fail;
2841 return true;
2843 fail:
2844 if (listener_pipe[0] != -1) {
2845 close(listener_pipe[0]);
2847 if (listener_pipe[1] != -1) {
2848 close(listener_pipe[1]);
2850 sconn->smb1.echo_handler.trusted_fd = -1;
2851 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2852 close(sconn->smb1.echo_handler.socket_lock_fd);
2854 sconn->smb1.echo_handler.trusted_fd = -1;
2855 sconn->smb1.echo_handler.socket_lock_fd = -1;
2856 return false;
2859 /****************************************************************************
2860 Process commands from the client
2861 ****************************************************************************/
2863 void smbd_process(void)
2865 TALLOC_CTX *frame = talloc_stackframe();
2866 struct sockaddr_storage ss;
2867 struct sockaddr *sa = NULL;
2868 socklen_t sa_len;
2869 struct tsocket_address *local_address = NULL;
2870 struct tsocket_address *remote_address = NULL;
2871 const char *remaddr = NULL;
2872 int ret;
2874 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2875 lp_security() != SEC_SHARE &&
2876 !lp_async_smb_echo_handler()) {
2878 * We're not making the desion here,
2879 * we're just allowing the client
2880 * to decide between SMB1 and SMB2
2881 * with the first negprot
2882 * packet.
2884 smbd_server_conn->using_smb2 = true;
2887 /* Ensure child is set to blocking mode */
2888 set_blocking(smbd_server_fd(),True);
2890 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2891 set_socket_options(smbd_server_fd(), lp_socket_options());
2893 sa = (struct sockaddr *)(void *)&ss;
2894 sa_len = sizeof(ss);
2895 ret = getpeername(smbd_server_fd(), sa, &sa_len);
2896 if (ret != 0) {
2897 int level = (errno == ENOTCONN)?2:0;
2898 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2899 exit_server_cleanly("getpeername() failed.\n");
2901 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2902 sa, sa_len,
2903 &remote_address);
2904 if (ret != 0) {
2905 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2906 __location__, strerror(errno)));
2907 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2910 sa = (struct sockaddr *)(void *)&ss;
2911 sa_len = sizeof(ss);
2912 ret = getsockname(smbd_server_fd(), sa, &sa_len);
2913 if (ret != 0) {
2914 int level = (errno == ENOTCONN)?2:0;
2915 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2916 exit_server_cleanly("getsockname() failed.\n");
2918 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2919 sa, sa_len,
2920 &local_address);
2921 if (ret != 0) {
2922 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2923 __location__, strerror(errno)));
2924 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2927 smbd_server_conn->local_address = local_address;
2928 smbd_server_conn->remote_address = remote_address;
2930 if (tsocket_address_is_inet(remote_address, "ip")) {
2931 remaddr = tsocket_address_inet_addr_string(
2932 smbd_server_conn->remote_address,
2933 talloc_tos());
2934 if (remaddr == NULL) {
2937 } else {
2938 remaddr = "0.0.0.0";
2941 /* this is needed so that we get decent entries
2942 in smbstatus for port 445 connects */
2943 set_remote_machine_name(remaddr, false);
2944 reload_services(true);
2947 * Before the first packet, check the global hosts allow/ hosts deny
2948 * parameters before doing any parsing of packets passed to us by the
2949 * client. This prevents attacks on our parsing code from hosts not in
2950 * the hosts allow list.
2953 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2954 lp_hostsdeny(-1))) {
2956 * send a negative session response "not listening on calling
2957 * name"
2959 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2960 DEBUG( 1, ("Connection denied from %s to %s\n",
2961 tsocket_address_string(remote_address, talloc_tos()),
2962 tsocket_address_string(local_address, talloc_tos())));
2963 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2964 0, false, NULL);
2965 exit_server_cleanly("connection denied");
2968 DEBUG(10, ("Connection allowed from %s to %s\n",
2969 tsocket_address_string(remote_address, talloc_tos()),
2970 tsocket_address_string(local_address, talloc_tos())));
2972 static_init_rpc;
2974 init_modules();
2976 smb_perfcount_init();
2978 if (!init_account_policy()) {
2979 exit_server("Could not open account policy tdb.\n");
2982 if (*lp_rootdir()) {
2983 if (chroot(lp_rootdir()) != 0) {
2984 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2985 exit_server("Failed to chroot()");
2987 if (chdir("/") == -1) {
2988 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2989 exit_server("Failed to chroot()");
2991 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2994 if (!srv_init_signing(smbd_server_conn)) {
2995 exit_server("Failed to init smb_signing");
2998 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2999 exit_server("Failed to fork echo handler");
3002 /* Setup oplocks */
3003 if (!init_oplocks(smbd_messaging_context()))
3004 exit_server("Failed to init oplocks");
3006 /* register our message handlers */
3007 messaging_register(smbd_messaging_context(), NULL,
3008 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3009 messaging_register(smbd_messaging_context(), NULL,
3010 MSG_SMB_RELEASE_IP, msg_release_ip);
3011 messaging_register(smbd_messaging_context(), NULL,
3012 MSG_SMB_CLOSE_FILE, msg_close_file);
3015 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3016 * MSGs to all child processes
3018 messaging_deregister(smbd_messaging_context(),
3019 MSG_DEBUG, NULL);
3020 messaging_register(smbd_messaging_context(), NULL,
3021 MSG_DEBUG, debug_message);
3023 if ((lp_keepalive() != 0)
3024 && !(event_add_idle(smbd_event_context(), NULL,
3025 timeval_set(lp_keepalive(), 0),
3026 "keepalive", keepalive_fn,
3027 NULL))) {
3028 DEBUG(0, ("Could not add keepalive event\n"));
3029 exit(1);
3032 if (!(event_add_idle(smbd_event_context(), NULL,
3033 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3034 "deadtime", deadtime_fn, NULL))) {
3035 DEBUG(0, ("Could not add deadtime event\n"));
3036 exit(1);
3039 if (!(event_add_idle(smbd_event_context(), NULL,
3040 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3041 "housekeeping", housekeeping_fn, NULL))) {
3042 DEBUG(0, ("Could not add housekeeping event\n"));
3043 exit(1);
3046 #ifdef CLUSTER_SUPPORT
3048 if (lp_clustering()) {
3050 * We need to tell ctdb about our client's TCP
3051 * connection, so that for failover ctdbd can send
3052 * tickle acks, triggering a reconnection by the
3053 * client.
3056 struct sockaddr_storage srv, clnt;
3058 if (client_get_tcp_info(&srv, &clnt) == 0) {
3060 NTSTATUS status;
3062 status = ctdbd_register_ips(
3063 messaging_ctdbd_connection(procid_self()),
3064 &srv, &clnt, release_ip, NULL);
3066 if (!NT_STATUS_IS_OK(status)) {
3067 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3068 nt_errstr(status)));
3070 } else
3072 DEBUG(0,("Unable to get tcp info for "
3073 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3074 strerror(errno)));
3078 #endif
3080 smbd_server_conn->nbt.got_session = false;
3082 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3084 smbd_server_conn->smb1.sessions.done_sesssetup = false;
3085 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
3086 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3087 /* users from session setup */
3088 smbd_server_conn->smb1.sessions.session_userlist = NULL;
3089 /* workgroup from session setup. */
3090 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
3091 /* this holds info on user ids that are already validated for this VC */
3092 smbd_server_conn->smb1.sessions.validated_users = NULL;
3093 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
3094 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
3096 conn_init(smbd_server_conn);
3097 if (!init_dptrs(smbd_server_conn)) {
3098 exit_server("init_dptrs() failed");
3101 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
3102 smbd_server_conn,
3103 smbd_server_fd(),
3104 EVENT_FD_READ,
3105 smbd_server_connection_handler,
3106 smbd_server_conn);
3107 if (!smbd_server_conn->smb1.fde) {
3108 exit_server("failed to create smbd_server_connection fde");
3111 TALLOC_FREE(frame);
3113 while (True) {
3114 NTSTATUS status;
3116 frame = talloc_stackframe_pool(8192);
3118 errno = 0;
3120 status = smbd_server_connection_loop_once(smbd_server_conn);
3121 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3122 !NT_STATUS_IS_OK(status)) {
3123 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3124 " exiting\n", nt_errstr(status)));
3125 break;
3128 TALLOC_FREE(frame);
3131 exit_server_cleanly(NULL);
3134 bool req_is_in_chain(struct smb_request *req)
3136 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3138 * We're right now handling a subsequent request, so we must
3139 * be in a chain
3141 return true;
3144 if (!is_andx_req(req->cmd)) {
3145 return false;
3148 if (req->wct < 2) {
3150 * Okay, an illegal request, but definitely not chained :-)
3152 return false;
3155 return (CVAL(req->vwv+0, 0) != 0xFF);