s3-spoolss: Fixed winreg_printer_query_XXX.
[Samba/ekacnet.git] / source3 / smbd / process.c
blob53c5e0b4089665f68385bd43cbbd2ea51e75da2c
1 /*
2 Unix SMB/CIFS implementation.
3 process incoming packets - main loop
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Volker Lendecke 2005-2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "smbd/globals.h"
23 #include "../librpc/gen_ndr/srv_dfs.h"
24 #include "../librpc/gen_ndr/srv_dssetup.h"
25 #include "../librpc/gen_ndr/srv_echo.h"
26 #include "../librpc/gen_ndr/srv_eventlog.h"
27 #include "../librpc/gen_ndr/srv_initshutdown.h"
28 #include "../librpc/gen_ndr/srv_lsa.h"
29 #include "../librpc/gen_ndr/srv_netlogon.h"
30 #include "../librpc/gen_ndr/srv_ntsvcs.h"
31 #include "../librpc/gen_ndr/srv_samr.h"
32 #include "../librpc/gen_ndr/srv_spoolss.h"
33 #include "../librpc/gen_ndr/srv_srvsvc.h"
34 #include "../librpc/gen_ndr/srv_svcctl.h"
35 #include "../librpc/gen_ndr/srv_winreg.h"
36 #include "../librpc/gen_ndr/srv_wkssvc.h"
38 extern bool global_machine_password_needs_changing;
40 static void construct_reply_common(struct smb_request *req, const char *inbuf,
41 char *outbuf);
42 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
44 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
46 bool ok;
48 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
49 return true;
52 smbd_server_conn->smb1.echo_handler.ref_count++;
54 if (smbd_server_conn->smb1.echo_handler.ref_count > 1) {
55 return true;
58 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
60 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
61 SMB_F_SETLKW, 0, 0, F_WRLCK);
62 if (!ok) {
63 return false;
66 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
68 return true;
71 void smbd_lock_socket(struct smbd_server_connection *sconn)
73 if (!smbd_lock_socket_internal(sconn)) {
74 exit_server_cleanly("failed to lock socket");
78 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
80 bool ok;
82 if (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
83 return true;
86 smbd_server_conn->smb1.echo_handler.ref_count--;
88 if (smbd_server_conn->smb1.echo_handler.ref_count > 0) {
89 return true;
92 ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
93 SMB_F_SETLKW, 0, 0, F_UNLCK);
94 if (!ok) {
95 return false;
98 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
100 return true;
103 void smbd_unlock_socket(struct smbd_server_connection *sconn)
105 if (!smbd_unlock_socket_internal(sconn)) {
106 exit_server_cleanly("failed to unlock socket");
110 /* Accessor function for smb_read_error for smbd functions. */
112 /****************************************************************************
113 Send an smb to a fd.
114 ****************************************************************************/
116 bool srv_send_smb(int fd, char *buffer,
117 bool do_signing, uint32_t seqnum,
118 bool do_encrypt,
119 struct smb_perfcount_data *pcd)
121 size_t len = 0;
122 size_t nwritten=0;
123 ssize_t ret;
124 char *buf_out = buffer;
126 smbd_lock_socket(smbd_server_conn);
128 if (do_signing) {
129 /* Sign the outgoing packet if required. */
130 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
133 if (do_encrypt) {
134 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
135 if (!NT_STATUS_IS_OK(status)) {
136 DEBUG(0, ("send_smb: SMB encryption failed "
137 "on outgoing packet! Error %s\n",
138 nt_errstr(status) ));
139 goto out;
143 len = smb_len(buf_out) + 4;
145 ret = write_data(fd,buf_out+nwritten,len - nwritten);
146 if (ret <= 0) {
147 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
148 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
149 srv_free_enc_buffer(buf_out);
150 goto out;
153 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
154 srv_free_enc_buffer(buf_out);
155 out:
156 SMB_PERFCOUNT_END(pcd);
158 smbd_unlock_socket(smbd_server_conn);
159 return true;
162 /*******************************************************************
163 Setup the word count and byte count for a smb message.
164 ********************************************************************/
166 int srv_set_message(char *buf,
167 int num_words,
168 int num_bytes,
169 bool zero)
171 if (zero && (num_words || num_bytes)) {
172 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
174 SCVAL(buf,smb_wct,num_words);
175 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
176 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
177 return (smb_size + num_words*2 + num_bytes);
180 static bool valid_smb_header(const uint8_t *inbuf)
182 if (is_encrypted_packet(inbuf)) {
183 return true;
186 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
187 * but it just looks weird to call strncmp for this one.
189 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
192 /* Socket functions for smbd packet processing. */
194 static bool valid_packet_size(size_t len)
197 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
198 * of header. Don't print the error if this fits.... JRA.
201 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
202 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
203 (unsigned long)len));
204 return false;
206 return true;
209 static NTSTATUS read_packet_remainder(int fd, char *buffer,
210 unsigned int timeout, ssize_t len)
212 if (len <= 0) {
213 return NT_STATUS_OK;
216 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
219 /****************************************************************************
220 Attempt a zerocopy writeX read. We know here that len > smb_size-4
221 ****************************************************************************/
224 * Unfortunately, earlier versions of smbclient/libsmbclient
225 * don't send this "standard" writeX header. I've fixed this
226 * for 3.2 but we'll use the old method with earlier versions.
227 * Windows and CIFSFS at least use this standard size. Not
228 * sure about MacOSX.
231 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
232 (2*14) + /* word count (including bcc) */ \
233 1 /* pad byte */)
235 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
236 const char lenbuf[4],
237 int fd, char **buffer,
238 unsigned int timeout,
239 size_t *p_unread,
240 size_t *len_ret)
242 /* Size of a WRITEX call (+4 byte len). */
243 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
244 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
245 ssize_t toread;
246 NTSTATUS status;
248 memcpy(writeX_header, lenbuf, 4);
250 status = read_fd_with_timeout(
251 fd, writeX_header + 4,
252 STANDARD_WRITE_AND_X_HEADER_SIZE,
253 STANDARD_WRITE_AND_X_HEADER_SIZE,
254 timeout, NULL);
256 if (!NT_STATUS_IS_OK(status)) {
257 return status;
261 * Ok - now try and see if this is a possible
262 * valid writeX call.
265 if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
267 * If the data offset is beyond what
268 * we've read, drain the extra bytes.
270 uint16_t doff = SVAL(writeX_header,smb_vwv11);
271 ssize_t newlen;
273 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
274 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
275 if (drain_socket(smbd_server_fd(), drain) != drain) {
276 smb_panic("receive_smb_raw_talloc_partial_read:"
277 " failed to drain pending bytes");
279 } else {
280 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
283 /* Spoof down the length and null out the bcc. */
284 set_message_bcc(writeX_header, 0);
285 newlen = smb_len(writeX_header);
287 /* Copy the header we've written. */
289 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
290 writeX_header,
291 sizeof(writeX_header));
293 if (*buffer == NULL) {
294 DEBUG(0, ("Could not allocate inbuf of length %d\n",
295 (int)sizeof(writeX_header)));
296 return NT_STATUS_NO_MEMORY;
299 /* Work out the remaining bytes. */
300 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
301 *len_ret = newlen + 4;
302 return NT_STATUS_OK;
305 if (!valid_packet_size(len)) {
306 return NT_STATUS_INVALID_PARAMETER;
310 * Not a valid writeX call. Just do the standard
311 * talloc and return.
314 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
316 if (*buffer == NULL) {
317 DEBUG(0, ("Could not allocate inbuf of length %d\n",
318 (int)len+4));
319 return NT_STATUS_NO_MEMORY;
322 /* Copy in what we already read. */
323 memcpy(*buffer,
324 writeX_header,
325 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
326 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
328 if(toread > 0) {
329 status = read_packet_remainder(
330 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
331 timeout, toread);
333 if (!NT_STATUS_IS_OK(status)) {
334 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
335 nt_errstr(status)));
336 return status;
340 *len_ret = len + 4;
341 return NT_STATUS_OK;
344 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
345 char **buffer, unsigned int timeout,
346 size_t *p_unread, size_t *plen)
348 char lenbuf[4];
349 size_t len;
350 int min_recv_size = lp_min_receive_file_size();
351 NTSTATUS status;
353 *p_unread = 0;
355 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
356 if (!NT_STATUS_IS_OK(status)) {
357 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
358 return status;
361 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
362 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
363 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
364 !srv_is_signing_active(smbd_server_conn) &&
365 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
367 return receive_smb_raw_talloc_partial_read(
368 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
371 if (!valid_packet_size(len)) {
372 return NT_STATUS_INVALID_PARAMETER;
376 * The +4 here can't wrap, we've checked the length above already.
379 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
381 if (*buffer == NULL) {
382 DEBUG(0, ("Could not allocate inbuf of length %d\n",
383 (int)len+4));
384 return NT_STATUS_NO_MEMORY;
387 memcpy(*buffer, lenbuf, sizeof(lenbuf));
389 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
390 if (!NT_STATUS_IS_OK(status)) {
391 return status;
394 *plen = len + 4;
395 return NT_STATUS_OK;
398 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
399 char **buffer, unsigned int timeout,
400 size_t *p_unread, bool *p_encrypted,
401 size_t *p_len,
402 uint32_t *seqnum,
403 bool trusted_channel)
405 size_t len = 0;
406 NTSTATUS status;
408 *p_encrypted = false;
410 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
411 p_unread, &len);
412 if (!NT_STATUS_IS_OK(status)) {
413 return status;
416 if (is_encrypted_packet((uint8_t *)*buffer)) {
417 status = srv_decrypt_buffer(*buffer);
418 if (!NT_STATUS_IS_OK(status)) {
419 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
420 "incoming packet! Error %s\n",
421 nt_errstr(status) ));
422 return status;
424 *p_encrypted = true;
427 /* Check the incoming SMB signature. */
428 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
429 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
430 "incoming packet!\n"));
431 return NT_STATUS_INVALID_NETWORK_RESPONSE;
434 *p_len = len;
435 return NT_STATUS_OK;
439 * Initialize a struct smb_request from an inbuf
442 static bool init_smb_request(struct smb_request *req, const uint8 *inbuf,
443 size_t unread_bytes, bool encrypted,
444 uint32_t seqnum)
446 struct smbd_server_connection *sconn = smbd_server_conn;
447 size_t req_size = smb_len(inbuf) + 4;
448 /* Ensure we have at least smb_size bytes. */
449 if (req_size < smb_size) {
450 DEBUG(0,("init_smb_request: invalid request size %u\n",
451 (unsigned int)req_size ));
452 return false;
454 req->cmd = CVAL(inbuf, smb_com);
455 req->flags2 = SVAL(inbuf, smb_flg2);
456 req->smbpid = SVAL(inbuf, smb_pid);
457 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
458 req->seqnum = seqnum;
459 req->vuid = SVAL(inbuf, smb_uid);
460 req->tid = SVAL(inbuf, smb_tid);
461 req->wct = CVAL(inbuf, smb_wct);
462 req->vwv = (uint16_t *)(inbuf+smb_vwv);
463 req->buflen = smb_buflen(inbuf);
464 req->buf = (const uint8_t *)smb_buf(inbuf);
465 req->unread_bytes = unread_bytes;
466 req->encrypted = encrypted;
467 req->conn = conn_find(sconn,req->tid);
468 req->chain_fsp = NULL;
469 req->chain_outbuf = NULL;
470 req->done = false;
471 req->smb2req = NULL;
472 smb_init_perfcount_data(&req->pcd);
474 /* Ensure we have at least wct words and 2 bytes of bcc. */
475 if (smb_size + req->wct*2 > req_size) {
476 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
477 (unsigned int)req->wct,
478 (unsigned int)req_size));
479 return false;
481 /* Ensure bcc is correct. */
482 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
483 DEBUG(0,("init_smb_request: invalid bcc number %u "
484 "(wct = %u, size %u)\n",
485 (unsigned int)req->buflen,
486 (unsigned int)req->wct,
487 (unsigned int)req_size));
488 return false;
491 req->outbuf = NULL;
492 return true;
495 static void process_smb(struct smbd_server_connection *conn,
496 uint8_t *inbuf, size_t nread, size_t unread_bytes,
497 uint32_t seqnum, bool encrypted,
498 struct smb_perfcount_data *deferred_pcd);
500 static void smbd_deferred_open_timer(struct event_context *ev,
501 struct timed_event *te,
502 struct timeval _tval,
503 void *private_data)
505 struct pending_message_list *msg = talloc_get_type(private_data,
506 struct pending_message_list);
507 TALLOC_CTX *mem_ctx = talloc_tos();
508 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
509 uint8_t *inbuf;
511 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
512 msg->buf.length);
513 if (inbuf == NULL) {
514 exit_server("smbd_deferred_open_timer: talloc failed\n");
515 return;
518 /* We leave this message on the queue so the open code can
519 know this is a retry. */
520 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
521 (unsigned long long)mid ));
523 /* Mark the message as processed so this is not
524 * re-processed in error. */
525 msg->processed = true;
527 process_smb(smbd_server_conn, inbuf,
528 msg->buf.length, 0,
529 msg->seqnum, msg->encrypted, &msg->pcd);
531 /* If it's still there and was processed, remove it. */
532 msg = get_deferred_open_message_smb(mid);
533 if (msg && msg->processed) {
534 remove_deferred_open_message_smb(mid);
538 /****************************************************************************
539 Function to push a message onto the tail of a linked list of smb messages ready
540 for processing.
541 ****************************************************************************/
543 static bool push_queued_message(struct smb_request *req,
544 struct timeval request_time,
545 struct timeval end_time,
546 char *private_data, size_t private_len)
548 int msg_len = smb_len(req->inbuf) + 4;
549 struct pending_message_list *msg;
551 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
553 if(msg == NULL) {
554 DEBUG(0,("push_message: malloc fail (1)\n"));
555 return False;
558 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
559 if(msg->buf.data == NULL) {
560 DEBUG(0,("push_message: malloc fail (2)\n"));
561 TALLOC_FREE(msg);
562 return False;
565 msg->request_time = request_time;
566 msg->seqnum = req->seqnum;
567 msg->encrypted = req->encrypted;
568 msg->processed = false;
569 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
571 if (private_data) {
572 msg->private_data = data_blob_talloc(msg, private_data,
573 private_len);
574 if (msg->private_data.data == NULL) {
575 DEBUG(0,("push_message: malloc fail (3)\n"));
576 TALLOC_FREE(msg);
577 return False;
581 msg->te = event_add_timed(smbd_event_context(),
582 msg,
583 end_time,
584 smbd_deferred_open_timer,
585 msg);
586 if (!msg->te) {
587 DEBUG(0,("push_message: event_add_timed failed\n"));
588 TALLOC_FREE(msg);
589 return false;
592 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
594 DEBUG(10,("push_message: pushed message length %u on "
595 "deferred_open_queue\n", (unsigned int)msg_len));
597 return True;
600 /****************************************************************************
601 Function to delete a sharing violation open message by mid.
602 ****************************************************************************/
604 void remove_deferred_open_message_smb(uint64_t mid)
606 struct pending_message_list *pml;
608 if (smbd_server_conn->allow_smb2) {
609 remove_deferred_open_message_smb2(mid);
610 return;
613 for (pml = deferred_open_queue; pml; pml = pml->next) {
614 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
615 DEBUG(10,("remove_deferred_open_message_smb: "
616 "deleting mid %llu len %u\n",
617 (unsigned long long)mid,
618 (unsigned int)pml->buf.length ));
619 DLIST_REMOVE(deferred_open_queue, pml);
620 TALLOC_FREE(pml);
621 return;
626 /****************************************************************************
627 Move a sharing violation open retry message to the front of the list and
628 schedule it for immediate processing.
629 ****************************************************************************/
631 void schedule_deferred_open_message_smb(uint64_t mid)
633 struct pending_message_list *pml;
634 int i = 0;
636 if (smbd_server_conn->allow_smb2) {
637 schedule_deferred_open_message_smb2(mid);
638 return;
641 for (pml = deferred_open_queue; pml; pml = pml->next) {
642 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
644 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
645 "msg_mid = %llu\n",
646 i++,
647 (unsigned long long)msg_mid ));
649 if (mid == msg_mid) {
650 struct timed_event *te;
652 if (pml->processed) {
653 /* A processed message should not be
654 * rescheduled. */
655 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
656 "message mid %llu was already processed\n",
657 (unsigned long long)msg_mid ));
658 continue;
661 DEBUG(10,("schedule_deferred_open_message_smb: "
662 "scheduling mid %llu\n",
663 (unsigned long long)mid ));
665 te = event_add_timed(smbd_event_context(),
666 pml,
667 timeval_zero(),
668 smbd_deferred_open_timer,
669 pml);
670 if (!te) {
671 DEBUG(10,("schedule_deferred_open_message_smb: "
672 "event_add_timed() failed, "
673 "skipping mid %llu\n",
674 (unsigned long long)msg_mid ));
677 TALLOC_FREE(pml->te);
678 pml->te = te;
679 DLIST_PROMOTE(deferred_open_queue, pml);
680 return;
684 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
685 "find message mid %llu\n",
686 (unsigned long long)mid ));
689 /****************************************************************************
690 Return true if this mid is on the deferred queue and was not yet processed.
691 ****************************************************************************/
693 bool open_was_deferred(uint64_t mid)
695 struct pending_message_list *pml;
697 if (smbd_server_conn->allow_smb2) {
698 return open_was_deferred_smb2(mid);
701 for (pml = deferred_open_queue; pml; pml = pml->next) {
702 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
703 return True;
706 return False;
709 /****************************************************************************
710 Return the message queued by this mid.
711 ****************************************************************************/
713 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
715 struct pending_message_list *pml;
717 for (pml = deferred_open_queue; pml; pml = pml->next) {
718 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
719 return pml;
722 return NULL;
725 /****************************************************************************
726 Get the state data queued by this mid.
727 ****************************************************************************/
729 bool get_deferred_open_message_state(struct smb_request *smbreq,
730 struct timeval *p_request_time,
731 void **pp_state)
733 struct pending_message_list *pml;
735 if (smbd_server_conn->allow_smb2) {
736 return get_deferred_open_message_state_smb2(smbreq->smb2req,
737 p_request_time,
738 pp_state);
741 pml = get_deferred_open_message_smb(smbreq->mid);
742 if (!pml) {
743 return false;
745 if (p_request_time) {
746 *p_request_time = pml->request_time;
748 if (pp_state) {
749 *pp_state = (void *)pml->private_data.data;
751 return true;
754 /****************************************************************************
755 Function to push a deferred open smb message onto a linked list of local smb
756 messages ready for processing.
757 ****************************************************************************/
759 bool push_deferred_open_message_smb(struct smb_request *req,
760 struct timeval request_time,
761 struct timeval timeout,
762 struct file_id id,
763 char *private_data, size_t priv_len)
765 struct timeval end_time;
767 if (req->smb2req) {
768 return push_deferred_open_message_smb2(req->smb2req,
769 request_time,
770 timeout,
772 private_data,
773 priv_len);
776 if (req->unread_bytes) {
777 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
778 "unread_bytes = %u\n",
779 (unsigned int)req->unread_bytes ));
780 smb_panic("push_deferred_open_message_smb: "
781 "logic error unread_bytes != 0" );
784 end_time = timeval_sum(&request_time, &timeout);
786 DEBUG(10,("push_deferred_open_message_smb: pushing message "
787 "len %u mid %llu timeout time [%u.%06u]\n",
788 (unsigned int) smb_len(req->inbuf)+4,
789 (unsigned long long)req->mid,
790 (unsigned int)end_time.tv_sec,
791 (unsigned int)end_time.tv_usec));
793 return push_queued_message(req, request_time, end_time,
794 private_data, priv_len);
797 struct idle_event {
798 struct timed_event *te;
799 struct timeval interval;
800 char *name;
801 bool (*handler)(const struct timeval *now, void *private_data);
802 void *private_data;
805 static void smbd_idle_event_handler(struct event_context *ctx,
806 struct timed_event *te,
807 struct timeval now,
808 void *private_data)
810 struct idle_event *event =
811 talloc_get_type_abort(private_data, struct idle_event);
813 TALLOC_FREE(event->te);
815 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
816 event->name, event->te));
818 if (!event->handler(&now, event->private_data)) {
819 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
820 event->name, event->te));
821 /* Don't repeat, delete ourselves */
822 TALLOC_FREE(event);
823 return;
826 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
827 event->name, event->te));
829 event->te = event_add_timed(ctx, event,
830 timeval_sum(&now, &event->interval),
831 smbd_idle_event_handler, event);
833 /* We can't do much but fail here. */
834 SMB_ASSERT(event->te != NULL);
837 struct idle_event *event_add_idle(struct event_context *event_ctx,
838 TALLOC_CTX *mem_ctx,
839 struct timeval interval,
840 const char *name,
841 bool (*handler)(const struct timeval *now,
842 void *private_data),
843 void *private_data)
845 struct idle_event *result;
846 struct timeval now = timeval_current();
848 result = TALLOC_P(mem_ctx, struct idle_event);
849 if (result == NULL) {
850 DEBUG(0, ("talloc failed\n"));
851 return NULL;
854 result->interval = interval;
855 result->handler = handler;
856 result->private_data = private_data;
858 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
859 DEBUG(0, ("talloc failed\n"));
860 TALLOC_FREE(result);
861 return NULL;
864 result->te = event_add_timed(event_ctx, result,
865 timeval_sum(&now, &interval),
866 smbd_idle_event_handler, result);
867 if (result->te == NULL) {
868 DEBUG(0, ("event_add_timed failed\n"));
869 TALLOC_FREE(result);
870 return NULL;
873 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
874 return result;
877 static void smbd_sig_term_handler(struct tevent_context *ev,
878 struct tevent_signal *se,
879 int signum,
880 int count,
881 void *siginfo,
882 void *private_data)
884 exit_server_cleanly("termination signal");
887 void smbd_setup_sig_term_handler(void)
889 struct tevent_signal *se;
891 se = tevent_add_signal(smbd_event_context(),
892 smbd_event_context(),
893 SIGTERM, 0,
894 smbd_sig_term_handler,
895 NULL);
896 if (!se) {
897 exit_server("failed to setup SIGTERM handler");
901 static void smbd_sig_hup_handler(struct tevent_context *ev,
902 struct tevent_signal *se,
903 int signum,
904 int count,
905 void *siginfo,
906 void *private_data)
908 change_to_root_user();
909 DEBUG(1,("Reloading services after SIGHUP\n"));
910 reload_services(False);
913 void smbd_setup_sig_hup_handler(void)
915 struct tevent_signal *se;
917 se = tevent_add_signal(smbd_event_context(),
918 smbd_event_context(),
919 SIGHUP, 0,
920 smbd_sig_hup_handler,
921 NULL);
922 if (!se) {
923 exit_server("failed to setup SIGHUP handler");
927 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
929 fd_set r_fds, w_fds;
930 int selrtn;
931 struct timeval to;
932 int maxfd = 0;
934 to.tv_sec = SMBD_SELECT_TIMEOUT;
935 to.tv_usec = 0;
938 * Setup the select fd sets.
941 FD_ZERO(&r_fds);
942 FD_ZERO(&w_fds);
945 * Are there any timed events waiting ? If so, ensure we don't
946 * select for longer than it would take to wait for them.
950 struct timeval now;
951 GetTimeOfDay(&now);
953 event_add_to_select_args(smbd_event_context(), &now,
954 &r_fds, &w_fds, &to, &maxfd);
957 /* Process a signal and timed events now... */
958 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
959 return NT_STATUS_RETRY;
963 int sav;
964 START_PROFILE(smbd_idle);
966 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
967 sav = errno;
969 END_PROFILE(smbd_idle);
970 errno = sav;
973 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
974 return NT_STATUS_RETRY;
977 /* Check if error */
978 if (selrtn == -1) {
979 /* something is wrong. Maybe the socket is dead? */
980 return map_nt_error_from_unix(errno);
983 /* Did we timeout ? */
984 if (selrtn == 0) {
985 return NT_STATUS_RETRY;
988 /* should not be reached */
989 return NT_STATUS_INTERNAL_ERROR;
993 * Only allow 5 outstanding trans requests. We're allocating memory, so
994 * prevent a DoS.
997 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
999 int count = 0;
1000 for (; list != NULL; list = list->next) {
1002 if (list->mid == mid) {
1003 return NT_STATUS_INVALID_PARAMETER;
1006 count += 1;
1008 if (count > 5) {
1009 return NT_STATUS_INSUFFICIENT_RESOURCES;
1012 return NT_STATUS_OK;
1016 These flags determine some of the permissions required to do an operation
1018 Note that I don't set NEED_WRITE on some write operations because they
1019 are used by some brain-dead clients when printing, and I don't want to
1020 force write permissions on print services.
1022 #define AS_USER (1<<0)
1023 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1024 #define TIME_INIT (1<<2)
1025 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1026 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1027 #define DO_CHDIR (1<<6)
1030 define a list of possible SMB messages and their corresponding
1031 functions. Any message that has a NULL function is unimplemented -
1032 please feel free to contribute implementations!
1034 static const struct smb_message_struct {
1035 const char *name;
1036 void (*fn)(struct smb_request *req);
1037 int flags;
1038 } smb_messages[256] = {
1040 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1041 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1042 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1043 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1044 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1045 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1046 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1047 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1048 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1049 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1050 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1051 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1052 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1053 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1054 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1055 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1056 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1057 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1058 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1059 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1060 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1061 /* 0x15 */ { NULL, NULL, 0 },
1062 /* 0x16 */ { NULL, NULL, 0 },
1063 /* 0x17 */ { NULL, NULL, 0 },
1064 /* 0x18 */ { NULL, NULL, 0 },
1065 /* 0x19 */ { NULL, NULL, 0 },
1066 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1067 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1068 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1069 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1070 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1071 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1072 /* 0x20 */ { "SMBwritec", NULL,0},
1073 /* 0x21 */ { NULL, NULL, 0 },
1074 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1075 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1076 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1077 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1078 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1079 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1080 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1081 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1082 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1083 /* 0x2b */ { "SMBecho",reply_echo,0},
1084 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1085 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1086 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1087 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1088 /* 0x30 */ { NULL, NULL, 0 },
1089 /* 0x31 */ { NULL, NULL, 0 },
1090 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1091 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1092 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1093 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1094 /* 0x36 */ { NULL, NULL, 0 },
1095 /* 0x37 */ { NULL, NULL, 0 },
1096 /* 0x38 */ { NULL, NULL, 0 },
1097 /* 0x39 */ { NULL, NULL, 0 },
1098 /* 0x3a */ { NULL, NULL, 0 },
1099 /* 0x3b */ { NULL, NULL, 0 },
1100 /* 0x3c */ { NULL, NULL, 0 },
1101 /* 0x3d */ { NULL, NULL, 0 },
1102 /* 0x3e */ { NULL, NULL, 0 },
1103 /* 0x3f */ { NULL, NULL, 0 },
1104 /* 0x40 */ { NULL, NULL, 0 },
1105 /* 0x41 */ { NULL, NULL, 0 },
1106 /* 0x42 */ { NULL, NULL, 0 },
1107 /* 0x43 */ { NULL, NULL, 0 },
1108 /* 0x44 */ { NULL, NULL, 0 },
1109 /* 0x45 */ { NULL, NULL, 0 },
1110 /* 0x46 */ { NULL, NULL, 0 },
1111 /* 0x47 */ { NULL, NULL, 0 },
1112 /* 0x48 */ { NULL, NULL, 0 },
1113 /* 0x49 */ { NULL, NULL, 0 },
1114 /* 0x4a */ { NULL, NULL, 0 },
1115 /* 0x4b */ { NULL, NULL, 0 },
1116 /* 0x4c */ { NULL, NULL, 0 },
1117 /* 0x4d */ { NULL, NULL, 0 },
1118 /* 0x4e */ { NULL, NULL, 0 },
1119 /* 0x4f */ { NULL, NULL, 0 },
1120 /* 0x50 */ { NULL, NULL, 0 },
1121 /* 0x51 */ { NULL, NULL, 0 },
1122 /* 0x52 */ { NULL, NULL, 0 },
1123 /* 0x53 */ { NULL, NULL, 0 },
1124 /* 0x54 */ { NULL, NULL, 0 },
1125 /* 0x55 */ { NULL, NULL, 0 },
1126 /* 0x56 */ { NULL, NULL, 0 },
1127 /* 0x57 */ { NULL, NULL, 0 },
1128 /* 0x58 */ { NULL, NULL, 0 },
1129 /* 0x59 */ { NULL, NULL, 0 },
1130 /* 0x5a */ { NULL, NULL, 0 },
1131 /* 0x5b */ { NULL, NULL, 0 },
1132 /* 0x5c */ { NULL, NULL, 0 },
1133 /* 0x5d */ { NULL, NULL, 0 },
1134 /* 0x5e */ { NULL, NULL, 0 },
1135 /* 0x5f */ { NULL, NULL, 0 },
1136 /* 0x60 */ { NULL, NULL, 0 },
1137 /* 0x61 */ { NULL, NULL, 0 },
1138 /* 0x62 */ { NULL, NULL, 0 },
1139 /* 0x63 */ { NULL, NULL, 0 },
1140 /* 0x64 */ { NULL, NULL, 0 },
1141 /* 0x65 */ { NULL, NULL, 0 },
1142 /* 0x66 */ { NULL, NULL, 0 },
1143 /* 0x67 */ { NULL, NULL, 0 },
1144 /* 0x68 */ { NULL, NULL, 0 },
1145 /* 0x69 */ { NULL, NULL, 0 },
1146 /* 0x6a */ { NULL, NULL, 0 },
1147 /* 0x6b */ { NULL, NULL, 0 },
1148 /* 0x6c */ { NULL, NULL, 0 },
1149 /* 0x6d */ { NULL, NULL, 0 },
1150 /* 0x6e */ { NULL, NULL, 0 },
1151 /* 0x6f */ { NULL, NULL, 0 },
1152 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1153 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1154 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1155 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1156 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1157 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1158 /* 0x76 */ { NULL, NULL, 0 },
1159 /* 0x77 */ { NULL, NULL, 0 },
1160 /* 0x78 */ { NULL, NULL, 0 },
1161 /* 0x79 */ { NULL, NULL, 0 },
1162 /* 0x7a */ { NULL, NULL, 0 },
1163 /* 0x7b */ { NULL, NULL, 0 },
1164 /* 0x7c */ { NULL, NULL, 0 },
1165 /* 0x7d */ { NULL, NULL, 0 },
1166 /* 0x7e */ { NULL, NULL, 0 },
1167 /* 0x7f */ { NULL, NULL, 0 },
1168 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1169 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1170 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1171 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1172 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1173 /* 0x85 */ { NULL, NULL, 0 },
1174 /* 0x86 */ { NULL, NULL, 0 },
1175 /* 0x87 */ { NULL, NULL, 0 },
1176 /* 0x88 */ { NULL, NULL, 0 },
1177 /* 0x89 */ { NULL, NULL, 0 },
1178 /* 0x8a */ { NULL, NULL, 0 },
1179 /* 0x8b */ { NULL, NULL, 0 },
1180 /* 0x8c */ { NULL, NULL, 0 },
1181 /* 0x8d */ { NULL, NULL, 0 },
1182 /* 0x8e */ { NULL, NULL, 0 },
1183 /* 0x8f */ { NULL, NULL, 0 },
1184 /* 0x90 */ { NULL, NULL, 0 },
1185 /* 0x91 */ { NULL, NULL, 0 },
1186 /* 0x92 */ { NULL, NULL, 0 },
1187 /* 0x93 */ { NULL, NULL, 0 },
1188 /* 0x94 */ { NULL, NULL, 0 },
1189 /* 0x95 */ { NULL, NULL, 0 },
1190 /* 0x96 */ { NULL, NULL, 0 },
1191 /* 0x97 */ { NULL, NULL, 0 },
1192 /* 0x98 */ { NULL, NULL, 0 },
1193 /* 0x99 */ { NULL, NULL, 0 },
1194 /* 0x9a */ { NULL, NULL, 0 },
1195 /* 0x9b */ { NULL, NULL, 0 },
1196 /* 0x9c */ { NULL, NULL, 0 },
1197 /* 0x9d */ { NULL, NULL, 0 },
1198 /* 0x9e */ { NULL, NULL, 0 },
1199 /* 0x9f */ { NULL, NULL, 0 },
1200 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1201 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1202 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1203 /* 0xa3 */ { NULL, NULL, 0 },
1204 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1205 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1206 /* 0xa6 */ { NULL, NULL, 0 },
1207 /* 0xa7 */ { NULL, NULL, 0 },
1208 /* 0xa8 */ { NULL, NULL, 0 },
1209 /* 0xa9 */ { NULL, NULL, 0 },
1210 /* 0xaa */ { NULL, NULL, 0 },
1211 /* 0xab */ { NULL, NULL, 0 },
1212 /* 0xac */ { NULL, NULL, 0 },
1213 /* 0xad */ { NULL, NULL, 0 },
1214 /* 0xae */ { NULL, NULL, 0 },
1215 /* 0xaf */ { NULL, NULL, 0 },
1216 /* 0xb0 */ { NULL, NULL, 0 },
1217 /* 0xb1 */ { NULL, NULL, 0 },
1218 /* 0xb2 */ { NULL, NULL, 0 },
1219 /* 0xb3 */ { NULL, NULL, 0 },
1220 /* 0xb4 */ { NULL, NULL, 0 },
1221 /* 0xb5 */ { NULL, NULL, 0 },
1222 /* 0xb6 */ { NULL, NULL, 0 },
1223 /* 0xb7 */ { NULL, NULL, 0 },
1224 /* 0xb8 */ { NULL, NULL, 0 },
1225 /* 0xb9 */ { NULL, NULL, 0 },
1226 /* 0xba */ { NULL, NULL, 0 },
1227 /* 0xbb */ { NULL, NULL, 0 },
1228 /* 0xbc */ { NULL, NULL, 0 },
1229 /* 0xbd */ { NULL, NULL, 0 },
1230 /* 0xbe */ { NULL, NULL, 0 },
1231 /* 0xbf */ { NULL, NULL, 0 },
1232 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1233 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1234 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1235 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1236 /* 0xc4 */ { NULL, NULL, 0 },
1237 /* 0xc5 */ { NULL, NULL, 0 },
1238 /* 0xc6 */ { NULL, NULL, 0 },
1239 /* 0xc7 */ { NULL, NULL, 0 },
1240 /* 0xc8 */ { NULL, NULL, 0 },
1241 /* 0xc9 */ { NULL, NULL, 0 },
1242 /* 0xca */ { NULL, NULL, 0 },
1243 /* 0xcb */ { NULL, NULL, 0 },
1244 /* 0xcc */ { NULL, NULL, 0 },
1245 /* 0xcd */ { NULL, NULL, 0 },
1246 /* 0xce */ { NULL, NULL, 0 },
1247 /* 0xcf */ { NULL, NULL, 0 },
1248 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1249 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1250 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1251 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1252 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1253 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1254 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1255 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1256 /* 0xd8 */ { NULL, NULL, 0 },
1257 /* 0xd9 */ { NULL, NULL, 0 },
1258 /* 0xda */ { NULL, NULL, 0 },
1259 /* 0xdb */ { NULL, NULL, 0 },
1260 /* 0xdc */ { NULL, NULL, 0 },
1261 /* 0xdd */ { NULL, NULL, 0 },
1262 /* 0xde */ { NULL, NULL, 0 },
1263 /* 0xdf */ { NULL, NULL, 0 },
1264 /* 0xe0 */ { NULL, NULL, 0 },
1265 /* 0xe1 */ { NULL, NULL, 0 },
1266 /* 0xe2 */ { NULL, NULL, 0 },
1267 /* 0xe3 */ { NULL, NULL, 0 },
1268 /* 0xe4 */ { NULL, NULL, 0 },
1269 /* 0xe5 */ { NULL, NULL, 0 },
1270 /* 0xe6 */ { NULL, NULL, 0 },
1271 /* 0xe7 */ { NULL, NULL, 0 },
1272 /* 0xe8 */ { NULL, NULL, 0 },
1273 /* 0xe9 */ { NULL, NULL, 0 },
1274 /* 0xea */ { NULL, NULL, 0 },
1275 /* 0xeb */ { NULL, NULL, 0 },
1276 /* 0xec */ { NULL, NULL, 0 },
1277 /* 0xed */ { NULL, NULL, 0 },
1278 /* 0xee */ { NULL, NULL, 0 },
1279 /* 0xef */ { NULL, NULL, 0 },
1280 /* 0xf0 */ { NULL, NULL, 0 },
1281 /* 0xf1 */ { NULL, NULL, 0 },
1282 /* 0xf2 */ { NULL, NULL, 0 },
1283 /* 0xf3 */ { NULL, NULL, 0 },
1284 /* 0xf4 */ { NULL, NULL, 0 },
1285 /* 0xf5 */ { NULL, NULL, 0 },
1286 /* 0xf6 */ { NULL, NULL, 0 },
1287 /* 0xf7 */ { NULL, NULL, 0 },
1288 /* 0xf8 */ { NULL, NULL, 0 },
1289 /* 0xf9 */ { NULL, NULL, 0 },
1290 /* 0xfa */ { NULL, NULL, 0 },
1291 /* 0xfb */ { NULL, NULL, 0 },
1292 /* 0xfc */ { NULL, NULL, 0 },
1293 /* 0xfd */ { NULL, NULL, 0 },
1294 /* 0xfe */ { NULL, NULL, 0 },
1295 /* 0xff */ { NULL, NULL, 0 }
1299 /*******************************************************************
1300 allocate and initialize a reply packet
1301 ********************************************************************/
1303 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1304 const char *inbuf, char **outbuf, uint8_t num_words,
1305 uint32_t num_bytes)
1308 * Protect against integer wrap
1310 if ((num_bytes > 0xffffff)
1311 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1312 char *msg;
1313 if (asprintf(&msg, "num_bytes too large: %u",
1314 (unsigned)num_bytes) == -1) {
1315 msg = CONST_DISCARD(char *, "num_bytes too large");
1317 smb_panic(msg);
1320 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1321 smb_size + num_words*2 + num_bytes);
1322 if (*outbuf == NULL) {
1323 return false;
1326 construct_reply_common(req, inbuf, *outbuf);
1327 srv_set_message(*outbuf, num_words, num_bytes, false);
1329 * Zero out the word area, the caller has to take care of the bcc area
1330 * himself
1332 if (num_words != 0) {
1333 memset(*outbuf + smb_vwv0, 0, num_words*2);
1336 return true;
1339 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1341 char *outbuf;
1342 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1343 num_bytes)) {
1344 smb_panic("could not allocate output buffer\n");
1346 req->outbuf = (uint8_t *)outbuf;
1350 /*******************************************************************
1351 Dump a packet to a file.
1352 ********************************************************************/
1354 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1356 int fd, i;
1357 char *fname = NULL;
1358 if (DEBUGLEVEL < 50) {
1359 return;
1362 if (len < 4) len = smb_len(data)+4;
1363 for (i=1;i<100;i++) {
1364 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1365 type ? "req" : "resp") == -1) {
1366 return;
1368 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1369 if (fd != -1 || errno != EEXIST) break;
1371 if (fd != -1) {
1372 ssize_t ret = write(fd, data, len);
1373 if (ret != len)
1374 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1375 close(fd);
1376 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1378 SAFE_FREE(fname);
1381 /****************************************************************************
1382 Prepare everything for calling the actual request function, and potentially
1383 call the request function via the "new" interface.
1385 Return False if the "legacy" function needs to be called, everything is
1386 prepared.
1388 Return True if we're done.
1390 I know this API sucks, but it is the one with the least code change I could
1391 find.
1392 ****************************************************************************/
1394 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1396 int flags;
1397 uint16 session_tag;
1398 connection_struct *conn = NULL;
1399 struct smbd_server_connection *sconn = smbd_server_conn;
1401 errno = 0;
1403 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1404 * so subtract 4 from it. */
1405 if (!valid_smb_header(req->inbuf)
1406 || (size < (smb_size - 4))) {
1407 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1408 smb_len(req->inbuf)));
1409 exit_server_cleanly("Non-SMB packet");
1412 if (smb_messages[type].fn == NULL) {
1413 DEBUG(0,("Unknown message type %d!\n",type));
1414 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1415 reply_unknown_new(req, type);
1416 return NULL;
1419 flags = smb_messages[type].flags;
1421 /* In share mode security we must ignore the vuid. */
1422 session_tag = (lp_security() == SEC_SHARE)
1423 ? UID_FIELD_INVALID : req->vuid;
1424 conn = req->conn;
1426 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1427 (int)sys_getpid(), (unsigned long)conn));
1429 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1431 /* Ensure this value is replaced in the incoming packet. */
1432 SSVAL(req->inbuf,smb_uid,session_tag);
1435 * Ensure the correct username is in current_user_info. This is a
1436 * really ugly bugfix for problems with multiple session_setup_and_X's
1437 * being done and allowing %U and %G substitutions to work correctly.
1438 * There is a reason this code is done here, don't move it unless you
1439 * know what you're doing... :-).
1440 * JRA.
1443 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1444 user_struct *vuser = NULL;
1446 sconn->smb1.sessions.last_session_tag = session_tag;
1447 if(session_tag != UID_FIELD_INVALID) {
1448 vuser = get_valid_user_struct(sconn, session_tag);
1449 if (vuser) {
1450 set_current_user_info(
1451 vuser->server_info->sanitized_username,
1452 vuser->server_info->unix_name,
1453 pdb_get_domain(vuser->server_info
1454 ->sam_account));
1459 /* Does this call need to be run as the connected user? */
1460 if (flags & AS_USER) {
1462 /* Does this call need a valid tree connection? */
1463 if (!conn) {
1465 * Amazingly, the error code depends on the command
1466 * (from Samba4).
1468 if (type == SMBntcreateX) {
1469 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1470 } else {
1471 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1473 return NULL;
1476 if (!change_to_user(conn,session_tag)) {
1477 DEBUG(0, ("Error: Could not change to user. Removing "
1478 "deferred open, mid=%llu.\n",
1479 (unsigned long long)req->mid));
1480 reply_force_doserror(req, ERRSRV, ERRbaduid);
1481 return conn;
1484 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1486 /* Does it need write permission? */
1487 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1488 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1489 return conn;
1492 /* IPC services are limited */
1493 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1494 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1495 return conn;
1497 } else {
1498 /* This call needs to be run as root */
1499 change_to_root_user();
1502 /* load service specific parameters */
1503 if (conn) {
1504 if (req->encrypted) {
1505 conn->encrypted_tid = true;
1506 /* encrypted required from now on. */
1507 conn->encrypt_level = Required;
1508 } else if (ENCRYPTION_REQUIRED(conn)) {
1509 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1510 exit_server_cleanly("encryption required "
1511 "on connection");
1512 return conn;
1516 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1517 (flags & (AS_USER|DO_CHDIR)
1518 ?True:False))) {
1519 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1520 return conn;
1522 conn->num_smb_operations++;
1525 /* does this protocol need to be run as guest? */
1526 if ((flags & AS_GUEST)
1527 && (!change_to_guest() ||
1528 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1529 lp_hostsdeny(-1)))) {
1530 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1531 return conn;
1534 smb_messages[type].fn(req);
1535 return req->conn;
1538 /****************************************************************************
1539 Construct a reply to the incoming packet.
1540 ****************************************************************************/
1542 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1543 uint32_t seqnum, bool encrypted,
1544 struct smb_perfcount_data *deferred_pcd)
1546 connection_struct *conn;
1547 struct smb_request *req;
1549 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1550 smb_panic("could not allocate smb_request");
1553 if (!init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted,
1554 seqnum)) {
1555 exit_server_cleanly("Invalid SMB request");
1558 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1560 /* we popped this message off the queue - keep original perf data */
1561 if (deferred_pcd)
1562 req->pcd = *deferred_pcd;
1563 else {
1564 SMB_PERFCOUNT_START(&req->pcd);
1565 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1566 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1569 conn = switch_message(req->cmd, req, size);
1571 if (req->unread_bytes) {
1572 /* writeX failed. drain socket. */
1573 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1574 req->unread_bytes) {
1575 smb_panic("failed to drain pending bytes");
1577 req->unread_bytes = 0;
1580 if (req->done) {
1581 TALLOC_FREE(req);
1582 return;
1585 if (req->outbuf == NULL) {
1586 return;
1589 if (CVAL(req->outbuf,0) == 0) {
1590 show_msg((char *)req->outbuf);
1593 if (!srv_send_smb(smbd_server_fd(),
1594 (char *)req->outbuf,
1595 true, req->seqnum+1,
1596 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1597 &req->pcd)) {
1598 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1601 TALLOC_FREE(req);
1603 return;
1606 /****************************************************************************
1607 Process an smb from the client
1608 ****************************************************************************/
1609 static void process_smb(struct smbd_server_connection *conn,
1610 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1611 uint32_t seqnum, bool encrypted,
1612 struct smb_perfcount_data *deferred_pcd)
1614 int msg_type = CVAL(inbuf,0);
1616 DO_PROFILE_INC(smb_count);
1618 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1619 smb_len(inbuf) ) );
1620 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1621 (int)nread,
1622 (unsigned int)unread_bytes ));
1624 if (msg_type != 0) {
1626 * NetBIOS session request, keepalive, etc.
1628 reply_special((char *)inbuf);
1629 goto done;
1632 if (smbd_server_conn->allow_smb2) {
1633 if (smbd_is_smb2_header(inbuf, nread)) {
1634 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1635 return;
1636 } else if (nread >= smb_size && valid_smb_header(inbuf)
1637 && CVAL(inbuf, smb_com) != 0x72) {
1638 /* This is a non-negprot SMB1 packet.
1639 Disable SMB2 from now on. */
1640 smbd_server_conn->allow_smb2 = false;
1644 show_msg((char *)inbuf);
1646 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1647 trans_num++;
1649 done:
1650 conn->smb1.num_requests++;
1652 /* The timeout_processing function isn't run nearly
1653 often enough to implement 'max log size' without
1654 overrunning the size of the file by many megabytes.
1655 This is especially true if we are running at debug
1656 level 10. Checking every 50 SMBs is a nice
1657 tradeoff of performance vs log file size overrun. */
1659 if ((conn->smb1.num_requests % 50) == 0 &&
1660 need_to_check_log_size()) {
1661 change_to_root_user();
1662 check_log_size();
1666 /****************************************************************************
1667 Return a string containing the function name of a SMB command.
1668 ****************************************************************************/
1670 const char *smb_fn_name(int type)
1672 const char *unknown_name = "SMBunknown";
1674 if (smb_messages[type].name == NULL)
1675 return(unknown_name);
1677 return(smb_messages[type].name);
1680 /****************************************************************************
1681 Helper functions for contruct_reply.
1682 ****************************************************************************/
1684 void add_to_common_flags2(uint32 v)
1686 common_flags2 |= v;
1689 void remove_from_common_flags2(uint32 v)
1691 common_flags2 &= ~v;
1694 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1695 char *outbuf)
1697 srv_set_message(outbuf,0,0,false);
1699 SCVAL(outbuf, smb_com, req->cmd);
1700 SIVAL(outbuf,smb_rcls,0);
1701 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1702 SSVAL(outbuf,smb_flg2,
1703 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1704 common_flags2);
1705 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1707 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1708 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1709 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1710 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1713 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1715 construct_reply_common(req, (char *)req->inbuf, outbuf);
1719 * How many bytes have we already accumulated up to the current wct field
1720 * offset?
1723 size_t req_wct_ofs(struct smb_request *req)
1725 size_t buf_size;
1727 if (req->chain_outbuf == NULL) {
1728 return smb_wct - 4;
1730 buf_size = talloc_get_size(req->chain_outbuf);
1731 if ((buf_size % 4) != 0) {
1732 buf_size += (4 - (buf_size % 4));
1734 return buf_size - 4;
1738 * Hack around reply_nterror & friends not being aware of chained requests,
1739 * generating illegal (i.e. wct==0) chain replies.
1742 static void fixup_chain_error_packet(struct smb_request *req)
1744 uint8_t *outbuf = req->outbuf;
1745 req->outbuf = NULL;
1746 reply_outbuf(req, 2, 0);
1747 memcpy(req->outbuf, outbuf, smb_wct);
1748 TALLOC_FREE(outbuf);
1749 SCVAL(req->outbuf, smb_vwv0, 0xff);
1753 * @brief Find the smb_cmd offset of the last command pushed
1754 * @param[in] buf The buffer we're building up
1755 * @retval Where can we put our next andx cmd?
1757 * While chaining requests, the "next" request we're looking at needs to put
1758 * its SMB_Command before the data the previous request already built up added
1759 * to the chain. Find the offset to the place where we have to put our cmd.
1762 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1764 uint8_t cmd;
1765 size_t ofs;
1767 cmd = CVAL(buf, smb_com);
1769 SMB_ASSERT(is_andx_req(cmd));
1771 ofs = smb_vwv0;
1773 while (CVAL(buf, ofs) != 0xff) {
1775 if (!is_andx_req(CVAL(buf, ofs))) {
1776 return false;
1780 * ofs is from start of smb header, so add the 4 length
1781 * bytes. The next cmd is right after the wct field.
1783 ofs = SVAL(buf, ofs+2) + 4 + 1;
1785 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1788 *pofs = ofs;
1789 return true;
1793 * @brief Do the smb chaining at a buffer level
1794 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1795 * @param[in] smb_command The command that we want to issue
1796 * @param[in] wct How many words?
1797 * @param[in] vwv The words, already in network order
1798 * @param[in] bytes_alignment How shall we align "bytes"?
1799 * @param[in] num_bytes How many bytes?
1800 * @param[in] bytes The data the request ships
1802 * smb_splice_chain() adds the vwv and bytes to the request already present in
1803 * *poutbuf.
1806 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1807 uint8_t wct, const uint16_t *vwv,
1808 size_t bytes_alignment,
1809 uint32_t num_bytes, const uint8_t *bytes)
1811 uint8_t *outbuf;
1812 size_t old_size, new_size;
1813 size_t ofs;
1814 size_t chain_padding = 0;
1815 size_t bytes_padding = 0;
1816 bool first_request;
1818 old_size = talloc_get_size(*poutbuf);
1821 * old_size == smb_wct means we're pushing the first request in for
1822 * libsmb/
1825 first_request = (old_size == smb_wct);
1827 if (!first_request && ((old_size % 4) != 0)) {
1829 * Align the wct field of subsequent requests to a 4-byte
1830 * boundary
1832 chain_padding = 4 - (old_size % 4);
1836 * After the old request comes the new wct field (1 byte), the vwv's
1837 * and the num_bytes field. After at we might need to align the bytes
1838 * given to us to "bytes_alignment", increasing the num_bytes value.
1841 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1843 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1844 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1847 new_size += bytes_padding + num_bytes;
1849 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1850 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1851 (unsigned)new_size));
1852 return false;
1855 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1856 if (outbuf == NULL) {
1857 DEBUG(0, ("talloc failed\n"));
1858 return false;
1860 *poutbuf = outbuf;
1862 if (first_request) {
1863 SCVAL(outbuf, smb_com, smb_command);
1864 } else {
1865 size_t andx_cmd_ofs;
1867 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1868 DEBUG(1, ("invalid command chain\n"));
1869 *poutbuf = TALLOC_REALLOC_ARRAY(
1870 NULL, *poutbuf, uint8_t, old_size);
1871 return false;
1874 if (chain_padding != 0) {
1875 memset(outbuf + old_size, 0, chain_padding);
1876 old_size += chain_padding;
1879 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1880 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1883 ofs = old_size;
1886 * Push the chained request:
1888 * wct field
1891 SCVAL(outbuf, ofs, wct);
1892 ofs += 1;
1895 * vwv array
1898 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1899 ofs += sizeof(uint16_t) * wct;
1902 * bcc (byte count)
1905 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1906 ofs += sizeof(uint16_t);
1909 * padding
1912 if (bytes_padding != 0) {
1913 memset(outbuf + ofs, 0, bytes_padding);
1914 ofs += bytes_padding;
1918 * The bytes field
1921 memcpy(outbuf + ofs, bytes, num_bytes);
1923 return true;
1926 /****************************************************************************
1927 Construct a chained reply and add it to the already made reply
1928 ****************************************************************************/
1930 void chain_reply(struct smb_request *req)
1932 size_t smblen = smb_len(req->inbuf);
1933 size_t already_used, length_needed;
1934 uint8_t chain_cmd;
1935 uint32_t chain_offset; /* uint32_t to avoid overflow */
1937 uint8_t wct;
1938 uint16_t *vwv;
1939 uint16_t buflen;
1940 uint8_t *buf;
1942 if (IVAL(req->outbuf, smb_rcls) != 0) {
1943 fixup_chain_error_packet(req);
1947 * Any of the AndX requests and replies have at least a wct of
1948 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1949 * beginning of the SMB header to the next wct field.
1951 * None of the AndX requests put anything valuable in vwv[0] and [1],
1952 * so we can overwrite it here to form the chain.
1955 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1956 if (req->chain_outbuf == NULL) {
1957 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1958 req, req->outbuf, uint8_t,
1959 smb_len(req->outbuf) + 4);
1960 if (req->chain_outbuf == NULL) {
1961 smb_panic("talloc failed");
1964 req->outbuf = NULL;
1965 goto error;
1969 * Here we assume that this is the end of the chain. For that we need
1970 * to set "next command" to 0xff and the offset to 0. If we later find
1971 * more commands in the chain, this will be overwritten again.
1974 SCVAL(req->outbuf, smb_vwv0, 0xff);
1975 SCVAL(req->outbuf, smb_vwv0+1, 0);
1976 SSVAL(req->outbuf, smb_vwv1, 0);
1978 if (req->chain_outbuf == NULL) {
1980 * In req->chain_outbuf we collect all the replies. Start the
1981 * chain by copying in the first reply.
1983 * We do the realloc because later on we depend on
1984 * talloc_get_size to determine the length of
1985 * chain_outbuf. The reply_xxx routines might have
1986 * over-allocated (reply_pipe_read_and_X used to be such an
1987 * example).
1989 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1990 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1991 if (req->chain_outbuf == NULL) {
1992 smb_panic("talloc failed");
1994 req->outbuf = NULL;
1995 } else {
1997 * Update smb headers where subsequent chained commands
1998 * may have updated them.
2000 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2001 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2003 if (!smb_splice_chain(&req->chain_outbuf,
2004 CVAL(req->outbuf, smb_com),
2005 CVAL(req->outbuf, smb_wct),
2006 (uint16_t *)(req->outbuf + smb_vwv),
2007 0, smb_buflen(req->outbuf),
2008 (uint8_t *)smb_buf(req->outbuf))) {
2009 goto error;
2011 TALLOC_FREE(req->outbuf);
2015 * We use the old request's vwv field to grab the next chained command
2016 * and offset into the chained fields.
2019 chain_cmd = CVAL(req->vwv+0, 0);
2020 chain_offset = SVAL(req->vwv+1, 0);
2022 if (chain_cmd == 0xff) {
2024 * End of chain, no more requests from the client. So ship the
2025 * replies.
2027 smb_setlen((char *)(req->chain_outbuf),
2028 talloc_get_size(req->chain_outbuf) - 4);
2030 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2031 true, req->seqnum+1,
2032 IS_CONN_ENCRYPTED(req->conn)
2033 ||req->encrypted,
2034 &req->pcd)) {
2035 exit_server_cleanly("chain_reply: srv_send_smb "
2036 "failed.");
2038 TALLOC_FREE(req->chain_outbuf);
2039 req->done = true;
2040 return;
2043 /* add a new perfcounter for this element of chain */
2044 SMB_PERFCOUNT_ADD(&req->pcd);
2045 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2046 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2049 * Check if the client tries to fool us. The request so far uses the
2050 * space to the end of the byte buffer in the request just
2051 * processed. The chain_offset can't point into that area. If that was
2052 * the case, we could end up with an endless processing of the chain,
2053 * we would always handle the same request.
2056 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2057 if (chain_offset < already_used) {
2058 goto error;
2062 * Next check: Make sure the chain offset does not point beyond the
2063 * overall smb request length.
2066 length_needed = chain_offset+1; /* wct */
2067 if (length_needed > smblen) {
2068 goto error;
2072 * Now comes the pointer magic. Goal here is to set up req->vwv and
2073 * req->buf correctly again to be able to call the subsequent
2074 * switch_message(). The chain offset (the former vwv[1]) points at
2075 * the new wct field.
2078 wct = CVAL(smb_base(req->inbuf), chain_offset);
2081 * Next consistency check: Make the new vwv array fits in the overall
2082 * smb request.
2085 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2086 if (length_needed > smblen) {
2087 goto error;
2089 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2092 * Now grab the new byte buffer....
2095 buflen = SVAL(vwv+wct, 0);
2098 * .. and check that it fits.
2101 length_needed += buflen;
2102 if (length_needed > smblen) {
2103 goto error;
2105 buf = (uint8_t *)(vwv+wct+1);
2107 req->cmd = chain_cmd;
2108 req->wct = wct;
2109 req->vwv = vwv;
2110 req->buflen = buflen;
2111 req->buf = buf;
2113 switch_message(chain_cmd, req, smblen);
2115 if (req->outbuf == NULL) {
2117 * This happens if the chained command has suspended itself or
2118 * if it has called srv_send_smb() itself.
2120 return;
2124 * We end up here if the chained command was not itself chained or
2125 * suspended, but for example a close() command. We now need to splice
2126 * the chained commands' outbuf into the already built up chain_outbuf
2127 * and ship the result.
2129 goto done;
2131 error:
2133 * We end up here if there's any error in the chain syntax. Report a
2134 * DOS error, just like Windows does.
2136 reply_force_doserror(req, ERRSRV, ERRerror);
2137 fixup_chain_error_packet(req);
2139 done:
2141 * This scary statement intends to set the
2142 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2143 * to the value req->outbuf carries
2145 SSVAL(req->chain_outbuf, smb_flg2,
2146 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2147 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2150 * Transfer the error codes from the subrequest to the main one
2152 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2153 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2155 if (!smb_splice_chain(&req->chain_outbuf,
2156 CVAL(req->outbuf, smb_com),
2157 CVAL(req->outbuf, smb_wct),
2158 (uint16_t *)(req->outbuf + smb_vwv),
2159 0, smb_buflen(req->outbuf),
2160 (uint8_t *)smb_buf(req->outbuf))) {
2161 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2163 TALLOC_FREE(req->outbuf);
2165 smb_setlen((char *)(req->chain_outbuf),
2166 talloc_get_size(req->chain_outbuf) - 4);
2168 show_msg((char *)(req->chain_outbuf));
2170 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2171 true, req->seqnum+1,
2172 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2173 &req->pcd)) {
2174 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2176 TALLOC_FREE(req->chain_outbuf);
2177 req->done = true;
2180 /****************************************************************************
2181 Check if services need reloading.
2182 ****************************************************************************/
2184 void check_reload(time_t t)
2186 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2188 if(last_smb_conf_reload_time == 0) {
2189 last_smb_conf_reload_time = t;
2190 /* Our printing subsystem might not be ready at smbd start up.
2191 Then no printer is available till the first printers check
2192 is performed. A lower initial interval circumvents this. */
2193 if ( printcap_cache_time > 60 )
2194 last_printer_reload_time = t - printcap_cache_time + 60;
2195 else
2196 last_printer_reload_time = t;
2199 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2200 /* randomize over 60 second the printcap reload to avoid all
2201 * process hitting cupsd at the same time */
2202 int time_range = 60;
2204 last_printer_reload_time += random() % time_range;
2205 mypid = getpid();
2208 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2209 reload_services(True);
2210 last_smb_conf_reload_time = t;
2213 /* 'printcap cache time = 0' disable the feature */
2215 if ( printcap_cache_time != 0 )
2217 /* see if it's time to reload or if the clock has been set back */
2219 if ( (t >= last_printer_reload_time+printcap_cache_time)
2220 || (t-last_printer_reload_time < 0) )
2222 DEBUG( 3,( "Printcap cache time expired.\n"));
2223 reload_printers();
2224 last_printer_reload_time = t;
2229 static bool fd_is_readable(int fd)
2231 fd_set fds;
2232 struct timeval timeout = {0, };
2233 int ret;
2235 FD_ZERO(&fds);
2236 FD_SET(fd, &fds);
2238 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2239 if (ret == -1) {
2240 return false;
2242 return FD_ISSET(fd, &fds);
2245 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2247 /* TODO: make write nonblocking */
2250 static void smbd_server_connection_read_handler(
2251 struct smbd_server_connection *conn, int fd)
2253 uint8_t *inbuf = NULL;
2254 size_t inbuf_len = 0;
2255 size_t unread_bytes = 0;
2256 bool encrypted = false;
2257 TALLOC_CTX *mem_ctx = talloc_tos();
2258 NTSTATUS status;
2259 uint32_t seqnum;
2261 bool from_client = (smbd_server_fd() == fd)?true:false;
2263 if (from_client) {
2264 smbd_lock_socket(conn);
2266 if (!fd_is_readable(smbd_server_fd())) {
2267 DEBUG(10,("the echo listener was faster\n"));
2268 smbd_unlock_socket(conn);
2269 return;
2272 /* TODO: make this completely nonblocking */
2273 status = receive_smb_talloc(mem_ctx, fd,
2274 (char **)(void *)&inbuf,
2275 0, /* timeout */
2276 &unread_bytes,
2277 &encrypted,
2278 &inbuf_len, &seqnum,
2279 false /* trusted channel */);
2280 smbd_unlock_socket(conn);
2281 } else {
2282 /* TODO: make this completely nonblocking */
2283 status = receive_smb_talloc(mem_ctx, fd,
2284 (char **)(void *)&inbuf,
2285 0, /* timeout */
2286 &unread_bytes,
2287 &encrypted,
2288 &inbuf_len, &seqnum,
2289 true /* trusted channel */);
2292 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2293 goto process;
2295 if (NT_STATUS_IS_ERR(status)) {
2296 exit_server_cleanly("failed to receive smb request");
2298 if (!NT_STATUS_IS_OK(status)) {
2299 return;
2302 process:
2303 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2304 seqnum, encrypted, NULL);
2307 static void smbd_server_connection_handler(struct event_context *ev,
2308 struct fd_event *fde,
2309 uint16_t flags,
2310 void *private_data)
2312 struct smbd_server_connection *conn = talloc_get_type(private_data,
2313 struct smbd_server_connection);
2315 if (flags & EVENT_FD_WRITE) {
2316 smbd_server_connection_write_handler(conn);
2317 } else if (flags & EVENT_FD_READ) {
2318 smbd_server_connection_read_handler(conn, smbd_server_fd());
2322 static void smbd_server_echo_handler(struct event_context *ev,
2323 struct fd_event *fde,
2324 uint16_t flags,
2325 void *private_data)
2327 struct smbd_server_connection *conn = talloc_get_type(private_data,
2328 struct smbd_server_connection);
2330 if (flags & EVENT_FD_WRITE) {
2331 smbd_server_connection_write_handler(conn);
2332 } else if (flags & EVENT_FD_READ) {
2333 smbd_server_connection_read_handler(
2334 conn, conn->smb1.echo_handler.trusted_fd);
2338 /****************************************************************************
2339 received when we should release a specific IP
2340 ****************************************************************************/
2341 static void release_ip(const char *ip, void *priv)
2343 char addr[INET6_ADDRSTRLEN];
2344 char *p = addr;
2346 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2348 if (strncmp("::ffff:", addr, 7) == 0) {
2349 p = addr + 7;
2352 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2353 /* we can't afford to do a clean exit - that involves
2354 database writes, which would potentially mean we
2355 are still running after the failover has finished -
2356 we have to get rid of this process ID straight
2357 away */
2358 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2359 ip));
2360 /* note we must exit with non-zero status so the unclean handler gets
2361 called in the parent, so that the brl database is tickled */
2362 _exit(1);
2366 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2367 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2369 release_ip((char *)data->data, NULL);
2372 #ifdef CLUSTER_SUPPORT
2373 static int client_get_tcp_info(struct sockaddr_storage *server,
2374 struct sockaddr_storage *client)
2376 socklen_t length;
2377 if (server_fd == -1) {
2378 return -1;
2380 length = sizeof(*server);
2381 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2382 return -1;
2384 length = sizeof(*client);
2385 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2386 return -1;
2388 return 0;
2390 #endif
2393 * Send keepalive packets to our client
2395 static bool keepalive_fn(const struct timeval *now, void *private_data)
2397 bool ret;
2399 smbd_lock_socket(smbd_server_conn);
2400 ret = send_keepalive(smbd_server_fd());
2401 smbd_unlock_socket(smbd_server_conn);
2403 if (!ret) {
2404 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2405 return False;
2407 return True;
2411 * Do the recurring check if we're idle
2413 static bool deadtime_fn(const struct timeval *now, void *private_data)
2415 struct smbd_server_connection *sconn = smbd_server_conn;
2417 if (sconn->allow_smb2) {
2418 /* TODO: implement real idle check */
2419 if (sconn->smb2.sessions.list) {
2420 return true;
2422 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2423 messaging_send(smbd_messaging_context(), procid_self(),
2424 MSG_SHUTDOWN, &data_blob_null);
2425 return false;
2428 if ((conn_num_open(sconn) == 0)
2429 || (conn_idle_all(sconn, now->tv_sec))) {
2430 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2431 messaging_send(smbd_messaging_context(), procid_self(),
2432 MSG_SHUTDOWN, &data_blob_null);
2433 return False;
2436 return True;
2440 * Do the recurring log file and smb.conf reload checks.
2443 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2445 change_to_root_user();
2447 /* update printer queue caches if necessary */
2448 update_monitored_printq_cache();
2450 /* check if we need to reload services */
2451 check_reload(time(NULL));
2453 /* Change machine password if neccessary. */
2454 attempt_machine_password_change();
2457 * Force a log file check.
2459 force_check_log_size();
2460 check_log_size();
2461 return true;
2464 static int create_unlink_tmp(const char *dir)
2466 char *fname;
2467 int fd;
2469 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2470 if (fname == NULL) {
2471 errno = ENOMEM;
2472 return -1;
2474 fd = mkstemp(fname);
2475 if (fd == -1) {
2476 TALLOC_FREE(fname);
2477 return -1;
2479 if (unlink(fname) == -1) {
2480 int sys_errno = errno;
2481 close(fd);
2482 TALLOC_FREE(fname);
2483 errno = sys_errno;
2484 return -1;
2486 TALLOC_FREE(fname);
2487 return fd;
2490 struct smbd_echo_state {
2491 struct tevent_context *ev;
2492 struct iovec *pending;
2493 struct smbd_server_connection *sconn;
2494 int parent_pipe;
2496 struct tevent_fd *parent_fde;
2498 struct tevent_fd *read_fde;
2499 struct tevent_req *write_req;
2502 static void smbd_echo_writer_done(struct tevent_req *req);
2504 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2506 int num_pending;
2508 if (state->write_req != NULL) {
2509 return;
2512 num_pending = talloc_array_length(state->pending);
2513 if (num_pending == 0) {
2514 return;
2517 state->write_req = writev_send(state, state->ev, NULL,
2518 state->parent_pipe, false,
2519 state->pending, num_pending);
2520 if (state->write_req == NULL) {
2521 DEBUG(1, ("writev_send failed\n"));
2522 exit(1);
2525 talloc_steal(state->write_req, state->pending);
2526 state->pending = NULL;
2528 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2529 state);
2532 static void smbd_echo_writer_done(struct tevent_req *req)
2534 struct smbd_echo_state *state = tevent_req_callback_data(
2535 req, struct smbd_echo_state);
2536 ssize_t written;
2537 int err;
2539 written = writev_recv(req, &err);
2540 TALLOC_FREE(req);
2541 state->write_req = NULL;
2542 if (written == -1) {
2543 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2544 exit(1);
2546 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2547 smbd_echo_activate_writer(state);
2550 static bool smbd_echo_reply(int fd,
2551 uint8_t *inbuf, size_t inbuf_len,
2552 uint32_t seqnum)
2554 struct smb_request req;
2555 uint16_t num_replies;
2556 size_t out_len;
2557 char *outbuf;
2558 bool ok;
2560 if (inbuf_len < smb_size) {
2561 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2562 return false;
2564 if (!valid_smb_header(inbuf)) {
2565 DEBUG(10, ("Got invalid SMB header\n"));
2566 return false;
2569 if (!init_smb_request(&req, inbuf, 0, false, seqnum)) {
2570 return false;
2572 req.inbuf = inbuf;
2574 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2575 smb_messages[req.cmd].name
2576 ? smb_messages[req.cmd].name : "unknown"));
2578 if (req.cmd != SMBecho) {
2579 return false;
2581 if (req.wct < 1) {
2582 return false;
2585 num_replies = SVAL(req.vwv+0, 0);
2586 if (num_replies != 1) {
2587 /* Not a Windows "Hey, you're still there?" request */
2588 return false;
2591 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2592 1, req.buflen)) {
2593 DEBUG(10, ("create_outbuf failed\n"));
2594 return false;
2596 req.outbuf = (uint8_t *)outbuf;
2598 SSVAL(req.outbuf, smb_vwv0, num_replies);
2600 if (req.buflen > 0) {
2601 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2604 out_len = smb_len(req.outbuf) + 4;
2606 ok = srv_send_smb(smbd_server_fd(),
2607 (char *)outbuf,
2608 true, seqnum+1,
2609 false, &req.pcd);
2610 TALLOC_FREE(outbuf);
2611 if (!ok) {
2612 exit(1);
2615 return true;
2618 static void smbd_echo_exit(struct tevent_context *ev,
2619 struct tevent_fd *fde, uint16_t flags,
2620 void *private_data)
2622 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2623 exit(0);
2626 static void smbd_echo_reader(struct tevent_context *ev,
2627 struct tevent_fd *fde, uint16_t flags,
2628 void *private_data)
2630 struct smbd_echo_state *state = talloc_get_type_abort(
2631 private_data, struct smbd_echo_state);
2632 struct smbd_server_connection *sconn = state->sconn;
2633 size_t unread, num_pending;
2634 NTSTATUS status;
2635 struct iovec *tmp;
2636 uint32_t seqnum = 0;
2637 bool reply;
2638 bool ok;
2639 bool encrypted = false;
2641 ok = smbd_lock_socket_internal(sconn);
2642 if (!ok) {
2643 DEBUG(0, ("%s: failed to lock socket\n",
2644 __location__));
2645 exit(1);
2648 if (!fd_is_readable(smbd_server_fd())) {
2649 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2650 (int)sys_getpid()));
2651 ok = smbd_unlock_socket_internal(sconn);
2652 if (!ok) {
2653 DEBUG(1, ("%s: failed to unlock socket in\n",
2654 __location__));
2655 exit(1);
2657 return;
2660 num_pending = talloc_array_length(state->pending);
2661 tmp = talloc_realloc(state, state->pending, struct iovec,
2662 num_pending+1);
2663 if (tmp == NULL) {
2664 DEBUG(1, ("talloc_realloc failed\n"));
2665 exit(1);
2667 state->pending = tmp;
2669 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2671 status = receive_smb_talloc(state, smbd_server_fd(),
2672 (char **)(void *)&state->pending[num_pending].iov_base,
2673 0 /* timeout */,
2674 &unread,
2675 &encrypted,
2676 &state->pending[num_pending].iov_len,
2677 &seqnum,
2678 false /* trusted_channel*/);
2679 if (!NT_STATUS_IS_OK(status)) {
2680 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2681 (int)sys_getpid(), nt_errstr(status)));
2682 exit(1);
2685 ok = smbd_unlock_socket_internal(sconn);
2686 if (!ok) {
2687 DEBUG(1, ("%s: failed to unlock socket in\n",
2688 __location__));
2689 exit(1);
2693 * place the seqnum in the packet so that the main process can reply
2694 * with signing
2696 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2697 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2699 reply = smbd_echo_reply(smbd_server_fd(),
2700 (uint8_t *)state->pending[num_pending].iov_base,
2701 state->pending[num_pending].iov_len,
2702 seqnum);
2703 if (reply) {
2704 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2705 /* no check, shrinking by some bytes does not fail */
2706 state->pending = talloc_realloc(state, state->pending,
2707 struct iovec,
2708 num_pending);
2709 } else {
2710 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2711 smbd_echo_activate_writer(state);
2715 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2716 int parent_pipe)
2718 struct smbd_echo_state *state;
2720 state = talloc_zero(sconn, struct smbd_echo_state);
2721 if (state == NULL) {
2722 DEBUG(1, ("talloc failed\n"));
2723 return;
2725 state->sconn = sconn;
2726 state->parent_pipe = parent_pipe;
2727 state->ev = s3_tevent_context_init(state);
2728 if (state->ev == NULL) {
2729 DEBUG(1, ("tevent_context_init failed\n"));
2730 TALLOC_FREE(state);
2731 return;
2733 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2734 TEVENT_FD_READ, smbd_echo_exit,
2735 state);
2736 if (state->parent_fde == NULL) {
2737 DEBUG(1, ("tevent_add_fd failed\n"));
2738 TALLOC_FREE(state);
2739 return;
2741 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2742 TEVENT_FD_READ, smbd_echo_reader,
2743 state);
2744 if (state->read_fde == NULL) {
2745 DEBUG(1, ("tevent_add_fd failed\n"));
2746 TALLOC_FREE(state);
2747 return;
2750 while (true) {
2751 if (tevent_loop_once(state->ev) == -1) {
2752 DEBUG(1, ("tevent_loop_once failed: %s\n",
2753 strerror(errno)));
2754 break;
2757 TALLOC_FREE(state);
2761 * Handle SMBecho requests in a forked child process
2763 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2765 int listener_pipe[2];
2766 int res;
2767 pid_t child;
2769 res = pipe(listener_pipe);
2770 if (res == -1) {
2771 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2772 return false;
2774 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2775 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2776 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2777 goto fail;
2780 child = sys_fork();
2781 if (child == 0) {
2782 NTSTATUS status;
2784 close(listener_pipe[0]);
2786 status = reinit_after_fork(smbd_messaging_context(),
2787 smbd_event_context(), false);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 DEBUG(1, ("reinit_after_fork failed: %s\n",
2790 nt_errstr(status)));
2791 exit(1);
2793 smbd_echo_loop(sconn, listener_pipe[1]);
2794 exit(0);
2796 close(listener_pipe[1]);
2797 listener_pipe[1] = -1;
2798 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2800 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2803 * Without smb signing this is the same as the normal smbd
2804 * listener. This needs to change once signing comes in.
2806 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2807 sconn,
2808 sconn->smb1.echo_handler.trusted_fd,
2809 EVENT_FD_READ,
2810 smbd_server_echo_handler,
2811 sconn);
2812 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2813 DEBUG(1, ("event_add_fd failed\n"));
2814 goto fail;
2817 return true;
2819 fail:
2820 if (listener_pipe[0] != -1) {
2821 close(listener_pipe[0]);
2823 if (listener_pipe[1] != -1) {
2824 close(listener_pipe[1]);
2826 sconn->smb1.echo_handler.trusted_fd = -1;
2827 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2828 close(sconn->smb1.echo_handler.socket_lock_fd);
2830 sconn->smb1.echo_handler.trusted_fd = -1;
2831 sconn->smb1.echo_handler.socket_lock_fd = -1;
2832 return false;
2835 /****************************************************************************
2836 Process commands from the client
2837 ****************************************************************************/
2839 void smbd_process(void)
2841 TALLOC_CTX *frame = talloc_stackframe();
2842 struct sockaddr_storage ss;
2843 struct sockaddr *sa = NULL;
2844 socklen_t sa_len;
2845 struct tsocket_address *local_address = NULL;
2846 struct tsocket_address *remote_address = NULL;
2847 const char *remaddr = NULL;
2848 int ret;
2850 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2851 lp_security() != SEC_SHARE &&
2852 !lp_async_smb_echo_handler()) {
2853 smbd_server_conn->allow_smb2 = true;
2856 /* Ensure child is set to blocking mode */
2857 set_blocking(smbd_server_fd(),True);
2859 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2860 set_socket_options(smbd_server_fd(), lp_socket_options());
2862 sa = (struct sockaddr *)(void *)&ss;
2863 sa_len = sizeof(ss);
2864 ret = getpeername(smbd_server_fd(), sa, &sa_len);
2865 if (ret != 0) {
2866 int level = (errno == ENOTCONN)?2:0;
2867 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2868 exit_server("getpeername() failed.\n");
2870 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2871 sa, sa_len,
2872 &remote_address);
2873 if (ret != 0) {
2874 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2875 __location__, strerror(errno)));
2876 exit_server("tsocket_address_bsd_from_sockaddr remote failed.\n");
2879 sa = (struct sockaddr *)(void *)&ss;
2880 sa_len = sizeof(ss);
2881 ret = getsockname(smbd_server_fd(), sa, &sa_len);
2882 if (ret != 0) {
2883 int level = (errno == ENOTCONN)?2:0;
2884 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2885 exit_server("getsockname() failed.\n");
2887 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2888 sa, sa_len,
2889 &local_address);
2890 if (ret != 0) {
2891 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2892 __location__, strerror(errno)));
2893 exit_server("tsocket_address_bsd_from_sockaddr remote failed.\n");
2896 smbd_server_conn->local_address = local_address;
2897 smbd_server_conn->remote_address = remote_address;
2899 if (tsocket_address_is_inet(remote_address, "ip")) {
2900 remaddr = tsocket_address_inet_addr_string(
2901 smbd_server_conn->remote_address,
2902 talloc_tos());
2903 if (remaddr == NULL) {
2906 } else {
2907 remaddr = "0.0.0.0";
2910 /* this is needed so that we get decent entries
2911 in smbstatus for port 445 connects */
2912 set_remote_machine_name(remaddr, false);
2913 reload_services(true);
2916 * Before the first packet, check the global hosts allow/ hosts deny
2917 * parameters before doing any parsing of packets passed to us by the
2918 * client. This prevents attacks on our parsing code from hosts not in
2919 * the hosts allow list.
2922 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2923 lp_hostsdeny(-1))) {
2925 * send a negative session response "not listening on calling
2926 * name"
2928 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2929 DEBUG( 1, ("Connection denied from %s to %s\n",
2930 tsocket_address_string(remote_address, talloc_tos()),
2931 tsocket_address_string(local_address, talloc_tos())));
2932 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2933 0, false, NULL);
2934 exit_server_cleanly("connection denied");
2937 DEBUG(10, ("Connection allowed from %s to %s\n",
2938 tsocket_address_string(remote_address, talloc_tos()),
2939 tsocket_address_string(local_address, talloc_tos())));
2941 static_init_rpc;
2943 init_modules();
2945 smb_perfcount_init();
2947 if (!init_account_policy()) {
2948 exit_server("Could not open account policy tdb.\n");
2951 if (*lp_rootdir()) {
2952 if (chroot(lp_rootdir()) != 0) {
2953 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2954 exit_server("Failed to chroot()");
2956 if (chdir("/") == -1) {
2957 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2958 exit_server("Failed to chroot()");
2960 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2963 if (!srv_init_signing(smbd_server_conn)) {
2964 exit_server("Failed to init smb_signing");
2967 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2968 exit_server("Failed to fork echo handler");
2971 /* Setup oplocks */
2972 if (!init_oplocks(smbd_messaging_context()))
2973 exit_server("Failed to init oplocks");
2975 /* register our message handlers */
2976 messaging_register(smbd_messaging_context(), NULL,
2977 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2978 messaging_register(smbd_messaging_context(), NULL,
2979 MSG_SMB_RELEASE_IP, msg_release_ip);
2980 messaging_register(smbd_messaging_context(), NULL,
2981 MSG_SMB_CLOSE_FILE, msg_close_file);
2984 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2985 * MSGs to all child processes
2987 messaging_deregister(smbd_messaging_context(),
2988 MSG_DEBUG, NULL);
2989 messaging_register(smbd_messaging_context(), NULL,
2990 MSG_DEBUG, debug_message);
2992 if ((lp_keepalive() != 0)
2993 && !(event_add_idle(smbd_event_context(), NULL,
2994 timeval_set(lp_keepalive(), 0),
2995 "keepalive", keepalive_fn,
2996 NULL))) {
2997 DEBUG(0, ("Could not add keepalive event\n"));
2998 exit(1);
3001 if (!(event_add_idle(smbd_event_context(), NULL,
3002 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3003 "deadtime", deadtime_fn, NULL))) {
3004 DEBUG(0, ("Could not add deadtime event\n"));
3005 exit(1);
3008 if (!(event_add_idle(smbd_event_context(), NULL,
3009 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3010 "housekeeping", housekeeping_fn, NULL))) {
3011 DEBUG(0, ("Could not add housekeeping event\n"));
3012 exit(1);
3015 #ifdef CLUSTER_SUPPORT
3017 if (lp_clustering()) {
3019 * We need to tell ctdb about our client's TCP
3020 * connection, so that for failover ctdbd can send
3021 * tickle acks, triggering a reconnection by the
3022 * client.
3025 struct sockaddr_storage srv, clnt;
3027 if (client_get_tcp_info(&srv, &clnt) == 0) {
3029 NTSTATUS status;
3031 status = ctdbd_register_ips(
3032 messaging_ctdbd_connection(),
3033 &srv, &clnt, release_ip, NULL);
3035 if (!NT_STATUS_IS_OK(status)) {
3036 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3037 nt_errstr(status)));
3039 } else
3041 DEBUG(0,("Unable to get tcp info for "
3042 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3043 strerror(errno)));
3047 #endif
3049 smbd_server_conn->nbt.got_session = false;
3051 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3053 smbd_server_conn->smb1.sessions.done_sesssetup = false;
3054 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
3055 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3056 /* users from session setup */
3057 smbd_server_conn->smb1.sessions.session_userlist = NULL;
3058 /* workgroup from session setup. */
3059 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
3060 /* this holds info on user ids that are already validated for this VC */
3061 smbd_server_conn->smb1.sessions.validated_users = NULL;
3062 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
3063 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
3064 #ifdef HAVE_NETGROUP
3065 smbd_server_conn->smb1.sessions.my_yp_domain = NULL;
3066 #endif
3068 conn_init(smbd_server_conn);
3069 if (!init_dptrs(smbd_server_conn)) {
3070 exit_server("init_dptrs() failed");
3073 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
3074 smbd_server_conn,
3075 smbd_server_fd(),
3076 EVENT_FD_READ,
3077 smbd_server_connection_handler,
3078 smbd_server_conn);
3079 if (!smbd_server_conn->smb1.fde) {
3080 exit_server("failed to create smbd_server_connection fde");
3083 TALLOC_FREE(frame);
3085 while (True) {
3086 NTSTATUS status;
3088 frame = talloc_stackframe_pool(8192);
3090 errno = 0;
3092 status = smbd_server_connection_loop_once(smbd_server_conn);
3093 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3094 !NT_STATUS_IS_OK(status)) {
3095 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3096 " exiting\n", nt_errstr(status)));
3097 break;
3100 TALLOC_FREE(frame);
3103 exit_server_cleanly(NULL);
3106 bool req_is_in_chain(struct smb_request *req)
3108 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3110 * We're right now handling a subsequent request, so we must
3111 * be in a chain
3113 return true;
3116 if (!is_andx_req(req->cmd)) {
3117 return false;
3120 if (req->wct < 2) {
3122 * Okay, an illegal request, but definitely not chained :-)
3124 return false;
3127 return (CVAL(req->vwv+0, 0) != 0xFF);