Convert to the new pstring interface. This diff is a pretty good
[kai/samba.git] / source3 / smbd / server.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Main SMB server routines
4    Copyright (C) Andrew Tridgell                1992-1998
5    Copyright (C) Martin Pool                    2002
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #define PSTRING_SANCTIFY
23
24 #include "includes.h"
25
26 extern fstring global_myworkgroup;
27 extern pstring global_myname;
28
29 int am_parent = 1;
30
31 /* the last message the was processed */
32 int last_message = -1;
33
34 /* a useful macro to debug the last message processed */
35 #define LAST_MESSAGE() smb_fn_name(last_message)
36
37 extern pstring user_socket_options;
38
39 #ifdef WITH_DFS
40 extern int dcelogin_atmost_once;
41 #endif /* WITH_DFS */
42
43 extern fstring remote_machine;
44
45 /* really we should have a top level context structure that has the
46    client file descriptor as an element. That would require a major rewrite :(
47
48    the following 2 functions are an alternative - they make the file
49    descriptor private to smbd
50  */
51 static int server_fd = -1;
52
53 int smbd_server_fd(void)
54 {
55         return server_fd;
56 }
57
58 void smbd_set_server_fd(int fd)
59 {
60         server_fd = fd;
61         client_setfd(fd);
62 }
63
64 /****************************************************************************
65   when exiting, take the whole family
66 ****************************************************************************/
67 static void *dflt_sig(void)
68 {
69         exit_server("caught signal");
70         return NULL;
71 }
72
73 /****************************************************************************
74   Send a SIGTERM to our process group.
75 *****************************************************************************/
76 static void  killkids(void)
77 {
78         if(am_parent) kill(0,SIGTERM);
79 }
80
81 /****************************************************************************
82   process a sam sync message - not sure whether to do this here or
83   somewhere else
84 ****************************************************************************/
85 static void msg_sam_sync(int UNUSED(msg_type), pid_t UNUSED(pid),
86                          void *UNUSED(buf), size_t UNUSED(len))
87 {
88         DEBUG(10, ("** sam sync message received, ignoring\n"));
89 }
90
91 /****************************************************************************
92   process a sam sync replicate message - not sure whether to do this here or
93   somewhere else
94 ****************************************************************************/
95 static void msg_sam_repl(int msg_type, pid_t pid, void *buf, size_t len)
96 {
97         uint32 low_serial;
98
99         if (len != sizeof(uint32))
100                 return;
101
102         low_serial = *((uint32 *)buf);
103
104         DEBUG(3, ("received sam replication message, serial = 0x%04x\n",
105                   low_serial));
106 }
107
108 /****************************************************************************
109   open the socket communication
110 ****************************************************************************/
111 static BOOL open_sockets_inetd(void)
112 {
113         /* Started from inetd. fd 0 is the socket. */
114         /* We will abort gracefully when the client or remote system 
115            goes away */
116         smbd_set_server_fd(dup(0));
117         
118         /* close our standard file descriptors */
119         close_low_fds();
120         
121         set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
122         set_socket_options(smbd_server_fd(), PSTR(user_socket_options));
123
124         return True;
125 }
126
127
128 /****************************************************************************
129   open the socket communication
130 ****************************************************************************/
131 static BOOL open_sockets(BOOL is_daemon,int port)
132 {
133         int num_interfaces = iface_count();
134         int fd_listenset[FD_SETSIZE];
135         fd_set listen_set;
136         int s;
137         int i;
138
139         if (!is_daemon) {
140                 return open_sockets_inetd();
141         }
142
143                 
144 #ifdef HAVE_ATEXIT
145         {
146                 static int atexit_set;
147                 if(atexit_set == 0) {
148                         atexit_set=1;
149                         atexit(killkids);
150                 }
151         }
152 #endif
153
154         /* Stop zombies */
155         CatchChild();
156                 
157                 
158         FD_ZERO(&listen_set);
159
160         if(lp_interfaces() && lp_bind_interfaces_only()) {
161                 /* We have been given an interfaces line, and been 
162                    told to only bind to those interfaces. Create a
163                    socket per interface and bind to only these.
164                 */
165                 
166                 if(num_interfaces > FD_SETSIZE) {
167                         DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
168 max can be %d\n", 
169                                  num_interfaces, FD_SETSIZE));
170                         return False;
171                 }
172                 
173                 /* Now open a listen socket for each of the
174                    interfaces. */
175                 for(i = 0; i < num_interfaces; i++) {
176                         struct in_addr *ifip = iface_n_ip(i);
177                         
178                         if(ifip == NULL) {
179                                 DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
180                                 continue;
181                         }
182                         s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
183                         if(s == -1)
184                                 return False;
185
186                         /* ready to listen */
187                         set_socket_options(s,"SO_KEEPALIVE"); 
188                         set_socket_options(s,PSTR(user_socket_options));
189       
190                         if (listen(s, 5) == -1) {
191                                 DEBUG(0,("listen: %s\n",strerror(errno)));
192                                 close(s);
193                                 return False;
194                         }
195                         FD_SET(s,&listen_set);
196                 }
197         } else {
198                 /* Just bind to 0.0.0.0 - accept connections
199                    from anywhere. */
200                 num_interfaces = 1;
201                 
202                 /* open an incoming socket */
203                 s = open_socket_in(SOCK_STREAM, port, 0,
204                                    interpret_addr(lp_socket_address()),True);
205                 if (s == -1)
206                         return(False);
207                 
208                 /* ready to listen */
209                 set_socket_options(s,"SO_KEEPALIVE"); 
210                 set_socket_options(s,PSTR(user_socket_options));
211
212                 if (listen(s, 5) == -1) {
213                         DEBUG(0,("open_sockets: listen: %s\n",
214                                  strerror(errno)));
215                         close(s);
216                         return False;
217                 }
218                 
219                 fd_listenset[0] = s;
220                 FD_SET(s,&listen_set);
221         } 
222
223         /* Listen to messages */
224
225         message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
226         message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
227
228         /* now accept incoming connections - forking a new process
229            for each incoming connection */
230         DEBUG(2,("waiting for a connection\n"));
231         while (1) {
232                 fd_set lfds;
233                 int num;
234                 
235                 /* Free up temporary memory from the main smbd. */
236                 lp_talloc_free();
237
238                 /* Ensure we respond to PING and DEBUG messages from the main smbd. */
239                 message_dispatch();
240
241                 memcpy((char *)&lfds, (char *)&listen_set, 
242                        sizeof(listen_set));
243                 
244                 num = sys_select(FD_SETSIZE,&lfds,NULL);
245                 
246                 if (num == -1 && errno == EINTR) {
247                         extern VOLATILE sig_atomic_t reload_after_sighup;
248
249                         /* check for sighup processing */
250                         if (reload_after_sighup) {
251                                 change_to_root_user();
252                                 DEBUG(1,("Reloading services after SIGHUP\n"));
253                                 reload_services(False);
254                                 reload_after_sighup = False;
255                         }
256
257                         continue;
258                 }
259                 
260                 /* check if we need to reload services */
261                 check_reload(time(NULL));
262
263                 /* Find the sockets that are read-ready -
264                    accept on these. */
265                 for( ; num > 0; num--) {
266                         struct sockaddr addr;
267                         socklen_t in_addrlen = sizeof(addr);
268                         
269                         s = -1;
270                         for(i = 0; i < num_interfaces; i++) {
271                                 if(FD_ISSET(fd_listenset[i],&lfds)) {
272                                         s = fd_listenset[i];
273                                         /* Clear this so we don't look
274                                            at it again. */
275                                         FD_CLR(fd_listenset[i],&lfds);
276                                         break;
277                                 }
278                         }
279
280                         smbd_set_server_fd(accept(s,&addr,&in_addrlen));
281                         
282                         if (smbd_server_fd() == -1 && errno == EINTR)
283                                 continue;
284                         
285                         if (smbd_server_fd() == -1) {
286                                 DEBUG(0,("open_sockets: accept: %s\n",
287                                          strerror(errno)));
288                                 continue;
289                         }
290                         
291                         if (smbd_server_fd() != -1 && sys_fork()==0) {
292                                 /* Child code ... */
293                                 
294                                 /* close the listening socket(s) */
295                                 for(i = 0; i < num_interfaces; i++)
296                                         close(fd_listenset[i]);
297                                 
298                                 /* close our standard file
299                                    descriptors */
300                                 close_low_fds();
301                                 am_parent = 0;
302                                 
303                                 set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
304                                 set_socket_options(smbd_server_fd(),PSTR(user_socket_options));
305                                 
306                                 /* Reset global variables in util.c so
307                                    that client substitutions will be
308                                    done correctly in the process.  */
309                                 reset_globals_after_fork();
310
311                                 /* tdb needs special fork handling */
312                                 tdb_reopen_all();
313
314                                 return True; 
315                         }
316                         /* The parent doesn't need this socket */
317                         close(smbd_server_fd()); 
318
319                         /* Sun May 6 18:56:14 2001 ackley@cs.unm.edu:
320                                 Clear the closed fd info out of server_fd --
321                                 and more importantly, out of client_fd in
322                                 util_sock.c, to avoid a possible
323                                 getpeername failure if we reopen the logs
324                                 and use %I in the filename.
325                         */
326
327                         smbd_set_server_fd(-1);
328
329                         /* Force parent to check log size after
330                          * spawning child.  Fix from
331                          * klausr@ITAP.Physik.Uni-Stuttgart.De.  The
332                          * parent smbd will log to logserver.smb.  It
333                          * writes only two messages for each child
334                          * started/finished. But each child writes,
335                          * say, 50 messages also in logserver.smb,
336                          * begining with the debug_count of the
337                          * parent, before the child opens its own log
338                          * file logserver.client. In a worst case
339                          * scenario the size of logserver.smb would be
340                          * checked after about 50*50=2500 messages
341                          * (ca. 100kb).
342                          * */
343                         force_check_log_size();
344  
345                 } /* end for num */
346         } /* end while 1 */
347
348 /* NOTREACHED   return True; */
349 }
350
351 /****************************************************************************
352   reload the services file
353   **************************************************************************/
354 BOOL reload_services(BOOL test)
355 {
356         BOOL ret;
357         
358         if (lp_loaded()) {
359                 pstring fname;
360                 pstrcpy(fname,lp_configfile());
361                 if (file_exist(PSTR(fname), NULL) &&
362                     !strcsequal(PSTR(fname), PSTR(dyn_CONFIGFILE))) {
363                         pstrcpy(dyn_CONFIGFILE, PSTR(fname));
364                         test = False;
365                 }
366         }
367
368         reopen_logs();
369
370         if (test && !lp_file_list_changed())
371                 return(True);
372
373         lp_killunused(conn_snum_used);
374         
375         ret = lp_load(PSTR(dyn_CONFIGFILE), False, False, True);
376
377         load_printers();
378
379         /* perhaps the config filename is now set */
380         if (!test)
381                 reload_services(True);
382
383         reopen_logs();
384
385         load_interfaces();
386
387         {
388                 if (smbd_server_fd() != -1) {      
389                         set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
390                         set_socket_options(smbd_server_fd(), PSTR(user_socket_options));
391                 }
392         }
393
394         reset_mangled_cache();
395         reset_stat_cache();
396
397         /* this forces service parameters to be flushed */
398         set_current_service(NULL,True);
399
400         return(ret);
401 }
402
403
404
405 /****************************************************************************
406  Catch a sighup.
407 ****************************************************************************/
408
409 VOLATILE sig_atomic_t reload_after_sighup = False;
410
411 static void sig_hup(int sig)
412 {
413         BlockSignals(True,SIGHUP);
414         DEBUG(0,("Got SIGHUP\n"));
415
416         sys_select_signal();
417         reload_after_sighup = True;
418         BlockSignals(False,SIGHUP);
419 }
420
421
422
423 #if DUMP_CORE
424 /*******************************************************************
425 prepare to dump a core file - carefully!
426 ********************************************************************/
427 static BOOL dump_core(void)
428 {
429         char *p;
430         pstring dname;
431         
432         pstrcpy(dname,lp_logfile());
433         if ((p=strrchr_m(PSTR(dname),'/'))) *p=0;
434         pstrcat(dname,"/corefiles");
435         mkdir(PSTR(dname),0700);
436         sys_chown(PSTR(dname),getuid(),getgid());
437         chmod(PSTR(dname),0700);
438         if (chdir(PSTR(dname))) return(False);
439         umask(~(0700));
440
441 #ifdef HAVE_GETRLIMIT
442 #ifdef RLIMIT_CORE
443         {
444                 struct rlimit rlp;
445                 getrlimit(RLIMIT_CORE, &rlp);
446                 rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
447                 setrlimit(RLIMIT_CORE, &rlp);
448                 getrlimit(RLIMIT_CORE, &rlp);
449                 DEBUG(3,("Core limits now %d %d\n",
450                          (int)rlp.rlim_cur,(int)rlp.rlim_max));
451         }
452 #endif
453 #endif
454
455
456         DEBUG(0,("Dumping core in %s\n", PSTR(dname)));
457         abort();
458         return(True);
459 }
460 #endif
461
462 /****************************************************************************
463 update the current smbd process count
464 ****************************************************************************/
465
466 static void decrement_smbd_process_count(void)
467 {
468         int32 total_smbds;
469
470         if (lp_max_smbd_processes()) {
471                 total_smbds = 0;
472                 tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
473         }
474 }
475
476 /****************************************************************************
477 exit the server
478 ****************************************************************************/
479 void exit_server(char *reason)
480 {
481         static int firsttime=1;
482         extern char *last_inbuf;
483         extern struct auth_context *negprot_global_auth_context;
484
485         if (!firsttime)
486                 exit(0);
487         firsttime = 0;
488
489         change_to_root_user();
490         DEBUG(2,("Closing connections\n"));
491
492         if (negprot_global_auth_context) {
493                 (negprot_global_auth_context->free)(&negprot_global_auth_context);
494         }
495
496         conn_close_all();
497
498         invalidate_all_vuids();
499
500         /* delete our entry in the connections database. */
501         yield_connection(NULL,"");
502
503         respond_to_all_remaining_local_messages();
504         decrement_smbd_process_count();
505
506 #ifdef WITH_DFS
507         if (dcelogin_atmost_once) {
508                 dfs_unlogin();
509         }
510 #endif
511
512         if (!reason) {   
513                 int oldlevel = DEBUGLEVEL;
514                 DEBUGLEVEL = 10;
515                 DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
516                 if (last_inbuf)
517                         show_msg(last_inbuf);
518                 DEBUGLEVEL = oldlevel;
519                 DEBUG(0,("===============================================================\n"));
520 #if DUMP_CORE
521                 if (dump_core()) return;
522 #endif
523         }    
524
525         locking_end();
526
527         DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
528         exit(0);
529 }
530
531 /****************************************************************************
532   initialise connect, service and file structs
533 ****************************************************************************/
534 static void init_structs(void )
535 {
536         /*
537          * Set the machine NETBIOS name if not already
538          * set from the config file.
539          */
540
541         if (!*PSTR(global_myname)) {
542                 char *p;
543                 pstrcpy( global_myname, myhostname() );
544                 p = strchr_m(PSTR(global_myname), '.' );
545                 if (p) 
546                         *p = 0;
547         }
548
549         strupper(PSTR_MUTABLE(global_myname));
550
551         conn_init();
552
553         file_init();
554
555         /* for RPC pipes */
556         init_rpc_pipe_hnd();
557
558         init_dptrs();
559
560         secrets_init();
561 }
562
563 /****************************************************************************
564 usage on the program
565 ****************************************************************************/
566 static void usage(char *pname)
567 {
568
569         d_printf("Usage: %s [-DaioPh?Vb] [-d debuglevel] [-l log basename] [-p port]\n", pname);
570         d_printf("       [-O socket options] [-s services file]\n");
571         d_printf("\t-D                    Become a daemon (default)\n");
572         d_printf("\t-a                    Append to log file (default)\n");
573         d_printf("\t-i                    Run interactive (not a daemon)\n" );
574         d_printf("\t-o                    Overwrite log file, don't append\n");
575         d_printf("\t-h                    Print usage\n");
576         d_printf("\t-?                    Print usage\n");
577         d_printf("\t-V                    Print version\n");
578         d_printf("\t-b                    Print build options\n");
579         d_printf("\t-d debuglevel         Set the debuglevel\n");
580         d_printf("\t-l log basename.      Basename for log/debug files\n");
581         d_printf("\t-p port               Listen on the specified port\n");
582         d_printf("\t-O socket options     Socket options\n");
583         d_printf("\t-s services file.     Filename of services file\n");
584         d_printf("\n");
585 }
586
587 /****************************************************************************
588   main program
589 ****************************************************************************/
590  int main(int argc,char *argv[])
591 {
592         extern BOOL append_log;
593         extern char *optarg;
594         /* shall I run as a daemon */
595         BOOL is_daemon = False;
596         BOOL interactive = False;
597         BOOL specified_logfile = False;
598         int port = SMB_PORT;
599         int opt;
600         pstring logfile;
601
602 #ifdef HAVE_SET_AUTH_PARAMETERS
603         set_auth_parameters(argc,argv);
604 #endif
605
606         /* this is for people who can't start the program correctly */
607         while (argc > 1 && (*argv[1] != '-')) {
608                 argv++;
609                 argc--;
610         }
611
612         while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dp:h?bVaiof:")) )
613                 switch (opt)  {
614                 case 'O':
615                         pstrcpy(user_socket_options,optarg);
616                         break;
617
618                 case 's':
619                         pstrcpy(dyn_CONFIGFILE,optarg);
620                         break;
621
622                 case 'l':
623                         specified_logfile = True;
624                         pstr_sprintf(logfile, "%s/log.smbd", optarg);
625                         lp_set_logfile(PSTR(logfile));
626                         break;
627
628                 case 'a':
629                         append_log = True;
630                         break;
631
632                 case 'i':
633                         interactive = True;
634                         break;
635
636                 case 'o':
637                         append_log = False;
638                         break;
639
640                 case 'D':
641                         is_daemon = True;
642                         break;
643
644                 case 'd':
645                         if (*optarg == 'A')
646                                 DEBUGLEVEL = 10000;
647                         else
648                                 DEBUGLEVEL = atoi(optarg);
649                         break;
650
651                 case 'p':
652                         port = atoi(optarg);
653                         break;
654
655                 case 'h':
656                 case '?':
657                         usage(argv[0]);
658                         exit(0);
659                         break;
660
661                 case 'V':
662                         d_printf("Version %s\n",VERSION);
663                         exit(0);
664                         break;
665                 case 'b':
666                         build_options(True); /* Display output to screen as well as debug */ 
667                         exit(0);
668                         break;
669                 default:
670                         DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
671                         usage(argv[0]);
672                         exit(1);
673                 }
674
675 #ifdef HAVE_SETLUID
676         /* needed for SecureWare on SCO */
677         setluid(0);
678 #endif
679
680         sec_init();
681
682         load_case_tables();
683
684         append_log = True;
685
686         if(!specified_logfile) {
687                 pstr_sprintf(logfile, "%s/log.smbd", PSTR(dyn_LOGFILEBASE));
688                 lp_set_logfile(PSTR(logfile));
689         }
690
691         fstrcpy(remote_machine, "smbd");
692
693         setup_logging(argv[0],interactive);
694
695         /* we want to re-seed early to prevent time delays causing
696            client problems at a later date. (tridge) */
697         generate_random_buffer(NULL, 0, False);
698
699         /* make absolutely sure we run as root - to handle cases where people
700            are crazy enough to have it setuid */
701
702         gain_root_privilege();
703         gain_root_group_privilege();
704
705         fault_setup((void (*)(void *))exit_server);
706         CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
707
708         /* we are never interested in SIGPIPE */
709         BlockSignals(True,SIGPIPE);
710
711 #if defined(SIGFPE)
712         /* we are never interested in SIGFPE */
713         BlockSignals(True,SIGFPE);
714 #endif
715
716 #if defined(SIGUSR2)
717         /* We are no longer interested in USR2 */
718         BlockSignals(True,SIGUSR2);
719 #endif
720
721         /* POSIX demands that signals are inherited. If the invoking process has
722          * these signals masked, we will have problems, as we won't recieve them. */
723         BlockSignals(False, SIGHUP);
724         BlockSignals(False, SIGUSR1);
725
726         /* we want total control over the permissions on created files,
727            so set our umask to 0 */
728         umask(0);
729
730         init_sec_ctx();
731
732         reopen_logs();
733
734         DEBUG(1,( "smbd version %s started.\n", VERSION));
735         DEBUGADD(1,( "Copyright Andrew Tridgell 1992-2002\n"));
736
737         DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
738                  (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
739
740         /* Output the build options to the debug log */ 
741         build_options(False);
742
743         if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
744                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
745                 exit(1);
746         }
747
748         /*
749          * Do this before reload_services.
750          */
751
752         if (!reload_services(False))
753                 return(-1);     
754
755         init_structs();
756
757         /* don't call winbind for our domain if we are the DC */
758         if (lp_domain_logons()) {
759                 winbind_exclude_domain(lp_workgroup());
760         }
761         
762 #ifdef WITH_PROFILE
763         if (!profile_setup(False)) {
764                 DEBUG(0,("ERROR: failed to setup profiling\n"));
765                 return -1;
766         }
767 #endif
768
769 #ifdef WITH_SSL
770         {
771                 extern BOOL sslEnabled;
772                 sslEnabled = lp_ssl_enabled();
773                 if(sslEnabled)
774                         sslutil_init(True);
775         }
776 #endif        /* WITH_SSL */
777
778         fstrcpy(global_myworkgroup, lp_workgroup());
779
780         CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
781         
782         DEBUG(3,( "loaded services\n"));
783
784         if (!is_daemon && !is_a_socket(0)) {
785                 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
786                 is_daemon = True;
787         }
788
789         if (is_daemon && !interactive) {
790                 DEBUG( 3, ( "Becoming a daemon.\n" ) );
791                 become_daemon();
792         }
793
794 #if HAVE_SETPGID
795         /*
796          * If we're interactive we want to set our own process group for
797          * signal management.
798          */
799         if (interactive)
800                 setpgid( (pid_t)0, (pid_t)0);
801 #endif
802
803         if (!directory_exist(lp_lockdir(), NULL)) {
804                 mkdir(lp_lockdir(), 0755);
805         }
806
807         if (is_daemon) {
808                 pidfile_create("smbd");
809         }
810
811         if (!message_init()) {
812                 exit(1);
813         }
814         register_msg_pool_usage();
815         register_dmalloc_msgs();
816
817         /* Setup the main smbd so that we can get messages. */
818         claim_connection(NULL,"",0,True);
819
820         /* 
821            DO NOT ENABLE THIS TILL YOU COPE WITH KILLING THESE TASKS AND INETD
822            THIS *killed* LOTS OF BUILD FARM MACHINES. IT CREATED HUNDREDS OF 
823            smbd PROCESSES THAT NEVER DIE
824            start_background_queue(); 
825         */
826
827         if (!open_sockets(is_daemon,port))
828                 exit(1);
829
830         /*
831          * everything after this point is run after the fork()
832          */ 
833
834         if (!locking_init(0))
835                 exit(1);
836
837         if (!print_backend_init())
838                 exit(1);
839
840         if (!share_info_db_init())
841                 exit(1);
842
843         if(!initialize_password_db(False))
844                 exit(1);
845
846         /* possibly reload the services file. */
847         reload_services(True);
848
849         if(!pdb_generate_sam_sid()) {
850                 DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
851                 exit(1);
852         }
853
854         if (!init_group_mapping()) {
855                 DEBUG(0,("Could not open tdb mapping file.\n"));
856                 return 0;
857         }
858
859         if (!init_account_policy()) {
860                 DEBUG(0,("Could not open account policy tdb.\n"));
861                 exit(1);
862         }
863
864         if (*lp_rootdir()) {
865                 if (sys_chroot(lp_rootdir()) == 0)
866                         DEBUG(2,("Changed root to %s\n", lp_rootdir()));
867         }
868
869         /* Setup oplocks */
870         if (!init_oplocks())
871                 exit(1);
872         
873         /* Setup mangle */
874         if (!init_mangle_tdb())
875                 exit(1);
876
877         /* Setup change notify */
878         if (!init_change_notify())
879                 exit(1);
880
881         smbd_process();
882         
883         uni_group_cache_shutdown();
884         exit_server("normal exit");
885         return(0);
886 }