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