And finally IDMAP in 3_0
[tprouty/samba.git] / source3 / smbd / server.c
index 9bc02c3e17578451f0dbded44b5df20475662427..edc7b57ba3988f32c84fc2fe2dc3648af00ae488 100644 (file)
@@ -3,7 +3,7 @@
    Main SMB server routines
    Copyright (C) Andrew Tridgell               1992-1998
    Copyright (C) Martin Pool                   2002
-   Copyright (C) Jelmer Vernooij               2002
+   Copyright (C) Jelmer Vernooij               2002-2003
    
    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
@@ -141,11 +141,45 @@ static void msg_exit_server(int msg_type, pid_t src, void *buf, size_t len)
 }
 
 
+/****************************************************************************
+ Have we reached the process limit ?
+****************************************************************************/
+
+BOOL allowable_number_of_smbd_processes(void)
+{
+       int max_processes = lp_max_smbd_processes();
+
+       if (!max_processes)
+               return True;
+
+       {
+               TDB_CONTEXT *tdb = conn_tdb_ctx();
+               int32 val;
+               if (!tdb) {
+                       DEBUG(0,("allowable_number_of_smbd_processes: can't open connection tdb.\n" ));
+                       return False;
+               }
+
+               val = tdb_fetch_int32(tdb, "INFO/total_smbds");
+               if (val == -1 && (tdb_error(tdb) != TDB_ERR_NOEXIST)) {
+                       DEBUG(0,("allowable_number_of_smbd_processes: can't fetch INFO/total_smbds. Error %s\n",
+                               tdb_errorstr(tdb) ));
+                       return False;
+               }
+               if (val > max_processes) {
+                       DEBUG(0,("allowable_number_of_smbd_processes: number of processes (%d) is over allowed limit (%d)\n",
+                               val, max_processes ));
+                       return False;
+               }
+       }
+       return True;
+}
+
 /****************************************************************************
  Open the socket communication.
 ****************************************************************************/
 
-static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
+static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports)
 {
        int num_interfaces = iface_count();
        int num_sockets = 0;
@@ -179,11 +213,12 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
        if (!smb_ports) {
                ports = lp_smb_ports();
                if (!ports || !*ports) {
-                       ports = SMB_PORTS;
+                       ports = smb_xstrdup(SMB_PORTS);
+               } else {
+                       ports = smb_xstrdup(ports);
                }
-               ports = strdup(ports);
        } else {
-               ports = strdup(smb_ports);
+               ports = smb_xstrdup(smb_ports);
        }
 
        if (lp_interfaces() && lp_bind_interfaces_only()) {
@@ -320,7 +355,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
                for( ; num > 0; num--) {
                        struct sockaddr addr;
                        socklen_t in_addrlen = sizeof(addr);
-                       
+
                        s = -1;
                        for(i = 0; i < num_sockets; i++) {
                                if(FD_ISSET(fd_listenset[i],&lfds)) {
@@ -342,8 +377,11 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
                                         strerror(errno)));
                                continue;
                        }
+
+                       if (smbd_server_fd() != -1 && interactive)
+                               return True;
                        
-                       if (smbd_server_fd() != -1 && sys_fork()==0) {
+                       if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) {
                                /* Child code ... */
                                
                                /* close the listening socket(s) */
@@ -360,7 +398,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
                                
                                /* this is needed so that we get decent entries
                                   in smbstatus for port 445 connects */
-                               set_remote_machine_name(get_socket_addr(smbd_server_fd()));
+                               set_remote_machine_name(get_socket_addr(smbd_server_fd()), False);
                                
                                /* Reset global variables in util.c so
                                   that client substitutions will be
@@ -373,10 +411,6 @@ static BOOL open_sockets_smbd(BOOL is_daemon,const char *smb_ports)
                                        return False;
                                }
 
-                               /* Load DSO's */
-                               if(lp_modules()) 
-                                       smb_load_modules(lp_modules());
-
                                return True; 
                        }
                        /* The parent doesn't need this socket */
@@ -467,25 +501,6 @@ BOOL reload_services(BOOL test)
        return(ret);
 }
 
-/*******************************************************************
- Print out all talloc memory info.
-********************************************************************/
-
-void return_all_talloc_info(int msg_type, pid_t src_pid, void *buf, size_t len)
-{
-       TALLOC_CTX *ctx = talloc_init("info context");
-       char *info = NULL;
-
-       if (!ctx)
-               return;
-
-       info = talloc_describe_all(ctx);
-       if (info)
-               DEBUG(10,(info));
-       message_send_pid(src_pid, MSG_TALLOC_USAGE, info, info ? strlen(info) + 1 : 0, True);
-       talloc_destroy(ctx);
-}
-
 #if DUMP_CORE
 /*******************************************************************
 prepare to dump a core file - carefully!
@@ -525,25 +540,11 @@ static BOOL dump_core(void)
 }
 #endif
 
-/****************************************************************************
-update the current smbd process count
-****************************************************************************/
-
-static void decrement_smbd_process_count(void)
-{
-       int32 total_smbds;
-
-       if (lp_max_smbd_processes()) {
-               total_smbds = 0;
-               tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
-       }
-}
-
 /****************************************************************************
  Exit the server.
 ****************************************************************************/
 
-void exit_server(char *reason)
+void exit_server(const char *reason)
 {
        static int firsttime=1;
        extern char *last_inbuf;
@@ -564,7 +565,10 @@ void exit_server(char *reason)
 
        invalidate_all_vuids();
 
-       print_notify_send_messages();   
+       print_notify_send_messages(3); /* 3 second timeout. */
+
+       /* run all registered exit events */
+       smb_run_exit_events();
 
        /* delete our entry in the connections database. */
        yield_connection(NULL,"");
@@ -635,6 +639,8 @@ static BOOL init_structs(void )
        /* shall I run as a daemon */
        static BOOL is_daemon = False;
        static BOOL interactive = False;
+       static BOOL Fork = True;
+       static BOOL log_stdout = False;
        static char *ports = NULL;
        int opt;
        poptContext pc;
@@ -643,13 +649,11 @@ static BOOL init_structs(void )
                POPT_AUTOHELP
        {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
        {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"},
+       {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
+       {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
        {"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
        {"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified ports"},
-       {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug},
-       {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_configfile},
-       {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_socket_options},
-       {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_log_base},
-       {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version},
+       POPT_COMMON_SAMBA
        { NULL }
        };
 
@@ -679,9 +683,19 @@ static BOOL init_structs(void )
 
        load_case_tables();
 
-       set_remote_machine_name("smbd");
+       set_remote_machine_name("smbd", False);
 
-       setup_logging(argv[0],interactive);
+       if (interactive) {
+               Fork = False;
+               log_stdout = True;
+       }
+
+       if (log_stdout && Fork) {
+               DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
+               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) */
@@ -725,7 +739,7 @@ static BOOL init_structs(void )
        reopen_logs();
 
        DEBUG(0,( "smbd version %s started.\n", VERSION));
-       DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2002\n"));
+       DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2003\n"));
 
        DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
                 (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
@@ -770,7 +784,7 @@ static BOOL init_structs(void )
 
        if (is_daemon && !interactive) {
                DEBUG( 3, ( "Becoming a daemon.\n" ) );
-               become_daemon();
+               become_daemon(Fork);
        }
 
 #if HAVE_SETPGID
@@ -791,10 +805,6 @@ static BOOL init_structs(void )
        if (!message_init())
                exit(1);
 
-       register_msg_pool_usage();
-       register_dmalloc_msgs();
-       message_register(MSG_REQ_TALLOC_USAGE, return_all_talloc_info);
-
        if (!print_backend_init())
                exit(1);
 
@@ -808,7 +818,7 @@ static BOOL init_structs(void )
           start_background_queue(); 
        */
 
-       if (!open_sockets_smbd(is_daemon,ports))
+       if (!open_sockets_smbd(is_daemon, interactive, ports))
                exit(1);
 
        /*
@@ -829,6 +839,16 @@ static BOOL init_structs(void )
        if(!initialize_password_db(False))
                exit(1);
 
+       if (!idmap_init())
+               exit(1);
+
+       if (!idmap_init_wellknown_sids())
+               exit(1);
+
+       static_init_rpc;
+
+       init_modules();
+
        uni_group_cache_init(); /* Non-critical */
        
        /* possibly reload the services file. */