source: trunk/samba/source/smbd/server.c @ 30

Last change on this file since 30 was 30, checked in by Paul Smedley, 14 years ago

Code updated to Samba 3.0.25rc2 level

File size: 29.0 KB
Line 
1/*
2   Unix SMB/CIFS implementation.
3   Main SMB server routines
4   Copyright (C) Andrew Tridgell                1992-1998
5   Copyright (C) Martin Pool                    2002
6   Copyright (C) Jelmer Vernooij                2002-2003
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
25static_decl_rpc;
26
27static int am_parent = 1;
28
29/* the last message the was processed */
30int last_message = -1;
31
32/* a useful macro to debug the last message processed */
33#define LAST_MESSAGE() smb_fn_name(last_message)
34
35extern struct auth_context *negprot_global_auth_context;
36extern pstring user_socket_options;
37extern SIG_ATOMIC_T got_sig_term;
38extern SIG_ATOMIC_T reload_after_sighup;
39static SIG_ATOMIC_T got_sig_cld;
40
41#ifdef WITH_DFS
42extern int dcelogin_atmost_once;
43#endif /* WITH_DFS */
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 */
51static int server_fd = -1;
52
53int smbd_server_fd(void)
54{
55        return server_fd;
56}
57
58static void smbd_set_server_fd(int fd)
59{
60        server_fd = fd;
61        client_setfd(fd);
62}
63
64struct event_context *smbd_event_context(void)
65{
66        static struct event_context *ctx;
67
68        if (!ctx && !(ctx = event_context_init(NULL))) {
69                smb_panic("Could not init smbd event context\n");
70        }
71        return ctx;
72}
73
74struct messaging_context *smbd_messaging_context(void)
75{
76        static struct messaging_context *ctx;
77
78        if (!ctx && !(ctx = messaging_init(NULL, server_id_self(),
79                                           smbd_event_context()))) {
80                smb_panic("Could not init smbd messaging context\n");
81        }
82        return ctx;
83}
84
85/*******************************************************************
86 What to do when smb.conf is updated.
87 ********************************************************************/
88
89static void smb_conf_updated(int msg_type, struct process_id src,
90                             void *buf, size_t len, void *private_data)
91{
92        DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
93        reload_services(False);
94}
95
96
97/*******************************************************************
98 Delete a statcache entry.
99 ********************************************************************/
100
101static void smb_stat_cache_delete(int msg_type, struct process_id src,
102                                  void *buf, size_t len, void *private_data)
103{
104        const char *name = (const char *)buf;
105        DEBUG(10,("smb_stat_cache_delete: delete name %s\n", name));
106        stat_cache_delete(name);
107}
108
109/****************************************************************************
110 Terminate signal.
111****************************************************************************/
112
113static void sig_term(void)
114{
115        got_sig_term = 1;
116        sys_select_signal(SIGTERM);
117}
118
119/****************************************************************************
120 Catch a sighup.
121****************************************************************************/
122
123static void sig_hup(int sig)
124{
125        reload_after_sighup = 1;
126        sys_select_signal(SIGHUP);
127}
128
129/****************************************************************************
130 Catch a sigcld
131****************************************************************************/
132static void sig_cld(int sig)
133{
134        got_sig_cld = 1;
135        sys_select_signal(SIGCLD);
136}
137
138/****************************************************************************
139  Send a SIGTERM to our process group.
140*****************************************************************************/
141
142static void  killkids(void)
143{
144        if(am_parent) kill(0,SIGTERM);
145}
146
147/****************************************************************************
148 Process a sam sync message - not sure whether to do this here or
149 somewhere else.
150****************************************************************************/
151
152static void msg_sam_sync(int UNUSED(msg_type), struct process_id UNUSED(pid),
153                         void *UNUSED(buf), size_t UNUSED(len),
154                         void *private_data)
155{
156        DEBUG(10, ("** sam sync message received, ignoring\n"));
157}
158
159/****************************************************************************
160 Process a sam sync replicate message - not sure whether to do this here or
161 somewhere else.
162****************************************************************************/
163
164static void msg_sam_repl(int msg_type, struct process_id pid,
165                         void *buf, size_t len, void *private_data)
166{
167        uint32 low_serial;
168
169        if (len != sizeof(uint32))
170                return;
171
172        low_serial = *((uint32 *)buf);
173
174        DEBUG(3, ("received sam replication message, serial = 0x%04x\n",
175                  low_serial));
176}
177
178/****************************************************************************
179 Open the socket communication - inetd.
180****************************************************************************/
181
182static BOOL open_sockets_inetd(void)
183{
184        /* Started from inetd. fd 0 is the socket. */
185        /* We will abort gracefully when the client or remote system
186           goes away */
187        smbd_set_server_fd(dup(0));
188       
189        /* close our standard file descriptors */
190        close_low_fds(False); /* Don't close stderr */
191       
192        set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
193        set_socket_options(smbd_server_fd(), user_socket_options);
194
195        return True;
196}
197
198static void msg_exit_server(int msg_type, struct process_id src,
199                            void *buf, size_t len, void *private_data)
200{
201        DEBUG(3, ("got a SHUTDOWN message\n"));
202        exit_server_cleanly(NULL);
203}
204
205#ifdef DEVELOPER
206static void msg_inject_fault(int msg_type, struct process_id src,
207                            void *buf, size_t len, void *private_data)
208{
209        int sig;
210
211        if (len != sizeof(int)) {
212               
213                DEBUG(0, ("Process %llu sent bogus signal injection request\n",
214                        (unsigned long long)src.pid));
215                return;
216        }
217
218        sig = *(int *)buf;
219        if (sig == -1) {
220                exit_server("internal error injected");
221                return;
222        }
223
224#if HAVE_STRSIGNAL
225        DEBUG(0, ("Process %llu requested injection of signal %d (%s)\n",
226                    (unsigned long long)src.pid, sig, strsignal(sig)));
227#else
228        DEBUG(0, ("Process %llu requested injection of signal %d\n",
229                    (unsigned long long)src.pid, sig));
230#endif
231
232        kill(sys_getpid(), sig);
233}
234#endif /* DEVELOPER */
235
236struct child_pid {
237        struct child_pid *prev, *next;
238        pid_t pid;
239};
240
241static struct child_pid *children;
242static int num_children;
243
244static void add_child_pid(pid_t pid)
245{
246        struct child_pid *child;
247
248        if (lp_max_smbd_processes() == 0) {
249                /* Don't bother with the child list if we don't care anyway */
250                return;
251        }
252
253        child = SMB_MALLOC_P(struct child_pid);
254        if (child == NULL) {
255                DEBUG(0, ("Could not add child struct -- malloc failed\n"));
256                return;
257        }
258        child->pid = pid;
259        DLIST_ADD(children, child);
260        num_children += 1;
261}
262
263static void remove_child_pid(pid_t pid)
264{
265        struct child_pid *child;
266
267        if (lp_max_smbd_processes() == 0) {
268                /* Don't bother with the child list if we don't care anyway */
269                return;
270        }
271
272        for (child = children; child != NULL; child = child->next) {
273                if (child->pid == pid) {
274                        struct child_pid *tmp = child;
275                        DLIST_REMOVE(children, child);
276                        SAFE_FREE(tmp);
277                        num_children -= 1;
278                        return;
279                }
280        }
281
282        DEBUG(0, ("Could not find child %d -- ignoring\n", (int)pid));
283}
284
285/****************************************************************************
286 Have we reached the process limit ?
287****************************************************************************/
288
289static BOOL allowable_number_of_smbd_processes(void)
290{
291        int max_processes = lp_max_smbd_processes();
292
293        if (!max_processes)
294                return True;
295
296        return num_children < max_processes;
297}
298
299/****************************************************************************
300 Open the socket communication.
301****************************************************************************/
302
303static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports)
304{
305        int num_interfaces = iface_count();
306        int num_sockets = 0;
307        int fd_listenset[FD_SETSIZE];
308        fd_set listen_set;
309        int s;
310        int maxfd = 0;
311        int i;
312        char *ports;
313
314        if (!is_daemon) {
315                return open_sockets_inetd();
316        }
317
318               
319#ifdef HAVE_ATEXIT
320        {
321                static int atexit_set;
322                if(atexit_set == 0) {
323                        atexit_set=1;
324                        atexit(killkids);
325                }
326        }
327#endif
328
329        /* Stop zombies */
330        CatchSignal(SIGCLD, sig_cld);
331                               
332        FD_ZERO(&listen_set);
333
334        /* use a reasonable default set of ports - listing on 445 and 139 */
335        if (!smb_ports) {
336                ports = lp_smb_ports();
337                if (!ports || !*ports) {
338                        ports = smb_xstrdup(SMB_PORTS);
339                } else {
340                        ports = smb_xstrdup(ports);
341                }
342        } else {
343                ports = smb_xstrdup(smb_ports);
344        }
345
346        if (lp_interfaces() && lp_bind_interfaces_only()) {
347                /* We have been given an interfaces line, and been
348                   told to only bind to those interfaces. Create a
349                   socket per interface and bind to only these.
350                */
351               
352                /* Now open a listen socket for each of the
353                   interfaces. */
354                for(i = 0; i < num_interfaces; i++) {
355                        struct in_addr *ifip = iface_n_ip(i);
356                        fstring tok;
357                        const char *ptr;
358
359                        if(ifip == NULL) {
360                                DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
361                                continue;
362                        }
363
364                        for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
365                                unsigned port = atoi(tok);
366                                if (port == 0) {
367                                        continue;
368                                }
369                                s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
370                                if(s == -1)
371                                        return False;
372
373                                /* ready to listen */
374                                set_socket_options(s,"SO_KEEPALIVE"); 
375                                set_socket_options(s,user_socket_options);
376     
377                                /* Set server socket to non-blocking for the accept. */
378                                set_blocking(s,False); 
379 
380                                if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
381                                        DEBUG(0,("listen: %s\n",strerror(errno)));
382                                        close(s);
383                                        return False;
384                                }
385                                FD_SET(s,&listen_set);
386                                maxfd = MAX( maxfd, s);
387
388                                num_sockets++;
389                                if (num_sockets >= FD_SETSIZE) {
390                                        DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
391                                        return False;
392                                }
393                        }
394                }
395        } else {
396                /* Just bind to 0.0.0.0 - accept connections
397                   from anywhere. */
398
399                fstring tok;
400                const char *ptr;
401
402                num_interfaces = 1;
403               
404                for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
405                        unsigned port = atoi(tok);
406                        if (port == 0) continue;
407                        /* open an incoming socket */
408                        s = open_socket_in(SOCK_STREAM, port, 0,
409                                           interpret_addr(lp_socket_address()),True);
410                        if (s == -1)
411                                return(False);
412               
413                        /* ready to listen */
414                        set_socket_options(s,"SO_KEEPALIVE"); 
415                        set_socket_options(s,user_socket_options);
416                       
417                        /* Set server socket to non-blocking for the accept. */
418                        set_blocking(s,False); 
419 
420                        if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
421                                DEBUG(0,("open_sockets_smbd: listen: %s\n",
422                                         strerror(errno)));
423                                close(s);
424                                return False;
425                        }
426
427                        fd_listenset[num_sockets] = s;
428                        FD_SET(s,&listen_set);
429                        maxfd = MAX( maxfd, s);
430
431                        num_sockets++;
432
433                        if (num_sockets >= FD_SETSIZE) {
434                                DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
435                                return False;
436                        }
437                }
438        } 
439
440        SAFE_FREE(ports);
441
442        /* Listen to messages */
443
444        message_register(MSG_SMB_SAM_SYNC, msg_sam_sync, NULL);
445        message_register(MSG_SMB_SAM_REPL, msg_sam_repl, NULL);
446        message_register(MSG_SHUTDOWN, msg_exit_server, NULL);
447        message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed, NULL);
448        message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated, NULL); 
449        message_register(MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete,
450                         NULL);
451
452#ifdef DEVELOPER
453        message_register(MSG_SMB_INJECT_FAULT, msg_inject_fault, NULL); 
454#endif
455
456        /* now accept incoming connections - forking a new process
457           for each incoming connection */
458        DEBUG(2,("waiting for a connection\n"));
459        while (1) {
460                fd_set lfds;
461                int num;
462               
463                /* Free up temporary memory from the main smbd. */
464                lp_TALLOC_FREE();
465
466                /* Ensure we respond to PING and DEBUG messages from the main smbd. */
467                message_dispatch();
468
469                if (got_sig_cld) {
470                        pid_t pid;
471                        got_sig_cld = False;
472
473                        while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
474                                remove_child_pid(pid);
475                        }
476                }
477
478                memcpy((char *)&lfds, (char *)&listen_set, 
479                       sizeof(listen_set));
480               
481                num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL);
482               
483                if (num == -1 && errno == EINTR) {
484                        if (got_sig_term) {
485                                exit_server_cleanly(NULL);
486                        }
487
488                        /* check for sighup processing */
489                        if (reload_after_sighup) {
490                                change_to_root_user();
491                                DEBUG(1,("Reloading services after SIGHUP\n"));
492                                reload_services(False);
493                                reload_after_sighup = 0;
494                        }
495
496                        continue;
497                }
498               
499                /* check if we need to reload services */
500                check_reload(time(NULL));
501
502                /* Find the sockets that are read-ready -
503                   accept on these. */
504                for( ; num > 0; num--) {
505                        struct sockaddr addr;
506                        socklen_t in_addrlen = sizeof(addr);
507                        pid_t child = 0;
508
509                        s = -1;
510                        for(i = 0; i < num_sockets; i++) {
511                                if(FD_ISSET(fd_listenset[i],&lfds)) {
512                                        s = fd_listenset[i];
513                                        /* Clear this so we don't look
514                                           at it again. */
515                                        FD_CLR(fd_listenset[i],&lfds);
516                                        break;
517                                }
518                        }
519
520                        smbd_set_server_fd(accept(s,&addr,&in_addrlen));
521                       
522                        if (smbd_server_fd() == -1 && errno == EINTR)
523                                continue;
524                       
525                        if (smbd_server_fd() == -1) {
526                                DEBUG(0,("open_sockets_smbd: accept: %s\n",
527                                         strerror(errno)));
528                                continue;
529                        }
530
531                        /* Ensure child is set to blocking mode */
532                        set_blocking(smbd_server_fd(),True);
533
534                        if (smbd_server_fd() != -1 && interactive)
535                                return True;
536                       
537                        if (allowable_number_of_smbd_processes() &&
538                            smbd_server_fd() != -1 &&
539                            ((child = sys_fork())==0)) {
540                                /* Child code ... */
541
542                                /* Stop zombies, the parent explicitly handles
543                                 * them, counting worker smbds. */
544                                CatchChild();
545                               
546                                /* close the listening socket(s) */
547                                for(i = 0; i < num_sockets; i++)
548                                        close(fd_listenset[i]);
549                               
550                                /* close our standard file
551                                   descriptors */
552                                close_low_fds(False);
553                                am_parent = 0;
554                               
555                                set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
556                                set_socket_options(smbd_server_fd(),user_socket_options);
557                               
558                                /* this is needed so that we get decent entries
559                                   in smbstatus for port 445 connects */
560                                set_remote_machine_name(get_peer_addr(smbd_server_fd()),
561                                                        False);
562                               
563                                /* Reset the state of the random
564                                 * number generation system, so
565                                 * children do not get the same random
566                                 * numbers as each other */
567
568                                set_need_random_reseed();
569                                /* tdb needs special fork handling - remove
570                                 * CLEAR_IF_FIRST flags */
571                                if (tdb_reopen_all(1) == -1) {
572                                        DEBUG(0,("tdb_reopen_all failed.\n"));
573                                        smb_panic("tdb_reopen_all failed.");
574                                }
575
576                                return True; 
577                        }
578
579                        /* Sun May 6 18:56:14 2001 ackley@cs.unm.edu:
580                                Clear the closed fd info out of server_fd --
581                                and more importantly, out of client_fd in
582                                util_sock.c, to avoid a possible
583                                getpeername failure if we reopen the logs
584                                and use %I in the filename.
585                        */
586
587                        smbd_set_server_fd(-1);
588
589                        if (child != 0) {
590                                add_child_pid(child);
591                        }
592
593                        /* Force parent to check log size after
594                         * spawning child.  Fix from
595                         * klausr@ITAP.Physik.Uni-Stuttgart.De.  The
596                         * parent smbd will log to logserver.smb.  It
597                         * writes only two messages for each child
598                         * started/finished. But each child writes,
599                         * say, 50 messages also in logserver.smb,
600                         * begining with the debug_count of the
601                         * parent, before the child opens its own log
602                         * file logserver.client. In a worst case
603                         * scenario the size of logserver.smb would be
604                         * checked after about 50*50=2500 messages
605                         * (ca. 100kb).
606                         * */
607                        force_check_log_size();
608 
609                } /* end for num */
610        } /* end while 1 */
611
612/* NOTREACHED   return True; */
613}
614
615/****************************************************************************
616 Reload printers
617**************************************************************************/
618void reload_printers(void)
619{
620        int snum;
621        int n_services = lp_numservices();
622        int pnum = lp_servicenumber(PRINTERS_NAME);
623        const char *pname;
624
625        pcap_cache_reload();
626
627        /* remove stale printers */
628        for (snum = 0; snum < n_services; snum++) {
629                /* avoid removing PRINTERS_NAME or non-autoloaded printers */
630                if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) &&
631                                      lp_autoloaded(snum)))
632                        continue;
633
634                pname = lp_printername(snum);
635                if (!pcap_printername_ok(pname)) {
636                        DEBUG(3, ("removing stale printer %s\n", pname));
637
638                        if (is_printer_published(NULL, snum, NULL))
639                                nt_printer_publish(NULL, snum, SPOOL_DS_UNPUBLISH);
640                        del_a_printer(pname);
641                        lp_killservice(snum);
642                }
643        }
644
645        load_printers();
646}
647
648/****************************************************************************
649 Reload the services file.
650**************************************************************************/
651
652BOOL reload_services(BOOL test)
653{
654        BOOL ret;
655       
656        if (lp_loaded()) {
657                pstring fname;
658                pstrcpy(fname,lp_configfile());
659                if (file_exist(fname, NULL) &&
660                    !strcsequal(fname, dyn_CONFIGFILE)) {
661                        pstrcpy(dyn_CONFIGFILE, fname);
662                        test = False;
663                }
664        }
665
666        reopen_logs();
667
668        if (test && !lp_file_list_changed())
669                return(True);
670
671        lp_killunused(conn_snum_used);
672
673        ret = lp_load(dyn_CONFIGFILE, False, False, True, True);
674
675        reload_printers();
676
677        /* perhaps the config filename is now set */
678        if (!test)
679                reload_services(True);
680
681        reopen_logs();
682
683        load_interfaces();
684
685        if (smbd_server_fd() != -1) {     
686                set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
687                set_socket_options(smbd_server_fd(), user_socket_options);
688        }
689
690        mangle_reset_cache();
691        reset_stat_cache();
692
693        /* this forces service parameters to be flushed */
694        set_current_service(NULL,0,True);
695
696        return(ret);
697}
698
699/****************************************************************************
700 Exit the server.
701****************************************************************************/
702
703/* Reasons for shutting down a server process. */
704enum server_exit_reason { SERVER_EXIT_NORMAL, SERVER_EXIT_ABNORMAL };
705
706static void exit_server_common(enum server_exit_reason how,
707        const char *const reason) NORETURN_ATTRIBUTE;
708
709static void exit_server_common(enum server_exit_reason how,
710        const char *const reason)
711{
712        static int firsttime=1;
713
714        if (!firsttime)
715                exit(0);
716        firsttime = 0;
717
718        change_to_root_user();
719
720        if (negprot_global_auth_context) {
721                (negprot_global_auth_context->free)(&negprot_global_auth_context);
722        }
723
724        conn_close_all();
725
726        invalidate_all_vuids();
727
728        print_notify_send_messages(3); /* 3 second timeout. */
729
730        /* delete our entry in the connections database. */
731        yield_connection(NULL,"");
732
733        respond_to_all_remaining_local_messages();
734
735#ifdef WITH_DFS
736        if (dcelogin_atmost_once) {
737                dfs_unlogin();
738        }
739#endif
740
741        locking_end();
742        printing_end();
743
744#ifdef __OS2__
745        /* On OS/2 - we need to remove the PID file on server exit otherwise we may not be able to restart Samba */
746        pstring pidFile;
747        slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), "smbd");
748        unlink(pidFile);
749#endif
750
751        if (how != SERVER_EXIT_NORMAL) {
752                int oldlevel = DEBUGLEVEL;
753                char *last_inbuf = get_InBuffer();
754
755                DEBUGLEVEL = 10;
756
757                DEBUGSEP(0);
758                DEBUG(0,("Abnormal server exit: %s\n",
759                        reason ? reason : "no explanation provided"));
760                DEBUGSEP(0);
761
762                log_stack_trace();
763                if (last_inbuf) {
764                        DEBUG(0,("Last message was %s\n", LAST_MESSAGE()));
765                        show_msg(last_inbuf);
766                }
767
768                DEBUGLEVEL = oldlevel;
769                dump_core();
770
771        } else {   
772                DEBUG(3,("Server exit (%s)\n",
773                        (reason ? reason : "normal exit")));
774        }
775
776        exit(0);
777}
778
779void exit_server(const char *const explanation)
780{
781        exit_server_common(SERVER_EXIT_ABNORMAL, explanation);
782}
783
784void exit_server_cleanly(const char *const explanation)
785{
786        exit_server_common(SERVER_EXIT_NORMAL, explanation);
787}
788
789void exit_server_fault(void)
790{
791        exit_server("critical server fault");
792}
793
794/****************************************************************************
795 Initialise connect, service and file structs.
796****************************************************************************/
797
798static BOOL init_structs(void )
799{
800        /*
801         * Set the machine NETBIOS name if not already
802         * set from the config file.
803         */
804
805        if (!init_names())
806                return False;
807
808        conn_init();
809
810        file_init();
811
812        /* for RPC pipes */
813        init_rpc_pipe_hnd();
814
815        init_dptrs();
816
817        secrets_init();
818
819        return True;
820}
821
822/****************************************************************************
823 main program.
824****************************************************************************/
825
826/* Declare prototype for build_options() to avoid having to run it through
827   mkproto.h.  Mixing $(builddir) and $(srcdir) source files in the current
828   prototype generation system is too complicated. */
829
830extern void build_options(BOOL screen);
831
832 int main(int argc,const char *argv[])
833{
834        /* shall I run as a daemon */
835        static BOOL is_daemon = False;
836        static BOOL interactive = False;
837        static BOOL Fork = True;
838        static BOOL no_process_group = False;
839        static BOOL log_stdout = False;
840        static char *ports = NULL;
841        static char *profile_level = NULL;
842        int opt;
843        poptContext pc;
844
845        struct poptOption long_options[] = {
846        POPT_AUTOHELP
847        {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
848        {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"},
849        {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools, etc.)" },
850        {"no-process-group", '\0', POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
851        {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
852        {"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
853        {"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified ports"},
854        {"profiling-level", 'P', POPT_ARG_STRING, &profile_level, 0, "Set profiling level","PROFILE_LEVEL"},
855        POPT_COMMON_SAMBA
856        POPT_COMMON_DYNCONFIG
857        POPT_TABLEEND
858        };
859
860        load_case_tables();
861
862        TimeInit();
863
864#ifdef HAVE_SET_AUTH_PARAMETERS
865        set_auth_parameters(argc,argv);
866#endif
867
868        pc = poptGetContext("smbd", argc, argv, long_options, 0);
869       
870        while((opt = poptGetNextOpt(pc)) != -1) {
871                switch (opt)  {
872                case 'b':
873                        build_options(True); /* Display output to screen as well as debug */ 
874                        exit(0);
875                        break;
876                }
877        }
878
879        poptFreeContext(pc);
880
881#ifdef HAVE_SETLUID
882        /* needed for SecureWare on SCO */
883        setluid(0);
884#endif
885
886        sec_init();
887
888        set_remote_machine_name("smbd", False);
889
890        if (interactive) {
891                Fork = False;
892                log_stdout = True;
893        }
894
895        if (interactive && (DEBUGLEVEL >= 9)) {
896                talloc_enable_leak_report();
897        }
898
899        if (log_stdout && Fork) {
900                DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
901                exit(1);
902        }
903
904        setup_logging(argv[0],log_stdout);
905
906        /* we want to re-seed early to prevent time delays causing
907           client problems at a later date. (tridge) */
908        generate_random_buffer(NULL, 0);
909
910        /* make absolutely sure we run as root - to handle cases where people
911           are crazy enough to have it setuid */
912
913        gain_root_privilege();
914        gain_root_group_privilege();
915
916        fault_setup((void (*)(void *))exit_server_fault);
917        dump_core_setup("smbd");
918
919        CatchSignal(SIGTERM , SIGNAL_CAST sig_term);
920        CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
921       
922        /* we are never interested in SIGPIPE */
923        BlockSignals(True,SIGPIPE);
924
925#if defined(SIGFPE)
926        /* we are never interested in SIGFPE */
927        BlockSignals(True,SIGFPE);
928#endif
929
930#if defined(SIGUSR2)
931        /* We are no longer interested in USR2 */
932        BlockSignals(True,SIGUSR2);
933#endif
934
935        /* POSIX demands that signals are inherited. If the invoking process has
936         * these signals masked, we will have problems, as we won't recieve them. */
937        BlockSignals(False, SIGHUP);
938        BlockSignals(False, SIGUSR1);
939        BlockSignals(False, SIGTERM);
940
941        /* we want total control over the permissions on created files,
942           so set our umask to 0 */
943        umask(0);
944
945        init_sec_ctx();
946
947        reopen_logs();
948#ifdef __OS2__
949        unsigned long  _System DosSetPriority (unsigned long  ulScope, unsigned long  ulClass, long lDelta, unsigned long ulID);
950        int rc;
951        rc = DosSetPriority(
952                0,                      /* Scope: only one process */
953                4,             /* set to PRTYC_FOREGROUNDSERVER */
954                31,                      /* set delta - was 0 */
955                0);                     /* Assume current process */
956        DEBUG(0,( "Server priority set to PRTYC_FOREGROUNDSERVER\n"));
957#endif
958        DEBUG(0,( "smbd version %s started.\n", SAMBA_VERSION_STRING));
959        DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) );
960
961        DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
962                 (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
963
964        /* Output the build options to the debug log */ 
965        build_options(False);
966
967        if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
968                DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
969                exit(1);
970        }
971
972        /*
973         * Do this before reload_services.
974         */
975
976        if (!reload_services(False))
977                return(-1);     
978
979        init_structs();
980
981#ifdef WITH_PROFILE
982        if (!profile_setup(False)) {
983                DEBUG(0,("ERROR: failed to setup profiling\n"));
984                return -1;
985        }
986        if (profile_level != NULL) {
987                int pl = atoi(profile_level);
988                struct process_id src;
989
990                DEBUG(1, ("setting profiling level: %s\n",profile_level));
991                src.pid = getpid();
992                set_profile_level(pl, src);
993        }
994#endif
995
996        DEBUG(3,( "loaded services\n"));
997
998        if (!is_daemon && !is_a_socket(0)) {
999                if (!interactive)
1000                        DEBUG(0,("standard input is not a socket, assuming -D option\n"));
1001
1002                /*
1003                 * Setting is_daemon here prevents us from eventually calling
1004                 * the open_sockets_inetd()
1005                 */
1006
1007                is_daemon = True;
1008        }
1009
1010        if (is_daemon && !interactive) {
1011                DEBUG( 3, ( "Becoming a daemon.\n" ) );
1012                become_daemon(Fork, no_process_group);
1013        }
1014
1015#if HAVE_SETPGID
1016        /*
1017         * If we're interactive we want to set our own process group for
1018         * signal management.
1019         */
1020        if (interactive && !no_process_group)
1021                setpgid( (pid_t)0, (pid_t)0);
1022#endif
1023
1024        if (!directory_exist(lp_lockdir(), NULL))
1025                mkdir(lp_lockdir(), 0755);
1026
1027        if (is_daemon)
1028                pidfile_create("smbd");
1029
1030        /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
1031        if (!message_init())
1032                exit(1);
1033
1034        /* Initialise the password backed before the global_sam_sid
1035           to ensure that we fetch from ldap before we make a domain sid up */
1036
1037        if(!initialize_password_db(False))
1038                exit(1);
1039
1040        if (!secrets_init()) {
1041                DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n"));
1042                exit(1);
1043        }
1044
1045        if(!get_global_sam_sid()) {
1046                DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
1047                exit(1);
1048        }
1049
1050        if (!session_init())
1051                exit(1);
1052
1053        if (conn_tdb_ctx() == NULL)
1054                exit(1);
1055
1056        if (!locking_init(0))
1057                exit(1);
1058
1059        namecache_enable();
1060
1061        if (!init_registry())
1062                exit(1);
1063
1064#if 0
1065        if (!init_svcctl_db())
1066                exit(1);
1067#endif
1068
1069        if (!print_backend_init())
1070                exit(1);
1071
1072        if (!init_guest_info()) {
1073                DEBUG(0,("ERROR: failed to setup guest info.\n"));
1074                return -1;
1075        }
1076
1077        /* Setup the main smbd so that we can get messages. */
1078        /* don't worry about general printing messages here */
1079
1080        claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
1081
1082        /* only start the background queue daemon if we are
1083           running as a daemon -- bad things will happen if
1084           smbd is launched via inetd and we fork a copy of
1085           ourselves here */
1086
1087        if ( is_daemon && !interactive )
1088                start_background_queue(); 
1089
1090        /* Always attempt to initialize DMAPI. We will only use it later if
1091         * lp_dmapi_support is set on the share, but we need a single global
1092         * session to work with.
1093         */
1094        dmapi_init_session();
1095
1096        if (!open_sockets_smbd(is_daemon, interactive, ports))
1097                exit(1);
1098
1099        /*
1100         * everything after this point is run after the fork()
1101         */ 
1102
1103        static_init_rpc;
1104
1105        init_modules();
1106
1107        /* Possibly reload the services file. Only worth doing in
1108         * daemon mode. In inetd mode, we know we only just loaded this.
1109         */
1110        if (is_daemon) {
1111                reload_services(True);
1112        }
1113
1114        if (!init_account_policy()) {
1115                DEBUG(0,("Could not open account policy tdb.\n"));
1116                exit(1);
1117        }
1118
1119        if (*lp_rootdir()) {
1120                if (sys_chroot(lp_rootdir()) == 0)
1121                        DEBUG(2,("Changed root to %s\n", lp_rootdir()));
1122        }
1123
1124        /* Setup oplocks */
1125        if (!init_oplocks())
1126                exit(1);
1127       
1128        /* Setup aio signal handler. */
1129        initialize_async_io_handler();
1130
1131        /* register our message handlers */
1132        message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis, NULL);
1133
1134        smbd_process();
1135
1136        namecache_shutdown();
1137
1138        exit_server_cleanly(NULL);
1139        return(0);
1140}
Note: See TracBrowser for help on using the repository browser.