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