root/source4/smbd/server.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. recursive_delete
  2. cleanup_tmp_files
  3. sig_hup
  4. sig_term
  5. setup_signals
  6. server_stdin_handler
  7. max_runtime_handler
  8. binary_smbd_main
  9. main

   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 3 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, see <http://www.gnu.org/licenses/>.
  23 */
  24 
  25 #include "includes.h"
  26 #include "lib/events/events.h"
  27 #include "version.h"
  28 #include "lib/cmdline/popt_common.h"
  29 #include "system/dir.h"
  30 #include "system/filesys.h"
  31 #include "ldb/include/ldb.h"
  32 #include "registry/registry.h"
  33 #include "ntvfs/ntvfs.h"
  34 #include "ntptr/ntptr.h"
  35 #include "auth/gensec/gensec.h"
  36 #include "smbd/process_model.h"
  37 #include "smbd/service.h"
  38 #include "param/secrets.h"
  39 #include "smbd/pidfile.h"
  40 #include "param/param.h"
  41 
  42 /*
  43   recursively delete a directory tree
  44 */
  45 static void recursive_delete(const char *path)
     /* [<][>][^][v][top][bottom][index][help] */
  46 {
  47         DIR *dir;
  48         struct dirent *de;
  49 
  50         dir = opendir(path);
  51         if (!dir) {
  52                 return;
  53         }
  54 
  55         for (de=readdir(dir);de;de=readdir(dir)) {
  56                 char *fname;
  57                 struct stat st;
  58 
  59                 if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) {
  60                         continue;
  61                 }
  62 
  63                 fname = talloc_asprintf(path, "%s/%s", path, de->d_name);
  64                 if (stat(fname, &st) != 0) {
  65                         continue;
  66                 }
  67                 if (S_ISDIR(st.st_mode)) {
  68                         recursive_delete(fname);
  69                         talloc_free(fname);
  70                         continue;
  71                 }
  72                 if (unlink(fname) != 0) {
  73                         DEBUG(0,("Unabled to delete '%s' - %s\n", 
  74                                  fname, strerror(errno)));
  75                         smb_panic("unable to cleanup tmp files");
  76                 }
  77                 talloc_free(fname);
  78         }
  79         closedir(dir);
  80 }
  81 
  82 /*
  83   cleanup temporary files. This is the new alternative to
  84   TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
  85   efficient on unix systems due to the lack of scaling of the byte
  86   range locking system. So instead of putting the burden on tdb to
  87   cleanup tmp files, this function deletes them. 
  88 */
  89 static void cleanup_tmp_files(struct loadparm_context *lp_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  90 {
  91         char *path;
  92         TALLOC_CTX *mem_ctx = talloc_new(NULL);
  93 
  94         path = smbd_tmp_path(mem_ctx, lp_ctx, NULL);
  95 
  96         recursive_delete(path);
  97         talloc_free(mem_ctx);
  98 }
  99 
 100 static void sig_hup(int sig)
     /* [<][>][^][v][top][bottom][index][help] */
 101 {
 102         debug_schedule_reopen_logs();
 103 }
 104 
 105 static void sig_term(int sig)
     /* [<][>][^][v][top][bottom][index][help] */
 106 {
 107 #if HAVE_GETPGRP
 108         static int done_sigterm;
 109         if (done_sigterm == 0 && getpgrp() == getpid()) {
 110                 DEBUG(0,("SIGTERM: killing children\n"));
 111                 done_sigterm = 1;
 112                 kill(-getpgrp(), SIGTERM);
 113         }
 114 #endif
 115         exit(0);
 116 }
 117 
 118 /*
 119   setup signal masks
 120 */
 121 static void setup_signals(void)
     /* [<][>][^][v][top][bottom][index][help] */
 122 {
 123         /* we are never interested in SIGPIPE */
 124         BlockSignals(true,SIGPIPE);
 125 
 126 #if defined(SIGFPE)
 127         /* we are never interested in SIGFPE */
 128         BlockSignals(true,SIGFPE);
 129 #endif
 130 
 131         /* We are no longer interested in USR1 */
 132         BlockSignals(true, SIGUSR1);
 133 
 134 #if defined(SIGUSR2)
 135         /* We are no longer interested in USR2 */
 136         BlockSignals(true,SIGUSR2);
 137 #endif
 138 
 139         /* POSIX demands that signals are inherited. If the invoking process has
 140          * these signals masked, we will have problems, as we won't recieve them. */
 141         BlockSignals(false, SIGHUP);
 142         BlockSignals(false, SIGTERM);
 143 
 144         CatchSignal(SIGHUP, sig_hup);
 145         CatchSignal(SIGTERM, sig_term);
 146 }
 147 
 148 /*
 149   handle io on stdin
 150 */
 151 static void server_stdin_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, 
     /* [<][>][^][v][top][bottom][index][help] */
 152                                  uint16_t flags, void *private_data)
 153 {
 154         const char *binary_name = (const char *)private_data;
 155         uint8_t c;
 156         if (read(0, &c, 1) == 0) {
 157                 DEBUG(0,("%s: EOF on stdin - terminating\n", binary_name));
 158 #if HAVE_GETPGRP
 159                 if (getpgrp() == getpid()) {
 160                         kill(-getpgrp(), SIGTERM);
 161                 }
 162 #endif
 163                 exit(0);
 164         }
 165 }
 166 
 167 /*
 168   die if the user selected maximum runtime is exceeded
 169 */
 170 _NORETURN_ static void max_runtime_handler(struct tevent_context *ev, 
     /* [<][>][^][v][top][bottom][index][help] */
 171                                            struct tevent_timer *te, 
 172                                            struct timeval t, void *private_data)
 173 {
 174         const char *binary_name = (const char *)private_data;
 175         DEBUG(0,("%s: maximum runtime exceeded - terminating\n", binary_name));
 176         exit(0);
 177 }
 178 
 179 /*
 180  main server.
 181 */
 182 static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
 183 {
 184         bool opt_daemon = false;
 185         bool opt_interactive = false;
 186         int opt;
 187         poptContext pc;
 188         extern NTSTATUS server_service_wrepl_init(void);
 189         extern NTSTATUS server_service_kdc_init(void);
 190         extern NTSTATUS server_service_ldap_init(void);
 191         extern NTSTATUS server_service_web_init(void);
 192         extern NTSTATUS server_service_ldap_init(void);
 193         extern NTSTATUS server_service_winbind_init(void);
 194         extern NTSTATUS server_service_nbtd_init(void);
 195         extern NTSTATUS server_service_auth_init(void);
 196         extern NTSTATUS server_service_cldapd_init(void);
 197         extern NTSTATUS server_service_smb_init(void);
 198         extern NTSTATUS server_service_drepl_init(void);
 199         extern NTSTATUS server_service_rpc_init(void);
 200         extern NTSTATUS server_service_ntp_signd_init(void);
 201         extern NTSTATUS server_service_samba3_smb_init(void);
 202         init_module_fn static_init[] = { STATIC_service_MODULES };
 203         init_module_fn *shared_init;
 204         struct tevent_context *event_ctx;
 205         uint16_t stdin_event_flags;
 206         NTSTATUS status;
 207         const char *model = "standard";
 208         int max_runtime = 0;
 209         enum {
 210                 OPT_DAEMON = 1000,
 211                 OPT_INTERACTIVE,
 212                 OPT_PROCESS_MODEL
 213         };
 214         struct poptOption long_options[] = {
 215                 POPT_AUTOHELP
 216                 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON,
 217                  "Become a daemon (default)", NULL },
 218                 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
 219                  "Run interactive (not a daemon)", NULL},
 220                 {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL, 
 221                  "Select process model", "MODEL"},
 222                 {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, 
 223                  "set maximum runtime of the server process, till autotermination", "seconds"},
 224                 POPT_COMMON_SAMBA
 225                 POPT_COMMON_VERSION
 226                 { NULL }
 227         };
 228 
 229         pc = poptGetContext(binary_name, argc, argv, long_options, 0);
 230         while((opt = poptGetNextOpt(pc)) != -1) {
 231                 switch(opt) {
 232                 case OPT_DAEMON:
 233                         opt_daemon = true;
 234                         break;
 235                 case OPT_INTERACTIVE:
 236                         opt_interactive = true;
 237                         break;
 238                 case OPT_PROCESS_MODEL:
 239                         model = poptGetOptArg(pc);
 240                         break;
 241                 default:
 242                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
 243                                   poptBadOption(pc, 0), poptStrerror(opt));
 244                         poptPrintUsage(pc, stderr, 0);
 245                         exit(1);
 246                 }
 247         }
 248 
 249         if (opt_daemon && opt_interactive) {
 250                 fprintf(stderr,"\nERROR: "
 251                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
 252                 poptPrintUsage(pc, stderr, 0);
 253                 exit(1);
 254         } else if (!opt_interactive) {
 255                 /* default is --daemon */
 256                 opt_daemon = true;
 257         }
 258 
 259         poptFreeContext(pc);
 260 
 261         setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE);
 262         setup_signals();
 263 
 264         /* we want total control over the permissions on created files,
 265            so set our umask to 0 */
 266         umask(0);
 267 
 268         DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
 269         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2009\n"));
 270 
 271         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
 272                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
 273                 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n",
 274                             (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t)));
 275                 exit(1);
 276         }
 277 
 278         if (opt_daemon) {
 279                 DEBUG(3,("Becoming a daemon.\n"));
 280                 become_daemon(true, false);
 281         }
 282 
 283         cleanup_tmp_files(cmdline_lp_ctx);
 284 
 285         if (!directory_exist(lp_lockdir(cmdline_lp_ctx))) {
 286                 mkdir(lp_lockdir(cmdline_lp_ctx), 0755);
 287         }
 288 
 289         pidfile_create(lp_piddir(cmdline_lp_ctx), binary_name);
 290 
 291         /* Do *not* remove this, until you have removed
 292          * passdb/secrets.c, and proved that Samba still builds... */
 293         /* Setup the SECRETS subsystem */
 294         if (secrets_init(talloc_autofree_context(), cmdline_lp_ctx) == NULL) {
 295                 exit(1);
 296         }
 297 
 298         gensec_init(cmdline_lp_ctx); /* FIXME: */
 299 
 300         ntptr_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization function 
 301                                                 of the spoolss RPC server instead? */
 302 
 303         ntvfs_init(cmdline_lp_ctx);     /* FIXME: maybe run this in the initialization functions 
 304                                                 of the SMB[,2] server instead? */
 305 
 306         process_model_init(cmdline_lp_ctx); 
 307 
 308         shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "service");
 309 
 310         run_init_functions(static_init);
 311         run_init_functions(shared_init);
 312 
 313         talloc_free(shared_init);
 314         
 315         /* the event context is the top level structure in smbd. Everything else
 316            should hang off that */
 317         event_ctx = s4_event_context_init(talloc_autofree_context());
 318 
 319         if (event_ctx == NULL) {
 320                 DEBUG(0,("Initializing event context failed\n"));
 321                 return 1;
 322         }
 323 
 324         if (opt_interactive) {
 325                 /* terminate when stdin goes away */
 326                 stdin_event_flags = TEVENT_FD_READ;
 327         } else {
 328                 /* stay alive forever */
 329                 stdin_event_flags = 0;
 330         }
 331 
 332         /* catch EOF on stdin */
 333 #ifdef SIGTTIN
 334         signal(SIGTTIN, SIG_IGN);
 335 #endif
 336         tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
 337                       server_stdin_handler,
 338                       discard_const(binary_name));
 339 
 340         if (max_runtime) {
 341                 tevent_add_timer(event_ctx, event_ctx,
 342                                  timeval_current_ofs(max_runtime, 0),
 343                                  max_runtime_handler,
 344                                  discard_const(binary_name));
 345         }
 346 
 347         DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
 348         status = server_service_startup(event_ctx, cmdline_lp_ctx, model, 
 349                                         lp_server_services(cmdline_lp_ctx));
 350         if (!NT_STATUS_IS_OK(status)) {
 351                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
 352                 return 1;
 353         }
 354 
 355         /* wait for events - this is where smbd sits for most of its
 356            life */
 357         tevent_loop_wait(event_ctx);
 358 
 359         /* as everything hangs off this event context, freeing it
 360            should initiate a clean shutdown of all services */
 361         talloc_free(event_ctx);
 362 
 363         return 0;
 364 }
 365 
 366  int main(int argc, const char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
 367 {
 368         return binary_smbd_main("smbd", argc, argv);
 369 }

/* [<][>][^][v][top][bottom][index][help] */