s3: Remove the smbd_messaging_context from spoolss_init_cb
[Samba/wip.git] / source3 / smbd / process.c
blob05e53904d77fd8a367c97e32716f92a47d4778a4
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"
38 #include "printing/nt_printing_migrate.h"
40 extern bool global_machine_password_needs_changing;
42 static void construct_reply_common(struct smb_request *req, const char *inbuf,
43 char *outbuf);
44 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
46 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
48 bool ok;
50 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
51 return true;
54 sconn->smb1.echo_handler.ref_count++;
56 if (sconn->smb1.echo_handler.ref_count > 1) {
57 return true;
60 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
62 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
63 SMB_F_SETLKW, 0, 0, F_WRLCK);
64 if (!ok) {
65 return false;
68 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
70 return true;
73 void smbd_lock_socket(struct smbd_server_connection *sconn)
75 if (!smbd_lock_socket_internal(sconn)) {
76 exit_server_cleanly("failed to lock socket");
80 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
82 bool ok;
84 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
85 return true;
88 sconn->smb1.echo_handler.ref_count--;
90 if (sconn->smb1.echo_handler.ref_count > 0) {
91 return true;
94 ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
95 SMB_F_SETLKW, 0, 0, F_UNLCK);
96 if (!ok) {
97 return false;
100 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
102 return true;
105 void smbd_unlock_socket(struct smbd_server_connection *sconn)
107 if (!smbd_unlock_socket_internal(sconn)) {
108 exit_server_cleanly("failed to unlock socket");
112 /* Accessor function for smb_read_error for smbd functions. */
114 /****************************************************************************
115 Send an smb to a fd.
116 ****************************************************************************/
118 bool srv_send_smb(int fd, char *buffer,
119 bool do_signing, uint32_t seqnum,
120 bool do_encrypt,
121 struct smb_perfcount_data *pcd)
123 size_t len = 0;
124 size_t nwritten=0;
125 ssize_t ret;
126 char *buf_out = buffer;
128 smbd_lock_socket(smbd_server_conn);
130 if (do_signing) {
131 /* Sign the outgoing packet if required. */
132 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
135 if (do_encrypt) {
136 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
137 if (!NT_STATUS_IS_OK(status)) {
138 DEBUG(0, ("send_smb: SMB encryption failed "
139 "on outgoing packet! Error %s\n",
140 nt_errstr(status) ));
141 goto out;
145 len = smb_len(buf_out) + 4;
147 ret = write_data(fd,buf_out+nwritten,len - nwritten);
148 if (ret <= 0) {
149 DEBUG(0,("pid[%d] Error writing %d bytes to client. %d. (%s)\n",
150 (int)sys_getpid(), (int)len,(int)ret, strerror(errno) ));
151 srv_free_enc_buffer(buf_out);
152 goto out;
155 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
156 srv_free_enc_buffer(buf_out);
157 out:
158 SMB_PERFCOUNT_END(pcd);
160 smbd_unlock_socket(smbd_server_conn);
161 return true;
164 /*******************************************************************
165 Setup the word count and byte count for a smb message.
166 ********************************************************************/
168 int srv_set_message(char *buf,
169 int num_words,
170 int num_bytes,
171 bool zero)
173 if (zero && (num_words || num_bytes)) {
174 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
176 SCVAL(buf,smb_wct,num_words);
177 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
178 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
179 return (smb_size + num_words*2 + num_bytes);
182 static bool valid_smb_header(const uint8_t *inbuf)
184 if (is_encrypted_packet(inbuf)) {
185 return true;
188 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
189 * but it just looks weird to call strncmp for this one.
191 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
194 /* Socket functions for smbd packet processing. */
196 static bool valid_packet_size(size_t len)
199 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
200 * of header. Don't print the error if this fits.... JRA.
203 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
204 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
205 (unsigned long)len));
206 return false;
208 return true;
211 static NTSTATUS read_packet_remainder(int fd, char *buffer,
212 unsigned int timeout, ssize_t len)
214 if (len <= 0) {
215 return NT_STATUS_OK;
218 return read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
221 /****************************************************************************
222 Attempt a zerocopy writeX read. We know here that len > smb_size-4
223 ****************************************************************************/
226 * Unfortunately, earlier versions of smbclient/libsmbclient
227 * don't send this "standard" writeX header. I've fixed this
228 * for 3.2 but we'll use the old method with earlier versions.
229 * Windows and CIFSFS at least use this standard size. Not
230 * sure about MacOSX.
233 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
234 (2*14) + /* word count (including bcc) */ \
235 1 /* pad byte */)
237 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
238 const char lenbuf[4],
239 int fd, char **buffer,
240 unsigned int timeout,
241 size_t *p_unread,
242 size_t *len_ret)
244 /* Size of a WRITEX call (+4 byte len). */
245 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
246 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
247 ssize_t toread;
248 NTSTATUS status;
250 memcpy(writeX_header, lenbuf, 4);
252 status = read_fd_with_timeout(
253 fd, writeX_header + 4,
254 STANDARD_WRITE_AND_X_HEADER_SIZE,
255 STANDARD_WRITE_AND_X_HEADER_SIZE,
256 timeout, NULL);
258 if (!NT_STATUS_IS_OK(status)) {
259 return status;
263 * Ok - now try and see if this is a possible
264 * valid writeX call.
267 if (is_valid_writeX_buffer(smbd_server_conn,
268 (uint8_t *)writeX_header)) {
270 * If the data offset is beyond what
271 * we've read, drain the extra bytes.
273 uint16_t doff = SVAL(writeX_header,smb_vwv11);
274 ssize_t newlen;
276 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
277 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
278 if (drain_socket(smbd_server_fd(), drain) != drain) {
279 smb_panic("receive_smb_raw_talloc_partial_read:"
280 " failed to drain pending bytes");
282 } else {
283 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
286 /* Spoof down the length and null out the bcc. */
287 set_message_bcc(writeX_header, 0);
288 newlen = smb_len(writeX_header);
290 /* Copy the header we've written. */
292 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
293 writeX_header,
294 sizeof(writeX_header));
296 if (*buffer == NULL) {
297 DEBUG(0, ("Could not allocate inbuf of length %d\n",
298 (int)sizeof(writeX_header)));
299 return NT_STATUS_NO_MEMORY;
302 /* Work out the remaining bytes. */
303 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
304 *len_ret = newlen + 4;
305 return NT_STATUS_OK;
308 if (!valid_packet_size(len)) {
309 return NT_STATUS_INVALID_PARAMETER;
313 * Not a valid writeX call. Just do the standard
314 * talloc and return.
317 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
319 if (*buffer == NULL) {
320 DEBUG(0, ("Could not allocate inbuf of length %d\n",
321 (int)len+4));
322 return NT_STATUS_NO_MEMORY;
325 /* Copy in what we already read. */
326 memcpy(*buffer,
327 writeX_header,
328 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
329 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
331 if(toread > 0) {
332 status = read_packet_remainder(
333 fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
334 timeout, toread);
336 if (!NT_STATUS_IS_OK(status)) {
337 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
338 nt_errstr(status)));
339 return status;
343 *len_ret = len + 4;
344 return NT_STATUS_OK;
347 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
348 char **buffer, unsigned int timeout,
349 size_t *p_unread, size_t *plen)
351 char lenbuf[4];
352 size_t len;
353 int min_recv_size = lp_min_receive_file_size();
354 NTSTATUS status;
356 *p_unread = 0;
358 status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
359 if (!NT_STATUS_IS_OK(status)) {
360 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
361 return status;
364 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
365 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
366 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
367 !srv_is_signing_active(smbd_server_conn) &&
368 smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
370 return receive_smb_raw_talloc_partial_read(
371 mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
374 if (!valid_packet_size(len)) {
375 return NT_STATUS_INVALID_PARAMETER;
379 * The +4 here can't wrap, we've checked the length above already.
382 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
384 if (*buffer == NULL) {
385 DEBUG(0, ("Could not allocate inbuf of length %d\n",
386 (int)len+4));
387 return NT_STATUS_NO_MEMORY;
390 memcpy(*buffer, lenbuf, sizeof(lenbuf));
392 status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
393 if (!NT_STATUS_IS_OK(status)) {
394 return status;
397 *plen = len + 4;
398 return NT_STATUS_OK;
401 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
402 char **buffer, unsigned int timeout,
403 size_t *p_unread, bool *p_encrypted,
404 size_t *p_len,
405 uint32_t *seqnum,
406 bool trusted_channel)
408 size_t len = 0;
409 NTSTATUS status;
411 *p_encrypted = false;
413 status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
414 p_unread, &len);
415 if (!NT_STATUS_IS_OK(status)) {
416 return status;
419 if (is_encrypted_packet((uint8_t *)*buffer)) {
420 status = srv_decrypt_buffer(*buffer);
421 if (!NT_STATUS_IS_OK(status)) {
422 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
423 "incoming packet! Error %s\n",
424 nt_errstr(status) ));
425 return status;
427 *p_encrypted = true;
430 /* Check the incoming SMB signature. */
431 if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
432 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
433 "incoming packet!\n"));
434 return NT_STATUS_INVALID_NETWORK_RESPONSE;
437 *p_len = len;
438 return NT_STATUS_OK;
442 * Initialize a struct smb_request from an inbuf
445 static bool init_smb_request(struct smb_request *req,
446 struct smbd_server_connection *sconn,
447 const uint8 *inbuf,
448 size_t unread_bytes, bool encrypted,
449 uint32_t seqnum)
451 size_t req_size = smb_len(inbuf) + 4;
452 /* Ensure we have at least smb_size bytes. */
453 if (req_size < smb_size) {
454 DEBUG(0,("init_smb_request: invalid request size %u\n",
455 (unsigned int)req_size ));
456 return false;
458 req->cmd = CVAL(inbuf, smb_com);
459 req->flags2 = SVAL(inbuf, smb_flg2);
460 req->smbpid = SVAL(inbuf, smb_pid);
461 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
462 req->seqnum = seqnum;
463 req->vuid = SVAL(inbuf, smb_uid);
464 req->tid = SVAL(inbuf, smb_tid);
465 req->wct = CVAL(inbuf, smb_wct);
466 req->vwv = (uint16_t *)(inbuf+smb_vwv);
467 req->buflen = smb_buflen(inbuf);
468 req->buf = (const uint8_t *)smb_buf(inbuf);
469 req->unread_bytes = unread_bytes;
470 req->encrypted = encrypted;
471 req->sconn = sconn;
472 req->conn = conn_find(sconn,req->tid);
473 req->chain_fsp = NULL;
474 req->chain_outbuf = NULL;
475 req->done = false;
476 req->smb2req = NULL;
477 smb_init_perfcount_data(&req->pcd);
479 /* Ensure we have at least wct words and 2 bytes of bcc. */
480 if (smb_size + req->wct*2 > req_size) {
481 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
482 (unsigned int)req->wct,
483 (unsigned int)req_size));
484 return false;
486 /* Ensure bcc is correct. */
487 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
488 DEBUG(0,("init_smb_request: invalid bcc number %u "
489 "(wct = %u, size %u)\n",
490 (unsigned int)req->buflen,
491 (unsigned int)req->wct,
492 (unsigned int)req_size));
493 return false;
496 req->outbuf = NULL;
497 return true;
500 static void process_smb(struct smbd_server_connection *conn,
501 uint8_t *inbuf, size_t nread, size_t unread_bytes,
502 uint32_t seqnum, bool encrypted,
503 struct smb_perfcount_data *deferred_pcd);
505 static void smbd_deferred_open_timer(struct event_context *ev,
506 struct timed_event *te,
507 struct timeval _tval,
508 void *private_data)
510 struct pending_message_list *msg = talloc_get_type(private_data,
511 struct pending_message_list);
512 TALLOC_CTX *mem_ctx = talloc_tos();
513 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
514 uint8_t *inbuf;
516 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
517 msg->buf.length);
518 if (inbuf == NULL) {
519 exit_server("smbd_deferred_open_timer: talloc failed\n");
520 return;
523 /* We leave this message on the queue so the open code can
524 know this is a retry. */
525 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
526 (unsigned long long)mid ));
528 /* Mark the message as processed so this is not
529 * re-processed in error. */
530 msg->processed = true;
532 process_smb(smbd_server_conn, inbuf,
533 msg->buf.length, 0,
534 msg->seqnum, msg->encrypted, &msg->pcd);
536 /* If it's still there and was processed, remove it. */
537 msg = get_deferred_open_message_smb(mid);
538 if (msg && msg->processed) {
539 remove_deferred_open_message_smb(mid);
543 /****************************************************************************
544 Function to push a message onto the tail of a linked list of smb messages ready
545 for processing.
546 ****************************************************************************/
548 static bool push_queued_message(struct smb_request *req,
549 struct timeval request_time,
550 struct timeval end_time,
551 char *private_data, size_t private_len)
553 int msg_len = smb_len(req->inbuf) + 4;
554 struct pending_message_list *msg;
556 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
558 if(msg == NULL) {
559 DEBUG(0,("push_message: malloc fail (1)\n"));
560 return False;
563 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
564 if(msg->buf.data == NULL) {
565 DEBUG(0,("push_message: malloc fail (2)\n"));
566 TALLOC_FREE(msg);
567 return False;
570 msg->request_time = request_time;
571 msg->seqnum = req->seqnum;
572 msg->encrypted = req->encrypted;
573 msg->processed = false;
574 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
576 if (private_data) {
577 msg->private_data = data_blob_talloc(msg, private_data,
578 private_len);
579 if (msg->private_data.data == NULL) {
580 DEBUG(0,("push_message: malloc fail (3)\n"));
581 TALLOC_FREE(msg);
582 return False;
586 msg->te = event_add_timed(smbd_event_context(),
587 msg,
588 end_time,
589 smbd_deferred_open_timer,
590 msg);
591 if (!msg->te) {
592 DEBUG(0,("push_message: event_add_timed failed\n"));
593 TALLOC_FREE(msg);
594 return false;
597 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
599 DEBUG(10,("push_message: pushed message length %u on "
600 "deferred_open_queue\n", (unsigned int)msg_len));
602 return True;
605 /****************************************************************************
606 Function to delete a sharing violation open message by mid.
607 ****************************************************************************/
609 void remove_deferred_open_message_smb(uint64_t mid)
611 struct pending_message_list *pml;
613 if (smbd_server_conn->using_smb2) {
614 remove_deferred_open_message_smb2(smbd_server_conn, mid);
615 return;
618 for (pml = deferred_open_queue; pml; pml = pml->next) {
619 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
620 DEBUG(10,("remove_deferred_open_message_smb: "
621 "deleting mid %llu len %u\n",
622 (unsigned long long)mid,
623 (unsigned int)pml->buf.length ));
624 DLIST_REMOVE(deferred_open_queue, pml);
625 TALLOC_FREE(pml);
626 return;
631 /****************************************************************************
632 Move a sharing violation open retry message to the front of the list and
633 schedule it for immediate processing.
634 ****************************************************************************/
636 void schedule_deferred_open_message_smb(uint64_t mid)
638 struct pending_message_list *pml;
639 int i = 0;
641 if (smbd_server_conn->using_smb2) {
642 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
643 return;
646 for (pml = deferred_open_queue; pml; pml = pml->next) {
647 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
649 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
650 "msg_mid = %llu\n",
651 i++,
652 (unsigned long long)msg_mid ));
654 if (mid == msg_mid) {
655 struct timed_event *te;
657 if (pml->processed) {
658 /* A processed message should not be
659 * rescheduled. */
660 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
661 "message mid %llu was already processed\n",
662 (unsigned long long)msg_mid ));
663 continue;
666 DEBUG(10,("schedule_deferred_open_message_smb: "
667 "scheduling mid %llu\n",
668 (unsigned long long)mid ));
670 te = event_add_timed(smbd_event_context(),
671 pml,
672 timeval_zero(),
673 smbd_deferred_open_timer,
674 pml);
675 if (!te) {
676 DEBUG(10,("schedule_deferred_open_message_smb: "
677 "event_add_timed() failed, "
678 "skipping mid %llu\n",
679 (unsigned long long)msg_mid ));
682 TALLOC_FREE(pml->te);
683 pml->te = te;
684 DLIST_PROMOTE(deferred_open_queue, pml);
685 return;
689 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
690 "find message mid %llu\n",
691 (unsigned long long)mid ));
694 /****************************************************************************
695 Return true if this mid is on the deferred queue and was not yet processed.
696 ****************************************************************************/
698 bool open_was_deferred(uint64_t mid)
700 struct pending_message_list *pml;
702 if (smbd_server_conn->using_smb2) {
703 return open_was_deferred_smb2(smbd_server_conn, mid);
706 for (pml = deferred_open_queue; pml; pml = pml->next) {
707 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
708 return True;
711 return False;
714 /****************************************************************************
715 Return the message queued by this mid.
716 ****************************************************************************/
718 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
720 struct pending_message_list *pml;
722 for (pml = deferred_open_queue; pml; pml = pml->next) {
723 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
724 return pml;
727 return NULL;
730 /****************************************************************************
731 Get the state data queued by this mid.
732 ****************************************************************************/
734 bool get_deferred_open_message_state(struct smb_request *smbreq,
735 struct timeval *p_request_time,
736 void **pp_state)
738 struct pending_message_list *pml;
740 if (smbd_server_conn->using_smb2) {
741 return get_deferred_open_message_state_smb2(smbreq->smb2req,
742 p_request_time,
743 pp_state);
746 pml = get_deferred_open_message_smb(smbreq->mid);
747 if (!pml) {
748 return false;
750 if (p_request_time) {
751 *p_request_time = pml->request_time;
753 if (pp_state) {
754 *pp_state = (void *)pml->private_data.data;
756 return true;
759 /****************************************************************************
760 Function to push a deferred open smb message onto a linked list of local smb
761 messages ready for processing.
762 ****************************************************************************/
764 bool push_deferred_open_message_smb(struct smb_request *req,
765 struct timeval request_time,
766 struct timeval timeout,
767 struct file_id id,
768 char *private_data, size_t priv_len)
770 struct timeval end_time;
772 if (req->smb2req) {
773 return push_deferred_open_message_smb2(req->smb2req,
774 request_time,
775 timeout,
777 private_data,
778 priv_len);
781 if (req->unread_bytes) {
782 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
783 "unread_bytes = %u\n",
784 (unsigned int)req->unread_bytes ));
785 smb_panic("push_deferred_open_message_smb: "
786 "logic error unread_bytes != 0" );
789 end_time = timeval_sum(&request_time, &timeout);
791 DEBUG(10,("push_deferred_open_message_smb: pushing message "
792 "len %u mid %llu timeout time [%u.%06u]\n",
793 (unsigned int) smb_len(req->inbuf)+4,
794 (unsigned long long)req->mid,
795 (unsigned int)end_time.tv_sec,
796 (unsigned int)end_time.tv_usec));
798 return push_queued_message(req, request_time, end_time,
799 private_data, priv_len);
802 struct idle_event {
803 struct timed_event *te;
804 struct timeval interval;
805 char *name;
806 bool (*handler)(const struct timeval *now, void *private_data);
807 void *private_data;
810 static void smbd_idle_event_handler(struct event_context *ctx,
811 struct timed_event *te,
812 struct timeval now,
813 void *private_data)
815 struct idle_event *event =
816 talloc_get_type_abort(private_data, struct idle_event);
818 TALLOC_FREE(event->te);
820 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
821 event->name, event->te));
823 if (!event->handler(&now, event->private_data)) {
824 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
825 event->name, event->te));
826 /* Don't repeat, delete ourselves */
827 TALLOC_FREE(event);
828 return;
831 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
832 event->name, event->te));
834 event->te = event_add_timed(ctx, event,
835 timeval_sum(&now, &event->interval),
836 smbd_idle_event_handler, event);
838 /* We can't do much but fail here. */
839 SMB_ASSERT(event->te != NULL);
842 struct idle_event *event_add_idle(struct event_context *event_ctx,
843 TALLOC_CTX *mem_ctx,
844 struct timeval interval,
845 const char *name,
846 bool (*handler)(const struct timeval *now,
847 void *private_data),
848 void *private_data)
850 struct idle_event *result;
851 struct timeval now = timeval_current();
853 result = TALLOC_P(mem_ctx, struct idle_event);
854 if (result == NULL) {
855 DEBUG(0, ("talloc failed\n"));
856 return NULL;
859 result->interval = interval;
860 result->handler = handler;
861 result->private_data = private_data;
863 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
864 DEBUG(0, ("talloc failed\n"));
865 TALLOC_FREE(result);
866 return NULL;
869 result->te = event_add_timed(event_ctx, result,
870 timeval_sum(&now, &interval),
871 smbd_idle_event_handler, result);
872 if (result->te == NULL) {
873 DEBUG(0, ("event_add_timed failed\n"));
874 TALLOC_FREE(result);
875 return NULL;
878 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
879 return result;
882 static void smbd_sig_term_handler(struct tevent_context *ev,
883 struct tevent_signal *se,
884 int signum,
885 int count,
886 void *siginfo,
887 void *private_data)
889 exit_server_cleanly("termination signal");
892 void smbd_setup_sig_term_handler(void)
894 struct tevent_signal *se;
896 se = tevent_add_signal(smbd_event_context(),
897 smbd_event_context(),
898 SIGTERM, 0,
899 smbd_sig_term_handler,
900 NULL);
901 if (!se) {
902 exit_server("failed to setup SIGTERM handler");
906 static void smbd_sig_hup_handler(struct tevent_context *ev,
907 struct tevent_signal *se,
908 int signum,
909 int count,
910 void *siginfo,
911 void *private_data)
913 struct messaging_context *msg_ctx = talloc_get_type_abort(
914 private_data, struct messaging_context);
915 change_to_root_user();
916 DEBUG(1,("Reloading services after SIGHUP\n"));
917 reload_services(msg_ctx, False);
920 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
921 struct messaging_context *msg_ctx)
923 struct tevent_signal *se;
925 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
926 msg_ctx);
927 if (!se) {
928 exit_server("failed to setup SIGHUP handler");
932 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
934 fd_set r_fds, w_fds;
935 int selrtn;
936 struct timeval to;
937 int maxfd = 0;
939 to.tv_sec = SMBD_SELECT_TIMEOUT;
940 to.tv_usec = 0;
943 * Setup the select fd sets.
946 FD_ZERO(&r_fds);
947 FD_ZERO(&w_fds);
950 * Are there any timed events waiting ? If so, ensure we don't
951 * select for longer than it would take to wait for them.
955 struct timeval now;
956 GetTimeOfDay(&now);
958 event_add_to_select_args(smbd_event_context(), &now,
959 &r_fds, &w_fds, &to, &maxfd);
962 /* Process a signal and timed events now... */
963 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
964 return NT_STATUS_RETRY;
968 int sav;
969 START_PROFILE(smbd_idle);
971 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
972 sav = errno;
974 END_PROFILE(smbd_idle);
975 errno = sav;
978 if ((conn->smb1.echo_handler.trusted_fd != -1)
979 && FD_ISSET(smbd_server_fd(), &r_fds)
980 && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
982 * Prefer to read pending requests from the echo handler. To
983 * quote Jeremy (da70f8ab1): This is a hack of monstrous
984 * proportions...
986 FD_CLR(smbd_server_fd(), &r_fds);
989 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
990 return NT_STATUS_RETRY;
993 /* Check if error */
994 if (selrtn == -1) {
995 /* something is wrong. Maybe the socket is dead? */
996 return map_nt_error_from_unix(errno);
999 /* Did we timeout ? */
1000 if (selrtn == 0) {
1001 return NT_STATUS_RETRY;
1004 /* should not be reached */
1005 return NT_STATUS_INTERNAL_ERROR;
1009 * Only allow 5 outstanding trans requests. We're allocating memory, so
1010 * prevent a DoS.
1013 NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1015 int count = 0;
1016 for (; list != NULL; list = list->next) {
1018 if (list->mid == mid) {
1019 return NT_STATUS_INVALID_PARAMETER;
1022 count += 1;
1024 if (count > 5) {
1025 return NT_STATUS_INSUFFICIENT_RESOURCES;
1028 return NT_STATUS_OK;
1032 These flags determine some of the permissions required to do an operation
1034 Note that I don't set NEED_WRITE on some write operations because they
1035 are used by some brain-dead clients when printing, and I don't want to
1036 force write permissions on print services.
1038 #define AS_USER (1<<0)
1039 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1040 #define TIME_INIT (1<<2)
1041 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1042 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1043 #define DO_CHDIR (1<<6)
1046 define a list of possible SMB messages and their corresponding
1047 functions. Any message that has a NULL function is unimplemented -
1048 please feel free to contribute implementations!
1050 static const struct smb_message_struct {
1051 const char *name;
1052 void (*fn)(struct smb_request *req);
1053 int flags;
1054 } smb_messages[256] = {
1056 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1057 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1058 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
1059 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1060 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1061 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1062 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1063 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1064 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1065 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1066 /* 0x0a */ { "SMBread",reply_read,AS_USER},
1067 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1068 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1069 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1070 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1071 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1072 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1073 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1074 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1075 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1076 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1077 /* 0x15 */ { NULL, NULL, 0 },
1078 /* 0x16 */ { NULL, NULL, 0 },
1079 /* 0x17 */ { NULL, NULL, 0 },
1080 /* 0x18 */ { NULL, NULL, 0 },
1081 /* 0x19 */ { NULL, NULL, 0 },
1082 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1083 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1084 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1085 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1086 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1087 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1088 /* 0x20 */ { "SMBwritec", NULL,0},
1089 /* 0x21 */ { NULL, NULL, 0 },
1090 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1091 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1092 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1093 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1094 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1095 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
1096 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
1097 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1098 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1099 /* 0x2b */ { "SMBecho",reply_echo,0},
1100 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1101 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1102 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1103 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1104 /* 0x30 */ { NULL, NULL, 0 },
1105 /* 0x31 */ { NULL, NULL, 0 },
1106 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1107 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1108 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1109 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1110 /* 0x36 */ { NULL, NULL, 0 },
1111 /* 0x37 */ { NULL, NULL, 0 },
1112 /* 0x38 */ { NULL, NULL, 0 },
1113 /* 0x39 */ { NULL, NULL, 0 },
1114 /* 0x3a */ { NULL, NULL, 0 },
1115 /* 0x3b */ { NULL, NULL, 0 },
1116 /* 0x3c */ { NULL, NULL, 0 },
1117 /* 0x3d */ { NULL, NULL, 0 },
1118 /* 0x3e */ { NULL, NULL, 0 },
1119 /* 0x3f */ { NULL, NULL, 0 },
1120 /* 0x40 */ { NULL, NULL, 0 },
1121 /* 0x41 */ { NULL, NULL, 0 },
1122 /* 0x42 */ { NULL, NULL, 0 },
1123 /* 0x43 */ { NULL, NULL, 0 },
1124 /* 0x44 */ { NULL, NULL, 0 },
1125 /* 0x45 */ { NULL, NULL, 0 },
1126 /* 0x46 */ { NULL, NULL, 0 },
1127 /* 0x47 */ { NULL, NULL, 0 },
1128 /* 0x48 */ { NULL, NULL, 0 },
1129 /* 0x49 */ { NULL, NULL, 0 },
1130 /* 0x4a */ { NULL, NULL, 0 },
1131 /* 0x4b */ { NULL, NULL, 0 },
1132 /* 0x4c */ { NULL, NULL, 0 },
1133 /* 0x4d */ { NULL, NULL, 0 },
1134 /* 0x4e */ { NULL, NULL, 0 },
1135 /* 0x4f */ { NULL, NULL, 0 },
1136 /* 0x50 */ { NULL, NULL, 0 },
1137 /* 0x51 */ { NULL, NULL, 0 },
1138 /* 0x52 */ { NULL, NULL, 0 },
1139 /* 0x53 */ { NULL, NULL, 0 },
1140 /* 0x54 */ { NULL, NULL, 0 },
1141 /* 0x55 */ { NULL, NULL, 0 },
1142 /* 0x56 */ { NULL, NULL, 0 },
1143 /* 0x57 */ { NULL, NULL, 0 },
1144 /* 0x58 */ { NULL, NULL, 0 },
1145 /* 0x59 */ { NULL, NULL, 0 },
1146 /* 0x5a */ { NULL, NULL, 0 },
1147 /* 0x5b */ { NULL, NULL, 0 },
1148 /* 0x5c */ { NULL, NULL, 0 },
1149 /* 0x5d */ { NULL, NULL, 0 },
1150 /* 0x5e */ { NULL, NULL, 0 },
1151 /* 0x5f */ { NULL, NULL, 0 },
1152 /* 0x60 */ { NULL, NULL, 0 },
1153 /* 0x61 */ { NULL, NULL, 0 },
1154 /* 0x62 */ { NULL, NULL, 0 },
1155 /* 0x63 */ { NULL, NULL, 0 },
1156 /* 0x64 */ { NULL, NULL, 0 },
1157 /* 0x65 */ { NULL, NULL, 0 },
1158 /* 0x66 */ { NULL, NULL, 0 },
1159 /* 0x67 */ { NULL, NULL, 0 },
1160 /* 0x68 */ { NULL, NULL, 0 },
1161 /* 0x69 */ { NULL, NULL, 0 },
1162 /* 0x6a */ { NULL, NULL, 0 },
1163 /* 0x6b */ { NULL, NULL, 0 },
1164 /* 0x6c */ { NULL, NULL, 0 },
1165 /* 0x6d */ { NULL, NULL, 0 },
1166 /* 0x6e */ { NULL, NULL, 0 },
1167 /* 0x6f */ { NULL, NULL, 0 },
1168 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1169 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1170 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1171 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1172 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1173 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1174 /* 0x76 */ { NULL, NULL, 0 },
1175 /* 0x77 */ { NULL, NULL, 0 },
1176 /* 0x78 */ { NULL, NULL, 0 },
1177 /* 0x79 */ { NULL, NULL, 0 },
1178 /* 0x7a */ { NULL, NULL, 0 },
1179 /* 0x7b */ { NULL, NULL, 0 },
1180 /* 0x7c */ { NULL, NULL, 0 },
1181 /* 0x7d */ { NULL, NULL, 0 },
1182 /* 0x7e */ { NULL, NULL, 0 },
1183 /* 0x7f */ { NULL, NULL, 0 },
1184 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1185 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1186 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1187 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1188 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1189 /* 0x85 */ { NULL, NULL, 0 },
1190 /* 0x86 */ { NULL, NULL, 0 },
1191 /* 0x87 */ { NULL, NULL, 0 },
1192 /* 0x88 */ { NULL, NULL, 0 },
1193 /* 0x89 */ { NULL, NULL, 0 },
1194 /* 0x8a */ { NULL, NULL, 0 },
1195 /* 0x8b */ { NULL, NULL, 0 },
1196 /* 0x8c */ { NULL, NULL, 0 },
1197 /* 0x8d */ { NULL, NULL, 0 },
1198 /* 0x8e */ { NULL, NULL, 0 },
1199 /* 0x8f */ { NULL, NULL, 0 },
1200 /* 0x90 */ { NULL, NULL, 0 },
1201 /* 0x91 */ { NULL, NULL, 0 },
1202 /* 0x92 */ { NULL, NULL, 0 },
1203 /* 0x93 */ { NULL, NULL, 0 },
1204 /* 0x94 */ { NULL, NULL, 0 },
1205 /* 0x95 */ { NULL, NULL, 0 },
1206 /* 0x96 */ { NULL, NULL, 0 },
1207 /* 0x97 */ { NULL, NULL, 0 },
1208 /* 0x98 */ { NULL, NULL, 0 },
1209 /* 0x99 */ { NULL, NULL, 0 },
1210 /* 0x9a */ { NULL, NULL, 0 },
1211 /* 0x9b */ { NULL, NULL, 0 },
1212 /* 0x9c */ { NULL, NULL, 0 },
1213 /* 0x9d */ { NULL, NULL, 0 },
1214 /* 0x9e */ { NULL, NULL, 0 },
1215 /* 0x9f */ { NULL, NULL, 0 },
1216 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1217 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1218 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1219 /* 0xa3 */ { NULL, NULL, 0 },
1220 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1221 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1222 /* 0xa6 */ { NULL, NULL, 0 },
1223 /* 0xa7 */ { NULL, NULL, 0 },
1224 /* 0xa8 */ { NULL, NULL, 0 },
1225 /* 0xa9 */ { NULL, NULL, 0 },
1226 /* 0xaa */ { NULL, NULL, 0 },
1227 /* 0xab */ { NULL, NULL, 0 },
1228 /* 0xac */ { NULL, NULL, 0 },
1229 /* 0xad */ { NULL, NULL, 0 },
1230 /* 0xae */ { NULL, NULL, 0 },
1231 /* 0xaf */ { NULL, NULL, 0 },
1232 /* 0xb0 */ { NULL, NULL, 0 },
1233 /* 0xb1 */ { NULL, NULL, 0 },
1234 /* 0xb2 */ { NULL, NULL, 0 },
1235 /* 0xb3 */ { NULL, NULL, 0 },
1236 /* 0xb4 */ { NULL, NULL, 0 },
1237 /* 0xb5 */ { NULL, NULL, 0 },
1238 /* 0xb6 */ { NULL, NULL, 0 },
1239 /* 0xb7 */ { NULL, NULL, 0 },
1240 /* 0xb8 */ { NULL, NULL, 0 },
1241 /* 0xb9 */ { NULL, NULL, 0 },
1242 /* 0xba */ { NULL, NULL, 0 },
1243 /* 0xbb */ { NULL, NULL, 0 },
1244 /* 0xbc */ { NULL, NULL, 0 },
1245 /* 0xbd */ { NULL, NULL, 0 },
1246 /* 0xbe */ { NULL, NULL, 0 },
1247 /* 0xbf */ { NULL, NULL, 0 },
1248 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1249 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1250 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1251 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1252 /* 0xc4 */ { NULL, NULL, 0 },
1253 /* 0xc5 */ { NULL, NULL, 0 },
1254 /* 0xc6 */ { NULL, NULL, 0 },
1255 /* 0xc7 */ { NULL, NULL, 0 },
1256 /* 0xc8 */ { NULL, NULL, 0 },
1257 /* 0xc9 */ { NULL, NULL, 0 },
1258 /* 0xca */ { NULL, NULL, 0 },
1259 /* 0xcb */ { NULL, NULL, 0 },
1260 /* 0xcc */ { NULL, NULL, 0 },
1261 /* 0xcd */ { NULL, NULL, 0 },
1262 /* 0xce */ { NULL, NULL, 0 },
1263 /* 0xcf */ { NULL, NULL, 0 },
1264 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1265 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1266 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1267 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1268 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1269 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1270 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1271 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1272 /* 0xd8 */ { NULL, NULL, 0 },
1273 /* 0xd9 */ { NULL, NULL, 0 },
1274 /* 0xda */ { NULL, NULL, 0 },
1275 /* 0xdb */ { NULL, NULL, 0 },
1276 /* 0xdc */ { NULL, NULL, 0 },
1277 /* 0xdd */ { NULL, NULL, 0 },
1278 /* 0xde */ { NULL, NULL, 0 },
1279 /* 0xdf */ { NULL, NULL, 0 },
1280 /* 0xe0 */ { NULL, NULL, 0 },
1281 /* 0xe1 */ { NULL, NULL, 0 },
1282 /* 0xe2 */ { NULL, NULL, 0 },
1283 /* 0xe3 */ { NULL, NULL, 0 },
1284 /* 0xe4 */ { NULL, NULL, 0 },
1285 /* 0xe5 */ { NULL, NULL, 0 },
1286 /* 0xe6 */ { NULL, NULL, 0 },
1287 /* 0xe7 */ { NULL, NULL, 0 },
1288 /* 0xe8 */ { NULL, NULL, 0 },
1289 /* 0xe9 */ { NULL, NULL, 0 },
1290 /* 0xea */ { NULL, NULL, 0 },
1291 /* 0xeb */ { NULL, NULL, 0 },
1292 /* 0xec */ { NULL, NULL, 0 },
1293 /* 0xed */ { NULL, NULL, 0 },
1294 /* 0xee */ { NULL, NULL, 0 },
1295 /* 0xef */ { NULL, NULL, 0 },
1296 /* 0xf0 */ { NULL, NULL, 0 },
1297 /* 0xf1 */ { NULL, NULL, 0 },
1298 /* 0xf2 */ { NULL, NULL, 0 },
1299 /* 0xf3 */ { NULL, NULL, 0 },
1300 /* 0xf4 */ { NULL, NULL, 0 },
1301 /* 0xf5 */ { NULL, NULL, 0 },
1302 /* 0xf6 */ { NULL, NULL, 0 },
1303 /* 0xf7 */ { NULL, NULL, 0 },
1304 /* 0xf8 */ { NULL, NULL, 0 },
1305 /* 0xf9 */ { NULL, NULL, 0 },
1306 /* 0xfa */ { NULL, NULL, 0 },
1307 /* 0xfb */ { NULL, NULL, 0 },
1308 /* 0xfc */ { NULL, NULL, 0 },
1309 /* 0xfd */ { NULL, NULL, 0 },
1310 /* 0xfe */ { NULL, NULL, 0 },
1311 /* 0xff */ { NULL, NULL, 0 }
1315 /*******************************************************************
1316 allocate and initialize a reply packet
1317 ********************************************************************/
1319 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1320 const char *inbuf, char **outbuf, uint8_t num_words,
1321 uint32_t num_bytes)
1324 * Protect against integer wrap
1326 if ((num_bytes > 0xffffff)
1327 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1328 char *msg;
1329 if (asprintf(&msg, "num_bytes too large: %u",
1330 (unsigned)num_bytes) == -1) {
1331 msg = CONST_DISCARD(char *, "num_bytes too large");
1333 smb_panic(msg);
1336 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1337 smb_size + num_words*2 + num_bytes);
1338 if (*outbuf == NULL) {
1339 return false;
1342 construct_reply_common(req, inbuf, *outbuf);
1343 srv_set_message(*outbuf, num_words, num_bytes, false);
1345 * Zero out the word area, the caller has to take care of the bcc area
1346 * himself
1348 if (num_words != 0) {
1349 memset(*outbuf + smb_vwv0, 0, num_words*2);
1352 return true;
1355 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1357 char *outbuf;
1358 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1359 num_bytes)) {
1360 smb_panic("could not allocate output buffer\n");
1362 req->outbuf = (uint8_t *)outbuf;
1366 /*******************************************************************
1367 Dump a packet to a file.
1368 ********************************************************************/
1370 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1372 int fd, i;
1373 char *fname = NULL;
1374 if (DEBUGLEVEL < 50) {
1375 return;
1378 if (len < 4) len = smb_len(data)+4;
1379 for (i=1;i<100;i++) {
1380 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1381 type ? "req" : "resp") == -1) {
1382 return;
1384 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1385 if (fd != -1 || errno != EEXIST) break;
1387 if (fd != -1) {
1388 ssize_t ret = write(fd, data, len);
1389 if (ret != len)
1390 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1391 close(fd);
1392 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1394 SAFE_FREE(fname);
1397 /****************************************************************************
1398 Prepare everything for calling the actual request function, and potentially
1399 call the request function via the "new" interface.
1401 Return False if the "legacy" function needs to be called, everything is
1402 prepared.
1404 Return True if we're done.
1406 I know this API sucks, but it is the one with the least code change I could
1407 find.
1408 ****************************************************************************/
1410 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1412 int flags;
1413 uint16 session_tag;
1414 connection_struct *conn = NULL;
1415 struct smbd_server_connection *sconn = req->sconn;
1417 errno = 0;
1419 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1420 * so subtract 4 from it. */
1421 if (!valid_smb_header(req->inbuf)
1422 || (size < (smb_size - 4))) {
1423 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1424 smb_len(req->inbuf)));
1425 exit_server_cleanly("Non-SMB packet");
1428 if (smb_messages[type].fn == NULL) {
1429 DEBUG(0,("Unknown message type %d!\n",type));
1430 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1431 reply_unknown_new(req, type);
1432 return NULL;
1435 flags = smb_messages[type].flags;
1437 /* In share mode security we must ignore the vuid. */
1438 session_tag = (lp_security() == SEC_SHARE)
1439 ? UID_FIELD_INVALID : req->vuid;
1440 conn = req->conn;
1442 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1443 (int)sys_getpid(), (unsigned long)conn));
1445 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1447 /* Ensure this value is replaced in the incoming packet. */
1448 SSVAL(req->inbuf,smb_uid,session_tag);
1451 * Ensure the correct username is in current_user_info. This is a
1452 * really ugly bugfix for problems with multiple session_setup_and_X's
1453 * being done and allowing %U and %G substitutions to work correctly.
1454 * There is a reason this code is done here, don't move it unless you
1455 * know what you're doing... :-).
1456 * JRA.
1459 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1460 user_struct *vuser = NULL;
1462 sconn->smb1.sessions.last_session_tag = session_tag;
1463 if(session_tag != UID_FIELD_INVALID) {
1464 vuser = get_valid_user_struct(sconn, session_tag);
1465 if (vuser) {
1466 set_current_user_info(
1467 vuser->server_info->sanitized_username,
1468 vuser->server_info->unix_name,
1469 vuser->server_info->info3->base.domain.string);
1474 /* Does this call need to be run as the connected user? */
1475 if (flags & AS_USER) {
1477 /* Does this call need a valid tree connection? */
1478 if (!conn) {
1480 * Amazingly, the error code depends on the command
1481 * (from Samba4).
1483 if (type == SMBntcreateX) {
1484 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1485 } else {
1486 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1488 return NULL;
1491 if (!change_to_user(conn,session_tag)) {
1492 DEBUG(0, ("Error: Could not change to user. Removing "
1493 "deferred open, mid=%llu.\n",
1494 (unsigned long long)req->mid));
1495 reply_force_doserror(req, ERRSRV, ERRbaduid);
1496 return conn;
1499 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1501 /* Does it need write permission? */
1502 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1503 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1504 return conn;
1507 /* IPC services are limited */
1508 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1509 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1510 return conn;
1512 } else {
1513 /* This call needs to be run as root */
1514 change_to_root_user();
1517 /* load service specific parameters */
1518 if (conn) {
1519 if (req->encrypted) {
1520 conn->encrypted_tid = true;
1521 /* encrypted required from now on. */
1522 conn->encrypt_level = Required;
1523 } else if (ENCRYPTION_REQUIRED(conn)) {
1524 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1525 exit_server_cleanly("encryption required "
1526 "on connection");
1527 return conn;
1531 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1532 (flags & (AS_USER|DO_CHDIR)
1533 ?True:False))) {
1534 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1535 return conn;
1537 conn->num_smb_operations++;
1540 /* does this protocol need to be run as guest? */
1541 if ((flags & AS_GUEST)
1542 && (!change_to_guest() ||
1543 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1544 lp_hostsdeny(-1)))) {
1545 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1546 return conn;
1549 smb_messages[type].fn(req);
1550 return req->conn;
1553 /****************************************************************************
1554 Construct a reply to the incoming packet.
1555 ****************************************************************************/
1557 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1558 uint32_t seqnum, bool encrypted,
1559 struct smb_perfcount_data *deferred_pcd)
1561 connection_struct *conn;
1562 struct smb_request *req;
1564 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1565 smb_panic("could not allocate smb_request");
1568 if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1569 unread_bytes, encrypted, seqnum)) {
1570 exit_server_cleanly("Invalid SMB request");
1573 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1575 /* we popped this message off the queue - keep original perf data */
1576 if (deferred_pcd)
1577 req->pcd = *deferred_pcd;
1578 else {
1579 SMB_PERFCOUNT_START(&req->pcd);
1580 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1581 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1584 conn = switch_message(req->cmd, req, size);
1586 if (req->unread_bytes) {
1587 /* writeX failed. drain socket. */
1588 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1589 req->unread_bytes) {
1590 smb_panic("failed to drain pending bytes");
1592 req->unread_bytes = 0;
1595 if (req->done) {
1596 TALLOC_FREE(req);
1597 return;
1600 if (req->outbuf == NULL) {
1601 return;
1604 if (CVAL(req->outbuf,0) == 0) {
1605 show_msg((char *)req->outbuf);
1608 if (!srv_send_smb(smbd_server_fd(),
1609 (char *)req->outbuf,
1610 true, req->seqnum+1,
1611 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1612 &req->pcd)) {
1613 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1616 TALLOC_FREE(req);
1618 return;
1621 /****************************************************************************
1622 Process an smb from the client
1623 ****************************************************************************/
1624 static void process_smb(struct smbd_server_connection *conn,
1625 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1626 uint32_t seqnum, bool encrypted,
1627 struct smb_perfcount_data *deferred_pcd)
1629 int msg_type = CVAL(inbuf,0);
1631 DO_PROFILE_INC(smb_count);
1633 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1634 smb_len(inbuf) ) );
1635 DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1636 (int)nread,
1637 (unsigned int)unread_bytes ));
1639 if (msg_type != 0) {
1641 * NetBIOS session request, keepalive, etc.
1643 reply_special(conn, (char *)inbuf);
1644 goto done;
1647 if (smbd_server_conn->using_smb2) {
1648 /* At this point we're not really using smb2,
1649 * we make the decision here.. */
1650 if (smbd_is_smb2_header(inbuf, nread)) {
1651 smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1652 return;
1653 } else if (nread >= smb_size && valid_smb_header(inbuf)
1654 && CVAL(inbuf, smb_com) != 0x72) {
1655 /* This is a non-negprot SMB1 packet.
1656 Disable SMB2 from now on. */
1657 smbd_server_conn->using_smb2 = false;
1661 show_msg((char *)inbuf);
1663 construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1664 trans_num++;
1666 done:
1667 conn->smb1.num_requests++;
1669 /* The timeout_processing function isn't run nearly
1670 often enough to implement 'max log size' without
1671 overrunning the size of the file by many megabytes.
1672 This is especially true if we are running at debug
1673 level 10. Checking every 50 SMBs is a nice
1674 tradeoff of performance vs log file size overrun. */
1676 if ((conn->smb1.num_requests % 50) == 0 &&
1677 need_to_check_log_size()) {
1678 change_to_root_user();
1679 check_log_size();
1683 /****************************************************************************
1684 Return a string containing the function name of a SMB command.
1685 ****************************************************************************/
1687 const char *smb_fn_name(int type)
1689 const char *unknown_name = "SMBunknown";
1691 if (smb_messages[type].name == NULL)
1692 return(unknown_name);
1694 return(smb_messages[type].name);
1697 /****************************************************************************
1698 Helper functions for contruct_reply.
1699 ****************************************************************************/
1701 void add_to_common_flags2(uint32 v)
1703 common_flags2 |= v;
1706 void remove_from_common_flags2(uint32 v)
1708 common_flags2 &= ~v;
1711 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1712 char *outbuf)
1714 srv_set_message(outbuf,0,0,false);
1716 SCVAL(outbuf, smb_com, req->cmd);
1717 SIVAL(outbuf,smb_rcls,0);
1718 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1719 SSVAL(outbuf,smb_flg2,
1720 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1721 common_flags2);
1722 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1724 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1725 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1726 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1727 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1730 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1732 construct_reply_common(req, (char *)req->inbuf, outbuf);
1736 * How many bytes have we already accumulated up to the current wct field
1737 * offset?
1740 size_t req_wct_ofs(struct smb_request *req)
1742 size_t buf_size;
1744 if (req->chain_outbuf == NULL) {
1745 return smb_wct - 4;
1747 buf_size = talloc_get_size(req->chain_outbuf);
1748 if ((buf_size % 4) != 0) {
1749 buf_size += (4 - (buf_size % 4));
1751 return buf_size - 4;
1755 * Hack around reply_nterror & friends not being aware of chained requests,
1756 * generating illegal (i.e. wct==0) chain replies.
1759 static void fixup_chain_error_packet(struct smb_request *req)
1761 uint8_t *outbuf = req->outbuf;
1762 req->outbuf = NULL;
1763 reply_outbuf(req, 2, 0);
1764 memcpy(req->outbuf, outbuf, smb_wct);
1765 TALLOC_FREE(outbuf);
1766 SCVAL(req->outbuf, smb_vwv0, 0xff);
1770 * @brief Find the smb_cmd offset of the last command pushed
1771 * @param[in] buf The buffer we're building up
1772 * @retval Where can we put our next andx cmd?
1774 * While chaining requests, the "next" request we're looking at needs to put
1775 * its SMB_Command before the data the previous request already built up added
1776 * to the chain. Find the offset to the place where we have to put our cmd.
1779 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1781 uint8_t cmd;
1782 size_t ofs;
1784 cmd = CVAL(buf, smb_com);
1786 SMB_ASSERT(is_andx_req(cmd));
1788 ofs = smb_vwv0;
1790 while (CVAL(buf, ofs) != 0xff) {
1792 if (!is_andx_req(CVAL(buf, ofs))) {
1793 return false;
1797 * ofs is from start of smb header, so add the 4 length
1798 * bytes. The next cmd is right after the wct field.
1800 ofs = SVAL(buf, ofs+2) + 4 + 1;
1802 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1805 *pofs = ofs;
1806 return true;
1810 * @brief Do the smb chaining at a buffer level
1811 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1812 * @param[in] smb_command The command that we want to issue
1813 * @param[in] wct How many words?
1814 * @param[in] vwv The words, already in network order
1815 * @param[in] bytes_alignment How shall we align "bytes"?
1816 * @param[in] num_bytes How many bytes?
1817 * @param[in] bytes The data the request ships
1819 * smb_splice_chain() adds the vwv and bytes to the request already present in
1820 * *poutbuf.
1823 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1824 uint8_t wct, const uint16_t *vwv,
1825 size_t bytes_alignment,
1826 uint32_t num_bytes, const uint8_t *bytes)
1828 uint8_t *outbuf;
1829 size_t old_size, new_size;
1830 size_t ofs;
1831 size_t chain_padding = 0;
1832 size_t bytes_padding = 0;
1833 bool first_request;
1835 old_size = talloc_get_size(*poutbuf);
1838 * old_size == smb_wct means we're pushing the first request in for
1839 * libsmb/
1842 first_request = (old_size == smb_wct);
1844 if (!first_request && ((old_size % 4) != 0)) {
1846 * Align the wct field of subsequent requests to a 4-byte
1847 * boundary
1849 chain_padding = 4 - (old_size % 4);
1853 * After the old request comes the new wct field (1 byte), the vwv's
1854 * and the num_bytes field. After at we might need to align the bytes
1855 * given to us to "bytes_alignment", increasing the num_bytes value.
1858 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1860 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1861 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1864 new_size += bytes_padding + num_bytes;
1866 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1867 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1868 (unsigned)new_size));
1869 return false;
1872 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1873 if (outbuf == NULL) {
1874 DEBUG(0, ("talloc failed\n"));
1875 return false;
1877 *poutbuf = outbuf;
1879 if (first_request) {
1880 SCVAL(outbuf, smb_com, smb_command);
1881 } else {
1882 size_t andx_cmd_ofs;
1884 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1885 DEBUG(1, ("invalid command chain\n"));
1886 *poutbuf = TALLOC_REALLOC_ARRAY(
1887 NULL, *poutbuf, uint8_t, old_size);
1888 return false;
1891 if (chain_padding != 0) {
1892 memset(outbuf + old_size, 0, chain_padding);
1893 old_size += chain_padding;
1896 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1897 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1900 ofs = old_size;
1903 * Push the chained request:
1905 * wct field
1908 SCVAL(outbuf, ofs, wct);
1909 ofs += 1;
1912 * vwv array
1915 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1916 ofs += sizeof(uint16_t) * wct;
1919 * bcc (byte count)
1922 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1923 ofs += sizeof(uint16_t);
1926 * padding
1929 if (bytes_padding != 0) {
1930 memset(outbuf + ofs, 0, bytes_padding);
1931 ofs += bytes_padding;
1935 * The bytes field
1938 memcpy(outbuf + ofs, bytes, num_bytes);
1940 return true;
1943 /****************************************************************************
1944 Construct a chained reply and add it to the already made reply
1945 ****************************************************************************/
1947 void chain_reply(struct smb_request *req)
1949 size_t smblen = smb_len(req->inbuf);
1950 size_t already_used, length_needed;
1951 uint8_t chain_cmd;
1952 uint32_t chain_offset; /* uint32_t to avoid overflow */
1954 uint8_t wct;
1955 uint16_t *vwv;
1956 uint16_t buflen;
1957 uint8_t *buf;
1959 if (IVAL(req->outbuf, smb_rcls) != 0) {
1960 fixup_chain_error_packet(req);
1964 * Any of the AndX requests and replies have at least a wct of
1965 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1966 * beginning of the SMB header to the next wct field.
1968 * None of the AndX requests put anything valuable in vwv[0] and [1],
1969 * so we can overwrite it here to form the chain.
1972 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1973 if (req->chain_outbuf == NULL) {
1974 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1975 req, req->outbuf, uint8_t,
1976 smb_len(req->outbuf) + 4);
1977 if (req->chain_outbuf == NULL) {
1978 smb_panic("talloc failed");
1981 req->outbuf = NULL;
1982 goto error;
1986 * Here we assume that this is the end of the chain. For that we need
1987 * to set "next command" to 0xff and the offset to 0. If we later find
1988 * more commands in the chain, this will be overwritten again.
1991 SCVAL(req->outbuf, smb_vwv0, 0xff);
1992 SCVAL(req->outbuf, smb_vwv0+1, 0);
1993 SSVAL(req->outbuf, smb_vwv1, 0);
1995 if (req->chain_outbuf == NULL) {
1997 * In req->chain_outbuf we collect all the replies. Start the
1998 * chain by copying in the first reply.
2000 * We do the realloc because later on we depend on
2001 * talloc_get_size to determine the length of
2002 * chain_outbuf. The reply_xxx routines might have
2003 * over-allocated (reply_pipe_read_and_X used to be such an
2004 * example).
2006 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2007 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2008 if (req->chain_outbuf == NULL) {
2009 smb_panic("talloc failed");
2011 req->outbuf = NULL;
2012 } else {
2014 * Update smb headers where subsequent chained commands
2015 * may have updated them.
2017 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2018 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2020 if (!smb_splice_chain(&req->chain_outbuf,
2021 CVAL(req->outbuf, smb_com),
2022 CVAL(req->outbuf, smb_wct),
2023 (uint16_t *)(req->outbuf + smb_vwv),
2024 0, smb_buflen(req->outbuf),
2025 (uint8_t *)smb_buf(req->outbuf))) {
2026 goto error;
2028 TALLOC_FREE(req->outbuf);
2032 * We use the old request's vwv field to grab the next chained command
2033 * and offset into the chained fields.
2036 chain_cmd = CVAL(req->vwv+0, 0);
2037 chain_offset = SVAL(req->vwv+1, 0);
2039 if (chain_cmd == 0xff) {
2041 * End of chain, no more requests from the client. So ship the
2042 * replies.
2044 smb_setlen((char *)(req->chain_outbuf),
2045 talloc_get_size(req->chain_outbuf) - 4);
2047 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2048 true, req->seqnum+1,
2049 IS_CONN_ENCRYPTED(req->conn)
2050 ||req->encrypted,
2051 &req->pcd)) {
2052 exit_server_cleanly("chain_reply: srv_send_smb "
2053 "failed.");
2055 TALLOC_FREE(req->chain_outbuf);
2056 req->done = true;
2057 return;
2060 /* add a new perfcounter for this element of chain */
2061 SMB_PERFCOUNT_ADD(&req->pcd);
2062 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2063 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2066 * Check if the client tries to fool us. The request so far uses the
2067 * space to the end of the byte buffer in the request just
2068 * processed. The chain_offset can't point into that area. If that was
2069 * the case, we could end up with an endless processing of the chain,
2070 * we would always handle the same request.
2073 already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2074 if (chain_offset < already_used) {
2075 goto error;
2079 * Next check: Make sure the chain offset does not point beyond the
2080 * overall smb request length.
2083 length_needed = chain_offset+1; /* wct */
2084 if (length_needed > smblen) {
2085 goto error;
2089 * Now comes the pointer magic. Goal here is to set up req->vwv and
2090 * req->buf correctly again to be able to call the subsequent
2091 * switch_message(). The chain offset (the former vwv[1]) points at
2092 * the new wct field.
2095 wct = CVAL(smb_base(req->inbuf), chain_offset);
2098 * Next consistency check: Make the new vwv array fits in the overall
2099 * smb request.
2102 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2103 if (length_needed > smblen) {
2104 goto error;
2106 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2109 * Now grab the new byte buffer....
2112 buflen = SVAL(vwv+wct, 0);
2115 * .. and check that it fits.
2118 length_needed += buflen;
2119 if (length_needed > smblen) {
2120 goto error;
2122 buf = (uint8_t *)(vwv+wct+1);
2124 req->cmd = chain_cmd;
2125 req->wct = wct;
2126 req->vwv = vwv;
2127 req->buflen = buflen;
2128 req->buf = buf;
2130 switch_message(chain_cmd, req, smblen);
2132 if (req->outbuf == NULL) {
2134 * This happens if the chained command has suspended itself or
2135 * if it has called srv_send_smb() itself.
2137 return;
2141 * We end up here if the chained command was not itself chained or
2142 * suspended, but for example a close() command. We now need to splice
2143 * the chained commands' outbuf into the already built up chain_outbuf
2144 * and ship the result.
2146 goto done;
2148 error:
2150 * We end up here if there's any error in the chain syntax. Report a
2151 * DOS error, just like Windows does.
2153 reply_force_doserror(req, ERRSRV, ERRerror);
2154 fixup_chain_error_packet(req);
2156 done:
2158 * This scary statement intends to set the
2159 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2160 * to the value req->outbuf carries
2162 SSVAL(req->chain_outbuf, smb_flg2,
2163 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2164 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2167 * Transfer the error codes from the subrequest to the main one
2169 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2170 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2172 if (!smb_splice_chain(&req->chain_outbuf,
2173 CVAL(req->outbuf, smb_com),
2174 CVAL(req->outbuf, smb_wct),
2175 (uint16_t *)(req->outbuf + smb_vwv),
2176 0, smb_buflen(req->outbuf),
2177 (uint8_t *)smb_buf(req->outbuf))) {
2178 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2180 TALLOC_FREE(req->outbuf);
2182 smb_setlen((char *)(req->chain_outbuf),
2183 talloc_get_size(req->chain_outbuf) - 4);
2185 show_msg((char *)(req->chain_outbuf));
2187 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
2188 true, req->seqnum+1,
2189 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2190 &req->pcd)) {
2191 exit_server_cleanly("construct_reply: srv_send_smb failed.");
2193 TALLOC_FREE(req->chain_outbuf);
2194 req->done = true;
2197 /****************************************************************************
2198 Check if services need reloading.
2199 ****************************************************************************/
2201 static void check_reload(struct messaging_context *msg_ctx, time_t t)
2203 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2205 if(last_smb_conf_reload_time == 0) {
2206 last_smb_conf_reload_time = t;
2207 /* Our printing subsystem might not be ready at smbd start up.
2208 Then no printer is available till the first printers check
2209 is performed. A lower initial interval circumvents this. */
2210 if ( printcap_cache_time > 60 )
2211 last_printer_reload_time = t - printcap_cache_time + 60;
2212 else
2213 last_printer_reload_time = t;
2216 if (mypid != getpid()) { /* First time or fork happened meanwhile */
2217 /* randomize over 60 second the printcap reload to avoid all
2218 * process hitting cupsd at the same time */
2219 int time_range = 60;
2221 last_printer_reload_time += random() % time_range;
2222 mypid = getpid();
2225 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2226 reload_services(msg_ctx, True);
2227 last_smb_conf_reload_time = t;
2230 /* 'printcap cache time = 0' disable the feature */
2232 if ( printcap_cache_time != 0 )
2234 /* see if it's time to reload or if the clock has been set back */
2236 if ( (t >= last_printer_reload_time+printcap_cache_time)
2237 || (t-last_printer_reload_time < 0) )
2239 DEBUG( 3,( "Printcap cache time expired.\n"));
2240 reload_printers(msg_ctx);
2241 last_printer_reload_time = t;
2246 static bool fd_is_readable(int fd)
2248 fd_set fds;
2249 struct timeval timeout = {0, };
2250 int ret;
2252 FD_ZERO(&fds);
2253 FD_SET(fd, &fds);
2255 ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2256 if (ret == -1) {
2257 return false;
2259 return FD_ISSET(fd, &fds);
2262 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2264 /* TODO: make write nonblocking */
2267 static void smbd_server_connection_read_handler(
2268 struct smbd_server_connection *conn, int fd)
2270 uint8_t *inbuf = NULL;
2271 size_t inbuf_len = 0;
2272 size_t unread_bytes = 0;
2273 bool encrypted = false;
2274 TALLOC_CTX *mem_ctx = talloc_tos();
2275 NTSTATUS status;
2276 uint32_t seqnum;
2278 bool from_client = (smbd_server_fd() == fd)?true:false;
2280 if (from_client) {
2281 smbd_lock_socket(conn);
2283 if (!fd_is_readable(smbd_server_fd())) {
2284 DEBUG(10,("the echo listener was faster\n"));
2285 smbd_unlock_socket(conn);
2286 return;
2289 /* TODO: make this completely nonblocking */
2290 status = receive_smb_talloc(mem_ctx, fd,
2291 (char **)(void *)&inbuf,
2292 0, /* timeout */
2293 &unread_bytes,
2294 &encrypted,
2295 &inbuf_len, &seqnum,
2296 false /* trusted channel */);
2297 smbd_unlock_socket(conn);
2298 } else {
2299 /* TODO: make this completely nonblocking */
2300 status = receive_smb_talloc(mem_ctx, fd,
2301 (char **)(void *)&inbuf,
2302 0, /* timeout */
2303 &unread_bytes,
2304 &encrypted,
2305 &inbuf_len, &seqnum,
2306 true /* trusted channel */);
2309 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2310 goto process;
2312 if (NT_STATUS_IS_ERR(status)) {
2313 exit_server_cleanly("failed to receive smb request");
2315 if (!NT_STATUS_IS_OK(status)) {
2316 return;
2319 process:
2320 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2321 seqnum, encrypted, NULL);
2324 static void smbd_server_connection_handler(struct event_context *ev,
2325 struct fd_event *fde,
2326 uint16_t flags,
2327 void *private_data)
2329 struct smbd_server_connection *conn = talloc_get_type(private_data,
2330 struct smbd_server_connection);
2332 if (flags & EVENT_FD_WRITE) {
2333 smbd_server_connection_write_handler(conn);
2334 } else if (flags & EVENT_FD_READ) {
2335 smbd_server_connection_read_handler(conn, smbd_server_fd());
2339 static void smbd_server_echo_handler(struct event_context *ev,
2340 struct fd_event *fde,
2341 uint16_t flags,
2342 void *private_data)
2344 struct smbd_server_connection *conn = talloc_get_type(private_data,
2345 struct smbd_server_connection);
2347 if (flags & EVENT_FD_WRITE) {
2348 smbd_server_connection_write_handler(conn);
2349 } else if (flags & EVENT_FD_READ) {
2350 smbd_server_connection_read_handler(
2351 conn, conn->smb1.echo_handler.trusted_fd);
2355 /****************************************************************************
2356 received when we should release a specific IP
2357 ****************************************************************************/
2358 static void release_ip(const char *ip, void *priv)
2360 char addr[INET6_ADDRSTRLEN];
2361 char *p = addr;
2363 client_socket_addr(get_client_fd(),addr,sizeof(addr));
2365 if (strncmp("::ffff:", addr, 7) == 0) {
2366 p = addr + 7;
2369 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2370 /* we can't afford to do a clean exit - that involves
2371 database writes, which would potentially mean we
2372 are still running after the failover has finished -
2373 we have to get rid of this process ID straight
2374 away */
2375 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2376 ip));
2377 /* note we must exit with non-zero status so the unclean handler gets
2378 called in the parent, so that the brl database is tickled */
2379 _exit(1);
2383 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2384 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2386 release_ip((char *)data->data, NULL);
2389 #ifdef CLUSTER_SUPPORT
2390 static int client_get_tcp_info(struct sockaddr_storage *server,
2391 struct sockaddr_storage *client)
2393 socklen_t length;
2394 if (server_fd == -1) {
2395 return -1;
2397 length = sizeof(*server);
2398 if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2399 return -1;
2401 length = sizeof(*client);
2402 if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2403 return -1;
2405 return 0;
2407 #endif
2410 * Send keepalive packets to our client
2412 static bool keepalive_fn(const struct timeval *now, void *private_data)
2414 struct smbd_server_connection *sconn = smbd_server_conn;
2415 bool ret;
2417 if (sconn->using_smb2) {
2418 /* Don't do keepalives on an SMB2 connection. */
2419 return false;
2422 smbd_lock_socket(smbd_server_conn);
2423 ret = send_keepalive(smbd_server_fd());
2424 smbd_unlock_socket(smbd_server_conn);
2426 if (!ret) {
2427 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
2428 return False;
2430 return True;
2434 * Do the recurring check if we're idle
2436 static bool deadtime_fn(const struct timeval *now, void *private_data)
2438 struct smbd_server_connection *sconn =
2439 (struct smbd_server_connection *)private_data;
2441 if (sconn->using_smb2) {
2442 /* TODO: implement real idle check */
2443 if (sconn->smb2.sessions.list) {
2444 return true;
2446 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2447 messaging_send(sconn->msg_ctx, procid_self(),
2448 MSG_SHUTDOWN, &data_blob_null);
2449 return false;
2452 if ((conn_num_open(sconn) == 0)
2453 || (conn_idle_all(sconn, now->tv_sec))) {
2454 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2455 messaging_send(sconn->msg_ctx, procid_self(),
2456 MSG_SHUTDOWN, &data_blob_null);
2457 return False;
2460 return True;
2464 * Do the recurring log file and smb.conf reload checks.
2467 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2469 struct messaging_context *msg_ctx = talloc_get_type_abort(
2470 private_data, struct messaging_context);
2471 change_to_root_user();
2473 /* update printer queue caches if necessary */
2474 update_monitored_printq_cache(msg_ctx);
2476 /* check if we need to reload services */
2477 check_reload(msg_ctx, time(NULL));
2479 /* Change machine password if neccessary. */
2480 attempt_machine_password_change();
2483 * Force a log file check.
2485 force_check_log_size();
2486 check_log_size();
2487 return true;
2490 static int create_unlink_tmp(const char *dir)
2492 char *fname;
2493 int fd;
2495 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2496 if (fname == NULL) {
2497 errno = ENOMEM;
2498 return -1;
2500 fd = mkstemp(fname);
2501 if (fd == -1) {
2502 TALLOC_FREE(fname);
2503 return -1;
2505 if (unlink(fname) == -1) {
2506 int sys_errno = errno;
2507 close(fd);
2508 TALLOC_FREE(fname);
2509 errno = sys_errno;
2510 return -1;
2512 TALLOC_FREE(fname);
2513 return fd;
2516 struct smbd_echo_state {
2517 struct tevent_context *ev;
2518 struct iovec *pending;
2519 struct smbd_server_connection *sconn;
2520 int parent_pipe;
2522 struct tevent_fd *parent_fde;
2524 struct tevent_fd *read_fde;
2525 struct tevent_req *write_req;
2528 static void smbd_echo_writer_done(struct tevent_req *req);
2530 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2532 int num_pending;
2534 if (state->write_req != NULL) {
2535 return;
2538 num_pending = talloc_array_length(state->pending);
2539 if (num_pending == 0) {
2540 return;
2543 state->write_req = writev_send(state, state->ev, NULL,
2544 state->parent_pipe, false,
2545 state->pending, num_pending);
2546 if (state->write_req == NULL) {
2547 DEBUG(1, ("writev_send failed\n"));
2548 exit(1);
2551 talloc_steal(state->write_req, state->pending);
2552 state->pending = NULL;
2554 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2555 state);
2558 static void smbd_echo_writer_done(struct tevent_req *req)
2560 struct smbd_echo_state *state = tevent_req_callback_data(
2561 req, struct smbd_echo_state);
2562 ssize_t written;
2563 int err;
2565 written = writev_recv(req, &err);
2566 TALLOC_FREE(req);
2567 state->write_req = NULL;
2568 if (written == -1) {
2569 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2570 exit(1);
2572 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2573 smbd_echo_activate_writer(state);
2576 static bool smbd_echo_reply(int fd,
2577 uint8_t *inbuf, size_t inbuf_len,
2578 uint32_t seqnum)
2580 struct smb_request req;
2581 uint16_t num_replies;
2582 size_t out_len;
2583 char *outbuf;
2584 bool ok;
2586 if (inbuf_len < smb_size) {
2587 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2588 return false;
2590 if (!valid_smb_header(inbuf)) {
2591 DEBUG(10, ("Got invalid SMB header\n"));
2592 return false;
2595 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2596 seqnum)) {
2597 return false;
2599 req.inbuf = inbuf;
2601 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2602 smb_messages[req.cmd].name
2603 ? smb_messages[req.cmd].name : "unknown"));
2605 if (req.cmd != SMBecho) {
2606 return false;
2608 if (req.wct < 1) {
2609 return false;
2612 num_replies = SVAL(req.vwv+0, 0);
2613 if (num_replies != 1) {
2614 /* Not a Windows "Hey, you're still there?" request */
2615 return false;
2618 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2619 1, req.buflen)) {
2620 DEBUG(10, ("create_outbuf failed\n"));
2621 return false;
2623 req.outbuf = (uint8_t *)outbuf;
2625 SSVAL(req.outbuf, smb_vwv0, num_replies);
2627 if (req.buflen > 0) {
2628 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2631 out_len = smb_len(req.outbuf) + 4;
2633 ok = srv_send_smb(smbd_server_fd(),
2634 (char *)outbuf,
2635 true, seqnum+1,
2636 false, &req.pcd);
2637 TALLOC_FREE(outbuf);
2638 if (!ok) {
2639 exit(1);
2642 return true;
2645 static void smbd_echo_exit(struct tevent_context *ev,
2646 struct tevent_fd *fde, uint16_t flags,
2647 void *private_data)
2649 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2650 exit(0);
2653 static void smbd_echo_reader(struct tevent_context *ev,
2654 struct tevent_fd *fde, uint16_t flags,
2655 void *private_data)
2657 struct smbd_echo_state *state = talloc_get_type_abort(
2658 private_data, struct smbd_echo_state);
2659 struct smbd_server_connection *sconn = state->sconn;
2660 size_t unread, num_pending;
2661 NTSTATUS status;
2662 struct iovec *tmp;
2663 uint32_t seqnum = 0;
2664 bool reply;
2665 bool ok;
2666 bool encrypted = false;
2668 ok = smbd_lock_socket_internal(sconn);
2669 if (!ok) {
2670 DEBUG(0, ("%s: failed to lock socket\n",
2671 __location__));
2672 exit(1);
2675 if (!fd_is_readable(smbd_server_fd())) {
2676 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2677 (int)sys_getpid()));
2678 ok = smbd_unlock_socket_internal(sconn);
2679 if (!ok) {
2680 DEBUG(1, ("%s: failed to unlock socket in\n",
2681 __location__));
2682 exit(1);
2684 return;
2687 num_pending = talloc_array_length(state->pending);
2688 tmp = talloc_realloc(state, state->pending, struct iovec,
2689 num_pending+1);
2690 if (tmp == NULL) {
2691 DEBUG(1, ("talloc_realloc failed\n"));
2692 exit(1);
2694 state->pending = tmp;
2696 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2698 status = receive_smb_talloc(state->pending, smbd_server_fd(),
2699 (char **)(void *)&state->pending[num_pending].iov_base,
2700 0 /* timeout */,
2701 &unread,
2702 &encrypted,
2703 &state->pending[num_pending].iov_len,
2704 &seqnum,
2705 false /* trusted_channel*/);
2706 if (!NT_STATUS_IS_OK(status)) {
2707 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2708 (int)sys_getpid(), nt_errstr(status)));
2709 exit(1);
2712 ok = smbd_unlock_socket_internal(sconn);
2713 if (!ok) {
2714 DEBUG(1, ("%s: failed to unlock socket in\n",
2715 __location__));
2716 exit(1);
2720 * place the seqnum in the packet so that the main process can reply
2721 * with signing
2723 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2724 SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2726 reply = smbd_echo_reply(smbd_server_fd(),
2727 (uint8_t *)state->pending[num_pending].iov_base,
2728 state->pending[num_pending].iov_len,
2729 seqnum);
2730 if (reply) {
2731 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2732 /* no check, shrinking by some bytes does not fail */
2733 state->pending = talloc_realloc(state, state->pending,
2734 struct iovec,
2735 num_pending);
2736 } else {
2737 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2738 smbd_echo_activate_writer(state);
2742 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2743 int parent_pipe)
2745 struct smbd_echo_state *state;
2747 state = talloc_zero(sconn, struct smbd_echo_state);
2748 if (state == NULL) {
2749 DEBUG(1, ("talloc failed\n"));
2750 return;
2752 state->sconn = sconn;
2753 state->parent_pipe = parent_pipe;
2754 state->ev = s3_tevent_context_init(state);
2755 if (state->ev == NULL) {
2756 DEBUG(1, ("tevent_context_init failed\n"));
2757 TALLOC_FREE(state);
2758 return;
2760 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2761 TEVENT_FD_READ, smbd_echo_exit,
2762 state);
2763 if (state->parent_fde == NULL) {
2764 DEBUG(1, ("tevent_add_fd failed\n"));
2765 TALLOC_FREE(state);
2766 return;
2768 state->read_fde = tevent_add_fd(state->ev, state, smbd_server_fd(),
2769 TEVENT_FD_READ, smbd_echo_reader,
2770 state);
2771 if (state->read_fde == NULL) {
2772 DEBUG(1, ("tevent_add_fd failed\n"));
2773 TALLOC_FREE(state);
2774 return;
2777 while (true) {
2778 if (tevent_loop_once(state->ev) == -1) {
2779 DEBUG(1, ("tevent_loop_once failed: %s\n",
2780 strerror(errno)));
2781 break;
2784 TALLOC_FREE(state);
2788 * Handle SMBecho requests in a forked child process
2790 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2792 int listener_pipe[2];
2793 int res;
2794 pid_t child;
2796 res = pipe(listener_pipe);
2797 if (res == -1) {
2798 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2799 return false;
2801 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2802 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2803 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2804 goto fail;
2807 child = sys_fork();
2808 if (child == 0) {
2809 NTSTATUS status;
2811 close(listener_pipe[0]);
2813 status = reinit_after_fork(sconn->msg_ctx,
2814 smbd_event_context(),
2815 procid_self(), false);
2816 if (!NT_STATUS_IS_OK(status)) {
2817 DEBUG(1, ("reinit_after_fork failed: %s\n",
2818 nt_errstr(status)));
2819 exit(1);
2821 smbd_echo_loop(sconn, listener_pipe[1]);
2822 exit(0);
2824 close(listener_pipe[1]);
2825 listener_pipe[1] = -1;
2826 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2828 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2831 * Without smb signing this is the same as the normal smbd
2832 * listener. This needs to change once signing comes in.
2834 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2835 sconn,
2836 sconn->smb1.echo_handler.trusted_fd,
2837 EVENT_FD_READ,
2838 smbd_server_echo_handler,
2839 sconn);
2840 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2841 DEBUG(1, ("event_add_fd failed\n"));
2842 goto fail;
2845 return true;
2847 fail:
2848 if (listener_pipe[0] != -1) {
2849 close(listener_pipe[0]);
2851 if (listener_pipe[1] != -1) {
2852 close(listener_pipe[1]);
2854 sconn->smb1.echo_handler.trusted_fd = -1;
2855 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2856 close(sconn->smb1.echo_handler.socket_lock_fd);
2858 sconn->smb1.echo_handler.trusted_fd = -1;
2859 sconn->smb1.echo_handler.socket_lock_fd = -1;
2860 return false;
2863 static bool spoolss_init_cb(void *ptr)
2865 struct messaging_context *msg_ctx = talloc_get_type_abort(
2866 ptr, struct messaging_context);
2867 return nt_printing_tdb_migrate(msg_ctx);
2870 /****************************************************************************
2871 Process commands from the client
2872 ****************************************************************************/
2874 void smbd_process(struct smbd_server_connection *sconn)
2876 TALLOC_CTX *frame = talloc_stackframe();
2877 struct sockaddr_storage ss;
2878 struct sockaddr *sa = NULL;
2879 socklen_t sa_len;
2880 struct tsocket_address *local_address = NULL;
2881 struct tsocket_address *remote_address = NULL;
2882 const char *remaddr = NULL;
2883 int ret;
2884 struct rpc_srv_callbacks spoolss_cb;
2886 if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2887 lp_security() != SEC_SHARE &&
2888 !lp_async_smb_echo_handler()) {
2890 * We're not making the desion here,
2891 * we're just allowing the client
2892 * to decide between SMB1 and SMB2
2893 * with the first negprot
2894 * packet.
2896 sconn->using_smb2 = true;
2899 /* Ensure child is set to blocking mode */
2900 set_blocking(smbd_server_fd(),True);
2902 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2903 set_socket_options(smbd_server_fd(), lp_socket_options());
2905 sa = (struct sockaddr *)(void *)&ss;
2906 sa_len = sizeof(ss);
2907 ret = getpeername(smbd_server_fd(), sa, &sa_len);
2908 if (ret != 0) {
2909 int level = (errno == ENOTCONN)?2:0;
2910 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2911 exit_server_cleanly("getpeername() failed.\n");
2913 ret = tsocket_address_bsd_from_sockaddr(sconn,
2914 sa, sa_len,
2915 &remote_address);
2916 if (ret != 0) {
2917 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2918 __location__, strerror(errno)));
2919 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2922 sa = (struct sockaddr *)(void *)&ss;
2923 sa_len = sizeof(ss);
2924 ret = getsockname(smbd_server_fd(), sa, &sa_len);
2925 if (ret != 0) {
2926 int level = (errno == ENOTCONN)?2:0;
2927 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2928 exit_server_cleanly("getsockname() failed.\n");
2930 ret = tsocket_address_bsd_from_sockaddr(sconn,
2931 sa, sa_len,
2932 &local_address);
2933 if (ret != 0) {
2934 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2935 __location__, strerror(errno)));
2936 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2939 sconn->local_address = local_address;
2940 sconn->remote_address = remote_address;
2942 if (tsocket_address_is_inet(remote_address, "ip")) {
2943 remaddr = tsocket_address_inet_addr_string(
2944 sconn->remote_address,
2945 talloc_tos());
2946 if (remaddr == NULL) {
2949 } else {
2950 remaddr = "0.0.0.0";
2953 /* this is needed so that we get decent entries
2954 in smbstatus for port 445 connects */
2955 set_remote_machine_name(remaddr, false);
2956 reload_services(sconn->msg_ctx, true);
2959 * Before the first packet, check the global hosts allow/ hosts deny
2960 * parameters before doing any parsing of packets passed to us by the
2961 * client. This prevents attacks on our parsing code from hosts not in
2962 * the hosts allow list.
2965 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2966 lp_hostsdeny(-1))) {
2968 * send a negative session response "not listening on calling
2969 * name"
2971 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2972 DEBUG( 1, ("Connection denied from %s to %s\n",
2973 tsocket_address_string(remote_address, talloc_tos()),
2974 tsocket_address_string(local_address, talloc_tos())));
2975 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2976 0, false, NULL);
2977 exit_server_cleanly("connection denied");
2980 DEBUG(10, ("Connection allowed from %s to %s\n",
2981 tsocket_address_string(remote_address, talloc_tos()),
2982 tsocket_address_string(local_address, talloc_tos())));
2984 init_modules();
2986 smb_perfcount_init();
2988 if (!init_account_policy()) {
2989 exit_server("Could not open account policy tdb.\n");
2992 if (*lp_rootdir()) {
2993 if (chroot(lp_rootdir()) != 0) {
2994 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2995 exit_server("Failed to chroot()");
2997 if (chdir("/") == -1) {
2998 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2999 exit_server("Failed to chroot()");
3001 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3004 if (!srv_init_signing(sconn)) {
3005 exit_server("Failed to init smb_signing");
3008 if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3009 exit_server("Failed to fork echo handler");
3012 /* Setup oplocks */
3013 if (!init_oplocks(sconn->msg_ctx))
3014 exit_server("Failed to init oplocks");
3016 /* register our message handlers */
3017 messaging_register(sconn->msg_ctx, NULL,
3018 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3019 messaging_register(sconn->msg_ctx, NULL,
3020 MSG_SMB_RELEASE_IP, msg_release_ip);
3021 messaging_register(sconn->msg_ctx, NULL,
3022 MSG_SMB_CLOSE_FILE, msg_close_file);
3025 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3026 * MSGs to all child processes
3028 messaging_deregister(sconn->msg_ctx,
3029 MSG_DEBUG, NULL);
3030 messaging_register(sconn->msg_ctx, NULL,
3031 MSG_DEBUG, debug_message);
3033 if ((lp_keepalive() != 0)
3034 && !(event_add_idle(smbd_event_context(), NULL,
3035 timeval_set(lp_keepalive(), 0),
3036 "keepalive", keepalive_fn,
3037 NULL))) {
3038 DEBUG(0, ("Could not add keepalive event\n"));
3039 exit(1);
3042 if (!(event_add_idle(smbd_event_context(), NULL,
3043 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3044 "deadtime", deadtime_fn, sconn))) {
3045 DEBUG(0, ("Could not add deadtime event\n"));
3046 exit(1);
3049 if (!(event_add_idle(smbd_event_context(), NULL,
3050 timeval_set(SMBD_SELECT_TIMEOUT, 0),
3051 "housekeeping", housekeeping_fn,
3052 sconn->msg_ctx))) {
3053 DEBUG(0, ("Could not add housekeeping event\n"));
3054 exit(1);
3057 #ifdef CLUSTER_SUPPORT
3059 if (lp_clustering()) {
3061 * We need to tell ctdb about our client's TCP
3062 * connection, so that for failover ctdbd can send
3063 * tickle acks, triggering a reconnection by the
3064 * client.
3067 struct sockaddr_storage srv, clnt;
3069 if (client_get_tcp_info(&srv, &clnt) == 0) {
3071 NTSTATUS status;
3073 status = ctdbd_register_ips(
3074 messaging_ctdbd_connection(procid_self()),
3075 &srv, &clnt, release_ip, NULL);
3077 if (!NT_STATUS_IS_OK(status)) {
3078 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3079 nt_errstr(status)));
3081 } else
3083 DEBUG(0,("Unable to get tcp info for "
3084 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3085 strerror(errno)));
3089 #endif
3091 sconn->nbt.got_session = false;
3093 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3095 sconn->smb1.sessions.done_sesssetup = false;
3096 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3097 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3098 /* users from session setup */
3099 sconn->smb1.sessions.session_userlist = NULL;
3100 /* workgroup from session setup. */
3101 sconn->smb1.sessions.session_workgroup = NULL;
3102 /* this holds info on user ids that are already validated for this VC */
3103 sconn->smb1.sessions.validated_users = NULL;
3104 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3105 sconn->smb1.sessions.num_validated_vuids = 0;
3107 conn_init(sconn);
3108 if (!init_dptrs(sconn)) {
3109 exit_server("init_dptrs() failed");
3112 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3113 sconn,
3114 smbd_server_fd(),
3115 EVENT_FD_READ,
3116 smbd_server_connection_handler,
3117 sconn);
3118 if (!sconn->smb1.fde) {
3119 exit_server("failed to create smbd_server_connection fde");
3123 * Initialize spoolss with an init function to convert printers first.
3124 * static_init_rpc will try to initialize the spoolss server too but you
3125 * can't register it twice.
3127 spoolss_cb.init = spoolss_init_cb;
3128 spoolss_cb.shutdown = NULL;
3129 spoolss_cb.private_data = sconn->msg_ctx;
3131 if (!NT_STATUS_IS_OK(rpc_winreg_init(NULL))) {
3132 exit(1);
3135 if (!NT_STATUS_IS_OK(rpc_spoolss_init(&spoolss_cb))) {
3136 exit(1);
3139 static_init_rpc;
3141 TALLOC_FREE(frame);
3143 while (True) {
3144 NTSTATUS status;
3146 frame = talloc_stackframe_pool(8192);
3148 errno = 0;
3150 status = smbd_server_connection_loop_once(sconn);
3151 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3152 !NT_STATUS_IS_OK(status)) {
3153 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3154 " exiting\n", nt_errstr(status)));
3155 break;
3158 TALLOC_FREE(frame);
3161 exit_server_cleanly(NULL);
3164 bool req_is_in_chain(struct smb_request *req)
3166 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3168 * We're right now handling a subsequent request, so we must
3169 * be in a chain
3171 return true;
3174 if (!is_andx_req(req->cmd)) {
3175 return false;
3178 if (req->wct < 2) {
3180 * Okay, an illegal request, but definitely not chained :-)
3182 return false;
3185 return (CVAL(req->vwv+0, 0) != 0xFF);