first public release of samba4 code
[bbaumbach/samba-autobuild/.git] / source4 / smbd / server.c
1 /* 
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>
8    
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.
13    
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.
18    
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.
22 */
23
24 #include "includes.h"
25
26
27 /*
28   called on a fatal error that should cause this server to terminate
29 */
30 void exit_server(struct server_context *smb, const char *reason)
31 {
32         smb->model_ops->terminate_connection(smb, reason);
33 }
34
35
36 /*
37   add a socket address to the list of events, one event per port
38 */
39 static void add_socket(struct event_context *events, 
40                        struct model_ops *model_ops, 
41                        struct in_addr *ifip)
42 {
43         char *ports = lp_smb_ports();
44         char *ptr, *tok;
45         const char *delim = ", ";
46
47         for (tok=strtok_r(ports, delim, &ptr); 
48              tok; 
49              tok=strtok_r(NULL, delim, &ptr)) {
50                 unsigned port = atoi(tok);
51                 struct fd_event fde;
52
53                 if (port == 0) continue;
54
55                 fde.fd = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
56                 if (fde.fd == -1) {
57                         DEBUG(0,("Failed to open socket on %s:%u - %s\n",
58                                  inet_ntoa(*ifip), port, strerror(errno)));
59                         continue;
60                 }
61
62                 /* ready to listen */
63                 set_socket_options(fde.fd, "SO_KEEPALIVE"); 
64                 set_socket_options(fde.fd, lp_socket_options());
65       
66                 if (listen(fde.fd, 10) == -1) {
67                         DEBUG(0,("Failed to listen on %s:%d - %s\n",
68                                  inet_ntoa(*ifip), port, strerror(errno)));
69                         close(fde.fd);
70                         continue;
71                 }
72
73                 /* we are only interested in read events on the listen socket */
74                 fde.flags = EVENT_FD_READ;
75                 fde.private = model_ops;
76                 fde.handler = model_ops->accept_connection;
77
78                 event_add_fd(events, &fde);
79         }
80 }
81
82 /****************************************************************************
83  Open the socket communication.
84 ****************************************************************************/
85 static void open_sockets_smbd(struct event_context *events,
86                               struct model_ops *model_ops)
87 {
88         if (lp_interfaces() && lp_bind_interfaces_only()) {
89                 int num_interfaces = iface_count();
90                 int i;
91
92                 /* We have been given an interfaces line, and been 
93                    told to only bind to those interfaces. Create a
94                    socket per interface and bind to only these.
95                 */
96                 for(i = 0; i < num_interfaces; i++) {
97                         struct in_addr *ifip = iface_n_ip(i);
98
99                         if (ifip == NULL) {
100                                 DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
101                                 continue;
102                         }
103
104                         add_socket(events, model_ops, ifip);
105                 }
106         } else {
107                 TALLOC_CTX *mem_ctx = talloc_init("open_sockets_smbd");
108                 
109                 struct in_addr *ifip = interpret_addr2(mem_ctx, lp_socket_address());
110                 /* Just bind to lp_socket_address() (usually 0.0.0.0) */
111                 if (!mem_ctx) {
112                         smb_panic("No memory");
113                 }
114                 add_socket(events, model_ops, ifip);
115                 talloc_destroy(mem_ctx);
116         } 
117 }
118
119 /****************************************************************************
120  Reload the services file.
121 **************************************************************************/
122 BOOL reload_services(struct server_context *smb, BOOL test)
123 {
124         BOOL ret;
125         
126         if (lp_loaded()) {
127                 pstring fname;
128                 pstrcpy(fname,lp_configfile());
129                 if (file_exist(fname, NULL) &&
130                     !strcsequal(fname, dyn_CONFIGFILE)) {
131                         pstrcpy(dyn_CONFIGFILE, fname);
132                         test = False;
133                 }
134         }
135
136         reopen_logs();
137
138         if (test && !lp_file_list_changed())
139                 return(True);
140
141         if (smb) {
142                 lp_killunused(smb, conn_snum_used);
143         }
144         
145         ret = lp_load(dyn_CONFIGFILE, False, False, True);
146
147         load_printers();
148
149         /* perhaps the config filename is now set */
150         if (!test)
151                 reload_services(smb, True);
152
153         reopen_logs();
154
155         load_interfaces();
156
157         mangle_reset_cache();
158         reset_stat_cache();
159
160         /* this forces service parameters to be flushed */
161         set_current_service(NULL,True);
162
163         return(ret);
164 }
165
166 /****************************************************************************
167  Initialise connect, service and file structs.
168 ****************************************************************************/
169 static BOOL init_structs(void)
170 {
171         init_names();
172         file_init();
173         init_rpc_pipe_hnd();
174         secrets_init();
175
176         /* we want to re-seed early to prevent time delays causing
177            client problems at a later date. (tridge) */
178         generate_random_buffer(NULL, 0, False);
179
180         return True;
181 }
182
183
184 /*
185   setup the events for the chosen process model
186 */
187 static void setup_process_model(struct event_context *events, 
188                                 const char *model)
189 {
190         struct model_ops *ops;
191
192         process_model_init();
193
194         ops = process_model_byname(model);
195         if (!ops) {
196                 DEBUG(0,("Unknown process model '%s'\n", model));
197                 exit(-1);
198         }
199
200         ops->model_startup();
201
202         /* now setup the listening sockets, adding 
203            event handlers to the events structure */
204         open_sockets_smbd(events, ops);
205 }
206
207 /****************************************************************************
208  main program.
209 ****************************************************************************/
210  int main(int argc,const char *argv[])
211 {
212         BOOL is_daemon = False;
213         BOOL interactive = False;
214         BOOL Fork = True;
215         BOOL log_stdout = False;
216         int opt;
217         poptContext pc;
218         struct event_context *events;
219         const char *model = "standard";
220         struct poptOption long_options[] = {
221                 POPT_AUTOHELP
222         {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
223         {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"},
224         {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
225         {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
226         {"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
227         {"port", 'p', POPT_ARG_STRING, NULL, 0, "Listen on the specified ports"},
228         {"model", 'M', POPT_ARG_STRING, &model, 0, "select process model"},
229         POPT_COMMON_SAMBA
230         { NULL }
231         };
232         
233         pc = poptGetContext("smbd", argc, argv, long_options, 0);
234         
235         while((opt = poptGetNextOpt(pc)) != -1) {
236                 switch (opt)  {
237                 case 'b':
238                         /* Display output to screen as well as debug */
239                         build_options(True); 
240                         exit(0);
241                         break;
242                 case 'p':
243                         lp_set_cmdline("smb ports", poptGetOptArg(pc));
244                         break;
245                 }
246         }
247         poptFreeContext(pc);
248
249         events = event_context_init();
250
251         load_case_tables();
252
253         if (interactive) {
254                 Fork = False;
255                 log_stdout = True;
256         }
257
258         if (log_stdout && Fork) {
259                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
260                 exit(1);
261         }
262         setup_logging(argv[0], log_stdout);
263
264         fault_setup((void (*)(void *))exit_server);
265         
266         /* we are never interested in SIGPIPE */
267         BlockSignals(True,SIGPIPE);
268
269 #if defined(SIGFPE)
270         /* we are never interested in SIGFPE */
271         BlockSignals(True,SIGFPE);
272 #endif
273
274 #if defined(SIGUSR2)
275         /* We are no longer interested in USR2 */
276         BlockSignals(True,SIGUSR2);
277 #endif
278
279         /* POSIX demands that signals are inherited. If the invoking process has
280          * these signals masked, we will have problems, as we won't recieve them. */
281         BlockSignals(False, SIGHUP);
282         BlockSignals(False, SIGUSR1);
283         BlockSignals(False, SIGTERM);
284
285         /* we want total control over the permissions on created files,
286            so set our umask to 0 */
287         umask(0);
288
289         reopen_logs();
290
291         DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION));
292         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2003\n"));
293
294         /* Output the build options to the debug log */ 
295         build_options(False);
296
297         if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
298                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
299                 exit(1);
300         }
301         DEBUG(0,("Using %s process model\n", model));
302                         
303         if (!reload_services(NULL, False))
304                 return(-1);     
305
306         init_structs();
307
308         if (!is_daemon && !is_a_socket(0)) {
309                 if (!interactive)
310                         DEBUG(0,("standard input is not a socket, assuming -D option\n"));
311
312                 /*
313                  * Setting is_daemon here prevents us from eventually calling
314                  * the open_sockets_inetd()
315                  */
316
317                 is_daemon = True;
318         }
319
320         if (is_daemon && !interactive) {
321                 DEBUG(3,("Becoming a daemon.\n"));
322                 become_daemon(Fork);
323         }
324
325         if (!directory_exist(lp_lockdir(), NULL)) {
326                 mkdir(lp_lockdir(), 0755);
327         }
328
329         if (is_daemon) {
330                 pidfile_create("smbd");
331         }
332
333         register_msg_pool_usage();
334         register_dmalloc_msgs();
335
336         setup_process_model(events, model);
337
338         /* wait for events */
339         return event_loop_wait(events);
340 }