Merge commit 'release-4-0-0alpha1' into v4-0-test
[kai/samba.git] / source / smb_server / smb_server.c
index 4fbc428a42c8b5e44435d1387bf56ff90711ea9e..691934f71c10544921cb614a426326e0bdb1ceaa 100644 (file)
@@ -6,7 +6,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -15,8 +15,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -32,6 +31,8 @@
 #include "system/network.h"
 #include "lib/socket/netif.h"
 #include "param/share.h"
+#include "dsdb/samdb/samdb.h"
+#include "param/param.h"
 
 static NTSTATUS smbsrv_recv_generic_request(void *private, DATA_BLOB blob)
 {
@@ -62,7 +63,7 @@ static NTSTATUS smbsrv_recv_generic_request(void *private, DATA_BLOB blob)
                packet_set_callback(smb_conn->packet, smbsrv_recv_smb_request);
                return smbsrv_recv_smb_request(smb_conn, blob);
        case SMB2_MAGIC:
-               if (lp_srv_maxprotocol() < PROTOCOL_SMB2) break;
+               if (lp_srv_maxprotocol(global_loadparm) < PROTOCOL_SMB2) break;
                status = smbsrv_init_smb2_connection(smb_conn);
                NT_STATUS_NOT_OK_RETURN(status);
                packet_set_callback(smb_conn->packet, smbsrv_recv_smb2_request);
@@ -173,11 +174,11 @@ static const struct stream_server_ops smb_stream_ops = {
 /*
   setup a listening socket on all the SMB ports for a particular address
 */
-static NTSTATUS smb_add_socket(struct event_context *event_context,
+_PUBLIC_ NTSTATUS smbsrv_add_socket(struct event_context *event_context,
                               const struct model_ops *model_ops,
                               const char *address)
 {
-       const char **ports = lp_smb_ports();
+       const char **ports = lp_smb_ports(global_loadparm);
        int i;
        NTSTATUS status;
 
@@ -192,6 +193,19 @@ static NTSTATUS smb_add_socket(struct event_context *event_context,
        return NT_STATUS_OK;
 }
 
+
+/*
+  pre-open some of our ldb databases, to prevent an explosion of memory usage
+  when we fork
+ */
+static void smbsrv_preopen_ldb(struct task_server *task)
+{
+       /* yes, this looks strange. It is a hack to preload the
+          schema. I'd like to share most of the ldb context with the
+          child too. That will come later */
+       talloc_free(samdb_connect(task, NULL));
+}
+
 /*
   open the smb server sockets
 */
@@ -201,7 +215,7 @@ static void smbsrv_task_init(struct task_server *task)
 
        task_server_set_title(task, "task[smbsrv]");
 
-       if (lp_interfaces() && lp_bind_interfaces_only()) {
+       if (lp_interfaces(global_loadparm) && lp_bind_interfaces_only(global_loadparm)) {
                int num_interfaces = iface_count();
                int i;
 
@@ -211,15 +225,18 @@ static void smbsrv_task_init(struct task_server *task)
                */
                for(i = 0; i < num_interfaces; i++) {
                        const char *address = iface_n_ip(i);
-                       status = smb_add_socket(task->event_ctx, task->model_ops, address);
+                       status = smbsrv_add_socket(task->event_ctx, task->model_ops, address);
                        if (!NT_STATUS_IS_OK(status)) goto failed;
                }
        } else {
                /* Just bind to lp_socket_address() (usually 0.0.0.0) */
-               status = smb_add_socket(task->event_ctx, task->model_ops, lp_socket_address());
+               status = smbsrv_add_socket(task->event_ctx, task->model_ops, 
+                                          lp_socket_address(global_loadparm));
                if (!NT_STATUS_IS_OK(status)) goto failed;
        }
 
+       smbsrv_preopen_ldb(task);
+
        return;
 failed:
        task_server_terminate(task, "Failed to startup smb server task");