r7356: fixed the problem mkaplan reported with not being able to run without -i
[jra/samba/.git] / source4 / smbd / server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Main SMB server routines
5
6    Copyright (C) Andrew Tridgell                1992-2005
7    Copyright (C) Martin Pool                    2002
8    Copyright (C) Jelmer Vernooij                2002
9    Copyright (C) James J Myers                  2003 <myersjj@samba.org>
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27 #include "lib/events/events.h"
28 #include "version.h"
29 #include "dynconfig.h"
30 #include "lib/cmdline/popt_common.h"
31 #include "system/dir.h"
32 #include "system/filesys.h"
33
34
35 /*
36   cleanup temporary files. This is the new alternative to
37   TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
38   efficient on unix systems due to the lack of scaling of the byte
39   range locking system. So instead of putting the burden on tdb to
40   cleanup tmp files, this function deletes them. 
41 */
42 static void cleanup_tmp_files(void)
43 {
44         char *path;
45         DIR *dir;
46         struct dirent *de;
47         TALLOC_CTX *mem_ctx = talloc_new(NULL);
48
49         path = smbd_tmp_path(mem_ctx, NULL);
50
51         dir = opendir(path);
52         if (!dir) {
53                 talloc_free(mem_ctx);
54                 return;
55         }
56
57         for (de=readdir(dir);de;de=readdir(dir)) {
58                 /*
59                  * Don't try to delete . and ..
60                  */
61                 if (strcmp(de->d_name, ".") != 0 &&
62                     strcmp(de->d_name, "..") != 0) {
63                     char *fname = talloc_asprintf(mem_ctx, "%s/%s", path, de->d_name);
64                     int ret = unlink(fname);
65                     if (ret == -1 &&
66                         errno != ENOENT &&
67                         errno != EPERM &&
68                         errno != EISDIR) {
69                             DEBUG(0,("Unabled to delete '%s' - %s\n", 
70                                       fname, strerror(errno)));
71                             smb_panic("unable to cleanup tmp files");
72                     }
73                     if (ret == -1 &&
74                         errno == EPERM) {
75                         /*
76                          * If it is a dir, don't complain
77                          * NOTE! The test will only happen if we have
78                          * sys/stat.h, otherwise we will always error out
79                          */
80 #ifdef HAVE_SYS_STAT_H
81                         struct stat sb;
82                         if (stat(fname, &sb) != -1 &&
83                             !S_ISDIR(sb.st_mode))
84 #endif
85                         {
86                              DEBUG(0,("Unable to delete '%s' - %s\n",
87                                       fname, strerror(errno)));
88                              smb_panic("unable to cleanup tmp files");
89                         }
90                     }
91                     talloc_free(fname);
92                 }
93         }
94         closedir(dir);
95
96         talloc_free(mem_ctx);
97 }
98
99 /*
100   setup signal masks
101 */
102 static void setup_signals(void)
103 {
104         fault_setup(NULL);
105         
106         /* we are never interested in SIGPIPE */
107         BlockSignals(True,SIGPIPE);
108
109 #if defined(SIGFPE)
110         /* we are never interested in SIGFPE */
111         BlockSignals(True,SIGFPE);
112 #endif
113
114 #if defined(SIGUSR2)
115         /* We are no longer interested in USR2 */
116         BlockSignals(True,SIGUSR2);
117 #endif
118
119         /* POSIX demands that signals are inherited. If the invoking process has
120          * these signals masked, we will have problems, as we won't recieve them. */
121         BlockSignals(False, SIGHUP);
122         BlockSignals(False, SIGUSR1);
123         BlockSignals(False, SIGTERM);
124 }
125
126
127 /*
128   handle io on stdin
129 */
130 static void server_stdin_handler(struct event_context *event_ctx, struct fd_event *fde, 
131                                  uint16_t flags, void *private)
132 {
133         uint8_t c;
134         if (read(0, &c, 1) == 0) {
135                 DEBUG(0,("EOF on stdin - terminating\n"));
136                 exit(0);
137         }
138 }
139
140 /*
141  main server.
142 */
143 static int binary_smbd_main(int argc, const char *argv[])
144 {
145         BOOL interactive = False;
146         int opt;
147         poptContext pc;
148         struct event_context *event_ctx;
149         NTSTATUS status;
150         const char *model = "standard";
151         struct poptOption long_options[] = {
152                 POPT_AUTOHELP
153                 POPT_COMMON_SAMBA
154                 {"interactive", 'i', POPT_ARG_VAL, &interactive, True, 
155                  "Run interactive (not a daemon)", NULL},
156                 {"model", 'M', POPT_ARG_STRING, &model, True, 
157                  "Select process model", "MODEL"},
158                 POPT_COMMON_VERSION
159                 POPT_TABLEEND
160         };
161         
162         pc = poptGetContext("smbd", argc, argv, long_options, 0);
163         
164         while((opt = poptGetNextOpt(pc)) != -1) /* noop */ ;
165
166         poptFreeContext(pc);
167
168         setup_logging(argv[0], interactive?DEBUG_STDOUT:DEBUG_FILE);
169         setup_signals();
170
171         /* we want total control over the permissions on created files,
172            so set our umask to 0 */
173         umask(0);
174
175         reopen_logs();
176
177         DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
178         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2005\n"));
179
180         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
181                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
182                 exit(1);
183         }
184
185         lp_load(dyn_CONFIGFILE, False, False, True);
186
187         reopen_logs();
188         load_interfaces();
189
190         if (!interactive) {
191                 DEBUG(3,("Becoming a daemon.\n"));
192                 become_daemon(True);
193         }
194
195         cleanup_tmp_files();
196
197         if (!directory_exist(lp_lockdir())) {
198                 mkdir(lp_lockdir(), 0755);
199         }
200
201         pidfile_create("smbd");
202
203         /* Do *not* remove this, until you have removed
204          * passdb/secrets.c, and proved that Samba still builds... */
205         /* Setup the SECRETS subsystem */
206         if (!secrets_init()) {
207                 exit(1);
208         }
209
210         smbd_init_subsystems;
211
212         /* the event context is the top level structure in smbd. Everything else
213            should hang off that */
214         event_ctx = event_context_init(NULL);
215
216         if (interactive) {
217                 /* catch EOF on stdin */
218                 event_add_fd(event_ctx, event_ctx, 0, EVENT_FD_READ, 
219                              server_stdin_handler, NULL);
220         }
221
222         DEBUG(0,("Using %s process model\n", model));
223         status = server_service_startup(event_ctx, model, lp_server_services());
224         if (!NT_STATUS_IS_OK(status)) {
225                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
226                 return 1;
227         }
228
229         /* wait for events - this is where smbd sits for most of its
230            life */
231         event_loop_wait(event_ctx);
232
233         /* as everything hangs off this event context, freeing it
234            should initiate a clean shutdown of all services */
235         talloc_free(event_ctx);
236
237         return 0;
238 }
239
240  int main(int argc, const char *argv[])
241 {
242         return binary_smbd_main(argc, argv);
243 }