1357541ceadfcbc67a30c6bf96650fe810cc247f
[metze/samba/wip.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, "..")) {
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  main server.
129 */
130 static int binary_smbd_main(int argc, const char *argv[])
131 {
132         BOOL interactive = False;
133         int opt;
134         poptContext pc;
135         struct event_context *event_ctx;
136         NTSTATUS status;
137         const char *model = "standard";
138         struct poptOption long_options[] = {
139                 POPT_AUTOHELP
140                 POPT_COMMON_SAMBA
141                 {"interactive", 'i', POPT_ARG_VAL, &interactive, True, 
142                  "Run interactive (not a daemon)", NULL},
143                 {"model", 'M', POPT_ARG_STRING, &model, True, 
144                  "Select process model", "MODEL"},
145                 POPT_COMMON_VERSION
146                 POPT_TABLEEND
147         };
148         
149         pc = poptGetContext("smbd", argc, argv, long_options, 0);
150         
151         while((opt = poptGetNextOpt(pc)) != -1) /* noop */ ;
152
153         poptFreeContext(pc);
154
155         setup_logging(argv[0], interactive?DEBUG_STDOUT:DEBUG_FILE);
156         setup_signals();
157
158         /* we want total control over the permissions on created files,
159            so set our umask to 0 */
160         umask(0);
161
162         reopen_logs();
163
164         DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
165         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2005\n"));
166
167         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
168                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
169                 exit(1);
170         }
171
172         lp_load(dyn_CONFIGFILE, False, False, True);
173
174         reopen_logs();
175         load_interfaces();
176
177         if (!interactive) {
178                 DEBUG(3,("Becoming a daemon.\n"));
179                 become_daemon(True);
180         }
181
182         cleanup_tmp_files();
183
184         if (!directory_exist(lp_lockdir())) {
185                 mkdir(lp_lockdir(), 0755);
186         }
187
188         pidfile_create("smbd");
189
190         /* Do *not* remove this, until you have removed
191          * passdb/secrets.c, and proved that Samba still builds... */
192         /* Setup the SECRETS subsystem */
193         if (!secrets_init()) {
194                 exit(1);
195         }
196
197         smbd_init_subsystems;
198
199         /* the event context is the top level structure in smbd. Everything else
200            should hang off that */
201         event_ctx = event_context_init(NULL);
202
203         DEBUG(0,("Using %s process model\n", model));
204         status = server_service_startup(event_ctx, model, lp_server_services());
205         if (!NT_STATUS_IS_OK(status)) {
206                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
207                 return 1;
208         }
209
210         /* wait for events - this is where smbd sits for most of its
211            life */
212         event_loop_wait(event_ctx);
213
214         /* as everything hangs off this event context, freeing it
215            should initiate a clean shutdown of all services */
216         talloc_free(event_ctx);
217
218         return 0;
219 }
220
221  int main(int argc, const char *argv[])
222 {
223         return binary_smbd_main(argc, argv);
224 }