root/source4/smb_server/smb_samba3.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. samba3_smb_accept
  2. samba3_add_socket
  3. samba3_smb_task_init
  4. server_service_samba3_smb_init

   1 /*
   2    Unix SMB/CIFS implementation.
   3 
   4    process incoming connections and fork a samba3 in inetd mode
   5 
   6    Copyright (C) Stefan Metzmacher      2008
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12 
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17 
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "smbd/service_task.h"
  24 #include "smbd/service_stream.h"
  25 #include "smbd/service.h"
  26 #include "lib/messaging/irpc.h"
  27 #include "lib/stream/packet.h"
  28 #include "lib/socket/socket.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 "param/param.h"
  35 #include "dynconfig/dynconfig.h"
  36 #include "smbd/process_model.h"
  37 
  38 /*
  39   initialise a server_context from a open socket and register a event handler
  40   for reading from that socket
  41 */
  42 static void samba3_smb_accept(struct stream_connection *conn)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         int i;
  45         int fd = socket_get_fd(conn->socket);
  46         const char *prog;
  47         char *argv[2];
  48         char *reason;
  49         extern char **environ;
  50 
  51         close(0);
  52         close(1);
  53         dup2(fd, 0);
  54         dup2(fd, 1);
  55         dup2(fd, 2);
  56         for (i=3;i<256;i++) {
  57                 close(i);
  58         }
  59 
  60         prog = lp_parm_string(conn->lp_ctx, NULL, "samba3", "smbd");
  61 
  62         if (prog == NULL) {
  63                 argv[0] = talloc_asprintf(conn, "%s/%s", dyn_BINDIR, "smbd3");
  64         }
  65         else {
  66                 argv[0] = talloc_strdup(conn, prog);
  67         }
  68 
  69         if (argv[0] == NULL) {
  70                 stream_terminate_connection(conn, "out of memory");
  71                 return;
  72         }
  73         argv[1] = NULL;
  74 
  75         execve(argv[0], argv, environ);
  76 
  77         /*
  78          * Should never get here
  79          */
  80         reason = talloc_asprintf(conn, "Could not execute %s", argv[0]);
  81         if (reason == NULL) {
  82                 stream_terminate_connection(conn, "out of memory");
  83                 return;
  84         }
  85         stream_terminate_connection(conn, reason);
  86         talloc_free(reason);
  87 }
  88 
  89 static const struct stream_server_ops samba3_smb_stream_ops = {
  90         .name                   = "samba3",
  91         .accept_connection      = samba3_smb_accept,
  92 };
  93 
  94 /*
  95   setup a listening socket on all the SMB ports for a particular address
  96 */
  97 static NTSTATUS samba3_add_socket(struct tevent_context *event_context,
     /* [<][>][^][v][top][bottom][index][help] */
  98                                   struct loadparm_context *lp_ctx,
  99                                   const struct model_ops *model_ops,
 100                                   const char *address)
 101 {
 102         const char **ports = lp_smb_ports(lp_ctx);
 103         int i;
 104         NTSTATUS status;
 105 
 106         for (i=0;ports[i];i++) {
 107                 uint16_t port = atoi(ports[i]);
 108                 if (port == 0) continue;
 109                 status = stream_setup_socket(event_context, lp_ctx,
 110                                              model_ops, &samba3_smb_stream_ops,
 111                                              "ip", address, &port,
 112                                              lp_socket_options(lp_ctx),
 113                                              NULL);
 114                 NT_STATUS_NOT_OK_RETURN(status);
 115         }
 116 
 117         return NT_STATUS_OK;
 118 }
 119 
 120 
 121 /*
 122   open the smb server sockets
 123 */
 124 static void samba3_smb_task_init(struct task_server *task)
     /* [<][>][^][v][top][bottom][index][help] */
 125 {
 126         NTSTATUS status;
 127         const struct model_ops *model_ops;
 128 
 129         model_ops = process_model_startup(task->event_ctx, "standard");
 130 
 131         if (model_ops == NULL) {
 132                 goto failed;
 133         }
 134 
 135         task_server_set_title(task, "task[samba3_smb]");
 136 
 137         if (lp_interfaces(task->lp_ctx)
 138             && lp_bind_interfaces_only(task->lp_ctx)) {
 139                 int num_interfaces;
 140                 int i;
 141                 struct interface *ifaces;
 142 
 143                 load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces);
 144 
 145                 num_interfaces = iface_count(ifaces);
 146 
 147                 /* We have been given an interfaces line, and been
 148                    told to only bind to those interfaces. Create a
 149                    socket per interface and bind to only these.
 150                 */
 151                 for(i = 0; i < num_interfaces; i++) {
 152                         const char *address = iface_n_ip(ifaces, i);
 153                         status = samba3_add_socket(task->event_ctx,
 154                                                    task->lp_ctx,
 155                                                    model_ops, address);
 156                         if (!NT_STATUS_IS_OK(status)) goto failed;
 157                 }
 158         } else {
 159                 /* Just bind to lp_socket_address() (usually 0.0.0.0) */
 160                 status = samba3_add_socket(task->event_ctx, task->lp_ctx,
 161                                            model_ops,
 162                                            lp_socket_address(task->lp_ctx));
 163                 if (!NT_STATUS_IS_OK(status)) goto failed;
 164         }
 165 
 166         return;
 167 failed:
 168         task_server_terminate(task, "Failed to startup samba3 smb task");
 169 }
 170 
 171 /* called at smbd startup - register ourselves as a server service */
 172 NTSTATUS server_service_samba3_smb_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 173 {
 174         return register_server_service("samba3_smb", samba3_smb_task_init);
 175 }

/* [<][>][^][v][top][bottom][index][help] */