2 Unix SMB/CIFS implementation.
3 Main SMB server routines
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Martin Pool 2002
6 Copyright (C) Jelmer Vernooij 2002
7 Copyright (C) James J Myers 2003 <myersjj@samba.org>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 called on a fatal error that should cause this server to terminate
30 void exit_server(struct server_context *smb, const char *reason)
32 smb->model_ops->terminate_connection(smb, reason);
37 setup a single listener of any type
39 static void setup_listen(struct event_context *events,
40 const struct model_ops *model_ops,
41 void (*accept_handler)(struct event_context *,struct fd_event *,time_t,uint16),
42 struct in_addr *ifip, unsigned port)
45 fde.fd = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
47 DEBUG(0,("Failed to open socket on %s:%u - %s\n",
48 inet_ntoa(*ifip), port, strerror(errno)));
53 set_socket_options(fde.fd, "SO_KEEPALIVE");
54 set_socket_options(fde.fd, lp_socket_options());
56 if (listen(fde.fd, SMBD_LISTEN_BACKLOG) == -1) {
57 DEBUG(0,("Failed to listen on %s:%d - %s\n",
58 inet_ntoa(*ifip), port, strerror(errno)));
63 /* we are only interested in read events on the listen socket */
64 fde.flags = EVENT_FD_READ;
65 fde.private = model_ops;
66 fde.handler = accept_handler;
68 event_add_fd(events, &fde);
72 add a socket address to the list of events, one event per port
74 static void add_socket(struct event_context *events,
75 const struct model_ops *model_ops,
79 const char *delim = ", ";
81 for (tok=strtok_r(lp_smb_ports(), delim, &ptr);
83 tok=strtok_r(NULL, delim, &ptr)) {
84 unsigned port = atoi(tok);
85 if (port == 0) continue;
86 setup_listen(events, model_ops, model_ops->accept_connection, ifip, port);
90 /****************************************************************************
91 Open the socket communication.
92 ****************************************************************************/
93 static void open_sockets_smbd(struct event_context *events,
94 const struct model_ops *model_ops)
96 if (lp_interfaces() && lp_bind_interfaces_only()) {
97 int num_interfaces = iface_count();
100 /* We have been given an interfaces line, and been
101 told to only bind to those interfaces. Create a
102 socket per interface and bind to only these.
104 for(i = 0; i < num_interfaces; i++) {
105 struct in_addr *ifip = iface_n_ip(i);
108 DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
112 add_socket(events, model_ops, ifip);
115 TALLOC_CTX *mem_ctx = talloc_init("open_sockets_smbd");
117 struct in_addr *ifip = interpret_addr2(mem_ctx, lp_socket_address());
118 /* Just bind to lp_socket_address() (usually 0.0.0.0) */
120 smb_panic("No memory");
122 add_socket(events, model_ops, ifip);
123 talloc_destroy(mem_ctx);
127 /****************************************************************************
128 Reload the services file.
129 **************************************************************************/
130 BOOL reload_services(struct server_context *smb, BOOL test)
136 pstrcpy(fname,lp_configfile());
137 if (file_exist(fname, NULL) &&
138 !strcsequal(fname, dyn_CONFIGFILE)) {
139 pstrcpy(dyn_CONFIGFILE, fname);
146 if (test && !lp_file_list_changed())
150 lp_killunused(smb, conn_snum_used);
153 ret = lp_load(dyn_CONFIGFILE, False, False, True);
157 /* perhaps the config filename is now set */
159 reload_services(smb, True);
165 mangle_reset_cache();
168 /* this forces service parameters to be flushed */
169 set_current_service(NULL,True);
174 /****************************************************************************
175 Initialise connect, service and file structs.
176 ****************************************************************************/
177 static BOOL init_structs(void)
183 /* we want to re-seed early to prevent time delays causing
184 client problems at a later date. (tridge) */
185 generate_random_buffer(NULL, 0, False);
192 setup the events for the chosen process model
194 static void setup_process_model(struct event_context *events,
197 const struct model_ops *ops;
199 ops = process_model_byname(model);
201 DEBUG(0,("Unknown process model '%s'\n", model));
205 ops->model_startup();
207 /* now setup the listening sockets, adding
208 event handlers to the events structure */
209 open_sockets_smbd(events, ops);
211 /* setup any sockets we need to listen on for RPC over TCP */
212 open_sockets_rpc(events, ops);
215 /****************************************************************************
217 ****************************************************************************/
218 int main(int argc,const char *argv[])
220 BOOL is_daemon = False;
221 BOOL interactive = False;
223 BOOL log_stdout = False;
226 struct event_context *events;
227 const char *model = "standard";
228 struct poptOption long_options[] = {
230 {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
231 {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"},
232 {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
233 {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
234 {"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
235 {"port", 'p', POPT_ARG_STRING, NULL, 0, "Listen on the specified ports"},
236 {"model", 'M', POPT_ARG_STRING, &model, 0, "select process model"},
241 pc = poptGetContext("smbd", argc, argv, long_options, 0);
243 while((opt = poptGetNextOpt(pc)) != -1) {
246 /* Display output to screen as well as debug */
251 lp_set_cmdline("smb ports", poptGetOptArg(pc));
257 events = event_context_init();
266 if (log_stdout && Fork) {
267 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
270 setup_logging(argv[0], log_stdout?DEBUG_STDOUT:DEBUG_FILE);
272 fault_setup((void (*)(void *))exit_server);
274 /* we are never interested in SIGPIPE */
275 BlockSignals(True,SIGPIPE);
278 /* we are never interested in SIGFPE */
279 BlockSignals(True,SIGFPE);
283 /* We are no longer interested in USR2 */
284 BlockSignals(True,SIGUSR2);
287 /* POSIX demands that signals are inherited. If the invoking process has
288 * these signals masked, we will have problems, as we won't recieve them. */
289 BlockSignals(False, SIGHUP);
290 BlockSignals(False, SIGUSR1);
291 BlockSignals(False, SIGTERM);
293 /* we want total control over the permissions on created files,
294 so set our umask to 0 */
299 DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
300 DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2004\n"));
302 /* Output the build options to the debug log */
303 build_options(False);
305 if (sizeof(uint16) < 2 || sizeof(uint32_t) < 4) {
306 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
309 DEBUG(0,("Using %s process model\n", model));
311 if (!reload_services(NULL, False))
316 if (!is_daemon && !is_a_socket(0)) {
318 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
321 * Setting is_daemon here prevents us from eventually calling
322 * the open_sockets_inetd()
328 if (is_daemon && !interactive) {
329 DEBUG(3,("Becoming a daemon.\n"));
333 if (!directory_exist(lp_lockdir(), NULL)) {
334 mkdir(lp_lockdir(), 0755);
338 pidfile_create("smbd");
341 register_msg_pool_usage();
342 register_dmalloc_msgs();
346 setup_process_model(events, model);
348 /* wait for events */
349 return event_loop_wait(events);