s3:configure: use correct SONAMEFLAG on Solaris depending on which linker is being...
[Samba.git] / source3 / smbd / process.c
blob128a612a86281259b8019f77354008594ecc84d5
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 (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
50 return true;
53 smbd_server_conn->smb1.echo_handler.ref_count++;
55 if (smbd_server_conn->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(smbd_server_conn->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 (smbd_server_conn->smb1.echo_handler.socket_lock_fd == -1) {
84 return true;
87 smbd_server_conn->smb1.echo_handler.ref_count--;
89 if (smbd_server_conn->smb1.echo_handler.ref_count > 0) {
90 return true;
93 ok = fcntl_lock(smbd_server_conn->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((uint8_t *)writeX_header)) {
268 * If the data offset is beyond what
269 * we've read, drain the extra bytes.
271 uint16_t doff = SVAL(writeX_header,smb_vwv11);
272 ssize_t newlen;
274 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
275 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
276 if (drain_socket(smbd_server_fd(), drain) != drain) {
277 smb_panic("receive_smb_raw_talloc_partial_read:"
278 " failed to drain pending bytes");
280 } else {
281 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
284 /* Spoof down the length and null out the bcc. */
285 set_message_bcc(writeX_header, 0);
286 newlen = smb_len(writeX_header);
288 /* Copy the header we've written. */
290 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
291 writeX_header,
292 sizeof(writeX_header));
294 if (*buffer == NULL) {
295 DEBUG(0, ("Could not allocate inbuf of length %d\n",
296 (int)sizeof(writeX_header)));
297 return NT_STATUS_NO_MEMORY;
300 /* Work out the remaining bytes. */
301 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
302 *len_ret = newlen + 4;
303 return NT_STATUS_OK;
306 if (!valid_packet_size(len)) {
307 return NT_STATUS_INVALID_PARAMETER;
311 * Not a valid writeX call. Just do the standard
312 * talloc and return.
315 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
317 if (*buffer == NULL) {
318 DEBUG(0, ("Could not allocate inbuf of length %d\n",
319 (int)len+4));
320 return NT_STATUS_NO_MEMORY;
323 /* Copy in what we already read. */
324 memcpy(*buffer,
325 writeX_header,
326 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
327 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
329 if(toread > 0) {
330 status = read_packet_remainder(
331 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
332 timeout, toread);
334 if (!NT_STATUS_IS_OK(status)) {
335 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
336 nt_errstr(status)));
337 return status;
341 *len_ret = len + 4;
342 return NT_STATUS_OK;
345 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
346 char **buffer, unsigned int timeout,
347 size_t *p_unread, size_t *plen)
349 char lenbuf[4];
350 size_t len;
351 int min_recv_size = lp_min_receive_file_size();
352 NTSTATUS status;
354 *p_unread = 0;
356 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
357 if (!NT_STATUS_IS_OK(status)) {
358 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
359 return status;
362 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
363 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
364 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
365 !srv_is_signing_active(smbd_server_conn) &&
366 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
368 return receive_smb_raw_talloc_partial_read(
369 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
372 if (!valid_packet_size(len)) {
373 return NT_STATUS_INVALID_PARAMETER;
377 * The +4 here can't wrap, we've checked the length above already.
380 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
382 if (*buffer == NULL) {
383 DEBUG(0, ("Could not allocate inbuf of length %d\n",
384 (int)len+4));
385 return NT_STATUS_NO_MEMORY;
388 memcpy(*buffer, lenbuf, sizeof(lenbuf));
390 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
391 if (!NT_STATUS_IS_OK(status)) {
392 return status;
395 *plen = len + 4;
396 return NT_STATUS_OK;
399 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
400 char **buffer, unsigned int timeout,
401 size_t *p_unread, bool *p_encrypted,
402 size_t *p_len,
403 uint32_t *seqnum,
404 bool trusted_channel)
406 size_t len = 0;
407 NTSTATUS status;
409 *p_encrypted = false;
411 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
412 p_unread, &len);
413 if (!NT_STATUS_IS_OK(status)) {
414 return status;
417 if (is_encrypted_packet((uint8_t *)*buffer)) {
418 status = srv_decrypt_buffer(*buffer);
419 if (!NT_STATUS_IS_OK(status)) {
420 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
421 "incoming packet! Error %s\n",
422 nt_errstr(status) ));
423 return status;
425 *p_encrypted = true;
428 /* Check the incoming SMB signature. */
429 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
430 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
431 "incoming packet!\n"));
432 return NT_STATUS_INVALID_NETWORK_RESPONSE;
435 *p_len = len;
436 return NT_STATUS_OK;
440 * Initialize a struct smb_request from an inbuf
443 static bool init_smb_request(struct smb_request *req, const uint8 *inbuf,
444 size_t unread_bytes, bool encrypted,
445 uint32_t seqnum)
447 struct smbd_server_connection *sconn = smbd_server_conn;
448 size_t req_size = smb_len(inbuf) + 4;
449 /* Ensure we have at least smb_size bytes. */
450 if (req_size < smb_size) {
451 DEBUG(0,("init_smb_request: invalid request size %u\n",
452 (unsigned int)req_size ));
453 return false;
455 req->cmd = CVAL(inbuf, smb_com);
456 req->flags2 = SVAL(inbuf, smb_flg2);
457 req->smbpid = SVAL(inbuf, smb_pid);
458 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
459 req->seqnum = seqnum;
460 req->vuid = SVAL(inbuf, smb_uid);
461 req->tid = SVAL(inbuf, smb_tid);
462 req->wct = CVAL(inbuf, smb_wct);
463 req->vwv = (uint16_t *)(inbuf+smb_vwv);
464 req->buflen = smb_buflen(inbuf);
465 req->buf = (const uint8_t *)smb_buf(inbuf);
466 req->unread_bytes = unread_bytes;
467 req->encrypted = encrypted;
468 req->conn = conn_find(sconn,req->tid);
469 req->chain_fsp = NULL;
470 req->chain_outbuf = NULL;
471 req->done = false;
472 req->smb2req = NULL;
473 smb_init_perfcount_data(&req->pcd);
475 /* Ensure we have at least wct words and 2 bytes of bcc. */
476 if (smb_size + req->wct*2 > req_size) {
477 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
478 (unsigned int)req->wct,
479 (unsigned int)req_size));
480 return false;
482 /* Ensure bcc is correct. */
483 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
484 DEBUG(0,("init_smb_request: invalid bcc number %u "
485 "(wct = %u, size %u)\n",
486 (unsigned int)req->buflen,
487 (unsigned int)req->wct,
488 (unsigned int)req_size));
489 return false;
492 req->outbuf = NULL;
493 return true;
496 static void process_smb(struct smbd_server_connection *conn,
497 uint8_t *inbuf, size_t nread, size_t unread_bytes,
498 uint32_t seqnum, bool encrypted,
499 struct smb_perfcount_data *deferred_pcd);
501 static void smbd_deferred_open_timer(struct event_context *ev,
502 struct timed_event *te,
503 struct timeval _tval,
504 void *private_data)
506 struct pending_message_list *msg = talloc_get_type(private_data,
507 struct pending_message_list);
508 TALLOC_CTX *mem_ctx = talloc_tos();
509 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
510 uint8_t *inbuf;
512 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
513 msg->buf.length);
514 if (inbuf == NULL) {
515 exit_server("smbd_deferred_open_timer: talloc failed\n");
516 return;
519 /* We leave this message on the queue so the open code can
520 know this is a retry. */
521 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
522 (unsigned long long)mid ));
524 /* Mark the message as processed so this is not
525 * re-processed in error. */
526 msg->processed = true;
528 process_smb(smbd_server_conn, inbuf,
529 msg->buf.length, 0,
530 msg->seqnum, msg->encrypted, &msg->pcd);
532 /* If it's still there and was processed, remove it. */
533 msg = get_deferred_open_message_smb(mid);
534 if (msg && msg->processed) {
535 remove_deferred_open_message_smb(mid);
539 /****************************************************************************
540 Function to push a message onto the tail of a linked list of smb messages ready
541 for processing.
542 ****************************************************************************/
544 static bool push_queued_message(struct smb_request *req,
545 struct timeval request_time,
546 struct timeval end_time,
547 char *private_data, size_t private_len)
549 int msg_len = smb_len(req->inbuf) + 4;
550 struct pending_message_list *msg;
552 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
554 if(msg == NULL) {
555 DEBUG(0,("push_message: malloc fail (1)\n"));
556 return False;
559 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
560 if(msg->buf.data == NULL) {
561 DEBUG(0,("push_message: malloc fail (2)\n"));
562 TALLOC_FREE(msg);
563 return False;
566 msg->request_time = request_time;
567 msg->seqnum = req->seqnum;
568 msg->encrypted = req->encrypted;
569 msg->processed = false;
570 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
572 if (private_data) {
573 msg->private_data = data_blob_talloc(msg, private_data,
574 private_len);
575 if (msg->private_data.data == NULL) {
576 DEBUG(0,("push_message: malloc fail (3)\n"));
577 TALLOC_FREE(msg);
578 return False;
582 msg->te = event_add_timed(smbd_event_context(),
583 msg,
584 end_time,
585 smbd_deferred_open_timer,
586 msg);
587 if (!msg->te) {
588 DEBUG(0,("push_message: event_add_timed failed\n"));
589 TALLOC_FREE(msg);
590 return false;
593 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
595 DEBUG(10,("push_message: pushed message length %u on "
596 "deferred_open_queue\n", (unsigned int)msg_len));
598 return True;
601 /****************************************************************************
602 Function to delete a sharing violation open message by mid.
603 ****************************************************************************/
605 void remove_deferred_open_message_smb(uint64_t mid)
607 struct pending_message_list *pml;
609 if (smbd_server_conn->allow_smb2) {
610 remove_deferred_open_message_smb2(mid);
611 return;
614 for (pml = deferred_open_queue; pml; pml = pml->next) {
615 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
616 DEBUG(10,("remove_deferred_open_message_smb: "
617 "deleting mid %llu len %u\n",
618 (unsigned long long)mid,
619 (unsigned int)pml->buf.length ));
620 DLIST_REMOVE(deferred_open_queue, pml);
621 TALLOC_FREE(pml);
622 return;
627 /****************************************************************************
628 Move a sharing violation open retry message to the front of the list and
629 schedule it for immediate processing.
630 ****************************************************************************/
632 void schedule_deferred_open_message_smb(uint64_t mid)
634 struct pending_message_list *pml;
635 int i = 0;
637 if (smbd_server_conn->allow_smb2) {
638 schedule_deferred_open_message_smb2(mid);
639 return;
642 for (pml = deferred_open_queue; pml; pml = pml->next) {
643 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
645 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
646 "msg_mid = %llu\n",
647 i++,
648 (unsigned long long)msg_mid ));
650 if (mid == msg_mid) {
651 struct timed_event *te;
653 if (pml->processed) {
654 /* A processed message should not be
655 * rescheduled. */
656 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
657 "message mid %llu was already processed\n",
658 (unsigned long long)msg_mid ));
659 continue;
662 DEBUG(10,("schedule_deferred_open_message_smb: "
663 "scheduling mid %llu\n",
664 (unsigned long long)mid ));
666 te = event_add_timed(smbd_event_context(),
667 pml,
668 timeval_zero(),
669 smbd_deferred_open_timer,
670 pml);
671 if (!te) {
672 DEBUG(10,("schedule_deferred_open_message_smb: "
673 "event_add_timed() failed, "
674 "skipping mid %llu\n",
675 (unsigned long long)msg_mid ));
678 TALLOC_FREE(pml->te);
679 pml->te = te;
680 DLIST_PROMOTE(deferred_open_queue, pml);
681 return;
685 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
686 "find message mid %llu\n",
687 (unsigned long long)mid ));
690 /****************************************************************************
691 Return true if this mid is on the deferred queue and was not yet processed.
692 ****************************************************************************/
694 bool open_was_deferred(uint64_t mid)
696 struct pending_message_list *pml;
698 if (smbd_server_conn->allow_smb2) {
699 return open_was_deferred_smb2(mid);
702 for (pml = deferred_open_queue; pml; pml = pml->next) {
703 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
704 return True;
707 return False;
710 /****************************************************************************
711 Return the message queued by this mid.
712 ****************************************************************************/
714 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
716 struct pending_message_list *pml;
718 for (pml = deferred_open_queue; pml; pml = pml->next) {
719 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
720 return pml;
723 return NULL;
726 /****************************************************************************
727 Get the state data queued by this mid.
728 ****************************************************************************/
730 bool get_deferred_open_message_state(struct smb_request *smbreq,
731 struct timeval *p_request_time,
732 void **pp_state)
734 struct pending_message_list *pml;
736 if (smbd_server_conn->allow_smb2) {
737 return get_deferred_open_message_state_smb2(smbreq->smb2req,
738 p_request_time,
739 pp_state);
742 pml = get_deferred_open_message_smb(smbreq->mid);
743 if (!pml) {
744 return false;
746 if (p_request_time) {
747 *p_request_time = pml->request_time;
749 if (pp_state) {
750 *pp_state = (void *)pml->private_data.data;
752 return true;
755 /****************************************************************************
756 Function to push a deferred open smb message onto a linked list of local smb
757 messages ready for processing.
758 ****************************************************************************/
760 bool push_deferred_open_message_smb(struct smb_request *req,
761 struct timeval request_time,
762 struct timeval timeout,
763 struct file_id id,
764 char *private_data, size_t priv_len)
766 struct timeval end_time;
768 if (req->smb2req) {
769 return push_deferred_open_message_smb2(req->smb2req,
770 request_time,
771 timeout,
773 private_data,
774 priv_len);
777 if (req->unread_bytes) {
778 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
779 "unread_bytes = %u\n",
780 (unsigned int)req->unread_bytes ));
781 smb_panic("push_deferred_open_message_smb: "
782 "logic error unread_bytes != 0" );
785 end_time = timeval_sum(&request_time, &timeout);
787 DEBUG(10,("push_deferred_open_message_smb: pushing message "
788 "len %u mid %llu timeout time [%u.%06u]\n",
789 (unsigned int) smb_len(req->inbuf)+4,
790 (unsigned long long)req->mid,
791 (unsigned int)end_time.tv_sec,
792 (unsigned int)end_time.tv_usec));
794 return push_queued_message(req, request_time, end_time,
795 private_data, priv_len);
798 struct idle_event {
799 struct timed_event *te;
800 struct timeval interval;
801 char *name;
802 bool (*handler)(const struct timeval *now, void *private_data);
803 void *private_data;
806 static void smbd_idle_event_handler(struct event_context *ctx,
807 struct timed_event *te,
808 struct timeval now,
809 void *private_data)
811 struct idle_event *event =
812 talloc_get_type_abort(private_data, struct idle_event);
814 TALLOC_FREE(event->te);
816 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
817 event->name, event->te));
819 if (!event->handler(&now, event->private_data)) {
820 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
821 event->name, event->te));
822 /* Don't repeat, delete ourselves */
823 TALLOC_FREE(event);
824 return;
827 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
828 event->name, event->te));
830 event->te = event_add_timed(ctx, event,
831 timeval_sum(&now, &event->interval),
832 smbd_idle_event_handler, event);
834 /* We can't do much but fail here. */
835 SMB_ASSERT(event->te != NULL);
838 struct idle_event *event_add_idle(struct event_context *event_ctx,
839 TALLOC_CTX *mem_ctx,
840 struct timeval interval,
841 const char *name,
842 bool (*handler)(const struct timeval *now,
843 void *private_data),
844 void *private_data)
846 struct idle_event *result;
847 struct timeval now = timeval_current();
849 result = TALLOC_P(mem_ctx, struct idle_event);
850 if (result == NULL) {
851 DEBUG(0, ("talloc failed\n"));
852 return NULL;
855 result->interval = interval;
856 result->handler = handler;
857 result->private_data = private_data;
859 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
860 DEBUG(0, ("talloc failed\n"));
861 TALLOC_FREE(result);
862 return NULL;
865 result->te = event_add_timed(event_ctx, result,
866 timeval_sum(&now, &interval),
867 smbd_idle_event_handler, result);
868 if (result->te == NULL) {
869 DEBUG(0, ("event_add_timed failed\n"));
870 TALLOC_FREE(result);
871 return NULL;
874 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
875 return result;
878 static void smbd_sig_term_handler(struct tevent_context *ev,
879 struct tevent_signal *se,
880 int signum,
881 int count,
882 void *siginfo,
883 void *private_data)
885 exit_server_cleanly("termination signal");
888 void smbd_setup_sig_term_handler(void)
890 struct tevent_signal *se;
892 se = tevent_add_signal(smbd_event_context(),
893 smbd_event_context(),
894 SIGTERM, 0,
895 smbd_sig_term_handler,
896 NULL);
897 if (!se) {
898 exit_server("failed to setup SIGTERM handler");
902 static void smbd_sig_hup_handler(struct tevent_context *ev,
903 struct tevent_signal *se,
904 int signum,
905 int count,
906 void *siginfo,
907 void *private_data)
909 change_to_root_user();
910 DEBUG(1,("Reloading services after SIGHUP\n"));
911 reload_services(False);
914 void smbd_setup_sig_hup_handler(void)
916 struct tevent_signal *se;
918 se = tevent_add_signal(smbd_event_context(),
919 smbd_event_context(),
920 SIGHUP, 0,
921 smbd_sig_hup_handler,
922 NULL);
923 if (!se) {
924 exit_server("failed to setup SIGHUP handler");
928 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
930 fd_set r_fds, w_fds;
931 int selrtn;
932 struct timeval to;
933 int maxfd = 0;
935 to.tv_sec = SMBD_SELECT_TIMEOUT;
936 to.tv_usec = 0;
939 * Setup the select fd sets.
942 FD_ZERO(&r_fds);
943 FD_ZERO(&w_fds);
946 * Are there any timed events waiting ? If so, ensure we don't
947 * select for longer than it would take to wait for them.
951 struct timeval now;
952 GetTimeOfDay(&now);
954 event_add_to_select_args(smbd_event_context(), &now,
955 &r_fds, &w_fds, &to, &maxfd);
958 /* Process a signal and timed events now... */
959 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
960 return NT_STATUS_RETRY;
964 int sav;
965 START_PROFILE(smbd_idle);
967 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
968 sav = errno;
970 END_PROFILE(smbd_idle);
971 errno = sav;
974 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
975 return NT_STATUS_RETRY;
978 /* Check if error */
979 if (selrtn == -1) {
980 /* something is wrong. Maybe the socket is dead? */
981 return map_nt_error_from_unix(errno);
984 /* Did we timeout ? */
985 if (selrtn == 0) {
986 return NT_STATUS_RETRY;
989 /* should not be reached */
990 return NT_STATUS_INTERNAL_ERROR;
994 * Only allow 5 outstanding trans requests. We're allocating memory, so
995 * prevent a DoS.
998 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1000 int count = 0;
1001 for (; list != NULL; list = list->next) {
1003 if (list->mid == mid) {
1004 return NT_STATUS_INVALID_PARAMETER;
1007 count += 1;
1009 if (count > 5) {
1010 return NT_STATUS_INSUFFICIENT_RESOURCES;
1013 return NT_STATUS_OK;
1017 These flags determine some of the permissions required to do an operation
1019 Note that I don't set NEED_WRITE on some write operations because they
1020 are used by some brain-dead clients when printing, and I don't want to
1021 force write permissions on print services.
1023 #define AS_USER (1<<0)
1024 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1025 #define TIME_INIT (1<<2)
1026 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1027 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1028 #define DO_CHDIR (1<<6)
1031 define a list of possible SMB messages and their corresponding
1032 functions. Any message that has a NULL function is unimplemented -
1033 please feel free to contribute implementations!
1035 static const struct smb_message_struct {
1036 const char *name;
1037 void (*fn)(struct smb_request *req);
1038 int flags;
1039 } smb_messages[256] = {
1041 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1042 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1043 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1044 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1045 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1046 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1047 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1048 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1049 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1050 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1051 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1052 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1053 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1054 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1055 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1056 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1057 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1058 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1059 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1060 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1061 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1062 /* 0x15 */ { NULL, NULL, 0 },
1063 /* 0x16 */ { NULL, NULL, 0 },
1064 /* 0x17 */ { NULL, NULL, 0 },
1065 /* 0x18 */ { NULL, NULL, 0 },
1066 /* 0x19 */ { NULL, NULL, 0 },
1067 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1068 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1069 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1070 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1071 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1072 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1073 /* 0x20 */ { "SMBwritec", NULL,0},
1074 /* 0x21 */ { NULL, NULL, 0 },
1075 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1076 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1077 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1078 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1079 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1080 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1081 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1082 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1083 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1084 /* 0x2b */ { "SMBecho",reply_echo,0},
1085 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1086 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1087 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1088 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1089 /* 0x30 */ { NULL, NULL, 0 },
1090 /* 0x31 */ { NULL, NULL, 0 },
1091 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1092 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1093 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1094 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1095 /* 0x36 */ { NULL, NULL, 0 },
1096 /* 0x37 */ { NULL, NULL, 0 },
1097 /* 0x38 */ { NULL, NULL, 0 },
1098 /* 0x39 */ { NULL, NULL, 0 },
1099 /* 0x3a */ { NULL, NULL, 0 },
1100 /* 0x3b */ { NULL, NULL, 0 },
1101 /* 0x3c */ { NULL, NULL, 0 },
1102 /* 0x3d */ { NULL, NULL, 0 },
1103 /* 0x3e */ { NULL, NULL, 0 },
1104 /* 0x3f */ { NULL, NULL, 0 },
1105 /* 0x40 */ { NULL, NULL, 0 },
1106 /* 0x41 */ { NULL, NULL, 0 },
1107 /* 0x42 */ { NULL, NULL, 0 },
1108 /* 0x43 */ { NULL, NULL, 0 },
1109 /* 0x44 */ { NULL, NULL, 0 },
1110 /* 0x45 */ { NULL, NULL, 0 },
1111 /* 0x46 */ { NULL, NULL, 0 },
1112 /* 0x47 */ { NULL, NULL, 0 },
1113 /* 0x48 */ { NULL, NULL, 0 },
1114 /* 0x49 */ { NULL, NULL, 0 },
1115 /* 0x4a */ { NULL, NULL, 0 },
1116 /* 0x4b */ { NULL, NULL, 0 },
1117 /* 0x4c */ { NULL, NULL, 0 },
1118 /* 0x4d */ { NULL, NULL, 0 },
1119 /* 0x4e */ { NULL, NULL, 0 },
1120 /* 0x4f */ { NULL, NULL, 0 },
1121 /* 0x50 */ { NULL, NULL, 0 },
1122 /* 0x51 */ { NULL, NULL, 0 },
1123 /* 0x52 */ { NULL, NULL, 0 },
1124 /* 0x53 */ { NULL, NULL, 0 },
1125 /* 0x54 */ { NULL, NULL, 0 },
1126 /* 0x55 */ { NULL, NULL, 0 },
1127 /* 0x56 */ { NULL, NULL, 0 },
1128 /* 0x57 */ { NULL, NULL, 0 },
1129 /* 0x58 */ { NULL, NULL, 0 },
1130 /* 0x59 */ { NULL, NULL, 0 },
1131 /* 0x5a */ { NULL, NULL, 0 },
1132 /* 0x5b */ { NULL, NULL, 0 },
1133 /* 0x5c */ { NULL, NULL, 0 },
1134 /* 0x5d */ { NULL, NULL, 0 },
1135 /* 0x5e */ { NULL, NULL, 0 },
1136 /* 0x5f */ { NULL, NULL, 0 },
1137 /* 0x60 */ { NULL, NULL, 0 },
1138 /* 0x61 */ { NULL, NULL, 0 },
1139 /* 0x62 */ { NULL, NULL, 0 },
1140 /* 0x63 */ { NULL, NULL, 0 },
1141 /* 0x64 */ { NULL, NULL, 0 },
1142 /* 0x65 */ { NULL, NULL, 0 },
1143 /* 0x66 */ { NULL, NULL, 0 },
1144 /* 0x67 */ { NULL, NULL, 0 },
1145 /* 0x68 */ { NULL, NULL, 0 },
1146 /* 0x69 */ { NULL, NULL, 0 },
1147 /* 0x6a */ { NULL, NULL, 0 },
1148 /* 0x6b */ { NULL, NULL, 0 },
1149 /* 0x6c */ { NULL, NULL, 0 },
1150 /* 0x6d */ { NULL, NULL, 0 },
1151 /* 0x6e */ { NULL, NULL, 0 },
1152 /* 0x6f */ { NULL, NULL, 0 },
1153 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1154 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1155 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1156 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1157 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1158 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1159 /* 0x76 */ { NULL, NULL, 0 },
1160 /* 0x77 */ { NULL, NULL, 0 },
1161 /* 0x78 */ { NULL, NULL, 0 },
1162 /* 0x79 */ { NULL, NULL, 0 },
1163 /* 0x7a */ { NULL, NULL, 0 },
1164 /* 0x7b */ { NULL, NULL, 0 },
1165 /* 0x7c */ { NULL, NULL, 0 },
1166 /* 0x7d */ { NULL, NULL, 0 },
1167 /* 0x7e */ { NULL, NULL, 0 },
1168 /* 0x7f */ { NULL, NULL, 0 },
1169 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1170 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1171 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1172 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1173 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1174 /* 0x85 */ { NULL, NULL, 0 },
1175 /* 0x86 */ { NULL, NULL, 0 },
1176 /* 0x87 */ { NULL, NULL, 0 },
1177 /* 0x88 */ { NULL, NULL, 0 },
1178 /* 0x89 */ { NULL, NULL, 0 },
1179 /* 0x8a */ { NULL, NULL, 0 },
1180 /* 0x8b */ { NULL, NULL, 0 },
1181 /* 0x8c */ { NULL, NULL, 0 },
1182 /* 0x8d */ { NULL, NULL, 0 },
1183 /* 0x8e */ { NULL, NULL, 0 },
1184 /* 0x8f */ { NULL, NULL, 0 },
1185 /* 0x90 */ { NULL, NULL, 0 },
1186 /* 0x91 */ { NULL, NULL, 0 },
1187 /* 0x92 */ { NULL, NULL, 0 },
1188 /* 0x93 */ { NULL, NULL, 0 },
1189 /* 0x94 */ { NULL, NULL, 0 },
1190 /* 0x95 */ { NULL, NULL, 0 },
1191 /* 0x96 */ { NULL, NULL, 0 },
1192 /* 0x97 */ { NULL, NULL, 0 },
1193 /* 0x98 */ { NULL, NULL, 0 },
1194 /* 0x99 */ { NULL, NULL, 0 },
1195 /* 0x9a */ { NULL, NULL, 0 },
1196 /* 0x9b */ { NULL, NULL, 0 },
1197 /* 0x9c */ { NULL, NULL, 0 },
1198 /* 0x9d */ { NULL, NULL, 0 },
1199 /* 0x9e */ { NULL, NULL, 0 },
1200 /* 0x9f */ { NULL, NULL, 0 },
1201 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1202 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1203 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1204 /* 0xa3 */ { NULL, NULL, 0 },
1205 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1206 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1207 /* 0xa6 */ { NULL, NULL, 0 },
1208 /* 0xa7 */ { NULL, NULL, 0 },
1209 /* 0xa8 */ { NULL, NULL, 0 },
1210 /* 0xa9 */ { NULL, NULL, 0 },
1211 /* 0xaa */ { NULL, NULL, 0 },
1212 /* 0xab */ { NULL, NULL, 0 },
1213 /* 0xac */ { NULL, NULL, 0 },
1214 /* 0xad */ { NULL, NULL, 0 },
1215 /* 0xae */ { NULL, NULL, 0 },
1216 /* 0xaf */ { NULL, NULL, 0 },
1217 /* 0xb0 */ { NULL, NULL, 0 },
1218 /* 0xb1 */ { NULL, NULL, 0 },
1219 /* 0xb2 */ { NULL, NULL, 0 },
1220 /* 0xb3 */ { NULL, NULL, 0 },
1221 /* 0xb4 */ { NULL, NULL, 0 },
1222 /* 0xb5 */ { NULL, NULL, 0 },
1223 /* 0xb6 */ { NULL, NULL, 0 },
1224 /* 0xb7 */ { NULL, NULL, 0 },
1225 /* 0xb8 */ { NULL, NULL, 0 },
1226 /* 0xb9 */ { NULL, NULL, 0 },
1227 /* 0xba */ { NULL, NULL, 0 },
1228 /* 0xbb */ { NULL, NULL, 0 },
1229 /* 0xbc */ { NULL, NULL, 0 },
1230 /* 0xbd */ { NULL, NULL, 0 },
1231 /* 0xbe */ { NULL, NULL, 0 },
1232 /* 0xbf */ { NULL, NULL, 0 },
1233 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1234 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1235 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1236 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1237 /* 0xc4 */ { NULL, NULL, 0 },
1238 /* 0xc5 */ { NULL, NULL, 0 },
1239 /* 0xc6 */ { NULL, NULL, 0 },
1240 /* 0xc7 */ { NULL, NULL, 0 },
1241 /* 0xc8 */ { NULL, NULL, 0 },
1242 /* 0xc9 */ { NULL, NULL, 0 },
1243 /* 0xca */ { NULL, NULL, 0 },
1244 /* 0xcb */ { NULL, NULL, 0 },
1245 /* 0xcc */ { NULL, NULL, 0 },
1246 /* 0xcd */ { NULL, NULL, 0 },
1247 /* 0xce */ { NULL, NULL, 0 },
1248 /* 0xcf */ { NULL, NULL, 0 },
1249 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1250 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1251 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1252 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1253 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1254 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1255 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1256 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1257 /* 0xd8 */ { NULL, NULL, 0 },
1258 /* 0xd9 */ { NULL, NULL, 0 },
1259 /* 0xda */ { NULL, NULL, 0 },
1260 /* 0xdb */ { NULL, NULL, 0 },
1261 /* 0xdc */ { NULL, NULL, 0 },
1262 /* 0xdd */ { NULL, NULL, 0 },
1263 /* 0xde */ { NULL, NULL, 0 },
1264 /* 0xdf */ { NULL, NULL, 0 },
1265 /* 0xe0 */ { NULL, NULL, 0 },
1266 /* 0xe1 */ { NULL, NULL, 0 },
1267 /* 0xe2 */ { NULL, NULL, 0 },
1268 /* 0xe3 */ { NULL, NULL, 0 },
1269 /* 0xe4 */ { NULL, NULL, 0 },
1270 /* 0xe5 */ { NULL, NULL, 0 },
1271 /* 0xe6 */ { NULL, NULL, 0 },
1272 /* 0xe7 */ { NULL, NULL, 0 },
1273 /* 0xe8 */ { NULL, NULL, 0 },
1274 /* 0xe9 */ { NULL, NULL, 0 },
1275 /* 0xea */ { NULL, NULL, 0 },
1276 /* 0xeb */ { NULL, NULL, 0 },
1277 /* 0xec */ { NULL, NULL, 0 },
1278 /* 0xed */ { NULL, NULL, 0 },
1279 /* 0xee */ { NULL, NULL, 0 },
1280 /* 0xef */ { NULL, NULL, 0 },
1281 /* 0xf0 */ { NULL, NULL, 0 },
1282 /* 0xf1 */ { NULL, NULL, 0 },
1283 /* 0xf2 */ { NULL, NULL, 0 },
1284 /* 0xf3 */ { NULL, NULL, 0 },
1285 /* 0xf4 */ { NULL, NULL, 0 },
1286 /* 0xf5 */ { NULL, NULL, 0 },
1287 /* 0xf6 */ { NULL, NULL, 0 },
1288 /* 0xf7 */ { NULL, NULL, 0 },
1289 /* 0xf8 */ { NULL, NULL, 0 },
1290 /* 0xf9 */ { NULL, NULL, 0 },
1291 /* 0xfa */ { NULL, NULL, 0 },
1292 /* 0xfb */ { NULL, NULL, 0 },
1293 /* 0xfc */ { NULL, NULL, 0 },
1294 /* 0xfd */ { NULL, NULL, 0 },
1295 /* 0xfe */ { NULL, NULL, 0 },
1296 /* 0xff */ { NULL, NULL, 0 }
1300 /*******************************************************************
1301 allocate and initialize a reply packet
1302 ********************************************************************/
1304 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1305 const char *inbuf, char **outbuf, uint8_t num_words,
1306 uint32_t num_bytes)
1309 * Protect against integer wrap
1311 if ((num_bytes > 0xffffff)
1312 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1313 char *msg;
1314 if (asprintf(&msg, "num_bytes too large: %u",
1315 (unsigned)num_bytes) == -1) {
1316 msg = CONST_DISCARD(char *, "num_bytes too large");
1318 smb_panic(msg);
1321 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1322 smb_size + num_words*2 + num_bytes);
1323 if (*outbuf == NULL) {
1324 return false;
1327 construct_reply_common(req, inbuf, *outbuf);
1328 srv_set_message(*outbuf, num_words, num_bytes, false);
1330 * Zero out the word area, the caller has to take care of the bcc area
1331 * himself
1333 if (num_words != 0) {
1334 memset(*outbuf + smb_vwv0, 0, num_words*2);
1337 return true;
1340 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1342 char *outbuf;
1343 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1344 num_bytes)) {
1345 smb_panic("could not allocate output buffer\n");
1347 req->outbuf = (uint8_t *)outbuf;
1351 /*******************************************************************
1352 Dump a packet to a file.
1353 ********************************************************************/
1355 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1357 int fd, i;
1358 char *fname = NULL;
1359 if (DEBUGLEVEL < 50) {
1360 return;
1363 if (len < 4) len = smb_len(data)+4;
1364 for (i=1;i<100;i++) {
1365 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1366 type ? "req" : "resp") == -1) {
1367 return;
1369 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1370 if (fd != -1 || errno != EEXIST) break;
1372 if (fd != -1) {
1373 ssize_t ret = write(fd, data, len);
1374 if (ret != len)
1375 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1376 close(fd);
1377 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1379 SAFE_FREE(fname);
1382 /****************************************************************************
1383 Prepare everything for calling the actual request function, and potentially
1384 call the request function via the "new" interface.
1386 Return False if the "legacy" function needs to be called, everything is
1387 prepared.
1389 Return True if we're done.
1391 I know this API sucks, but it is the one with the least code change I could
1392 find.
1393 ****************************************************************************/
1395 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1397 int flags;
1398 uint16 session_tag;
1399 connection_struct *conn = NULL;
1400 struct smbd_server_connection *sconn = smbd_server_conn;
1402 errno = 0;
1404 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1405 * so subtract 4 from it. */
1406 if (!valid_smb_header(req->inbuf)
1407 || (size < (smb_size - 4))) {
1408 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1409 smb_len(req->inbuf)));
1410 exit_server_cleanly("Non-SMB packet");
1413 if (smb_messages[type].fn == NULL) {
1414 DEBUG(0,("Unknown message type %d!\n",type));
1415 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1416 reply_unknown_new(req, type);
1417 return NULL;
1420 flags = smb_messages[type].flags;
1422 /* In share mode security we must ignore the vuid. */
1423 session_tag = (lp_security() == SEC_SHARE)
1424 ? UID_FIELD_INVALID : req->vuid;
1425 conn = req->conn;
1427 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1428 (int)sys_getpid(), (unsigned long)conn));
1430 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1432 /* Ensure this value is replaced in the incoming packet. */
1433 SSVAL(req->inbuf,smb_uid,session_tag);
1436 * Ensure the correct username is in current_user_info. This is a
1437 * really ugly bugfix for problems with multiple session_setup_and_X's
1438 * being done and allowing %U and %G substitutions to work correctly.
1439 * There is a reason this code is done here, don't move it unless you
1440 * know what you're doing... :-).
1441 * JRA.
1444 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1445 user_struct *vuser = NULL;
1447 sconn->smb1.sessions.last_session_tag = session_tag;
1448 if(session_tag != UID_FIELD_INVALID) {
1449 vuser = get_valid_user_struct(sconn, session_tag);
1450 if (vuser) {
1451 set_current_user_info(
1452 vuser->server_info->sanitized_username,
1453 vuser->server_info->unix_name,
1454 pdb_get_domain(vuser->server_info
1455 ->sam_account));
1460 /* Does this call need to be run as the connected user? */
1461 if (flags & AS_USER) {
1463 /* Does this call need a valid tree connection? */
1464 if (!conn) {
1466 * Amazingly, the error code depends on the command
1467 * (from Samba4).
1469 if (type == SMBntcreateX) {
1470 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1471 } else {
1472 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1474 return NULL;
1477 if (!change_to_user(conn,session_tag)) {
1478 DEBUG(0, ("Error: Could not change to user. Removing "
1479 "deferred open, mid=%llu.\n",
1480 (unsigned long long)req->mid));
1481 reply_force_doserror(req, ERRSRV, ERRbaduid);
1482 return conn;
1485 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1487 /* Does it need write permission? */
1488 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1489 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1490 return conn;
1493 /* IPC services are limited */
1494 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1495 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1496 return conn;
1498 } else {
1499 /* This call needs to be run as root */
1500 change_to_root_user();
1503 /* load service specific parameters */
1504 if (conn) {
1505 if (req->encrypted) {
1506 conn->encrypted_tid = true;
1507 /* encrypted required from now on. */
1508 conn->encrypt_level = Required;
1509 } else if (ENCRYPTION_REQUIRED(conn)) {
1510 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1511 exit_server_cleanly("encryption required "
1512 "on connection");
1513 return conn;
1517 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1518 (flags & (AS_USER|DO_CHDIR)
1519 ?True:False))) {
1520 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1521 return conn;
1523 conn->num_smb_operations++;
1526 /* does this protocol need to be run as guest? */
1527 if ((flags & AS_GUEST)
1528 && (!change_to_guest() ||
1529 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1530 lp_hostsdeny(-1)))) {
1531 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1532 return conn;
1535 smb_messages[type].fn(req);
1536 return req->conn;
1539 /****************************************************************************
1540 Construct a reply to the incoming packet.
1541 ****************************************************************************/
1543 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1544 uint32_t seqnum, bool encrypted,
1545 struct smb_perfcount_data *deferred_pcd)
1547 connection_struct *conn;
1548 struct smb_request *req;
1550 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1551 smb_panic("could not allocate smb_request");
1554 if (!init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted,
1555 seqnum)) {
1556 exit_server_cleanly("Invalid SMB request");
1559 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1561 /* we popped this message off the queue - keep original perf data */
1562 if (deferred_pcd)
1563 req->pcd = *deferred_pcd;
1564 else {
1565 SMB_PERFCOUNT_START(&req->pcd);
1566 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1567 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1570 conn = switch_message(req->cmd, req, size);
1572 if (req->unread_bytes) {
1573 /* writeX failed. drain socket. */
1574 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1575 req->unread_bytes) {
1576 smb_panic("failed to drain pending bytes");
1578 req->unread_bytes = 0;
1581 if (req->done) {
1582 TALLOC_FREE(req);
1583 return;
1586 if (req->outbuf == NULL) {
1587 return;
1590 if (CVAL(req->outbuf,0) == 0) {
1591 show_msg((char *)req->outbuf);
1594 if (!srv_send_smb(smbd_server_fd(),
1595 (char *)req->outbuf,
1596 true, req->seqnum+1,
1597 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1598 &req->pcd)) {
1599 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1602 TALLOC_FREE(req);
1604 return;
1607 /****************************************************************************
1608 Process an smb from the client
1609 ****************************************************************************/
1610 static void process_smb(struct smbd_server_connection *conn,
1611 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1612 uint32_t seqnum, bool encrypted,
1613 struct smb_perfcount_data *deferred_pcd)
1615 int msg_type = CVAL(inbuf,0);
1617 DO_PROFILE_INC(smb_count);
1619 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1620 smb_len(inbuf) ) );
1621 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1622 (int)nread,
1623 (unsigned int)unread_bytes ));
1625 if (msg_type != 0) {
1627 * NetBIOS session request, keepalive, etc.
1629 reply_special((char *)inbuf);
1630 goto done;
1633 if (smbd_server_conn->allow_smb2) {
1634 if (smbd_is_smb2_header(inbuf, nread)) {
1635 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1636 return;
1637 } else if (nread >= smb_size && valid_smb_header(inbuf)
1638 && CVAL(inbuf, smb_com) != 0x72) {
1639 /* This is a non-negprot SMB1 packet.
1640 Disable SMB2 from now on. */
1641 smbd_server_conn->allow_smb2 = false;
1645 show_msg((char *)inbuf);
1647 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1648 trans_num++;
1650 done:
1651 conn->smb1.num_requests++;
1653 /* The timeout_processing function isn't run nearly
1654 often enough to implement 'max log size' without
1655 overrunning the size of the file by many megabytes.
1656 This is especially true if we are running at debug
1657 level 10. Checking every 50 SMBs is a nice
1658 tradeoff of performance vs log file size overrun. */
1660 if ((conn->smb1.num_requests % 50) == 0 &&
1661 need_to_check_log_size()) {
1662 change_to_root_user();
1663 check_log_size();
1667 /****************************************************************************
1668 Return a string containing the function name of a SMB command.
1669 ****************************************************************************/
1671 const char *smb_fn_name(int type)
1673 const char *unknown_name = "SMBunknown";
1675 if (smb_messages[type].name == NULL)
1676 return(unknown_name);
1678 return(smb_messages[type].name);
1681 /****************************************************************************
1682 Helper functions for contruct_reply.
1683 ****************************************************************************/
1685 void add_to_common_flags2(uint32 v)
1687 common_flags2 |= v;
1690 void remove_from_common_flags2(uint32 v)
1692 common_flags2 &= ~v;
1695 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1696 char *outbuf)
1698 srv_set_message(outbuf,0,0,false);
1700 SCVAL(outbuf, smb_com, req->cmd);
1701 SIVAL(outbuf,smb_rcls,0);
1702 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1703 SSVAL(outbuf,smb_flg2,
1704 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1705 common_flags2);
1706 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1708 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1709 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1710 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1711 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1714 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1716 construct_reply_common(req, (char *)req->inbuf, outbuf);
1720 * How many bytes have we already accumulated up to the current wct field
1721 * offset?
1724 size_t req_wct_ofs(struct smb_request *req)
1726 size_t buf_size;
1728 if (req->chain_outbuf == NULL) {
1729 return smb_wct - 4;
1731 buf_size = talloc_get_size(req->chain_outbuf);
1732 if ((buf_size % 4) != 0) {
1733 buf_size += (4 - (buf_size % 4));
1735 return buf_size - 4;
1739 * Hack around reply_nterror & friends not being aware of chained requests,
1740 * generating illegal (i.e. wct==0) chain replies.
1743 static void fixup_chain_error_packet(struct smb_request *req)
1745 uint8_t *outbuf = req->outbuf;
1746 req->outbuf = NULL;
1747 reply_outbuf(req, 2, 0);
1748 memcpy(req->outbuf, outbuf, smb_wct);
1749 TALLOC_FREE(outbuf);
1750 SCVAL(req->outbuf, smb_vwv0, 0xff);
1754 * @brief Find the smb_cmd offset of the last command pushed
1755 * @param[in] buf The buffer we're building up
1756 * @retval Where can we put our next andx cmd?
1758 * While chaining requests, the "next" request we're looking at needs to put
1759 * its SMB_Command before the data the previous request already built up added
1760 * to the chain. Find the offset to the place where we have to put our cmd.
1763 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1765 uint8_t cmd;
1766 size_t ofs;
1768 cmd = CVAL(buf, smb_com);
1770 SMB_ASSERT(is_andx_req(cmd));
1772 ofs = smb_vwv0;
1774 while (CVAL(buf, ofs) != 0xff) {
1776 if (!is_andx_req(CVAL(buf, ofs))) {
1777 return false;
1781 * ofs is from start of smb header, so add the 4 length
1782 * bytes. The next cmd is right after the wct field.
1784 ofs = SVAL(buf, ofs+2) + 4 + 1;
1786 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1789 *pofs = ofs;
1790 return true;
1794 * @brief Do the smb chaining at a buffer level
1795 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1796 * @param[in] smb_command The command that we want to issue
1797 * @param[in] wct How many words?
1798 * @param[in] vwv The words, already in network order
1799 * @param[in] bytes_alignment How shall we align "bytes"?
1800 * @param[in] num_bytes How many bytes?
1801 * @param[in] bytes The data the request ships
1803 * smb_splice_chain() adds the vwv and bytes to the request already present in
1804 * *poutbuf.
1807 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1808 uint8_t wct, const uint16_t *vwv,
1809 size_t bytes_alignment,
1810 uint32_t num_bytes, const uint8_t *bytes)
1812 uint8_t *outbuf;
1813 size_t old_size, new_size;
1814 size_t ofs;
1815 size_t chain_padding = 0;
1816 size_t bytes_padding = 0;
1817 bool first_request;
1819 old_size = talloc_get_size(*poutbuf);
1822 * old_size == smb_wct means we're pushing the first request in for
1823 * libsmb/
1826 first_request = (old_size == smb_wct);
1828 if (!first_request && ((old_size % 4) != 0)) {
1830 * Align the wct field of subsequent requests to a 4-byte
1831 * boundary
1833 chain_padding = 4 - (old_size % 4);
1837 * After the old request comes the new wct field (1 byte), the vwv's
1838 * and the num_bytes field. After at we might need to align the bytes
1839 * given to us to "bytes_alignment", increasing the num_bytes value.
1842 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1844 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1845 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1848 new_size += bytes_padding + num_bytes;
1850 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1851 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1852 (unsigned)new_size));
1853 return false;
1856 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1857 if (outbuf == NULL) {
1858 DEBUG(0, ("talloc failed\n"));
1859 return false;
1861 *poutbuf = outbuf;
1863 if (first_request) {
1864 SCVAL(outbuf, smb_com, smb_command);
1865 } else {
1866 size_t andx_cmd_ofs;
1868 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1869 DEBUG(1, ("invalid command chain\n"));
1870 *poutbuf = TALLOC_REALLOC_ARRAY(
1871 NULL, *poutbuf, uint8_t, old_size);
1872 return false;
1875 if (chain_padding != 0) {
1876 memset(outbuf + old_size, 0, chain_padding);
1877 old_size += chain_padding;
1880 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1881 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1884 ofs = old_size;
1887 * Push the chained request:
1889 * wct field
1892 SCVAL(outbuf, ofs, wct);
1893 ofs += 1;
1896 * vwv array
1899 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1900 ofs += sizeof(uint16_t) * wct;
1903 * bcc (byte count)
1906 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1907 ofs += sizeof(uint16_t);
1910 * padding
1913 if (bytes_padding != 0) {
1914 memset(outbuf + ofs, 0, bytes_padding);
1915 ofs += bytes_padding;
1919 * The bytes field
1922 memcpy(outbuf + ofs, bytes, num_bytes);
1924 return true;
1927 /****************************************************************************
1928 Construct a chained reply and add it to the already made reply
1929 ****************************************************************************/
1931 void chain_reply(struct smb_request *req)
1933 size_t smblen = smb_len(req->inbuf);
1934 size_t already_used, length_needed;
1935 uint8_t chain_cmd;
1936 uint32_t chain_offset; /* uint32_t to avoid overflow */
1938 uint8_t wct;
1939 uint16_t *vwv;
1940 uint16_t buflen;
1941 uint8_t *buf;
1943 if (IVAL(req->outbuf, smb_rcls) != 0) {
1944 fixup_chain_error_packet(req);
1948 * Any of the AndX requests and replies have at least a wct of
1949 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1950 * beginning of the SMB header to the next wct field.
1952 * None of the AndX requests put anything valuable in vwv[0] and [1],
1953 * so we can overwrite it here to form the chain.
1956 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1957 if (req->chain_outbuf == NULL) {
1958 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1959 req, req->outbuf, uint8_t,
1960 smb_len(req->outbuf) + 4);
1961 if (req->chain_outbuf == NULL) {
1962 smb_panic("talloc failed");
1965 req->outbuf = NULL;
1966 goto error;
1970 * Here we assume that this is the end of the chain. For that we need
1971 * to set "next command" to 0xff and the offset to 0. If we later find
1972 * more commands in the chain, this will be overwritten again.
1975 SCVAL(req->outbuf, smb_vwv0, 0xff);
1976 SCVAL(req->outbuf, smb_vwv0+1, 0);
1977 SSVAL(req->outbuf, smb_vwv1, 0);
1979 if (req->chain_outbuf == NULL) {
1981 * In req->chain_outbuf we collect all the replies. Start the
1982 * chain by copying in the first reply.
1984 * We do the realloc because later on we depend on
1985 * talloc_get_size to determine the length of
1986 * chain_outbuf. The reply_xxx routines might have
1987 * over-allocated (reply_pipe_read_and_X used to be such an
1988 * example).
1990 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1991 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1992 if (req->chain_outbuf == NULL) {
1993 smb_panic("talloc failed");
1995 req->outbuf = NULL;
1996 } else {
1998 * Update smb headers where subsequent chained commands
1999 * may have updated them.
2001 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2002 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2004 if (!smb_splice_chain(&req->chain_outbuf,
2005 CVAL(req->outbuf, smb_com),
2006 CVAL(req->outbuf, smb_wct),
2007 (uint16_t *)(req->outbuf + smb_vwv),
2008 0, smb_buflen(req->outbuf),
2009 (uint8_t *)smb_buf(req->outbuf))) {
2010 goto error;
2012 TALLOC_FREE(req->outbuf);
2016 * We use the old request's vwv field to grab the next chained command
2017 * and offset into the chained fields.
2020 chain_cmd = CVAL(req->vwv+0, 0);
2021 chain_offset = SVAL(req->vwv+1, 0);
2023 if (chain_cmd == 0xff) {
2025 * End of chain, no more requests from the client. So ship the
2026 * replies.
2028 smb_setlen((char *)(req->chain_outbuf),
2029 talloc_get_size(req->chain_outbuf) - 4);
2031 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2032 true, req->seqnum+1,
2033 IS_CONN_ENCRYPTED(req->conn)
2034 ||req->encrypted,
2035 &req->pcd)) {
2036 exit_server_cleanly("chain_reply: srv_send_smb "
2037 "failed.");
2039 TALLOC_FREE(req->chain_outbuf);
2040 req->done = true;
2041 return;
2044 /* add a new perfcounter for this element of chain */
2045 SMB_PERFCOUNT_ADD(&req->pcd);
2046 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2047 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2050 * Check if the client tries to fool us. The request so far uses the
2051 * space to the end of the byte buffer in the request just
2052 * processed. The chain_offset can't point into that area. If that was
2053 * the case, we could end up with an endless processing of the chain,
2054 * we would always handle the same request.
2057 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2058 if (chain_offset < already_used) {
2059 goto error;
2063 * Next check: Make sure the chain offset does not point beyond the
2064 * overall smb request length.
2067 length_needed = chain_offset+1; /* wct */
2068 if (length_needed > smblen) {
2069 goto error;
2073 * Now comes the pointer magic. Goal here is to set up req->vwv and
2074 * req->buf correctly again to be able to call the subsequent
2075 * switch_message(). The chain offset (the former vwv[1]) points at
2076 * the new wct field.
2079 wct = CVAL(smb_base(req->inbuf), chain_offset);
2082 * Next consistency check: Make the new vwv array fits in the overall
2083 * smb request.
2086 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2087 if (length_needed > smblen) {
2088 goto error;
2090 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2093 * Now grab the new byte buffer....
2096 buflen = SVAL(vwv+wct, 0);
2099 * .. and check that it fits.
2102 length_needed += buflen;
2103 if (length_needed > smblen) {
2104 goto error;
2106 buf = (uint8_t *)(vwv+wct+1);
2108 req->cmd = chain_cmd;
2109 req->wct = wct;
2110 req->vwv = vwv;
2111 req->buflen = buflen;
2112 req->buf = buf;
2114 switch_message(chain_cmd, req, smblen);
2116 if (req->outbuf == NULL) {
2118 * This happens if the chained command has suspended itself or
2119 * if it has called srv_send_smb() itself.
2121 return;
2125 * We end up here if the chained command was not itself chained or
2126 * suspended, but for example a close() command. We now need to splice
2127 * the chained commands' outbuf into the already built up chain_outbuf
2128 * and ship the result.
2130 goto done;
2132 error:
2134 * We end up here if there's any error in the chain syntax. Report a
2135 * DOS error, just like Windows does.
2137 reply_force_doserror(req, ERRSRV, ERRerror);
2138 fixup_chain_error_packet(req);
2140 done:
2142 * This scary statement intends to set the
2143 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2144 * to the value req->outbuf carries
2146 SSVAL(req->chain_outbuf, smb_flg2,
2147 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2148 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2151 * Transfer the error codes from the subrequest to the main one
2153 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2154 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2156 if (!smb_splice_chain(&req->chain_outbuf,
2157 CVAL(req->outbuf, smb_com),
2158 CVAL(req->outbuf, smb_wct),
2159 (uint16_t *)(req->outbuf + smb_vwv),
2160 0, smb_buflen(req->outbuf),
2161 (uint8_t *)smb_buf(req->outbuf))) {
2162 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2164 TALLOC_FREE(req->outbuf);
2166 smb_setlen((char *)(req->chain_outbuf),
2167 talloc_get_size(req->chain_outbuf) - 4);
2169 show_msg((char *)(req->chain_outbuf));
2171 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2172 true, req->seqnum+1,
2173 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2174 &req->pcd)) {
2175 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2177 TALLOC_FREE(req->chain_outbuf);
2178 req->done = true;
2181 /****************************************************************************
2182 Check if services need reloading.
2183 ****************************************************************************/
2185 void check_reload(time_t t)
2187 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2189 if(last_smb_conf_reload_time == 0) {
2190 last_smb_conf_reload_time = t;
2191 /* Our printing subsystem might not be ready at smbd start up.
2192 Then no printer is available till the first printers check
2193 is performed. A lower initial interval circumvents this. */
2194 if ( printcap_cache_time > 60 )
2195 last_printer_reload_time = t - printcap_cache_time + 60;
2196 else
2197 last_printer_reload_time = t;
2200 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2201 /* randomize over 60 second the printcap reload to avoid all
2202 * process hitting cupsd at the same time */
2203 int time_range = 60;
2205 last_printer_reload_time += random() % time_range;
2206 mypid = getpid();
2209 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2210 reload_services(True);
2211 last_smb_conf_reload_time = t;
2214 /* 'printcap cache time = 0' disable the feature */
2216 if ( printcap_cache_time != 0 )
2218 /* see if it's time to reload or if the clock has been set back */
2220 if ( (t >= last_printer_reload_time+printcap_cache_time)
2221 || (t-last_printer_reload_time < 0) )
2223 DEBUG( 3,( "Printcap cache time expired.\n"));
2224 reload_printers();
2225 last_printer_reload_time = t;
2230 static bool fd_is_readable(int fd)
2232 fd_set fds;
2233 struct timeval timeout = {0, };
2234 int ret;
2236 FD_ZERO(&fds);
2237 FD_SET(fd, &fds);
2239 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2240 if (ret == -1) {
2241 return false;
2243 return FD_ISSET(fd, &fds);
2246 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2248 /* TODO: make write nonblocking */
2251 static void smbd_server_connection_read_handler(
2252 struct smbd_server_connection *conn, int fd)
2254 uint8_t *inbuf = NULL;
2255 size_t inbuf_len = 0;
2256 size_t unread_bytes = 0;
2257 bool encrypted = false;
2258 TALLOC_CTX *mem_ctx = talloc_tos();
2259 NTSTATUS status;
2260 uint32_t seqnum;
2262 bool from_client = (smbd_server_fd() == fd)?true:false;
2264 if (from_client) {
2265 smbd_lock_socket(conn);
2267 if (!fd_is_readable(smbd_server_fd())) {
2268 DEBUG(10,("the echo listener was faster\n"));
2269 smbd_unlock_socket(conn);
2270 return;
2273 /* TODO: make this completely nonblocking */
2274 status = receive_smb_talloc(mem_ctx, fd,
2275 (char **)(void *)&inbuf,
2276 0, /* timeout */
2277 &unread_bytes,
2278 &encrypted,
2279 &inbuf_len, &seqnum,
2280 false /* trusted channel */);
2281 smbd_unlock_socket(conn);
2282 } else {
2283 /* TODO: make this completely nonblocking */
2284 status = receive_smb_talloc(mem_ctx, fd,
2285 (char **)(void *)&inbuf,
2286 0, /* timeout */
2287 &unread_bytes,
2288 &encrypted,
2289 &inbuf_len, &seqnum,
2290 true /* trusted channel */);
2293 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2294 goto process;
2296 if (NT_STATUS_IS_ERR(status)) {
2297 exit_server_cleanly("failed to receive smb request");
2299 if (!NT_STATUS_IS_OK(status)) {
2300 return;
2303 process:
2304 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2305 seqnum, encrypted, NULL);
2308 static void smbd_server_connection_handler(struct event_context *ev,
2309 struct fd_event *fde,
2310 uint16_t flags,
2311 void *private_data)
2313 struct smbd_server_connection *conn = talloc_get_type(private_data,
2314 struct smbd_server_connection);
2316 if (flags & EVENT_FD_WRITE) {
2317 smbd_server_connection_write_handler(conn);
2318 } else if (flags & EVENT_FD_READ) {
2319 smbd_server_connection_read_handler(conn, smbd_server_fd());
2323 static void smbd_server_echo_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(
2335 conn, conn->smb1.echo_handler.trusted_fd);
2339 /****************************************************************************
2340 received when we should release a specific IP
2341 ****************************************************************************/
2342 static void release_ip(const char *ip, void *priv)
2344 char addr[INET6_ADDRSTRLEN];
2345 char *p = addr;
2347 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2349 if (strncmp("::ffff:", addr, 7) == 0) {
2350 p = addr + 7;
2353 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2354 /* we can't afford to do a clean exit - that involves
2355 database writes, which would potentially mean we
2356 are still running after the failover has finished -
2357 we have to get rid of this process ID straight
2358 away */
2359 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2360 ip));
2361 /* note we must exit with non-zero status so the unclean handler gets
2362 called in the parent, so that the brl database is tickled */
2363 _exit(1);
2367 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2368 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2370 release_ip((char *)data->data, NULL);
2373 #ifdef CLUSTER_SUPPORT
2374 static int client_get_tcp_info(struct sockaddr_storage *server,
2375 struct sockaddr_storage *client)
2377 socklen_t length;
2378 if (server_fd == -1) {
2379 return -1;
2381 length = sizeof(*server);
2382 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2383 return -1;
2385 length = sizeof(*client);
2386 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2387 return -1;
2389 return 0;
2391 #endif
2394 * Send keepalive packets to our client
2396 static bool keepalive_fn(const struct timeval *now, void *private_data)
2398 bool ret;
2400 smbd_lock_socket(smbd_server_conn);
2401 ret = send_keepalive(smbd_server_fd());
2402 smbd_unlock_socket(smbd_server_conn);
2404 if (!ret) {
2405 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2406 return False;
2408 return True;
2412 * Do the recurring check if we're idle
2414 static bool deadtime_fn(const struct timeval *now, void *private_data)
2416 struct smbd_server_connection *sconn = smbd_server_conn;
2418 if (sconn->allow_smb2) {
2419 /* TODO: implement real idle check */
2420 if (sconn->smb2.sessions.list) {
2421 return true;
2423 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2424 messaging_send(smbd_messaging_context(), procid_self(),
2425 MSG_SHUTDOWN, &data_blob_null);
2426 return false;
2429 if ((conn_num_open(sconn) == 0)
2430 || (conn_idle_all(sconn, now->tv_sec))) {
2431 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2432 messaging_send(smbd_messaging_context(), procid_self(),
2433 MSG_SHUTDOWN, &data_blob_null);
2434 return False;
2437 return True;
2441 * Do the recurring log file and smb.conf reload checks.
2444 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2446 change_to_root_user();
2448 /* update printer queue caches if necessary */
2449 update_monitored_printq_cache();
2451 /* check if we need to reload services */
2452 check_reload(time(NULL));
2454 /* Change machine password if neccessary. */
2455 attempt_machine_password_change();
2458 * Force a log file check.
2460 force_check_log_size();
2461 check_log_size();
2462 return true;
2465 static int create_unlink_tmp(const char *dir)
2467 char *fname;
2468 int fd;
2470 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2471 if (fname == NULL) {
2472 errno = ENOMEM;
2473 return -1;
2475 fd = mkstemp(fname);
2476 if (fd == -1) {
2477 TALLOC_FREE(fname);
2478 return -1;
2480 if (unlink(fname) == -1) {
2481 int sys_errno = errno;
2482 close(fd);
2483 TALLOC_FREE(fname);
2484 errno = sys_errno;
2485 return -1;
2487 TALLOC_FREE(fname);
2488 return fd;
2491 struct smbd_echo_state {
2492 struct tevent_context *ev;
2493 struct iovec *pending;
2494 struct smbd_server_connection *sconn;
2495 int parent_pipe;
2497 struct tevent_fd *parent_fde;
2499 struct tevent_fd *read_fde;
2500 struct tevent_req *write_req;
2503 static void smbd_echo_writer_done(struct tevent_req *req);
2505 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2507 int num_pending;
2509 if (state->write_req != NULL) {
2510 return;
2513 num_pending = talloc_array_length(state->pending);
2514 if (num_pending == 0) {
2515 return;
2518 state->write_req = writev_send(state, state->ev, NULL,
2519 state->parent_pipe, false,
2520 state->pending, num_pending);
2521 if (state->write_req == NULL) {
2522 DEBUG(1, ("writev_send failed\n"));
2523 exit(1);
2526 talloc_steal(state->write_req, state->pending);
2527 state->pending = NULL;
2529 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2530 state);
2533 static void smbd_echo_writer_done(struct tevent_req *req)
2535 struct smbd_echo_state *state = tevent_req_callback_data(
2536 req, struct smbd_echo_state);
2537 ssize_t written;
2538 int err;
2540 written = writev_recv(req, &err);
2541 TALLOC_FREE(req);
2542 state->write_req = NULL;
2543 if (written == -1) {
2544 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2545 exit(1);
2547 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2548 smbd_echo_activate_writer(state);
2551 static bool smbd_echo_reply(int fd,
2552 uint8_t *inbuf, size_t inbuf_len,
2553 uint32_t seqnum)
2555 struct smb_request req;
2556 uint16_t num_replies;
2557 size_t out_len;
2558 char *outbuf;
2559 bool ok;
2561 if (inbuf_len < smb_size) {
2562 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2563 return false;
2565 if (!valid_smb_header(inbuf)) {
2566 DEBUG(10, ("Got invalid SMB header\n"));
2567 return false;
2570 if (!init_smb_request(&req, inbuf, 0, false, seqnum)) {
2571 return false;
2573 req.inbuf = inbuf;
2575 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2576 smb_messages[req.cmd].name
2577 ? smb_messages[req.cmd].name : "unknown"));
2579 if (req.cmd != SMBecho) {
2580 return false;
2582 if (req.wct < 1) {
2583 return false;
2586 num_replies = SVAL(req.vwv+0, 0);
2587 if (num_replies != 1) {
2588 /* Not a Windows "Hey, you're still there?" request */
2589 return false;
2592 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2593 1, req.buflen)) {
2594 DEBUG(10, ("create_outbuf failed\n"));
2595 return false;
2597 req.outbuf = (uint8_t *)outbuf;
2599 SSVAL(req.outbuf, smb_vwv0, num_replies);
2601 if (req.buflen > 0) {
2602 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2605 out_len = smb_len(req.outbuf) + 4;
2607 ok = srv_send_smb(smbd_server_fd(),
2608 (char *)outbuf,
2609 true, seqnum+1,
2610 false, &req.pcd);
2611 TALLOC_FREE(outbuf);
2612 if (!ok) {
2613 exit(1);
2616 return true;
2619 static void smbd_echo_exit(struct tevent_context *ev,
2620 struct tevent_fd *fde, uint16_t flags,
2621 void *private_data)
2623 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2624 exit(0);
2627 static void smbd_echo_reader(struct tevent_context *ev,
2628 struct tevent_fd *fde, uint16_t flags,
2629 void *private_data)
2631 struct smbd_echo_state *state = talloc_get_type_abort(
2632 private_data, struct smbd_echo_state);
2633 struct smbd_server_connection *sconn = state->sconn;
2634 size_t unread, num_pending;
2635 NTSTATUS status;
2636 struct iovec *tmp;
2637 uint32_t seqnum = 0;
2638 bool reply;
2639 bool ok;
2640 bool encrypted = false;
2642 ok = smbd_lock_socket_internal(sconn);
2643 if (!ok) {
2644 DEBUG(0, ("%s: failed to lock socket\n",
2645 __location__));
2646 exit(1);
2649 if (!fd_is_readable(smbd_server_fd())) {
2650 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2651 (int)sys_getpid()));
2652 ok = smbd_unlock_socket_internal(sconn);
2653 if (!ok) {
2654 DEBUG(1, ("%s: failed to unlock socket in\n",
2655 __location__));
2656 exit(1);
2658 return;
2661 num_pending = talloc_array_length(state->pending);
2662 tmp = talloc_realloc(state, state->pending, struct iovec,
2663 num_pending+1);
2664 if (tmp == NULL) {
2665 DEBUG(1, ("talloc_realloc failed\n"));
2666 exit(1);
2668 state->pending = tmp;
2670 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2672 status = receive_smb_talloc(state, smbd_server_fd(),
2673 (char **)(void *)&state->pending[num_pending].iov_base,
2674 0 /* timeout */,
2675 &unread,
2676 &encrypted,
2677 &state->pending[num_pending].iov_len,
2678 &seqnum,
2679 false /* trusted_channel*/);
2680 if (!NT_STATUS_IS_OK(status)) {
2681 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2682 (int)sys_getpid(), nt_errstr(status)));
2683 exit(1);
2686 ok = smbd_unlock_socket_internal(sconn);
2687 if (!ok) {
2688 DEBUG(1, ("%s: failed to unlock socket in\n",
2689 __location__));
2690 exit(1);
2694 * place the seqnum in the packet so that the main process can reply
2695 * with signing
2697 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2698 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2700 reply = smbd_echo_reply(smbd_server_fd(),
2701 (uint8_t *)state->pending[num_pending].iov_base,
2702 state->pending[num_pending].iov_len,
2703 seqnum);
2704 if (reply) {
2705 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2706 /* no check, shrinking by some bytes does not fail */
2707 state->pending = talloc_realloc(state, state->pending,
2708 struct iovec,
2709 num_pending);
2710 } else {
2711 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2712 smbd_echo_activate_writer(state);
2716 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2717 int parent_pipe)
2719 struct smbd_echo_state *state;
2721 state = talloc_zero(sconn, struct smbd_echo_state);
2722 if (state == NULL) {
2723 DEBUG(1, ("talloc failed\n"));
2724 return;
2726 state->sconn = sconn;
2727 state->parent_pipe = parent_pipe;
2728 state->ev = s3_tevent_context_init(state);
2729 if (state->ev == NULL) {
2730 DEBUG(1, ("tevent_context_init failed\n"));
2731 TALLOC_FREE(state);
2732 return;
2734 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2735 TEVENT_FD_READ, smbd_echo_exit,
2736 state);
2737 if (state->parent_fde == NULL) {
2738 DEBUG(1, ("tevent_add_fd failed\n"));
2739 TALLOC_FREE(state);
2740 return;
2742 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2743 TEVENT_FD_READ, smbd_echo_reader,
2744 state);
2745 if (state->read_fde == NULL) {
2746 DEBUG(1, ("tevent_add_fd failed\n"));
2747 TALLOC_FREE(state);
2748 return;
2751 while (true) {
2752 if (tevent_loop_once(state->ev) == -1) {
2753 DEBUG(1, ("tevent_loop_once failed: %s\n",
2754 strerror(errno)));
2755 break;
2758 TALLOC_FREE(state);
2762 * Handle SMBecho requests in a forked child process
2764 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2766 int listener_pipe[2];
2767 int res;
2768 pid_t child;
2770 res = pipe(listener_pipe);
2771 if (res == -1) {
2772 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2773 return false;
2775 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2776 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2777 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2778 goto fail;
2781 child = sys_fork();
2782 if (child == 0) {
2783 NTSTATUS status;
2785 close(listener_pipe[0]);
2787 status = reinit_after_fork(smbd_messaging_context(),
2788 smbd_event_context(), false);
2789 if (!NT_STATUS_IS_OK(status)) {
2790 DEBUG(1, ("reinit_after_fork failed: %s\n",
2791 nt_errstr(status)));
2792 exit(1);
2794 smbd_echo_loop(sconn, listener_pipe[1]);
2795 exit(0);
2797 close(listener_pipe[1]);
2798 listener_pipe[1] = -1;
2799 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2801 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2804 * Without smb signing this is the same as the normal smbd
2805 * listener. This needs to change once signing comes in.
2807 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2808 sconn,
2809 sconn->smb1.echo_handler.trusted_fd,
2810 EVENT_FD_READ,
2811 smbd_server_echo_handler,
2812 sconn);
2813 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2814 DEBUG(1, ("event_add_fd failed\n"));
2815 goto fail;
2818 return true;
2820 fail:
2821 if (listener_pipe[0] != -1) {
2822 close(listener_pipe[0]);
2824 if (listener_pipe[1] != -1) {
2825 close(listener_pipe[1]);
2827 sconn->smb1.echo_handler.trusted_fd = -1;
2828 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2829 close(sconn->smb1.echo_handler.socket_lock_fd);
2831 sconn->smb1.echo_handler.trusted_fd = -1;
2832 sconn->smb1.echo_handler.socket_lock_fd = -1;
2833 return false;
2836 /****************************************************************************
2837 Process commands from the client
2838 ****************************************************************************/
2840 void smbd_process(void)
2842 TALLOC_CTX *frame = talloc_stackframe();
2843 struct sockaddr_storage ss;
2844 struct sockaddr *sa = NULL;
2845 socklen_t sa_len;
2846 struct tsocket_address *local_address = NULL;
2847 struct tsocket_address *remote_address = NULL;
2848 const char *remaddr = NULL;
2849 int ret;
2851 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2852 lp_security() != SEC_SHARE &&
2853 !lp_async_smb_echo_handler()) {
2854 smbd_server_conn->allow_smb2 = true;
2857 /* Ensure child is set to blocking mode */
2858 set_blocking(smbd_server_fd(),True);
2860 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2861 set_socket_options(smbd_server_fd(), lp_socket_options());
2863 sa = (struct sockaddr *)(void *)&ss;
2864 sa_len = sizeof(ss);
2865 ret = getpeername(smbd_server_fd(), sa, &sa_len);
2866 if (ret != 0) {
2867 int level = (errno == ENOTCONN)?2:0;
2868 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2869 exit_server("getpeername() failed.\n");
2871 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2872 sa, sa_len,
2873 &remote_address);
2874 if (ret != 0) {
2875 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2876 __location__, strerror(errno)));
2877 exit_server("tsocket_address_bsd_from_sockaddr remote failed.\n");
2880 sa = (struct sockaddr *)(void *)&ss;
2881 sa_len = sizeof(ss);
2882 ret = getsockname(smbd_server_fd(), sa, &sa_len);
2883 if (ret != 0) {
2884 int level = (errno == ENOTCONN)?2:0;
2885 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2886 exit_server("getsockname() failed.\n");
2888 ret = tsocket_address_bsd_from_sockaddr(smbd_server_conn,
2889 sa, sa_len,
2890 &local_address);
2891 if (ret != 0) {
2892 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2893 __location__, strerror(errno)));
2894 exit_server("tsocket_address_bsd_from_sockaddr remote failed.\n");
2897 smbd_server_conn->local_address = local_address;
2898 smbd_server_conn->remote_address = remote_address;
2900 if (tsocket_address_is_inet(remote_address, "ip")) {
2901 remaddr = tsocket_address_inet_addr_string(
2902 smbd_server_conn->remote_address,
2903 talloc_tos());
2904 if (remaddr == NULL) {
2907 } else {
2908 remaddr = "0.0.0.0";
2911 /* this is needed so that we get decent entries
2912 in smbstatus for port 445 connects */
2913 set_remote_machine_name(remaddr, false);
2914 reload_services(true);
2917 * Before the first packet, check the global hosts allow/ hosts deny
2918 * parameters before doing any parsing of packets passed to us by the
2919 * client. This prevents attacks on our parsing code from hosts not in
2920 * the hosts allow list.
2923 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2924 lp_hostsdeny(-1))) {
2926 * send a negative session response "not listening on calling
2927 * name"
2929 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2930 DEBUG( 1, ("Connection denied from %s to %s\n",
2931 tsocket_address_string(remote_address, talloc_tos()),
2932 tsocket_address_string(local_address, talloc_tos())));
2933 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2934 0, false, NULL);
2935 exit_server_cleanly("connection denied");
2938 DEBUG(10, ("Connection allowed from %s to %s\n",
2939 tsocket_address_string(remote_address, talloc_tos()),
2940 tsocket_address_string(local_address, talloc_tos())));
2942 static_init_rpc;
2944 init_modules();
2946 smb_perfcount_init();
2948 if (!init_account_policy()) {
2949 exit_server("Could not open account policy tdb.\n");
2952 if (*lp_rootdir()) {
2953 if (chroot(lp_rootdir()) != 0) {
2954 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2955 exit_server("Failed to chroot()");
2957 if (chdir("/") == -1) {
2958 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2959 exit_server("Failed to chroot()");
2961 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2964 if (!srv_init_signing(smbd_server_conn)) {
2965 exit_server("Failed to init smb_signing");
2968 if (lp_async_smb_echo_handler() && !fork_echo_handler(smbd_server_conn)) {
2969 exit_server("Failed to fork echo handler");
2972 /* Setup oplocks */
2973 if (!init_oplocks(smbd_messaging_context()))
2974 exit_server("Failed to init oplocks");
2976 /* register our message handlers */
2977 messaging_register(smbd_messaging_context(), NULL,
2978 MSG_SMB_FORCE_TDIS, msg_force_tdis);
2979 messaging_register(smbd_messaging_context(), NULL,
2980 MSG_SMB_RELEASE_IP, msg_release_ip);
2981 messaging_register(smbd_messaging_context(), NULL,
2982 MSG_SMB_CLOSE_FILE, msg_close_file);
2985 * Use the default MSG_DEBUG handler to avoid rebroadcasting
2986 * MSGs to all child processes
2988 messaging_deregister(smbd_messaging_context(),
2989 MSG_DEBUG, NULL);
2990 messaging_register(smbd_messaging_context(), NULL,
2991 MSG_DEBUG, debug_message);
2993 if ((lp_keepalive() != 0)
2994 && !(event_add_idle(smbd_event_context(), NULL,
2995 timeval_set(lp_keepalive(), 0),
2996 "keepalive", keepalive_fn,
2997 NULL))) {
2998 DEBUG(0, ("Could not add keepalive event\n"));
2999 exit(1);
3002 if (!(event_add_idle(smbd_event_context(), NULL,
3003 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3004 "deadtime", deadtime_fn, NULL))) {
3005 DEBUG(0, ("Could not add deadtime event\n"));
3006 exit(1);
3009 if (!(event_add_idle(smbd_event_context(), NULL,
3010 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3011 "housekeeping", housekeeping_fn, NULL))) {
3012 DEBUG(0, ("Could not add housekeeping event\n"));
3013 exit(1);
3016 #ifdef CLUSTER_SUPPORT
3018 if (lp_clustering()) {
3020 * We need to tell ctdb about our client's TCP
3021 * connection, so that for failover ctdbd can send
3022 * tickle acks, triggering a reconnection by the
3023 * client.
3026 struct sockaddr_storage srv, clnt;
3028 if (client_get_tcp_info(&srv, &clnt) == 0) {
3030 NTSTATUS status;
3032 status = ctdbd_register_ips(
3033 messaging_ctdbd_connection(),
3034 &srv, &clnt, release_ip, NULL);
3036 if (!NT_STATUS_IS_OK(status)) {
3037 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3038 nt_errstr(status)));
3040 } else
3042 DEBUG(0,("Unable to get tcp info for "
3043 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3044 strerror(errno)));
3048 #endif
3050 smbd_server_conn->nbt.got_session = false;
3052 smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3054 smbd_server_conn->smb1.sessions.done_sesssetup = false;
3055 smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
3056 smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3057 /* users from session setup */
3058 smbd_server_conn->smb1.sessions.session_userlist = NULL;
3059 /* workgroup from session setup. */
3060 smbd_server_conn->smb1.sessions.session_workgroup = NULL;
3061 /* this holds info on user ids that are already validated for this VC */
3062 smbd_server_conn->smb1.sessions.validated_users = NULL;
3063 smbd_server_conn->smb1.sessions.next_vuid = VUID_OFFSET;
3064 smbd_server_conn->smb1.sessions.num_validated_vuids = 0;
3065 #ifdef HAVE_NETGROUP
3066 smbd_server_conn->smb1.sessions.my_yp_domain = NULL;
3067 #endif
3069 conn_init(smbd_server_conn);
3070 if (!init_dptrs(smbd_server_conn)) {
3071 exit_server("init_dptrs() failed");
3074 smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
3075 smbd_server_conn,
3076 smbd_server_fd(),
3077 EVENT_FD_READ,
3078 smbd_server_connection_handler,
3079 smbd_server_conn);
3080 if (!smbd_server_conn->smb1.fde) {
3081 exit_server("failed to create smbd_server_connection fde");
3084 TALLOC_FREE(frame);
3086 while (True) {
3087 NTSTATUS status;
3089 frame = talloc_stackframe_pool(8192);
3091 errno = 0;
3093 status = smbd_server_connection_loop_once(smbd_server_conn);
3094 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3095 !NT_STATUS_IS_OK(status)) {
3096 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3097 " exiting\n", nt_errstr(status)));
3098 break;
3101 TALLOC_FREE(frame);
3104 exit_server_cleanly(NULL);
3107 bool req_is_in_chain(struct smb_request *req)
3109 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3111 * We're right now handling a subsequent request, so we must
3112 * be in a chain
3114 return true;
3117 if (!is_andx_req(req->cmd)) {
3118 return false;
3121 if (req->wct < 2) {
3123 * Okay, an illegal request, but definitely not chained :-)
3125 return false;
3128 return (CVAL(req->vwv+0, 0) != 0xFF);