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