Remove redundant parameter fd from SMB_VFS_FTRUNCATE().
[ira/wip.git] / source3 / smbd / server.c
index fbf886ee678cdcd4a2e1355afae6314f9ee9d607..43a6d62a2898c544b45a6654d13cbfe1bb7b515b 100644 (file)
@@ -27,14 +27,7 @@ static_decl_rpc;
 
 static int am_parent = 1;
 
-/* the last message the was processed */
-int last_message = -1;
-
-/* a useful macro to debug the last message processed */
-#define LAST_MESSAGE() smb_fn_name(last_message)
-
 extern struct auth_context *negprot_global_auth_context;
-extern pstring user_socket_options;
 extern SIG_ATOMIC_T got_sig_term;
 extern SIG_ATOMIC_T reload_after_sighup;
 static SIG_ATOMIC_T got_sig_cld;
@@ -87,6 +80,19 @@ struct messaging_context *smbd_messaging_context(void)
        return ctx;
 }
 
+struct memcache *smbd_memcache(void)
+{
+       static struct memcache *cache;
+
+       if (!cache
+           && !(cache = memcache_init(NULL,
+                                      lp_max_stat_cache_size()*1024))) {
+
+               smb_panic("Could not init smbd memcache");
+       }
+       return cache;
+}
+
 /*******************************************************************
  What to do when smb.conf is updated.
  ********************************************************************/
@@ -186,7 +192,7 @@ static bool open_sockets_inetd(void)
        close_low_fds(False); /* Don't close stderr */
        
        set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
-       set_socket_options(smbd_server_fd(), user_socket_options);
+       set_socket_options(smbd_server_fd(), lp_socket_options());
 
        return True;
 }
@@ -312,6 +318,8 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
        int maxfd = 0;
        int i;
        char *ports;
+       struct dns_reg_state * dns_reg = NULL;
+       unsigned dns_port = 0;
 
        if (!is_daemon) {
                return open_sockets_inetd();
@@ -353,9 +361,10 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                /* Now open a listen socket for each of the
                   interfaces. */
                for(i = 0; i < num_interfaces; i++) {
+                       TALLOC_CTX *frame = NULL;
                        const struct sockaddr_storage *ifss =
                                        iface_n_sockaddr_storage(i);
-                       fstring tok;
+                       char *tok;
                        const char *ptr;
 
                        if (ifss == NULL) {
@@ -365,12 +374,21 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                continue;
                        }
 
-                       for (ptr=ports; next_token(&ptr, tok, " \t,",
-                                               sizeof(tok)); ) {
+                       frame = talloc_stackframe();
+                       for (ptr=ports;
+                                       next_token_talloc(frame,&ptr, &tok, " \t,");) {
                                unsigned port = atoi(tok);
                                if (port == 0 || port > 0xffff) {
                                        continue;
                                }
+
+                               /* Keep the first port for mDNS service
+                                * registration.
+                                */
+                               if (dns_port == 0) {
+                                       dns_port = port;
+                               }
+
                                s = fd_listenset[num_sockets] =
                                        open_socket_in(SOCK_STREAM, port, 0,
                                                        ifss, True);
@@ -380,7 +398,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 
                                /* ready to listen */
                                set_socket_options(s,"SO_KEEPALIVE");
-                               set_socket_options(s,user_socket_options);
+                               set_socket_options(s,lp_socket_options());
 
                                /* Set server socket to
                                 * non-blocking for the accept. */
@@ -390,6 +408,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                        DEBUG(0,("open_sockets_smbd: listen: "
                                                "%s\n", strerror(errno)));
                                        close(s);
+                                       TALLOC_FREE(frame);
                                        return False;
                                }
                                FD_SET(s,&listen_set);
@@ -399,18 +418,21 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                if (num_sockets >= FD_SETSIZE) {
                                        DEBUG(0,("open_sockets_smbd: Too "
                                                "many sockets to bind to\n"));
+                                       TALLOC_FREE(frame);
                                        return False;
                                }
                        }
+                       TALLOC_FREE(frame);
                }
        } else {
                /* Just bind to 0.0.0.0 - accept connections
                   from anywhere. */
 
-               fstring tok;
+               TALLOC_CTX *frame = talloc_stackframe();
+               char *tok;
                const char *ptr;
                const char *sock_addr = lp_socket_address();
-               fstring sock_tok;
+               char *sock_tok;
                const char *sock_ptr;
 
                if (strequal(sock_addr, "0.0.0.0") ||
@@ -422,16 +444,23 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 #endif
                }
 
-               for (sock_ptr=sock_addr; next_token(&sock_ptr, sock_tok, " \t,",
-                                       sizeof(sock_tok)); ) {
-                       for (ptr=ports; next_token(&ptr, tok, " \t,",
-                                               sizeof(tok)); ) {
+               for (sock_ptr=sock_addr;
+                               next_token_talloc(frame, &sock_ptr, &sock_tok, " \t,"); ) {
+                       for (ptr=ports; next_token_talloc(frame, &ptr, &tok, " \t,"); ) {
                                struct sockaddr_storage ss;
 
                                unsigned port = atoi(tok);
                                if (port == 0 || port > 0xffff) {
                                        continue;
                                }
+
+                               /* Keep the first port for mDNS service
+                                * registration.
+                                */
+                               if (dns_port == 0) {
+                                       dns_port = port;
+                               }
+
                                /* open an incoming socket */
                                if (!interpret_string_addr(&ss, sock_tok,
                                                AI_NUMERICHOST|AI_PASSIVE)) {
@@ -446,7 +475,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
 
                                /* ready to listen */
                                set_socket_options(s,"SO_KEEPALIVE");
-                               set_socket_options(s,user_socket_options);
+                               set_socket_options(s,lp_socket_options());
 
                                /* Set server socket to non-blocking
                                 * for the accept. */
@@ -457,6 +486,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                                "listen: %s\n",
                                                 strerror(errno)));
                                        close(s);
+                                       TALLOC_FREE(frame);
                                        return False;
                                }
 
@@ -469,10 +499,12 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                if (num_sockets >= FD_SETSIZE) {
                                        DEBUG(0,("open_sockets_smbd: Too "
                                                "many sockets to bind to\n"));
+                                       TALLOC_FREE(frame);
                                        return False;
                                }
                        }
                }
+               TALLOC_FREE(frame);
        }
 
        SAFE_FREE(ports);
@@ -536,6 +568,12 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                FD_ZERO(&w_fds);
                GetTimeOfDay(&now);
 
+               /* Kick off our mDNS registration. */
+               if (dns_port != 0) {
+                       dns_register_smbd(&dns_reg, dns_port, &maxfd,
+                                       &r_fds, &idle_timeout);
+               }
+
                event_add_to_select_args(smbd_event_context(), &now,
                                         &r_fds, &w_fds, &idle_timeout,
                                         &maxfd);
@@ -560,6 +598,11 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                        continue;
                }
 
+               /* process pending nDNS responses */
+               if (dns_register_smbd_reply(dns_reg, &r_fds, &idle_timeout)) {
+                       --num;
+               }
+
                if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
                        continue;
                }
@@ -617,13 +660,17 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
                                for(i = 0; i < num_sockets; i++)
                                        close(fd_listenset[i]);
 
+                               /* close our mDNS daemon handle */
+                               dns_register_close(&dns_reg);
+
                                /* close our standard file
                                   descriptors */
                                close_low_fds(False);
                                am_parent = 0;
 
                                set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
-                               set_socket_options(smbd_server_fd(),user_socket_options);
+                               set_socket_options(smbd_server_fd(),
+                                                  lp_socket_options());
 
                                /* this is needed so that we get decent entries
                                   in smbstatus for port 445 connects */
@@ -726,13 +773,12 @@ void reload_printers(void)
 bool reload_services(bool test)
 {
        bool ret;
-       
+
        if (lp_loaded()) {
-               pstring fname;
-               pstrcpy(fname,lp_configfile());
+               char *fname = lp_configfile();
                if (file_exist(fname, NULL) &&
-                   !strcsequal(fname, dyn_CONFIGFILE)) {
-                       pstrcpy(dyn_CONFIGFILE, fname);
+                   !strcsequal(fname, get_dyn_CONFIGFILE())) {
+                       set_dyn_CONFIGFILE(fname);
                        test = False;
                }
        }
@@ -744,7 +790,7 @@ bool reload_services(bool test)
 
        lp_killunused(conn_snum_used);
 
-       ret = lp_load(dyn_CONFIGFILE, False, False, True, True);
+       ret = lp_load(get_dyn_CONFIGFILE(), False, False, True, True);
 
        reload_printers();
 
@@ -756,9 +802,9 @@ bool reload_services(bool test)
 
        load_interfaces();
 
-       if (smbd_server_fd() != -1) {      
+       if (smbd_server_fd() != -1) {
                set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
-               set_socket_options(smbd_server_fd(), user_socket_options);
+               set_socket_options(smbd_server_fd(), lp_socket_options());
        }
 
        mangle_reset_cache();
@@ -955,8 +1001,7 @@ extern void build_options(bool screen);
        POPT_COMMON_DYNCONFIG
        POPT_TABLEEND
        };
-
-       load_case_tables();
+       TALLOC_CTX *frame = talloc_stackframe(); /* Setup tos. */
 
        TimeInit();
 
@@ -994,11 +1039,20 @@ extern void build_options(bool screen);
        }
        poptFreeContext(pc);
 
+       if (interactive) {
+               Fork = False;
+               log_stdout = True;
+       }
+
+       setup_logging(argv[0],log_stdout);
+
        if (print_build_options) {
                build_options(True); /* Display output to screen as well as debug */
                exit(0);
        }
 
+       load_case_tables();
+
 #ifdef HAVE_SETLUID
        /* needed for SecureWare on SCO */
        setluid(0);
@@ -1008,11 +1062,6 @@ extern void build_options(bool screen);
 
        set_remote_machine_name("smbd", False);
 
-       if (interactive) {
-               Fork = False;
-               log_stdout = True;
-       }
-
        if (interactive && (DEBUGLEVEL >= 9)) {
                talloc_enable_leak_report();
        }
@@ -1022,8 +1071,6 @@ extern void build_options(bool screen);
                exit(1);
        }
 
-       setup_logging(argv[0],log_stdout);
-
        /* we want to re-seed early to prevent time delays causing
            client problems at a later date. (tridge) */
        generate_random_buffer(NULL, 0);
@@ -1144,6 +1191,12 @@ extern void build_options(bool screen);
        if (smbd_messaging_context() == NULL)
                exit(1);
 
+       if (smbd_memcache() == NULL) {
+               exit(1);
+       }
+
+       memcache_set_global(smbd_memcache());
+
        /* Initialise the password backed before the global_sam_sid
           to ensure that we fetch from ldap before we make a domain sid up */
 
@@ -1166,7 +1219,7 @@ extern void build_options(bool screen);
        if (!connections_init(True))
                exit(1);
 
-       if (!locking_init(0))
+       if (!locking_init())
                exit(1);
 
        namecache_enable();
@@ -1232,7 +1285,7 @@ extern void build_options(bool screen);
        /* Setup oplocks */
        if (!init_oplocks(smbd_messaging_context()))
                exit(1);
-       
+
        /* Setup aio signal handler. */
        initialize_async_io_handler();
 
@@ -1263,6 +1316,8 @@ extern void build_options(bool screen);
                exit(1);
        }
 
+       TALLOC_FREE(frame);
+
        smbd_process();
 
        namecache_shutdown();