LCOV - code coverage report
Current view: top level - source4/smb_server - smb_server.c (source / functions) Hit Total Coverage
Test: coverage report for master 469b22b8 Lines: 66 83 79.5 %
Date: 2024-06-10 12:05:21 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    process incoming packets - main loop
       4             :    Copyright (C) Andrew Tridgell        2004-2005
       5             :    Copyright (C) Stefan Metzmacher      2004-2005
       6             :    
       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.
      11             :    
      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.
      16             :    
      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/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "samba/service_task.h"
      23             : #include "samba/service_stream.h"
      24             : #include "samba/service.h"
      25             : #include "smb_server/smb_server.h"
      26             : #include "smb_server/service_smb_proto.h"
      27             : #include "lib/messaging/irpc.h"
      28             : #include "lib/stream/packet.h"
      29             : #include "libcli/smb2/smb2.h"
      30             : #include "smb_server/smb2/smb2_server.h"
      31             : #include "system/network.h"
      32             : #include "lib/socket/netif.h"
      33             : #include "param/share.h"
      34             : #include "dsdb/samdb/samdb.h"
      35             : #include "param/param.h"
      36             : 
      37        2495 : static NTSTATUS smbsrv_recv_generic_request(void *private_data, DATA_BLOB blob)
      38             : {
      39           0 :         NTSTATUS status;
      40        2495 :         struct smbsrv_connection *smb_conn = talloc_get_type(private_data, struct smbsrv_connection);
      41           0 :         uint32_t protocol_version;
      42             : 
      43             :         /* see if its a special NBT packet */
      44        2495 :         if (CVAL(blob.data,0) != 0) {
      45           6 :                 status = smbsrv_init_smb_connection(smb_conn, smb_conn->lp_ctx);
      46           6 :                 NT_STATUS_NOT_OK_RETURN(status);
      47           6 :                 return smbsrv_recv_smb_request(smb_conn, blob);
      48             :         }
      49             : 
      50        2489 :         if (blob.length < (NBT_HDR_SIZE + MIN_SMB_SIZE)) {
      51           0 :                 DEBUG(2,("Invalid SMB packet length count %ld\n", (long)blob.length));
      52           0 :                 smbsrv_terminate_connection(smb_conn, "Invalid SMB packet");
      53           0 :                 return NT_STATUS_OK;
      54             :         }
      55             : 
      56        2489 :         protocol_version = IVAL(blob.data, NBT_HDR_SIZE);
      57             : 
      58        2489 :         switch (protocol_version) {
      59        2095 :         case SMB_MAGIC:
      60        2095 :                 status = smbsrv_init_smb_connection(smb_conn, smb_conn->lp_ctx);
      61        2095 :                 NT_STATUS_NOT_OK_RETURN(status);
      62        2095 :                 packet_set_callback(smb_conn->packet, smbsrv_recv_smb_request);
      63        2095 :                 return smbsrv_recv_smb_request(smb_conn, blob);
      64         394 :         case SMB2_MAGIC:
      65         394 :                 if (lpcfg_server_max_protocol(smb_conn->lp_ctx) < PROTOCOL_SMB2_02) break;
      66         394 :                 status = smbsrv_init_smb2_connection(smb_conn);
      67         394 :                 NT_STATUS_NOT_OK_RETURN(status);
      68         394 :                 packet_set_callback(smb_conn->packet, smbsrv_recv_smb2_request);
      69         394 :                 return smbsrv_recv_smb2_request(smb_conn, blob);
      70             :         }
      71             : 
      72           0 :         DEBUG(2,("Invalid SMB packet: protocol prefix: 0x%08X\n", protocol_version));
      73           0 :         smbsrv_terminate_connection(smb_conn, "NON-SMB packet");
      74           0 :         return NT_STATUS_OK;
      75             : }
      76             : 
      77             : /*
      78             :   close the socket and shutdown a server_context
      79             : */
      80        2500 : void smbsrv_terminate_connection(struct smbsrv_connection *smb_conn, const char *reason)
      81             : {
      82        2500 :         stream_terminate_connection(smb_conn->connection, reason);
      83        2500 : }
      84             : 
      85             : /*
      86             :   called when a SMB socket becomes readable
      87             : */
      88     1710128 : static void smbsrv_recv(struct stream_connection *conn, uint16_t flags)
      89             : {
      90     1710128 :         struct smbsrv_connection *smb_conn = talloc_get_type(conn->private_data,
      91             :                                                              struct smbsrv_connection);
      92             : 
      93     1710128 :         DEBUG(10,("smbsrv_recv\n"));
      94             : 
      95     1710128 :         packet_recv(smb_conn->packet);
      96     1710128 : }
      97             : 
      98             : /*
      99             :   called when a SMB socket becomes writable
     100             : */
     101      882934 : static void smbsrv_send(struct stream_connection *conn, uint16_t flags)
     102             : {
     103      882934 :         struct smbsrv_connection *smb_conn = talloc_get_type(conn->private_data,
     104             :                                                              struct smbsrv_connection);
     105      882934 :         packet_queue_run(smb_conn->packet);
     106      882934 : }
     107             : 
     108             : /*
     109             :   handle socket recv errors
     110             : */
     111        2495 : static void smbsrv_recv_error(void *private_data, NTSTATUS status)
     112             : {
     113        2495 :         struct smbsrv_connection *smb_conn = talloc_get_type(private_data, struct smbsrv_connection);
     114             :         
     115        2495 :         smbsrv_terminate_connection(smb_conn, nt_errstr(status));
     116        2495 : }
     117             : 
     118             : /*
     119             :   initialise a server_context from a open socket and register a event handler
     120             :   for reading from that socket
     121             : */
     122        2503 : static void smbsrv_accept(struct stream_connection *conn)
     123             : {
     124           0 :         struct smbsrv_connection *smb_conn;
     125             : 
     126        2503 :         DEBUG(5,("smbsrv_accept\n"));
     127             : 
     128        2503 :         smb_conn = talloc_zero(conn, struct smbsrv_connection);
     129        2503 :         if (!smb_conn) {
     130           0 :                 stream_terminate_connection(conn, "out of memory");
     131           0 :                 return;
     132             :         }
     133             : 
     134        2503 :         smb_conn->packet = packet_init(smb_conn);
     135        2503 :         if (!smb_conn->packet) {
     136           0 :                 smbsrv_terminate_connection(smb_conn, "out of memory");
     137           0 :                 return;
     138             :         }
     139        2503 :         packet_set_private(smb_conn->packet, smb_conn);
     140        2503 :         packet_set_socket(smb_conn->packet, conn->socket);
     141        2503 :         packet_set_callback(smb_conn->packet, smbsrv_recv_generic_request);
     142        2503 :         packet_set_full_request(smb_conn->packet, packet_full_request_nbt);
     143        2503 :         packet_set_error_handler(smb_conn->packet, smbsrv_recv_error);
     144        2503 :         packet_set_event_context(smb_conn->packet, conn->event.ctx);
     145        2503 :         packet_set_fde(smb_conn->packet, conn->event.fde);
     146        2503 :         packet_set_serialise(smb_conn->packet);
     147        2503 :         packet_set_initial_read(smb_conn->packet, 4);
     148             : 
     149        2503 :         smb_conn->lp_ctx = conn->lp_ctx;
     150        2503 :         smb_conn->connection = conn;
     151        2503 :         conn->private_data = smb_conn;
     152             : 
     153        2503 :         smb_conn->statistics.connect_time = timeval_current();
     154             : 
     155        2503 :         smbsrv_management_init(smb_conn);
     156             : 
     157        2503 :         irpc_add_name(conn->msg_ctx, "smb_server");
     158             : 
     159        2503 :         if (!NT_STATUS_IS_OK(share_get_context(smb_conn,
     160             :                                                smb_conn->lp_ctx,
     161             :                                                &(smb_conn->share_context)))) {
     162           0 :                 smbsrv_terminate_connection(smb_conn, "share_init failed!");
     163           0 :                 return;
     164             :         }
     165             : }
     166             : 
     167             : static const struct stream_server_ops smb_stream_ops = {
     168             :         .name                   = "smbsrv",
     169             :         .accept_connection      = smbsrv_accept,
     170             :         .recv_handler           = smbsrv_recv,
     171             :         .send_handler           = smbsrv_send,
     172             : };
     173             : 
     174             : /*
     175             :   setup a listening socket on all the SMB ports for a particular address
     176             : */
     177          32 : _PUBLIC_ NTSTATUS smbsrv_add_socket(TALLOC_CTX *mem_ctx,
     178             :                                     struct tevent_context *event_context,
     179             :                                     struct loadparm_context *lp_ctx,
     180             :                                     const struct model_ops *model_ops,
     181             :                                     const char *address,
     182             :                                     void *process_context)
     183             : {
     184          32 :         const char **ports = lpcfg_smb_ports(lp_ctx);
     185           0 :         int i;
     186           0 :         NTSTATUS status;
     187             : 
     188          96 :         for (i=0;ports[i];i++) {
     189          64 :                 uint16_t port = atoi(ports[i]);
     190          64 :                 if (port == 0) continue;
     191          64 :                 status = stream_setup_socket(mem_ctx, event_context, lp_ctx,
     192             :                                              model_ops, &smb_stream_ops, 
     193             :                                              "ip", address, &port,
     194             :                                              lpcfg_socket_options(lp_ctx),
     195             :                                              NULL, process_context);
     196          64 :                 NT_STATUS_NOT_OK_RETURN(status);
     197             :         }
     198             : 
     199          32 :         return NT_STATUS_OK;
     200             : }
     201             : 
     202             : 
     203             : 

Generated by: LCOV version 1.14