LCOV - code coverage report
Current view: top level - source3/smbd - server.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 456 870 52.4 %
Date: 2021-08-25 13:27:56 Functions: 29 46 63.0 %

          Line data    Source code
       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             :    Copyright (C) Volker Lendecke                1993-2007
       8             :    Copyright (C) Jeremy Allison                 1993-2007
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "system/filesys.h"
      26             : #include "lib/util/server_id.h"
      27             : #include "lib/util/close_low_fd.h"
      28             : #include "lib/cmdline/cmdline.h"
      29             : #include "locking/share_mode_lock.h"
      30             : #include "smbd/smbd.h"
      31             : #include "smbd/globals.h"
      32             : #include "registry/reg_init_full.h"
      33             : #include "libcli/auth/schannel.h"
      34             : #include "secrets.h"
      35             : #include "../lib/util/memcache.h"
      36             : #include "ctdbd_conn.h"
      37             : #include "util_cluster.h"
      38             : #include "printing/queue_process.h"
      39             : #include "rpc_server/rpc_service_setup.h"
      40             : #include "rpc_server/rpc_config.h"
      41             : #include "passdb.h"
      42             : #include "auth.h"
      43             : #include "messages.h"
      44             : #include "messages_ctdb.h"
      45             : #include "smbprofile.h"
      46             : #include "lib/id_cache.h"
      47             : #include "lib/param/param.h"
      48             : #include "lib/background.h"
      49             : #include "../lib/util/pidfile.h"
      50             : #include "lib/smbd_shim.h"
      51             : #include "scavenger.h"
      52             : #include "locking/leases_db.h"
      53             : #include "smbd/notifyd/notifyd.h"
      54             : #include "smbd/smbd_cleanupd.h"
      55             : #include "lib/util/sys_rw.h"
      56             : #include "cleanupdb.h"
      57             : #include "g_lock.h"
      58             : #include "rpc_server/epmd.h"
      59             : #include "rpc_server/lsasd.h"
      60             : #include "rpc_server/fssd.h"
      61             : #include "rpc_server/mdssd.h"
      62             : #include "lib/global_contexts.h"
      63             : 
      64             : #ifdef CLUSTER_SUPPORT
      65             : #include "ctdb_protocol.h"
      66             : #endif
      67             : 
      68             : struct smbd_open_socket;
      69             : struct smbd_child_pid;
      70             : 
      71             : struct smbd_parent_context {
      72             :         bool interactive;
      73             : 
      74             :         struct tevent_context *ev_ctx;
      75             :         struct messaging_context *msg_ctx;
      76             :         struct dcesrv_context *dce_ctx;
      77             : 
      78             :         /* the list of listening sockets */
      79             :         struct smbd_open_socket *sockets;
      80             : 
      81             :         /* the list of current child processes */
      82             :         struct smbd_child_pid *children;
      83             :         size_t num_children;
      84             : 
      85             :         struct server_id cleanupd;
      86             :         struct server_id notifyd;
      87             : 
      88             :         struct tevent_timer *cleanup_te;
      89             : };
      90             : 
      91             : struct smbd_open_socket {
      92             :         struct smbd_open_socket *prev, *next;
      93             :         struct smbd_parent_context *parent;
      94             :         int fd;
      95             :         struct tevent_fd *fde;
      96             : };
      97             : 
      98             : struct smbd_child_pid {
      99             :         struct smbd_child_pid *prev, *next;
     100             :         pid_t pid;
     101             : };
     102             : 
     103             : /*******************************************************************
     104             :  What to do when smb.conf is updated.
     105             :  ********************************************************************/
     106             : 
     107             : static NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx,
     108             :                                            uint32_t msg_type, DATA_BLOB* data);
     109             : 
     110         207 : static void smbd_parent_conf_updated(struct messaging_context *msg,
     111             :                                      void *private_data,
     112             :                                      uint32_t msg_type,
     113             :                                      struct server_id server_id,
     114             :                                      DATA_BLOB *data)
     115             : {
     116         207 :         struct tevent_context *ev_ctx =
     117             :                 talloc_get_type_abort(private_data, struct tevent_context);
     118             :         bool ok;
     119             : 
     120         207 :         DEBUG(10,("smbd_parent_conf_updated: Got message saying smb.conf was "
     121             :                   "updated. Reloading.\n"));
     122         207 :         change_to_root_user();
     123         207 :         reload_services(NULL, NULL, false);
     124         207 :         printing_subsystem_update(ev_ctx, msg, false);
     125             : 
     126         207 :         ok = reinit_guest_session_info(NULL);
     127         207 :         if (!ok) {
     128           0 :                 DBG_ERR("Failed to reinit guest info\n");
     129             :         }
     130         207 :         messaging_send_to_children(msg, MSG_SMB_CONF_UPDATED, NULL);
     131         207 : }
     132             : 
     133             : /*******************************************************************
     134             :  Delete a statcache entry.
     135             :  ********************************************************************/
     136             : 
     137       17649 : static void smb_stat_cache_delete(struct messaging_context *msg,
     138             :                                   void *private_data,
     139             :                                   uint32_t msg_tnype,
     140             :                                   struct server_id server_id,
     141             :                                   DATA_BLOB *data)
     142             : {
     143       17649 :         const char *name = (const char *)data->data;
     144       17649 :         DEBUG(10,("smb_stat_cache_delete: delete name %s\n", name));
     145       17649 :         stat_cache_delete(name);
     146       17649 : }
     147             : 
     148             : /****************************************************************************
     149             :   Send a SIGTERM to our process group.
     150             : *****************************************************************************/
     151             : 
     152       27531 : static void  killkids(void)
     153             : {
     154       27531 :         if(am_parent) kill(0,SIGTERM);
     155       27531 : }
     156             : 
     157           7 : static void msg_exit_server(struct messaging_context *msg,
     158             :                             void *private_data,
     159             :                             uint32_t msg_type,
     160             :                             struct server_id server_id,
     161             :                             DATA_BLOB *data)
     162             : {
     163           7 :         DEBUG(3, ("got a SHUTDOWN message\n"));
     164           7 :         exit_server_cleanly(NULL);
     165             : }
     166             : 
     167             : #ifdef DEVELOPER
     168           0 : static void msg_inject_fault(struct messaging_context *msg,
     169             :                              void *private_data,
     170             :                              uint32_t msg_type,
     171             :                              struct server_id src,
     172             :                              DATA_BLOB *data)
     173             : {
     174             :         int sig;
     175             :         struct server_id_buf tmp;
     176             : 
     177           0 :         if (data->length != sizeof(sig)) {
     178           0 :                 DEBUG(0, ("Process %s sent bogus signal injection request\n",
     179             :                           server_id_str_buf(src, &tmp)));
     180           0 :                 return;
     181             :         }
     182             : 
     183           0 :         sig = *(int *)data->data;
     184           0 :         if (sig == -1) {
     185           0 :                 exit_server("internal error injected");
     186             :                 return;
     187             :         }
     188             : 
     189             : #ifdef HAVE_STRSIGNAL
     190           0 :         DEBUG(0, ("Process %s requested injection of signal %d (%s)\n",
     191             :                   server_id_str_buf(src, &tmp), sig, strsignal(sig)));
     192             : #else
     193             :         DEBUG(0, ("Process %s requested injection of signal %d\n",
     194             :                   server_id_str_buf(src, &tmp), sig));
     195             : #endif
     196             : 
     197           0 :         kill(getpid(), sig);
     198             : }
     199             : #endif /* DEVELOPER */
     200             : 
     201             : #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
     202             : /*
     203             :  * Sleep for the specified number of seconds.
     204             :  */
     205           0 : static void msg_sleep(struct messaging_context *msg,
     206             :                       void *private_data,
     207             :                       uint32_t msg_type,
     208             :                       struct server_id src,
     209             :                       DATA_BLOB *data)
     210             : {
     211             :         unsigned int seconds;
     212             :         struct server_id_buf tmp;
     213             : 
     214           0 :         if (data->length != sizeof(seconds)) {
     215           0 :                 DBG_ERR("Process %s sent bogus sleep request\n",
     216             :                         server_id_str_buf(src, &tmp));
     217           0 :                 return;
     218             :         }
     219             : 
     220           0 :         seconds = *(unsigned int *)data->data;
     221           0 :         DBG_ERR("Process %s request a sleep of %u seconds\n",
     222             :                 server_id_str_buf(src, &tmp),
     223             :                 seconds);
     224           0 :         sleep(seconds);
     225           0 :         DBG_ERR("Restarting after %u second sleep requested by process %s\n",
     226             :                 seconds,
     227             :                 server_id_str_buf(src, &tmp));
     228             : }
     229             : #endif /* DEVELOPER */
     230             : 
     231         458 : static NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx,
     232             :                                            uint32_t msg_type, DATA_BLOB* data)
     233             : {
     234             :         NTSTATUS status;
     235         458 :         struct smbd_parent_context *parent = am_parent;
     236             :         struct smbd_child_pid *child;
     237             : 
     238         458 :         if (parent == NULL) {
     239         148 :                 return NT_STATUS_INTERNAL_ERROR;
     240             :         }
     241             : 
     242        2133 :         for (child = parent->children; child != NULL; child = child->next) {
     243        1823 :                 status = messaging_send(parent->msg_ctx,
     244             :                                         pid_to_procid(child->pid),
     245             :                                         msg_type, data);
     246        1823 :                 if (!NT_STATUS_IS_OK(status)) {
     247          19 :                         DBG_DEBUG("messaging_send(%d) failed: %s\n",
     248             :                                   (int)child->pid, nt_errstr(status));
     249             :                 }
     250             :         }
     251         310 :         return NT_STATUS_OK;
     252             : }
     253             : 
     254         101 : static void smb_parent_send_to_children(struct messaging_context *ctx,
     255             :                                         void* data,
     256             :                                         uint32_t msg_type,
     257             :                                         struct server_id srv_id,
     258             :                                         DATA_BLOB* msg_data)
     259             : {
     260         101 :         messaging_send_to_children(ctx, msg_type, msg_data);
     261         101 : }
     262             : 
     263             : /*
     264             :  * Parent smbd process sets its own debug level first and then
     265             :  * sends a message to all the smbd children to adjust their debug
     266             :  * level to that of the parent.
     267             :  */
     268             : 
     269           0 : static void smbd_msg_debug(struct messaging_context *msg_ctx,
     270             :                            void *private_data,
     271             :                            uint32_t msg_type,
     272             :                            struct server_id server_id,
     273             :                            DATA_BLOB *data)
     274             : {
     275           0 :         debug_message(msg_ctx, private_data, MSG_DEBUG, server_id, data);
     276             : 
     277           0 :         messaging_send_to_children(msg_ctx, MSG_DEBUG, data);
     278           0 : }
     279             : 
     280           0 : static void smbd_parent_id_cache_kill(struct messaging_context *msg_ctx,
     281             :                                       void *private_data,
     282             :                                       uint32_t msg_type,
     283             :                                       struct server_id server_id,
     284             :                                       DATA_BLOB* data)
     285             : {
     286           0 :         const char *msg = (data && data->data)
     287           0 :                 ? (const char *)data->data : "<NULL>";
     288             :         struct id_cache_ref id;
     289             : 
     290           0 :         if (!id_cache_ref_parse(msg, &id)) {
     291           0 :                 DEBUG(0, ("Invalid ?ID: %s\n", msg));
     292           0 :                 return;
     293             :         }
     294             : 
     295           0 :         id_cache_delete_from_cache(&id);
     296             : 
     297           0 :         messaging_send_to_children(msg_ctx, msg_type, data);
     298             : }
     299             : 
     300         150 : static void smbd_parent_id_cache_delete(struct messaging_context *ctx,
     301             :                                         void* data,
     302             :                                         uint32_t msg_type,
     303             :                                         struct server_id srv_id,
     304             :                                         DATA_BLOB* msg_data)
     305             : {
     306         150 :         id_cache_delete_message(ctx, data, msg_type, srv_id, msg_data);
     307             : 
     308         150 :         messaging_send_to_children(ctx, msg_type, msg_data);
     309         150 : }
     310             : 
     311       27671 : static void add_child_pid(struct smbd_parent_context *parent,
     312             :                           pid_t pid)
     313             : {
     314             :         struct smbd_child_pid *child;
     315             : 
     316       27671 :         child = talloc_zero(parent, struct smbd_child_pid);
     317       27671 :         if (child == NULL) {
     318           0 :                 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
     319           0 :                 return;
     320             :         }
     321       27671 :         child->pid = pid;
     322       27671 :         DLIST_ADD(parent->children, child);
     323       27671 :         parent->num_children += 1;
     324             : }
     325             : 
     326           0 : static void smb_tell_num_children(struct messaging_context *ctx, void *data,
     327             :                                   uint32_t msg_type, struct server_id srv_id,
     328             :                                   DATA_BLOB *msg_data)
     329             : {
     330             :         uint8_t buf[sizeof(uint32_t)];
     331             : 
     332           0 :         if (am_parent) {
     333           0 :                 SIVAL(buf, 0, am_parent->num_children);
     334           0 :                 messaging_send_buf(ctx, srv_id, MSG_SMB_NUM_CHILDREN,
     335             :                                    buf, sizeof(buf));
     336             :         }
     337           0 : }
     338             : 
     339             : static void notifyd_stopped(struct tevent_req *req);
     340             : 
     341           0 : static struct tevent_req *notifyd_req(struct messaging_context *msg_ctx,
     342             :                                       struct tevent_context *ev)
     343             : {
     344             :         struct tevent_req *req;
     345           0 :         sys_notify_watch_fn sys_notify_watch = NULL;
     346           0 :         struct sys_notify_context *sys_notify_ctx = NULL;
     347           0 :         struct ctdbd_connection *ctdbd_conn = NULL;
     348             : 
     349           0 :         if (lp_kernel_change_notify()) {
     350             : 
     351             : #ifdef HAVE_INOTIFY
     352           0 :                 if (lp_parm_bool(-1, "notify", "inotify", true)) {
     353           0 :                         sys_notify_watch = inotify_watch;
     354             :                 }
     355             : #endif
     356             : 
     357             : #ifdef HAVE_FAM
     358             :                 if (lp_parm_bool(-1, "notify", "fam",
     359             :                                  (sys_notify_watch == NULL))) {
     360             :                         sys_notify_watch = fam_watch;
     361             :                 }
     362             : #endif
     363             :         }
     364             : 
     365           0 :         if (sys_notify_watch != NULL) {
     366           0 :                 sys_notify_ctx = sys_notify_context_create(msg_ctx, ev);
     367           0 :                 if (sys_notify_ctx == NULL) {
     368           0 :                         return NULL;
     369             :                 }
     370             :         }
     371             : 
     372           0 :         if (lp_clustering()) {
     373           0 :                 ctdbd_conn = messaging_ctdb_connection();
     374             :         }
     375             : 
     376           0 :         req = notifyd_send(msg_ctx, ev, msg_ctx, ctdbd_conn,
     377             :                            sys_notify_watch, sys_notify_ctx);
     378           0 :         if (req == NULL) {
     379           0 :                 TALLOC_FREE(sys_notify_ctx);
     380           0 :                 return NULL;
     381             :         }
     382           0 :         tevent_req_set_callback(req, notifyd_stopped, msg_ctx);
     383             : 
     384           0 :         return req;
     385             : }
     386             : 
     387           0 : static void notifyd_stopped(struct tevent_req *req)
     388             : {
     389             :         int ret;
     390             : 
     391           0 :         ret = notifyd_recv(req);
     392           0 :         TALLOC_FREE(req);
     393           0 :         DEBUG(1, ("notifyd stopped: %s\n", strerror(ret)));
     394           0 : }
     395             : 
     396           0 : static void notifyd_sig_hup_handler(struct tevent_context *ev,
     397             :                                     struct tevent_signal *se,
     398             :                                     int signum,
     399             :                                     int count,
     400             :                                     void *siginfo,
     401             :                                     void *pvt)
     402             : {
     403           0 :         DBG_NOTICE("notifyd: Reloading services after SIGHUP\n");
     404           0 :         reload_services(NULL, NULL, false);
     405           0 : }
     406             : 
     407          82 : static bool smbd_notifyd_init(struct messaging_context *msg, bool interactive,
     408             :                               struct server_id *ppid)
     409             : {
     410          82 :         struct tevent_context *ev = messaging_tevent_context(msg);
     411             :         struct tevent_req *req;
     412             :         pid_t pid;
     413             :         NTSTATUS status;
     414             :         bool ok;
     415             :         struct tevent_signal *se;
     416             : 
     417          82 :         if (interactive) {
     418           0 :                 req = notifyd_req(msg, ev);
     419           0 :                 return (req != NULL);
     420             :         }
     421             : 
     422          82 :         pid = fork();
     423          82 :         if (pid == -1) {
     424           0 :                 DEBUG(1, ("%s: fork failed: %s\n", __func__,
     425             :                           strerror(errno)));
     426           0 :                 return false;
     427             :         }
     428             : 
     429          82 :         if (pid != 0) {
     430          82 :                 if (am_parent != NULL) {
     431          82 :                         add_child_pid(am_parent, pid);
     432             :                 }
     433          82 :                 *ppid = pid_to_procid(pid);
     434          82 :                 return true;
     435             :         }
     436             : 
     437           0 :         status = smbd_reinit_after_fork(msg, ev, true, "smbd-notifyd");
     438           0 :         if (!NT_STATUS_IS_OK(status)) {
     439           0 :                 DEBUG(1, ("%s: reinit_after_fork failed: %s\n",
     440             :                           __func__, nt_errstr(status)));
     441           0 :                 exit(1);
     442             :         }
     443             : 
     444           0 :         reopen_logs();
     445             : 
     446             :         /* Set up sighup handler for notifyd */
     447           0 :         se = tevent_add_signal(ev,
     448             :                                ev,
     449             :                                SIGHUP, 0,
     450             :                                notifyd_sig_hup_handler,
     451             :                                NULL);
     452           0 :         if (!se) {
     453           0 :                 DEBUG(0, ("failed to setup notifyd SIGHUP handler\n"));
     454           0 :                 exit(1);
     455             :         }
     456             : 
     457           0 :         req = notifyd_req(msg, ev);
     458           0 :         if (req == NULL) {
     459           0 :                 exit(1);
     460             :         }
     461           0 :         tevent_req_set_callback(req, notifyd_stopped, msg);
     462             : 
     463             :         /* Block those signals that we are not handling */
     464           0 :         BlockSignals(True, SIGUSR1);
     465             : 
     466           0 :         messaging_send(msg, pid_to_procid(getppid()), MSG_SMB_NOTIFY_STARTED,
     467             :                        NULL);
     468             : 
     469           0 :         ok = tevent_req_poll(req, ev);
     470           0 :         if (!ok) {
     471           0 :                 DBG_WARNING("tevent_req_poll returned %s\n", strerror(errno));
     472           0 :                 exit(1);
     473             :         }
     474           0 :         exit(0);
     475             : }
     476             : 
     477             : static void notifyd_init_trigger(struct tevent_req *req);
     478             : 
     479             : struct notifyd_init_state {
     480             :         bool ok;
     481             :         struct tevent_context *ev;
     482             :         struct messaging_context *msg;
     483             :         struct server_id *ppid;
     484             : };
     485             : 
     486           0 : static struct tevent_req *notifyd_init_send(struct tevent_context *ev,
     487             :                                             TALLOC_CTX *mem_ctx,
     488             :                                             struct messaging_context *msg,
     489             :                                             struct server_id *ppid)
     490             : {
     491           0 :         struct tevent_req *req = NULL;
     492           0 :         struct tevent_req *subreq = NULL;
     493           0 :         struct notifyd_init_state *state = NULL;
     494             : 
     495           0 :         req = tevent_req_create(mem_ctx, &state, struct notifyd_init_state);
     496           0 :         if (req == NULL) {
     497           0 :                 return NULL;
     498             :         }
     499             : 
     500           0 :         *state = (struct notifyd_init_state) {
     501             :                 .msg = msg,
     502             :                 .ev = ev,
     503             :                 .ppid = ppid
     504             :         };
     505             : 
     506           0 :         subreq = tevent_wakeup_send(state, ev, tevent_timeval_current_ofs(1, 0));
     507           0 :         if (tevent_req_nomem(subreq, req)) {
     508           0 :                 return tevent_req_post(req, ev);
     509             :         }
     510             : 
     511           0 :         tevent_req_set_callback(subreq, notifyd_init_trigger, req);
     512           0 :         return req;
     513             : }
     514             : 
     515           0 : static void notifyd_init_trigger(struct tevent_req *subreq)
     516             : {
     517           0 :         struct tevent_req *req = tevent_req_callback_data(
     518             :                 subreq, struct tevent_req);
     519           0 :         struct notifyd_init_state *state = tevent_req_data(
     520             :                 req, struct notifyd_init_state);
     521             :         bool ok;
     522             : 
     523           0 :         DBG_NOTICE("Triggering notifyd startup\n");
     524             : 
     525           0 :         ok = tevent_wakeup_recv(subreq);
     526           0 :         TALLOC_FREE(subreq);
     527           0 :         if (!ok) {
     528           0 :                 tevent_req_error(req, ENOMEM);
     529           0 :                 return;
     530             :         }
     531             : 
     532           0 :         state->ok = smbd_notifyd_init(state->msg, false, state->ppid);
     533           0 :         if (state->ok) {
     534           0 :                 DBG_WARNING("notifyd restarted\n");
     535           0 :                 tevent_req_done(req);
     536           0 :                 return;
     537             :         }
     538             : 
     539           0 :         DBG_NOTICE("notifyd startup failed, rescheduling\n");
     540             : 
     541           0 :         subreq = tevent_wakeup_send(state, state->ev,
     542             :                                     tevent_timeval_current_ofs(1, 0));
     543           0 :         if (tevent_req_nomem(subreq, req)) {
     544           0 :                 DBG_ERR("scheduling notifyd restart failed, giving up\n");
     545           0 :                 return;
     546             :         }
     547             : 
     548           0 :         tevent_req_set_callback(subreq, notifyd_init_trigger, req);
     549           0 :         return;
     550             : }
     551             : 
     552           0 : static bool notifyd_init_recv(struct tevent_req *req)
     553             : {
     554           0 :         struct notifyd_init_state *state = tevent_req_data(
     555             :                 req, struct notifyd_init_state);
     556             : 
     557           0 :         return state->ok;
     558             : }
     559             : 
     560           0 : static void notifyd_started(struct tevent_req *req)
     561             : {
     562             :         bool ok;
     563             : 
     564           0 :         ok = notifyd_init_recv(req);
     565           0 :         TALLOC_FREE(req);
     566           0 :         if (!ok) {
     567           0 :                 DBG_ERR("Failed to restart notifyd, giving up\n");
     568           0 :                 return;
     569             :         }
     570             : }
     571             : 
     572             : static void cleanupd_stopped(struct tevent_req *req);
     573             : 
     574         136 : static bool cleanupd_init(struct messaging_context *msg, bool interactive,
     575             :                           struct server_id *ppid)
     576             : {
     577         136 :         struct tevent_context *ev = messaging_tevent_context(msg);
     578         136 :         struct server_id parent_id = messaging_server_id(msg);
     579             :         struct tevent_req *req;
     580             :         pid_t pid;
     581             :         NTSTATUS status;
     582             :         ssize_t rwret;
     583             :         int ret;
     584             :         bool ok;
     585             :         char c;
     586             :         int up_pipe[2];
     587             : 
     588         136 :         if (interactive) {
     589           0 :                 req = smbd_cleanupd_send(msg, ev, msg, parent_id.pid);
     590           0 :                 *ppid = messaging_server_id(msg);
     591           0 :                 return (req != NULL);
     592             :         }
     593             : 
     594         136 :         ret = pipe(up_pipe);
     595         136 :         if (ret == -1) {
     596           0 :                 DBG_WARNING("pipe failed: %s\n", strerror(errno));
     597           0 :                 return false;
     598             :         }
     599             : 
     600         136 :         pid = fork();
     601         129 :         if (pid == -1) {
     602           0 :                 DBG_WARNING("fork failed: %s\n", strerror(errno));
     603           0 :                 close(up_pipe[0]);
     604           0 :                 close(up_pipe[1]);
     605           0 :                 return false;
     606             :         }
     607             : 
     608         129 :         if (pid != 0) {
     609             : 
     610         129 :                 close(up_pipe[1]);
     611         129 :                 rwret = sys_read(up_pipe[0], &c, 1);
     612         129 :                 close(up_pipe[0]);
     613             : 
     614         129 :                 if (rwret == -1) {
     615           0 :                         DBG_WARNING("sys_read failed: %s\n", strerror(errno));
     616           0 :                         return false;
     617             :                 }
     618         129 :                 if (rwret == 0) {
     619           0 :                         DBG_WARNING("cleanupd could not start\n");
     620           0 :                         return false;
     621             :                 }
     622         129 :                 if (c != 0) {
     623           0 :                         DBG_WARNING("cleanupd returned %d\n", (int)c);
     624           0 :                         return false;
     625             :                 }
     626             : 
     627         129 :                 DBG_DEBUG("Started cleanupd pid=%d\n", (int)pid);
     628             : 
     629         129 :                 if (am_parent != NULL) {
     630         129 :                         add_child_pid(am_parent, pid);
     631             :                 }
     632             : 
     633         129 :                 *ppid = pid_to_procid(pid);
     634         129 :                 return true;
     635             :         }
     636             : 
     637           0 :         close(up_pipe[0]);
     638             : 
     639           0 :         status = smbd_reinit_after_fork(msg, ev, true, "cleanupd");
     640           0 :         if (!NT_STATUS_IS_OK(status)) {
     641           0 :                 DBG_WARNING("reinit_after_fork failed: %s\n",
     642             :                             nt_errstr(status));
     643           0 :                 c = 1;
     644           0 :                 sys_write(up_pipe[1], &c, 1);
     645             : 
     646           0 :                 exit(1);
     647             :         }
     648             : 
     649           0 :         req = smbd_cleanupd_send(msg, ev, msg, parent_id.pid);
     650           0 :         if (req == NULL) {
     651           0 :                 DBG_WARNING("smbd_cleanupd_send failed\n");
     652           0 :                 c = 2;
     653           0 :                 sys_write(up_pipe[1], &c, 1);
     654             : 
     655           0 :                 exit(1);
     656             :         }
     657             : 
     658           0 :         tevent_req_set_callback(req, cleanupd_stopped, msg);
     659             : 
     660           0 :         c = 0;
     661           0 :         rwret = sys_write(up_pipe[1], &c, 1);
     662           0 :         close(up_pipe[1]);
     663             : 
     664           0 :         if (rwret == -1) {
     665           0 :                 DBG_WARNING("sys_write failed: %s\n", strerror(errno));
     666           0 :                 exit(1);
     667             :         }
     668           0 :         if (rwret != 1) {
     669           0 :                 DBG_WARNING("sys_write could not write result\n");
     670           0 :                 exit(1);
     671             :         }
     672             : 
     673           0 :         ok = tevent_req_poll(req, ev);
     674           0 :         if (!ok) {
     675           0 :                 DBG_WARNING("tevent_req_poll returned %s\n", strerror(errno));
     676             :         }
     677           0 :         exit(0);
     678             : }
     679             : 
     680           0 : static void cleanupd_stopped(struct tevent_req *req)
     681             : {
     682             :         NTSTATUS status;
     683             : 
     684           0 :         status = smbd_cleanupd_recv(req);
     685           0 :         DBG_WARNING("cleanupd stopped: %s\n", nt_errstr(status));
     686           0 : }
     687             : 
     688             : static void cleanupd_init_trigger(struct tevent_req *req);
     689             : 
     690             : struct cleanup_init_state {
     691             :         bool ok;
     692             :         struct tevent_context *ev;
     693             :         struct messaging_context *msg;
     694             :         struct server_id *ppid;
     695             : };
     696             : 
     697          54 : static struct tevent_req *cleanupd_init_send(struct tevent_context *ev,
     698             :                                              TALLOC_CTX *mem_ctx,
     699             :                                              struct messaging_context *msg,
     700             :                                              struct server_id *ppid)
     701             : {
     702          54 :         struct tevent_req *req = NULL;
     703          54 :         struct tevent_req *subreq = NULL;
     704          54 :         struct cleanup_init_state *state = NULL;
     705             : 
     706          54 :         req = tevent_req_create(mem_ctx, &state, struct cleanup_init_state);
     707          54 :         if (req == NULL) {
     708           0 :                 return NULL;
     709             :         }
     710             : 
     711          54 :         *state = (struct cleanup_init_state) {
     712             :                 .msg = msg,
     713             :                 .ev = ev,
     714             :                 .ppid = ppid
     715             :         };
     716             : 
     717          54 :         subreq = tevent_wakeup_send(state, ev, tevent_timeval_current_ofs(0, 0));
     718          54 :         if (tevent_req_nomem(subreq, req)) {
     719           0 :                 return tevent_req_post(req, ev);
     720             :         }
     721             : 
     722          54 :         tevent_req_set_callback(subreq, cleanupd_init_trigger, req);
     723          54 :         return req;
     724             : }
     725             : 
     726          54 : static void cleanupd_init_trigger(struct tevent_req *subreq)
     727             : {
     728          54 :         struct tevent_req *req = tevent_req_callback_data(
     729             :                 subreq, struct tevent_req);
     730          54 :         struct cleanup_init_state *state = tevent_req_data(
     731             :                 req, struct cleanup_init_state);
     732             :         bool ok;
     733             : 
     734          54 :         DBG_NOTICE("Triggering cleanupd startup\n");
     735             : 
     736          54 :         ok = tevent_wakeup_recv(subreq);
     737          54 :         TALLOC_FREE(subreq);
     738          54 :         if (!ok) {
     739           0 :                 tevent_req_error(req, ENOMEM);
     740           0 :                 return;
     741             :         }
     742             : 
     743          54 :         state->ok = cleanupd_init(state->msg, false, state->ppid);
     744          54 :         if (state->ok) {
     745          54 :                 DBG_WARNING("cleanupd restarted\n");
     746          54 :                 tevent_req_done(req);
     747          54 :                 return;
     748             :         }
     749             : 
     750           0 :         DBG_NOTICE("cleanupd startup failed, rescheduling\n");
     751             : 
     752           0 :         subreq = tevent_wakeup_send(state, state->ev,
     753             :                                     tevent_timeval_current_ofs(1, 0));
     754           0 :         if (tevent_req_nomem(subreq, req)) {
     755           0 :                 DBG_ERR("scheduling cleanupd restart failed, giving up\n");
     756           0 :                 return;
     757             :         }
     758             : 
     759           0 :         tevent_req_set_callback(subreq, cleanupd_init_trigger, req);
     760           0 :         return;
     761             : }
     762             : 
     763          54 : static bool cleanupd_init_recv(struct tevent_req *req)
     764             : {
     765          54 :         struct cleanup_init_state *state = tevent_req_data(
     766             :                 req, struct cleanup_init_state);
     767             : 
     768          54 :         return state->ok;
     769             : }
     770             : 
     771          54 : static void cleanupd_started(struct tevent_req *req)
     772             : {
     773             :         bool ok;
     774             :         NTSTATUS status;
     775          54 :         struct smbd_parent_context *parent = tevent_req_callback_data(
     776             :                 req, struct smbd_parent_context);
     777             : 
     778          54 :         ok = cleanupd_init_recv(req);
     779          54 :         TALLOC_FREE(req);
     780          54 :         if (!ok) {
     781           0 :                 DBG_ERR("Failed to restart cleanupd, giving up\n");
     782           0 :                 return;
     783             :         }
     784             : 
     785          54 :         status = messaging_send(parent->msg_ctx,
     786             :                                 parent->cleanupd,
     787             :                                 MSG_SMB_NOTIFY_CLEANUP,
     788             :                                 &data_blob_null);
     789          54 :         if (!NT_STATUS_IS_OK(status)) {
     790           0 :                 DBG_ERR("messaging_send returned %s\n",
     791             :                         nt_errstr(status));
     792             :         }
     793             : }
     794             : 
     795       27493 : static void remove_child_pid(struct smbd_parent_context *parent,
     796             :                              pid_t pid,
     797             :                              bool unclean_shutdown)
     798             : {
     799             :         struct smbd_child_pid *child;
     800             :         NTSTATUS status;
     801             :         bool ok;
     802             : 
     803       41808 :         for (child = parent->children; child != NULL; child = child->next) {
     804       41747 :                 if (child->pid == pid) {
     805       27432 :                         struct smbd_child_pid *tmp = child;
     806       27432 :                         DLIST_REMOVE(parent->children, child);
     807       27432 :                         TALLOC_FREE(tmp);
     808       27432 :                         parent->num_children -= 1;
     809       27432 :                         break;
     810             :                 }
     811             :         }
     812             : 
     813       27493 :         if (child == NULL) {
     814             :                 /* not all forked child processes are added to the children list */
     815          61 :                 DEBUG(2, ("Could not find child %d -- ignoring\n", (int)pid));
     816         176 :                 return;
     817             :         }
     818             : 
     819       27432 :         if (pid == procid_to_pid(&parent->cleanupd)) {
     820             :                 struct tevent_req *req;
     821             : 
     822          54 :                 server_id_set_disconnected(&parent->cleanupd);
     823             : 
     824          54 :                 DBG_WARNING("Restarting cleanupd\n");
     825          54 :                 req = cleanupd_init_send(messaging_tevent_context(parent->msg_ctx),
     826             :                                          parent,
     827             :                                          parent->msg_ctx,
     828             :                                          &parent->cleanupd);
     829          54 :                 if (req == NULL) {
     830           0 :                         DBG_ERR("Failed to restart cleanupd\n");
     831           0 :                         return;
     832             :                 }
     833          54 :                 tevent_req_set_callback(req, cleanupd_started, parent);
     834          54 :                 return;
     835             :         }
     836             : 
     837       27378 :         if (pid == procid_to_pid(&parent->notifyd)) {
     838             :                 struct tevent_req *req;
     839           0 :                 struct tevent_context *ev = messaging_tevent_context(
     840             :                         parent->msg_ctx);
     841             : 
     842           0 :                 server_id_set_disconnected(&parent->notifyd);
     843             : 
     844           0 :                 DBG_WARNING("Restarting notifyd\n");
     845           0 :                 req = notifyd_init_send(ev,
     846             :                                         parent,
     847             :                                         parent->msg_ctx,
     848             :                                         &parent->notifyd);
     849           0 :                 if (req == NULL) {
     850           0 :                         DBG_ERR("Failed to restart notifyd\n");
     851           0 :                         return;
     852             :                 }
     853           0 :                 tevent_req_set_callback(req, notifyd_started, parent);
     854           0 :                 return;
     855             :         }
     856             : 
     857       27378 :         ok = cleanupdb_store_child(pid, unclean_shutdown);
     858       27378 :         if (!ok) {
     859           0 :                 DBG_ERR("cleanupdb_store_child failed\n");
     860           0 :                 return;
     861             :         }
     862             : 
     863       27378 :         if (!server_id_is_disconnected(&parent->cleanupd)) {
     864       27376 :                 status = messaging_send(parent->msg_ctx,
     865             :                                         parent->cleanupd,
     866             :                                         MSG_SMB_NOTIFY_CLEANUP,
     867             :                                         &data_blob_null);
     868       27376 :                 if (!NT_STATUS_IS_OK(status)) {
     869           0 :                         DBG_ERR("messaging_send returned %s\n",
     870             :                                 nt_errstr(status));
     871             :                 }
     872             :         }
     873             : }
     874             : 
     875             : /****************************************************************************
     876             :  Have we reached the process limit ?
     877             : ****************************************************************************/
     878             : 
     879       26983 : static bool allowable_number_of_smbd_processes(struct smbd_parent_context *parent)
     880             : {
     881       27513 :         int max_processes = lp_max_smbd_processes();
     882             : 
     883       27513 :         if (!max_processes)
     884       26983 :                 return True;
     885             : 
     886           0 :         return parent->num_children < max_processes;
     887             : }
     888             : 
     889       27028 : static void smbd_sig_chld_handler(struct tevent_context *ev,
     890             :                                   struct tevent_signal *se,
     891             :                                   int signum,
     892             :                                   int count,
     893             :                                   void *siginfo,
     894             :                                   void *private_data)
     895             : {
     896             :         pid_t pid;
     897             :         int status;
     898       27028 :         struct smbd_parent_context *parent =
     899             :                 talloc_get_type_abort(private_data,
     900             :                 struct smbd_parent_context);
     901             : 
     902       81549 :         while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
     903       27493 :                 bool unclean_shutdown = False;
     904             : 
     905             :                 /* If the child terminated normally, assume
     906             :                    it was an unclean shutdown unless the
     907             :                    status is 0
     908             :                 */
     909       27493 :                 if (WIFEXITED(status)) {
     910       27437 :                         unclean_shutdown = WEXITSTATUS(status);
     911             :                 }
     912             :                 /* If the child terminated due to a signal
     913             :                    we always assume it was unclean.
     914             :                 */
     915       27493 :                 if (WIFSIGNALED(status)) {
     916          56 :                         unclean_shutdown = True;
     917             :                 }
     918       27493 :                 remove_child_pid(parent, pid, unclean_shutdown);
     919             :         }
     920       27028 : }
     921             : 
     922          75 : static void smbd_setup_sig_chld_handler(struct smbd_parent_context *parent)
     923             : {
     924             :         struct tevent_signal *se;
     925             : 
     926          75 :         se = tevent_add_signal(parent->ev_ctx,
     927             :                                parent, /* mem_ctx */
     928             :                                SIGCHLD, 0,
     929             :                                smbd_sig_chld_handler,
     930             :                                parent);
     931          75 :         if (!se) {
     932           0 :                 exit_server("failed to setup SIGCHLD handler");
     933             :         }
     934          75 : }
     935             : 
     936      110060 : static void smbd_open_socket_close_fn(struct tevent_context *ev,
     937             :                                       struct tevent_fd *fde,
     938             :                                       int fd,
     939             :                                       void *private_data)
     940             : {
     941             :         /* this might be the socket_wrapper swrap_close() */
     942      110060 :         close(fd);
     943      110060 : }
     944             : 
     945       27513 : static void smbd_accept_connection(struct tevent_context *ev,
     946             :                                    struct tevent_fd *fde,
     947             :                                    uint16_t flags,
     948             :                                    void *private_data)
     949             : {
     950       27513 :         struct smbd_open_socket *s = talloc_get_type_abort(private_data,
     951             :                                      struct smbd_open_socket);
     952       27513 :         struct messaging_context *msg_ctx = s->parent->msg_ctx;
     953       27513 :         struct dcesrv_context *dce_ctx = s->parent->dce_ctx;
     954             :         struct sockaddr_storage addr;
     955       27513 :         socklen_t in_addrlen = sizeof(addr);
     956             :         int fd;
     957       27513 :         pid_t pid = 0;
     958             : 
     959       27513 :         fd = accept(s->fd, (struct sockaddr *)(void *)&addr,&in_addrlen);
     960       27513 :         if (fd == -1 && errno == EINTR)
     961           0 :                 return;
     962             : 
     963       27513 :         if (fd == -1) {
     964           0 :                 DEBUG(0,("accept: %s\n",
     965             :                          strerror(errno)));
     966           0 :                 return;
     967             :         }
     968       27513 :         smb_set_close_on_exec(fd);
     969             : 
     970       27513 :         if (s->parent->interactive) {
     971           0 :                 reinit_after_fork(msg_ctx, ev, true, NULL);
     972           0 :                 smbd_process(ev, msg_ctx, dce_ctx, fd, true);
     973           0 :                 exit_server_cleanly("end of interactive mode");
     974             :                 return;
     975             :         }
     976             : 
     977       27513 :         if (!allowable_number_of_smbd_processes(s->parent)) {
     978           0 :                 close(fd);
     979           0 :                 return;
     980             :         }
     981             : 
     982       27513 :         pid = fork();
     983       54971 :         if (pid == 0) {
     984       27511 :                 NTSTATUS status = NT_STATUS_OK;
     985             : 
     986             :                 /*
     987             :                  * Can't use TALLOC_FREE here. Nulling out the argument to it
     988             :                  * would overwrite memory we've just freed.
     989             :                  */
     990       27511 :                 talloc_free(s->parent);
     991       27511 :                 s = NULL;
     992             : 
     993             :                 /* Stop zombies, the parent explicitly handles
     994             :                  * them, counting worker smbds. */
     995       27511 :                 CatchChild();
     996             : 
     997       27511 :                 status = smbd_reinit_after_fork(msg_ctx, ev, true, NULL);
     998       27511 :                 if (!NT_STATUS_IS_OK(status)) {
     999           0 :                         if (NT_STATUS_EQUAL(status,
    1000             :                                             NT_STATUS_TOO_MANY_OPENED_FILES)) {
    1001           0 :                                 DEBUG(0,("child process cannot initialize "
    1002             :                                          "because too many files are open\n"));
    1003           0 :                                 goto exit;
    1004             :                         }
    1005           0 :                         if (lp_clustering() &&
    1006           0 :                             (NT_STATUS_EQUAL(
    1007           0 :                                     status, NT_STATUS_INTERNAL_DB_ERROR) ||
    1008           0 :                              NT_STATUS_EQUAL(
    1009             :                                     status, NT_STATUS_CONNECTION_REFUSED))) {
    1010           0 :                                 DEBUG(1, ("child process cannot initialize "
    1011             :                                           "because connection to CTDB "
    1012             :                                           "has failed: %s\n",
    1013             :                                           nt_errstr(status)));
    1014           0 :                                 goto exit;
    1015             :                         }
    1016             : 
    1017           0 :                         DEBUG(0,("reinit_after_fork() failed\n"));
    1018           0 :                         smb_panic("reinit_after_fork() failed");
    1019             :                 }
    1020             : 
    1021       27511 :                 smbd_process(ev, msg_ctx, dce_ctx, fd, false);
    1022           0 :          exit:
    1023           0 :                 exit_server_cleanly("end of child");
    1024             :                 return;
    1025             :         }
    1026             : 
    1027       27460 :         if (pid < 0) {
    1028           0 :                 DEBUG(0,("smbd_accept_connection: fork() failed: %s\n",
    1029             :                          strerror(errno)));
    1030             :         }
    1031             : 
    1032             :         /* The parent doesn't need this socket */
    1033       27460 :         close(fd);
    1034             : 
    1035             :         /* Sun May 6 18:56:14 2001 ackley@cs.unm.edu:
    1036             :                 Clear the closed fd info out of server_fd --
    1037             :                 and more importantly, out of client_fd in
    1038             :                 util_sock.c, to avoid a possible
    1039             :                 getpeername failure if we reopen the logs
    1040             :                 and use %I in the filename.
    1041             :         */
    1042             : 
    1043       26932 :         if (pid != 0) {
    1044       27460 :                 add_child_pid(s->parent, pid);
    1045             :         }
    1046             : 
    1047             :         /* Force parent to check log size after
    1048             :          * spawning child.  Fix from
    1049             :          * klausr@ITAP.Physik.Uni-Stuttgart.De.  The
    1050             :          * parent smbd will log to logserver.smb.  It
    1051             :          * writes only two messages for each child
    1052             :          * started/finished. But each child writes,
    1053             :          * say, 50 messages also in logserver.smb,
    1054             :          * beginning with the debug_count of the
    1055             :          * parent, before the child opens its own log
    1056             :          * file logserver.client. In a worst case
    1057             :          * scenario the size of logserver.smb would be
    1058             :          * checked after about 50*50=2500 messages
    1059             :          * (ca. 100kb).
    1060             :          * */
    1061       27460 :         force_check_log_size();
    1062             : }
    1063             : 
    1064         300 : static bool smbd_open_one_socket(struct smbd_parent_context *parent,
    1065             :                                  struct tevent_context *ev_ctx,
    1066             :                                  const struct sockaddr_storage *ifss,
    1067             :                                  uint16_t port)
    1068             : {
    1069             :         struct smbd_open_socket *s;
    1070             : 
    1071         300 :         s = talloc(parent, struct smbd_open_socket);
    1072         300 :         if (!s) {
    1073           0 :                 return false;
    1074             :         }
    1075             : 
    1076         300 :         s->parent = parent;
    1077             : 
    1078         300 :         s->fd = open_socket_in(SOCK_STREAM, ifss, port, true);
    1079         300 :         if (s->fd < 0) {
    1080           0 :                 int err = -(s->fd);
    1081           0 :                 DBG_ERR("open_socket_in failed: %s\n", strerror(err));
    1082           0 :                 TALLOC_FREE(s);
    1083             :                 /*
    1084             :                  * We ignore an error here, as we've done before
    1085             :                  */
    1086           0 :                 return true;
    1087             :         }
    1088             : 
    1089             :         /* ready to listen */
    1090         300 :         set_socket_options(s->fd, "SO_KEEPALIVE");
    1091         300 :         set_socket_options(s->fd, lp_socket_options());
    1092             : 
    1093             :         /* Set server socket to
    1094             :          * non-blocking for the accept. */
    1095         300 :         set_blocking(s->fd, False);
    1096             : 
    1097         300 :         if (listen(s->fd, SMBD_LISTEN_BACKLOG) == -1) {
    1098           0 :                 DEBUG(0,("smbd_open_one_socket: listen: "
    1099             :                         "%s\n", strerror(errno)));
    1100           0 :                         close(s->fd);
    1101           0 :                 TALLOC_FREE(s);
    1102           0 :                 return false;
    1103             :         }
    1104             : 
    1105         300 :         s->fde = tevent_add_fd(ev_ctx,
    1106             :                                s,
    1107             :                                s->fd, TEVENT_FD_READ,
    1108             :                                smbd_accept_connection,
    1109             :                                s);
    1110         300 :         if (!s->fde) {
    1111           0 :                 DEBUG(0,("smbd_open_one_socket: "
    1112             :                          "tevent_add_fd: %s\n",
    1113             :                          strerror(errno)));
    1114           0 :                 close(s->fd);
    1115           0 :                 TALLOC_FREE(s);
    1116           0 :                 return false;
    1117             :         }
    1118         300 :         tevent_fd_set_close_fn(s->fde, smbd_open_socket_close_fn);
    1119             : 
    1120         300 :         DLIST_ADD_END(parent->sockets, s);
    1121             : 
    1122         292 :         return true;
    1123             : }
    1124             : 
    1125             : /****************************************************************************
    1126             :  Open the socket communication.
    1127             : ****************************************************************************/
    1128             : 
    1129          75 : static bool open_sockets_smbd(struct smbd_parent_context *parent,
    1130             :                               struct tevent_context *ev_ctx,
    1131             :                               struct messaging_context *msg_ctx,
    1132             :                               const char *smb_ports)
    1133             : {
    1134          75 :         int num_interfaces = iface_count();
    1135             :         int i,j;
    1136             :         const char **ports;
    1137          75 :         unsigned dns_port = 0;
    1138             : 
    1139             : #ifdef HAVE_ATEXIT
    1140          75 :         atexit(killkids);
    1141             : #endif
    1142             : 
    1143             :         /* Stop zombies */
    1144          75 :         smbd_setup_sig_chld_handler(parent);
    1145             : 
    1146          75 :         ports = lp_smb_ports();
    1147             : 
    1148             :         /* use a reasonable default set of ports - listing on 445 and 139 */
    1149          75 :         if (smb_ports) {
    1150             :                 char **l;
    1151           0 :                 l = str_list_make_v3(talloc_tos(), smb_ports, NULL);
    1152           0 :                 ports = discard_const_p(const char *, l);
    1153             :         }
    1154             : 
    1155         225 :         for (j = 0; ports && ports[j]; j++) {
    1156         154 :                 unsigned port = atoi(ports[j]);
    1157             : 
    1158         150 :                 if (port == 0 || port > 0xffff) {
    1159           0 :                         exit_server_cleanly("Invalid port in the config or on "
    1160             :                                             "the commandline specified!");
    1161             :                 }
    1162             :         }
    1163             : 
    1164         108 :         if (lp_interfaces() && lp_bind_interfaces_only()) {
    1165             :                 /* We have been given an interfaces line, and been
    1166             :                    told to only bind to those interfaces. Create a
    1167             :                    socket per interface and bind to only these.
    1168             :                 */
    1169             : 
    1170             :                 /* Now open a listen socket for each of the
    1171             :                    interfaces. */
    1172          99 :                 for(i = 0; i < num_interfaces; i++) {
    1173          66 :                         const struct sockaddr_storage *ifss =
    1174             :                                         iface_n_sockaddr_storage(i);
    1175          66 :                         if (ifss == NULL) {
    1176           0 :                                 DEBUG(0,("open_sockets_smbd: "
    1177             :                                         "interface %d has NULL IP address !\n",
    1178             :                                         i));
    1179           0 :                                 continue;
    1180             :                         }
    1181             : 
    1182         198 :                         for (j = 0; ports && ports[j]; j++) {
    1183         132 :                                 unsigned port = atoi(ports[j]);
    1184             : 
    1185             :                                 /* Keep the first port for mDNS service
    1186             :                                  * registration.
    1187             :                                  */
    1188         132 :                                 if (dns_port == 0) {
    1189          33 :                                         dns_port = port;
    1190             :                                 }
    1191             : 
    1192         132 :                                 if (!smbd_open_one_socket(parent,
    1193             :                                                           ev_ctx,
    1194             :                                                           ifss,
    1195             :                                                           port)) {
    1196           0 :                                         return false;
    1197             :                                 }
    1198             :                         }
    1199             :                 }
    1200             :         } else {
    1201             :                 /* Just bind to 0.0.0.0 - accept connections
    1202             :                    from anywhere. */
    1203             : 
    1204             :                 const char *sock_addr;
    1205             :                 char *sock_tok;
    1206             :                 const char *sock_ptr;
    1207             : 
    1208             : #ifdef HAVE_IPV6
    1209          42 :                 sock_addr = "::,0.0.0.0";
    1210             : #else
    1211             :                 sock_addr = "0.0.0.0";
    1212             : #endif
    1213             : 
    1214         168 :                 for (sock_ptr=sock_addr;
    1215         126 :                      next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) {
    1216         248 :                         for (j = 0; ports && ports[j]; j++) {
    1217             :                                 struct sockaddr_storage ss;
    1218         176 :                                 unsigned port = atoi(ports[j]);
    1219             : 
    1220             :                                 /* Keep the first port for mDNS service
    1221             :                                  * registration.
    1222             :                                  */
    1223         160 :                                 if (dns_port == 0) {
    1224          40 :                                         dns_port = port;
    1225             :                                 }
    1226             : 
    1227             :                                 /* open an incoming socket */
    1228         168 :                                 if (!interpret_string_addr(&ss, sock_tok,
    1229             :                                                 AI_NUMERICHOST|AI_PASSIVE)) {
    1230           0 :                                         continue;
    1231             :                                 }
    1232             : 
    1233             :                                 /*
    1234             :                                  * If we fail to open any sockets
    1235             :                                  * in this loop the parent-sockets == NULL
    1236             :                                  * case below will prevent us from starting.
    1237             :                                  */
    1238             : 
    1239         168 :                                 (void)smbd_open_one_socket(parent,
    1240             :                                                   ev_ctx,
    1241             :                                                   &ss,
    1242             :                                                   port);
    1243             :                         }
    1244             :                 }
    1245             :         }
    1246             : 
    1247          75 :         if (parent->sockets == NULL) {
    1248           0 :                 DEBUG(0,("open_sockets_smbd: No "
    1249             :                         "sockets available to bind to.\n"));
    1250           0 :                 return false;
    1251             :         }
    1252             : 
    1253             :         /* Listen to messages */
    1254             : 
    1255          75 :         messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server);
    1256          75 :         messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED,
    1257             :                            smbd_parent_conf_updated);
    1258          75 :         messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE,
    1259             :                            smb_stat_cache_delete);
    1260          75 :         messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug);
    1261          75 :         messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS,
    1262             :                            smb_parent_send_to_children);
    1263          75 :         messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS_DENIED,
    1264             :                            smb_parent_send_to_children);
    1265          75 :         messaging_register(msg_ctx, NULL, MSG_SMB_KILL_CLIENT_IP,
    1266             :                            smb_parent_send_to_children);
    1267          75 :         messaging_register(msg_ctx, NULL, MSG_SMB_TELL_NUM_CHILDREN,
    1268             :                            smb_tell_num_children);
    1269             : 
    1270          75 :         messaging_register(msg_ctx, NULL,
    1271             :                            ID_CACHE_DELETE, smbd_parent_id_cache_delete);
    1272          75 :         messaging_register(msg_ctx, NULL,
    1273             :                            ID_CACHE_KILL, smbd_parent_id_cache_kill);
    1274          75 :         messaging_register(msg_ctx, NULL, MSG_SMB_NOTIFY_STARTED,
    1275             :                            smb_parent_send_to_children);
    1276             : 
    1277             : #ifdef DEVELOPER
    1278          75 :         messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT,
    1279             :                            msg_inject_fault);
    1280             : #endif
    1281             : 
    1282             : #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
    1283          75 :         messaging_register(msg_ctx, NULL, MSG_SMB_SLEEP, msg_sleep);
    1284             : #endif
    1285             : 
    1286          75 :         if (lp_multicast_dns_register() && (dns_port != 0)) {
    1287             : #ifdef WITH_DNSSD_SUPPORT
    1288             :                 smbd_setup_mdns_registration(ev_ctx,
    1289             :                                              parent, dns_port);
    1290             : #endif
    1291             : #ifdef WITH_AVAHI_SUPPORT
    1292             :                 void *avahi_conn;
    1293             : 
    1294             :                 avahi_conn = avahi_start_register(ev_ctx,
    1295             :                                                   ev_ctx,
    1296             :                                                   dns_port);
    1297             :                 if (avahi_conn == NULL) {
    1298             :                         DEBUG(10, ("avahi_start_register failed\n"));
    1299             :                 }
    1300             : #endif
    1301             :         }
    1302             : 
    1303          75 :         return true;
    1304             : }
    1305             : 
    1306             : 
    1307             : /*
    1308             :   handle stdin becoming readable when we are in --foreground mode
    1309             :  */
    1310           0 : static void smbd_stdin_handler(struct tevent_context *ev,
    1311             :                                struct tevent_fd *fde,
    1312             :                                uint16_t flags,
    1313             :                                void *private_data)
    1314             : {
    1315             :         char c;
    1316           0 :         if (read(0, &c, 1) != 1) {
    1317             :                 /* we have reached EOF on stdin, which means the
    1318             :                    parent has exited. Shutdown the server */
    1319           0 :                 exit_server_cleanly("EOF on stdin");
    1320             :         }
    1321           0 : }
    1322             : 
    1323             : struct smbd_parent_tevent_trace_state {
    1324             :         TALLOC_CTX *frame;
    1325             : };
    1326             : 
    1327      419379 : static void smbd_parent_tevent_trace_callback(enum tevent_trace_point point,
    1328             :                                               void *private_data)
    1329             : {
    1330      419379 :         struct smbd_parent_tevent_trace_state *state =
    1331             :                 (struct smbd_parent_tevent_trace_state *)private_data;
    1332             : 
    1333      419379 :         switch (point) {
    1334       92362 :         case TEVENT_TRACE_BEFORE_WAIT:
    1335       92362 :                 break;
    1336       92362 :         case TEVENT_TRACE_AFTER_WAIT:
    1337       92362 :                 break;
    1338      115899 :         case TEVENT_TRACE_BEFORE_LOOP_ONCE:
    1339      115899 :                 TALLOC_FREE(state->frame);
    1340      115899 :                 state->frame = talloc_stackframe();
    1341      115899 :                 break;
    1342      115824 :         case TEVENT_TRACE_AFTER_LOOP_ONCE:
    1343      115824 :                 TALLOC_FREE(state->frame);
    1344      114165 :                 break;
    1345             :         }
    1346             : 
    1347      419379 :         errno = 0;
    1348      419379 : }
    1349             : 
    1350          75 : static void smbd_parent_loop(struct tevent_context *ev_ctx,
    1351             :                              struct smbd_parent_context *parent)
    1352             : {
    1353          75 :         struct smbd_parent_tevent_trace_state trace_state = {
    1354             :                 .frame = NULL,
    1355             :         };
    1356          75 :         int ret = 0;
    1357             : 
    1358          75 :         tevent_set_trace_callback(ev_ctx, smbd_parent_tevent_trace_callback,
    1359             :                                   &trace_state);
    1360             : 
    1361             :         /* now accept incoming connections - forking a new process
    1362             :            for each incoming connection */
    1363          75 :         DEBUG(2,("waiting for connections\n"));
    1364             : 
    1365          75 :         ret = tevent_loop_wait(ev_ctx);
    1366           0 :         if (ret != 0) {
    1367           0 :                 DEBUG(0, ("tevent_loop_wait failed: %d, %s, exiting\n",
    1368             :                           ret, strerror(errno)));
    1369             :         }
    1370             : 
    1371           0 :         TALLOC_FREE(trace_state.frame);
    1372             : 
    1373             : /* NOTREACHED   return True; */
    1374           0 : }
    1375             : 
    1376             : 
    1377             : /****************************************************************************
    1378             :  Initialise connect, service and file structs.
    1379             : ****************************************************************************/
    1380             : 
    1381          80 : static bool init_structs(void )
    1382             : {
    1383             :         /*
    1384             :          * Set the machine NETBIOS name if not already
    1385             :          * set from the config file.
    1386             :          */
    1387             : 
    1388          82 :         if (!secrets_init())
    1389           0 :                 return False;
    1390             : 
    1391          80 :         return True;
    1392             : }
    1393             : 
    1394           0 : static void smbd_parent_sig_term_handler(struct tevent_context *ev,
    1395             :                                          struct tevent_signal *se,
    1396             :                                          int signum,
    1397             :                                          int count,
    1398             :                                          void *siginfo,
    1399             :                                          void *private_data)
    1400             : {
    1401           0 :         exit_server_cleanly("termination signal");
    1402             : }
    1403             : 
    1404          54 : static void smbd_parent_sig_hup_handler(struct tevent_context *ev,
    1405             :                                         struct tevent_signal *se,
    1406             :                                         int signum,
    1407             :                                         int count,
    1408             :                                         void *siginfo,
    1409             :                                         void *private_data)
    1410             : {
    1411          54 :         struct smbd_parent_context *parent =
    1412             :                 talloc_get_type_abort(private_data,
    1413             :                 struct smbd_parent_context);
    1414             : 
    1415          54 :         change_to_root_user();
    1416          54 :         DEBUG(1,("parent: Reloading services after SIGHUP\n"));
    1417          54 :         reload_services(NULL, NULL, false);
    1418             : 
    1419          54 :         printing_subsystem_update(parent->ev_ctx, parent->msg_ctx, true);
    1420          54 : }
    1421             : 
    1422             : struct smbd_claim_version_state {
    1423             :         TALLOC_CTX *mem_ctx;
    1424             :         char *version;
    1425             : };
    1426             : 
    1427           0 : static void smbd_claim_version_parser(struct server_id exclusive,
    1428             :                                       size_t num_shared,
    1429             :                                       struct server_id *shared,
    1430             :                                       const uint8_t *data,
    1431             :                                       size_t datalen,
    1432             :                                       void *private_data)
    1433             : {
    1434           0 :         struct smbd_claim_version_state *state = private_data;
    1435             : 
    1436           0 :         if (datalen == 0) {
    1437           0 :                 state->version = NULL;
    1438           0 :                 return;
    1439             :         }
    1440           0 :         if (data[datalen-1] != '\0') {
    1441           0 :                 DBG_WARNING("Invalid samba version\n");
    1442           0 :                 dump_data(DBGLVL_WARNING, data, datalen);
    1443           0 :                 state->version = NULL;
    1444           0 :                 return;
    1445             :         }
    1446           0 :         state->version = talloc_strdup(state->mem_ctx, (const char *)data);
    1447             : }
    1448             : 
    1449           0 : static NTSTATUS smbd_claim_version(struct messaging_context *msg,
    1450             :                                    const char *version)
    1451             : {
    1452           0 :         const char *name = "samba_version_string";
    1453           0 :         const TDB_DATA key = string_term_tdb_data(name);
    1454             :         struct smbd_claim_version_state state;
    1455             :         struct g_lock_ctx *ctx;
    1456             :         NTSTATUS status;
    1457             : 
    1458           0 :         ctx = g_lock_ctx_init(msg, msg);
    1459           0 :         if (ctx == NULL) {
    1460           0 :                 DBG_WARNING("g_lock_ctx_init failed\n");
    1461           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1462             :         }
    1463             : 
    1464           0 :         status = g_lock_lock(
    1465           0 :                 ctx, key, G_LOCK_READ, (struct timeval) { .tv_sec = 60 });
    1466           0 :         if (!NT_STATUS_IS_OK(status)) {
    1467           0 :                 DBG_WARNING("g_lock_lock(G_LOCK_READ) failed: %s\n",
    1468             :                             nt_errstr(status));
    1469           0 :                 TALLOC_FREE(ctx);
    1470           0 :                 return status;
    1471             :         }
    1472             : 
    1473           0 :         state = (struct smbd_claim_version_state) { .mem_ctx = ctx };
    1474             : 
    1475           0 :         status = g_lock_dump(ctx, key, smbd_claim_version_parser, &state);
    1476           0 :         if (!NT_STATUS_IS_OK(status) &&
    1477           0 :             !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1478           0 :                 DBG_ERR("Could not read samba_version_string\n");
    1479           0 :                 g_lock_unlock(ctx, key);
    1480           0 :                 TALLOC_FREE(ctx);
    1481           0 :                 return status;
    1482             :         }
    1483             : 
    1484           0 :         if ((state.version != NULL) && (strcmp(version, state.version) == 0)) {
    1485             :                 /*
    1486             :                  * Leave the read lock for us around. Someone else already
    1487             :                  * set the version correctly
    1488             :                  */
    1489           0 :                 TALLOC_FREE(ctx);
    1490           0 :                 return NT_STATUS_OK;
    1491             :         }
    1492             : 
    1493           0 :         status = g_lock_lock(
    1494           0 :                 ctx, key, G_LOCK_UPGRADE, (struct timeval) { .tv_sec = 60 });
    1495           0 :         if (!NT_STATUS_IS_OK(status)) {
    1496           0 :                 DBG_WARNING("g_lock_lock(G_LOCK_WRITE) failed: %s\n",
    1497             :                             nt_errstr(status));
    1498           0 :                 DBG_ERR("smbd %s already running, refusing to start "
    1499             :                         "version %s\n", state.version, version);
    1500           0 :                 TALLOC_FREE(ctx);
    1501           0 :                 return NT_STATUS_SXS_VERSION_CONFLICT;
    1502             :         }
    1503             : 
    1504           0 :         status = g_lock_write_data(
    1505           0 :                 ctx, key, (const uint8_t *)version, strlen(version)+1);
    1506           0 :         if (!NT_STATUS_IS_OK(status)) {
    1507           0 :                 DBG_WARNING("g_lock_write_data failed: %s\n",
    1508             :                             nt_errstr(status));
    1509           0 :                 TALLOC_FREE(ctx);
    1510           0 :                 return status;
    1511             :         }
    1512             : 
    1513           0 :         status = g_lock_lock(
    1514           0 :                 ctx, key, G_LOCK_DOWNGRADE, (struct timeval) { .tv_sec = 60 });
    1515           0 :         if (!NT_STATUS_IS_OK(status)) {
    1516           0 :                 DBG_WARNING("g_lock_lock(G_LOCK_READ) failed: %s\n",
    1517             :                             nt_errstr(status));
    1518           0 :                 TALLOC_FREE(ctx);
    1519           0 :                 return status;
    1520             :         }
    1521             : 
    1522             :         /*
    1523             :          * Leave "ctx" dangling so that g_lock.tdb keeps opened.
    1524             :          */
    1525           0 :         return NT_STATUS_OK;
    1526             : }
    1527             : 
    1528             : /****************************************************************************
    1529             :  main program.
    1530             : ****************************************************************************/
    1531             : 
    1532             : /* Declare prototype for build_options() to avoid having to run it through
    1533             :    mkproto.h.  Mixing $(builddir) and $(srcdir) source files in the current
    1534             :    prototype generation system is too complicated. */
    1535             : 
    1536             : extern void build_options(bool screen);
    1537             : 
    1538         126 :  int main(int argc,const char *argv[])
    1539             : {
    1540             :         /* shall I run as a daemon */
    1541         126 :         bool is_daemon = false;
    1542         126 :         bool interactive = false;
    1543         126 :         bool Fork = true;
    1544         126 :         bool no_process_group = false;
    1545         126 :         bool log_stdout = false;
    1546         126 :         char *ports = NULL;
    1547         126 :         char *profile_level = NULL;
    1548             :         int opt;
    1549             :         poptContext pc;
    1550         126 :         bool print_build_options = False;
    1551         126 :         bool serving_printers = false;
    1552         126 :         struct server_id main_server_id = {0};
    1553             :         enum {
    1554             :                 OPT_DAEMON = 1000,
    1555             :                 OPT_INTERACTIVE,
    1556             :                 OPT_FORK,
    1557             :                 OPT_NO_PROCESS_GROUP,
    1558             :         };
    1559         378 :         struct poptOption long_options[] = {
    1560             :                 POPT_AUTOHELP
    1561             :                 {
    1562             :                         .longName   = "daemon",
    1563             :                         .shortName  = 'D',
    1564             :                         .argInfo    = POPT_ARG_NONE,
    1565             :                         .arg        = NULL,
    1566             :                         .val        = OPT_DAEMON,
    1567             :                         .descrip    = "Become a daemon (default)" ,
    1568             :                 },
    1569             :                 {
    1570             :                         .longName   = "interactive",
    1571             :                         .shortName  = 'i',
    1572             :                         .argInfo    = POPT_ARG_NONE,
    1573             :                         .arg        = NULL,
    1574             :                         .val        = OPT_INTERACTIVE,
    1575             :                         .descrip    = "Run interactive (not a daemon) and log to stdout",
    1576             :                 },
    1577             :                 {
    1578             :                         .longName   = "foreground",
    1579             :                         .shortName  = 'F',
    1580             :                         .argInfo    = POPT_ARG_NONE,
    1581             :                         .arg        = NULL,
    1582             :                         .val        = OPT_FORK,
    1583             :                         .descrip    = "Run daemon in foreground (for daemontools, etc.)",
    1584             :                 },
    1585             :                 {
    1586             :                         .longName   = "no-process-group",
    1587             :                         .shortName  = '\0',
    1588             :                         .argInfo    = POPT_ARG_NONE,
    1589             :                         .arg        = NULL,
    1590             :                         .val        = OPT_NO_PROCESS_GROUP,
    1591             :                         .descrip    = "Don't create a new process group" ,
    1592             :                 },
    1593             :                 {
    1594             :                         .longName   = "build-options",
    1595             :                         .shortName  = 'b',
    1596             :                         .argInfo    = POPT_ARG_NONE,
    1597             :                         .arg        = NULL,
    1598             :                         .val        = 'b',
    1599             :                         .descrip    = "Print build options" ,
    1600             :                 },
    1601             :                 {
    1602             :                         .longName   = "port",
    1603             :                         .shortName  = 'p',
    1604             :                         .argInfo    = POPT_ARG_STRING,
    1605             :                         .arg        = &ports,
    1606             :                         .val        = 0,
    1607             :                         .descrip    = "Listen on the specified ports",
    1608             :                 },
    1609             :                 {
    1610             :                         .longName   = "profiling-level",
    1611             :                         .shortName  = 'P',
    1612             :                         .argInfo    = POPT_ARG_STRING,
    1613             :                         .arg        = &profile_level,
    1614             :                         .val        = 0,
    1615             :                         .descrip    = "Set profiling level","PROFILE_LEVEL",
    1616             :                 },
    1617         126 :                 POPT_COMMON_SAMBA
    1618         126 :                 POPT_COMMON_VERSION
    1619             :                 POPT_TABLEEND
    1620             :         };
    1621         126 :         struct smbd_parent_context *parent = NULL;
    1622             :         TALLOC_CTX *frame;
    1623             :         NTSTATUS status;
    1624             :         struct tevent_context *ev_ctx;
    1625             :         struct messaging_context *msg_ctx;
    1626         126 :         struct dcesrv_context *dce_ctx = NULL;
    1627             :         struct server_id server_id;
    1628             :         struct tevent_signal *se;
    1629             :         int profiling_level;
    1630         126 :         char *np_dir = NULL;
    1631         126 :         const struct loadparm_substitution *lp_sub =
    1632             :                 loadparm_s3_global_substitution();
    1633             :         static const struct smbd_shim smbd_shim_fns =
    1634             :         {
    1635             :                 .send_stat_cache_delete_message = smbd_send_stat_cache_delete_message,
    1636             :                 .change_to_root_user = smbd_change_to_root_user,
    1637             :                 .become_authenticated_pipe_user = smbd_become_authenticated_pipe_user,
    1638             :                 .unbecome_authenticated_pipe_user = smbd_unbecome_authenticated_pipe_user,
    1639             : 
    1640             :                 .contend_level2_oplocks_begin = smbd_contend_level2_oplocks_begin,
    1641             :                 .contend_level2_oplocks_end = smbd_contend_level2_oplocks_end,
    1642             : 
    1643             :                 .become_root = smbd_become_root,
    1644             :                 .unbecome_root = smbd_unbecome_root,
    1645             : 
    1646             :                 .exit_server = smbd_exit_server,
    1647             :                 .exit_server_cleanly = smbd_exit_server_cleanly,
    1648             :         };
    1649             :         bool ok;
    1650             : 
    1651             :         /*
    1652             :          * Do this before any other talloc operation
    1653             :          */
    1654         126 :         talloc_enable_null_tracking();
    1655         126 :         frame = talloc_stackframe();
    1656             : 
    1657         126 :         smb_init_locale();
    1658             : 
    1659         126 :         set_smbd_shim(&smbd_shim_fns);
    1660             : 
    1661         126 :         smbd_init_globals();
    1662             : 
    1663         126 :         TimeInit();
    1664             : 
    1665             : #ifdef HAVE_SET_AUTH_PARAMETERS
    1666             :         set_auth_parameters(argc,argv);
    1667             : #endif
    1668             : 
    1669         126 :         ok = samba_cmdline_init(frame,
    1670             :                                 SAMBA_CMDLINE_CONFIG_SERVER,
    1671             :                                 true /* require_smbconf */);
    1672         126 :         if (!ok) {
    1673           0 :                 DBG_ERR("Failed to setup cmdline parser!\n");
    1674           0 :                 exit(ENOMEM);
    1675             :         }
    1676             : 
    1677         126 :         pc = samba_popt_get_context(getprogname(),
    1678             :                                     argc,
    1679             :                                     argv,
    1680             :                                     long_options,
    1681             :                                     0);
    1682         126 :         if (pc == NULL) {
    1683           0 :                 DBG_ERR("Failed to get popt context!\n");
    1684           0 :                 exit(ENOMEM);
    1685             :         }
    1686             : 
    1687         456 :         while((opt = poptGetNextOpt(pc)) != -1) {
    1688         208 :                 switch (opt)  {
    1689          47 :                 case OPT_DAEMON:
    1690          47 :                         is_daemon = true;
    1691          47 :                         break;
    1692           0 :                 case OPT_INTERACTIVE:
    1693           0 :                         interactive = true;
    1694           0 :                         break;
    1695          82 :                 case OPT_FORK:
    1696          82 :                         Fork = false;
    1697          82 :                         break;
    1698          33 :                 case OPT_NO_PROCESS_GROUP:
    1699          33 :                         no_process_group = true;
    1700          33 :                         break;
    1701          44 :                 case 'b':
    1702          44 :                         print_build_options = True;
    1703          44 :                         break;
    1704           0 :                 default:
    1705           0 :                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1706             :                                   poptBadOption(pc, 0), poptStrerror(opt));
    1707           0 :                         poptPrintUsage(pc, stderr, 0);
    1708           0 :                         exit(1);
    1709             :                 }
    1710             :         }
    1711         126 :         poptFreeContext(pc);
    1712             : 
    1713         126 :         log_stdout = (debug_get_log_type() == DEBUG_STDOUT);
    1714             : 
    1715         126 :         if (interactive) {
    1716           0 :                 Fork = False;
    1717           0 :                 log_stdout = True;
    1718             :         }
    1719             : 
    1720         126 :         if (!log_stdout) {
    1721          44 :                 setup_logging(argv[0], DEBUG_FILE);
    1722             :         }
    1723             : 
    1724         126 :         if (print_build_options) {
    1725          44 :                 build_options(True); /* Display output to screen as well as debug */
    1726          44 :                 exit(0);
    1727             :         }
    1728             : 
    1729             : #ifdef HAVE_SETLUID
    1730             :         /* needed for SecureWare on SCO */
    1731             :         setluid(0);
    1732             : #endif
    1733             : 
    1734          82 :         set_remote_machine_name("smbd", False);
    1735             : 
    1736          82 :         if (interactive && (DEBUGLEVEL >= 9)) {
    1737           0 :                 talloc_enable_leak_report();
    1738             :         }
    1739             : 
    1740          82 :         if (log_stdout && Fork) {
    1741           0 :                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
    1742           0 :                 exit(1);
    1743             :         }
    1744             : 
    1745             :         /*
    1746             :          * We want to die early if we can't open /dev/urandom
    1747             :          */
    1748          82 :         generate_random_buffer(NULL, 0);
    1749             : 
    1750             :         /* get initial effective uid and gid */
    1751          82 :         sec_init();
    1752             : 
    1753             :         /* make absolutely sure we run as root - to handle cases where people
    1754             :            are crazy enough to have it setuid */
    1755          82 :         gain_root_privilege();
    1756          82 :         gain_root_group_privilege();
    1757             : 
    1758          82 :         dump_core_setup("smbd", lp_logfile(talloc_tos(), lp_sub));
    1759             : 
    1760             :         /* we are never interested in SIGPIPE */
    1761          82 :         BlockSignals(True,SIGPIPE);
    1762             : 
    1763             : #if defined(SIGFPE)
    1764             :         /* we are never interested in SIGFPE */
    1765          82 :         BlockSignals(True,SIGFPE);
    1766             : #endif
    1767             : 
    1768             : #if defined(SIGUSR2)
    1769             :         /* We are no longer interested in USR2 */
    1770          82 :         BlockSignals(True,SIGUSR2);
    1771             : #endif
    1772             : 
    1773             :         /*
    1774             :          * POSIX demands that signals are inherited. If the invoking
    1775             :          * process has these signals masked, we will have problems, as
    1776             :          * we won't receive them.
    1777             :          */
    1778          82 :         BlockSignals(False, SIGHUP);
    1779          82 :         BlockSignals(False, SIGUSR1);
    1780          82 :         BlockSignals(False, SIGTERM);
    1781             : 
    1782             :         /* Ensure we leave no zombies until we
    1783             :          * correctly set up child handling below. */
    1784             : 
    1785          82 :         CatchChild();
    1786             : 
    1787             :         /* we want total control over the permissions on created files,
    1788             :            so set our umask to 0 */
    1789          82 :         umask(0);
    1790             : 
    1791          82 :         reopen_logs();
    1792             : 
    1793          82 :         DEBUG(0,("smbd version %s started.\n", samba_version_string()));
    1794          82 :         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
    1795             : 
    1796          82 :         DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
    1797             :                  (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
    1798             : 
    1799             :         /* Output the build options to the debug log */ 
    1800          82 :         build_options(False);
    1801             : 
    1802             :         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4) {
    1803             :                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
    1804             :                 exit(1);
    1805             :         }
    1806             : 
    1807             :         /*
    1808             :          * This calls unshare(CLONE_FS); on linux
    1809             :          * in order to check if the running kernel/container
    1810             :          * environment supports it.
    1811             :          */
    1812          82 :         per_thread_cwd_check();
    1813             : 
    1814          82 :         if (!cluster_probe_ok()) {
    1815           0 :                 exit(1);
    1816             :         }
    1817             : 
    1818             :         /* Init the security context and global current_user */
    1819          82 :         init_sec_ctx();
    1820             : 
    1821             :         /*
    1822             :          * Initialize the event context. The event context needs to be
    1823             :          * initialized before the messaging context, cause the messaging
    1824             :          * context holds an event context.
    1825             :          */
    1826          82 :         ev_ctx = global_event_context();
    1827          82 :         if (ev_ctx == NULL) {
    1828           0 :                 exit(1);
    1829             :         }
    1830             : 
    1831             :         /*
    1832             :          * Init the messaging context
    1833             :          * FIXME: This should only call messaging_init()
    1834             :          */
    1835          82 :         msg_ctx = global_messaging_context();
    1836          82 :         if (msg_ctx == NULL) {
    1837           0 :                 exit(1);
    1838             :         }
    1839             : 
    1840          82 :         dce_ctx = global_dcesrv_context();
    1841          82 :         if (dce_ctx == NULL) {
    1842           0 :                 exit(1);
    1843             :         }
    1844             : 
    1845             :         /*
    1846             :          * Reloading of the printers will not work here as we don't have a
    1847             :          * server info and rpc services set up. It will be called later.
    1848             :          */
    1849          82 :         if (!reload_services(NULL, NULL, false)) {
    1850           0 :                 exit(1);
    1851             :         }
    1852             : 
    1853          82 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
    1854          49 :                 if (!lp_parm_bool(-1, "server role check", "inhibit", false)) {
    1855           0 :                         DBG_ERR("server role = 'active directory domain controller' not compatible with running smbd standalone. \n");
    1856           0 :                         DEBUGADD(0, ("You should start 'samba' instead, and it will control starting smbd if required\n"));
    1857           0 :                         exit(1);
    1858             :                 }
    1859             :                 /* Main 'samba' daemon will notify */
    1860          49 :                 daemon_sd_notifications(false);
    1861             :         }
    1862             : 
    1863             :         /* ...NOTE... Log files are working from this point! */
    1864             : 
    1865          82 :         DEBUG(3,("loaded services\n"));
    1866             : 
    1867          80 :         init_structs();
    1868             : 
    1869          82 :         if (!profile_setup(msg_ctx, False)) {
    1870           0 :                 DEBUG(0,("ERROR: failed to setup profiling\n"));
    1871           0 :                 return -1;
    1872             :         }
    1873             : 
    1874          82 :         if (profile_level != NULL) {
    1875           0 :                 profiling_level = atoi(profile_level);
    1876             :         } else {
    1877          82 :                 profiling_level = lp_smbd_profiling_level();
    1878             :         }
    1879          82 :         main_server_id = messaging_server_id(msg_ctx);
    1880          82 :         set_profile_level(profiling_level, &main_server_id);
    1881             : 
    1882          82 :         if (!is_daemon && !is_a_socket(0)) {
    1883          33 :                 if (!interactive) {
    1884          33 :                         DEBUG(3, ("Standard input is not a socket, "
    1885             :                                   "assuming -D option\n"));
    1886             :                 }
    1887             : 
    1888             :                 /*
    1889             :                  * Setting is_daemon here prevents us from eventually calling
    1890             :                  * the open_sockets_inetd()
    1891             :                  */
    1892             : 
    1893          33 :                 is_daemon = True;
    1894             :         }
    1895             : 
    1896          82 :         if (is_daemon && !interactive) {
    1897          82 :                 DEBUG(3, ("Becoming a daemon.\n"));
    1898          82 :                 become_daemon(Fork, no_process_group, log_stdout);
    1899             :         } else {
    1900           0 :                 daemon_status("smbd", "Starting process ...");
    1901             :         }
    1902             : 
    1903             : #ifdef HAVE_SETPGID
    1904             :         /*
    1905             :          * If we're interactive we want to set our own process group for
    1906             :          * signal management.
    1907             :          */
    1908          82 :         if (interactive && !no_process_group)
    1909           0 :                 setpgid( (pid_t)0, (pid_t)0);
    1910             : #endif
    1911             : 
    1912          82 :         if (!directory_exist(lp_lock_directory()))
    1913           0 :                 mkdir(lp_lock_directory(), 0755);
    1914             : 
    1915          82 :         if (!directory_exist(lp_pid_directory()))
    1916           0 :                 mkdir(lp_pid_directory(), 0755);
    1917             : 
    1918          82 :         if (is_daemon)
    1919          82 :                 pidfile_create(lp_pid_directory(), "smbd");
    1920             : 
    1921          82 :         status = reinit_after_fork(msg_ctx, ev_ctx, false, NULL);
    1922          82 :         if (!NT_STATUS_IS_OK(status)) {
    1923           0 :                 exit_daemon("reinit_after_fork() failed", map_errno_from_nt_status(status));
    1924             :         }
    1925             : 
    1926          82 :         if (!interactive) {
    1927             :                 /*
    1928             :                  * Do not initialize the parent-child-pipe before becoming a
    1929             :                  * daemon: this is used to detect a died parent in the child
    1930             :                  * process.
    1931             :                  */
    1932          82 :                 status = init_before_fork();
    1933          82 :                 if (!NT_STATUS_IS_OK(status)) {
    1934           0 :                         exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
    1935             :                 }
    1936             :         }
    1937             : 
    1938          82 :         parent = talloc_zero(ev_ctx, struct smbd_parent_context);
    1939          82 :         if (!parent) {
    1940           0 :                 exit_server("talloc(struct smbd_parent_context) failed");
    1941             :         }
    1942          82 :         parent->interactive = interactive;
    1943          82 :         parent->ev_ctx = ev_ctx;
    1944          82 :         parent->msg_ctx = msg_ctx;
    1945          82 :         parent->dce_ctx = dce_ctx;
    1946          82 :         am_parent = parent;
    1947             : 
    1948          82 :         se = tevent_add_signal(parent->ev_ctx,
    1949             :                                parent,
    1950             :                                SIGTERM, 0,
    1951             :                                smbd_parent_sig_term_handler,
    1952             :                                parent);
    1953          82 :         if (!se) {
    1954           0 :                 exit_server("failed to setup SIGTERM handler");
    1955             :         }
    1956          82 :         se = tevent_add_signal(parent->ev_ctx,
    1957             :                                parent,
    1958             :                                SIGHUP, 0,
    1959             :                                smbd_parent_sig_hup_handler,
    1960             :                                parent);
    1961          82 :         if (!se) {
    1962           0 :                 exit_server("failed to setup SIGHUP handler");
    1963             :         }
    1964             : 
    1965             :         /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
    1966             : 
    1967          82 :         if (smbd_memcache() == NULL) {
    1968           0 :                 exit_daemon("no memcache available", EACCES);
    1969             :         }
    1970             : 
    1971          82 :         memcache_set_global(smbd_memcache());
    1972             : 
    1973             :         /* Initialise the password backed before the global_sam_sid
    1974             :            to ensure that we fetch from ldap before we make a domain sid up */
    1975             : 
    1976          82 :         if(!initialize_password_db(false, ev_ctx))
    1977           0 :                 exit(1);
    1978             : 
    1979          82 :         if (!secrets_init()) {
    1980           0 :                 exit_daemon("smbd can not open secrets.tdb", EACCES);
    1981             :         }
    1982             : 
    1983          82 :         if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
    1984           8 :                 struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
    1985           8 :                 if (!open_schannel_session_store(NULL, lp_ctx)) {
    1986           0 :                         exit_daemon("ERROR: Samba cannot open schannel store for secured NETLOGON operations.", EACCES);
    1987             :                 }
    1988           8 :                 TALLOC_FREE(lp_ctx);
    1989             :         }
    1990             : 
    1991          82 :         if(!get_global_sam_sid()) {
    1992           0 :                 exit_daemon("Samba cannot create a SAM SID", EACCES);
    1993             :         }
    1994             : 
    1995          82 :         server_id = messaging_server_id(msg_ctx);
    1996          82 :         status = smbXsrv_version_global_init(&server_id);
    1997          82 :         if (!NT_STATUS_IS_OK(status)) {
    1998           0 :                 exit_daemon("Samba cannot init server context", EACCES);
    1999             :         }
    2000             : 
    2001          82 :         status = smbXsrv_client_global_init();
    2002          82 :         if (!NT_STATUS_IS_OK(status)) {
    2003           0 :                 exit_daemon("Samba cannot init clients context", EACCES);
    2004             :         }
    2005             : 
    2006          82 :         status = smbXsrv_session_global_init(msg_ctx);
    2007          82 :         if (!NT_STATUS_IS_OK(status)) {
    2008           0 :                 exit_daemon("Samba cannot init session context", EACCES);
    2009             :         }
    2010             : 
    2011          82 :         status = smbXsrv_tcon_global_init();
    2012          82 :         if (!NT_STATUS_IS_OK(status)) {
    2013           0 :                 exit_daemon("Samba cannot init tcon context", EACCES);
    2014             :         }
    2015             : 
    2016          82 :         if (!locking_init())
    2017           0 :                 exit_daemon("Samba cannot init locking", EACCES);
    2018             : 
    2019          82 :         if (!leases_db_init(false)) {
    2020           0 :                 exit_daemon("Samba cannot init leases", EACCES);
    2021             :         }
    2022             : 
    2023          82 :         if (!smbd_notifyd_init(msg_ctx, interactive, &parent->notifyd)) {
    2024           0 :                 exit_daemon("Samba cannot init notification", EACCES);
    2025             :         }
    2026             : 
    2027          82 :         if (!cleanupd_init(msg_ctx, interactive, &parent->cleanupd)) {
    2028           0 :                 exit_daemon("Samba cannot init the cleanupd", EACCES);
    2029             :         }
    2030             : 
    2031          75 :         if (!messaging_parent_dgm_cleanup_init(msg_ctx)) {
    2032           0 :                 exit(1);
    2033             :         }
    2034             : 
    2035          75 :         if (!smbd_scavenger_init(NULL, msg_ctx, ev_ctx)) {
    2036           0 :                 exit_daemon("Samba cannot init scavenging", EACCES);
    2037             :         }
    2038             : 
    2039          75 :         if (!W_ERROR_IS_OK(registry_init_full()))
    2040           0 :                 exit_daemon("Samba cannot init registry", EACCES);
    2041             : 
    2042             :         /* Open the share_info.tdb here, so we don't have to open
    2043             :            after the fork on every single connection.  This is a small
    2044             :            performance improvment and reduces the total number of system
    2045             :            fds used. */
    2046          75 :         status = share_info_db_init();
    2047          75 :         if (!NT_STATUS_IS_OK(status)) {
    2048           0 :                 exit_daemon("ERROR: failed to load share info db.", EACCES);
    2049             :         }
    2050             : 
    2051          75 :         status = init_system_session_info(NULL);
    2052          75 :         if (!NT_STATUS_IS_OK(status)) {
    2053           0 :                 DEBUG(1, ("ERROR: failed to setup system user info: %s.\n",
    2054             :                           nt_errstr(status)));
    2055           0 :                 return -1;
    2056             :         }
    2057             : 
    2058          75 :         if (!init_guest_session_info(NULL)) {
    2059           0 :                 DEBUG(0,("ERROR: failed to setup guest info.\n"));
    2060           0 :                 return -1;
    2061             :         }
    2062             : 
    2063          75 :         if (!file_init_global()) {
    2064           0 :                 DEBUG(0, ("ERROR: file_init_global() failed\n"));
    2065           0 :                 return -1;
    2066             :         }
    2067          75 :         status = smbXsrv_open_global_init();
    2068          75 :         if (!NT_STATUS_IS_OK(status)) {
    2069           0 :                 exit_daemon("Samba cannot init global open", map_errno_from_nt_status(status));
    2070             :         }
    2071             : 
    2072          75 :         if (lp_clustering() && !lp_allow_unsafe_cluster_upgrade()) {
    2073           0 :                 status = smbd_claim_version(msg_ctx, samba_version_string());
    2074           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2075           0 :                         DBG_ERR("Could not claim version: %s\n",
    2076             :                                     nt_errstr(status));
    2077           0 :                         return -1;
    2078             :                 }
    2079             :         }
    2080             : 
    2081             :         /* This MUST be done before start_epmd() because otherwise
    2082             :          * start_epmd() forks and races against dcesrv_ep_setup() to
    2083             :          * call directory_create_or_exist() */
    2084          75 :         if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
    2085           0 :                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
    2086             :                           lp_ncalrpc_dir(), strerror(errno)));
    2087           0 :                 return -1;
    2088             :         }
    2089             : 
    2090          75 :         np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
    2091          75 :         if (!np_dir) {
    2092           0 :                 DEBUG(0, ("%s: Out of memory\n", __location__));
    2093           0 :                 return -1;
    2094             :         }
    2095             : 
    2096          75 :         if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) {
    2097           0 :                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
    2098             :                           np_dir, strerror(errno)));
    2099           0 :                 return -1;
    2100             :         }
    2101             : 
    2102          75 :         status = dcesrv_init(ev_ctx, ev_ctx, msg_ctx, dce_ctx);
    2103          75 :         if (!NT_STATUS_IS_OK(status)) {
    2104           0 :                 DBG_ERR("Failed to setup RPC server: %s\n", nt_errstr(status));
    2105           0 :                 exit_daemon("Samba cannot setup ep pipe", EACCES);
    2106             :         }
    2107             : 
    2108          75 :         if (!interactive) {
    2109          75 :                 daemon_ready("smbd");
    2110             :         }
    2111             : 
    2112         150 :         serving_printers = (!lp__disable_spoolss() &&
    2113          75 :                             (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED));
    2114             : 
    2115             :         /* only start other daemons if we are running as a daemon
    2116             :          * -- bad things will happen if smbd is launched via inetd
    2117             :          *  and we fork a copy of ourselves here */
    2118          75 :         if (is_daemon && !interactive) {
    2119             : 
    2120          75 :                 if (rpc_epmapper_daemon() == RPC_DAEMON_FORK) {
    2121          10 :                         start_epmd(ev_ctx, msg_ctx, dce_ctx);
    2122             :                 }
    2123             : 
    2124          75 :                 if (rpc_lsasd_daemon() == RPC_DAEMON_FORK) {
    2125          10 :                         start_lsasd(ev_ctx, msg_ctx, dce_ctx);
    2126             :                 }
    2127             : 
    2128          75 :                 if (rpc_fss_daemon() == RPC_DAEMON_FORK) {
    2129           6 :                         start_fssd(ev_ctx, msg_ctx, dce_ctx);
    2130             :                 }
    2131             : 
    2132          75 :                 if (serving_printers) {
    2133          75 :                         bool bgq = lp_parm_bool(-1, "smbd", "backgroundqueue", true);
    2134          75 :                         ok = printing_subsystem_init(ev_ctx,
    2135             :                                                      msg_ctx,
    2136             :                                                      dce_ctx,
    2137             :                                                      true,
    2138             :                                                      bgq);
    2139          75 :                         if (!ok) {
    2140           0 :                                 exit_daemon("Samba failed to init printing subsystem", EACCES);
    2141             :                         }
    2142             :                 }
    2143             : 
    2144             : #ifdef WITH_SPOTLIGHT
    2145         190 :                 if ((rpc_mdssvc_mode() == RPC_SERVICE_MODE_EXTERNAL) &&
    2146          42 :                     (rpc_mdssd_daemon() == RPC_DAEMON_FORK)) {
    2147           0 :                         start_mdssd(ev_ctx, msg_ctx, dce_ctx);
    2148             :                 }
    2149             : #endif
    2150           0 :         } else if (serving_printers) {
    2151           0 :                 ok = printing_subsystem_init(ev_ctx,
    2152             :                                              msg_ctx,
    2153             :                                              dce_ctx,
    2154             :                                              false,
    2155             :                                              false);
    2156           0 :                 if (!ok) {
    2157           0 :                         exit(1);
    2158             :                 }
    2159             :         }
    2160             : 
    2161          75 :         if (!is_daemon) {
    2162             :                 int ret, sock;
    2163             : 
    2164             :                 /* inetd mode */
    2165           0 :                 TALLOC_FREE(frame);
    2166             : 
    2167             :                 /* Started from inetd. fd 0 is the socket. */
    2168             :                 /* We will abort gracefully when the client or remote system
    2169             :                    goes away */
    2170           0 :                 sock = dup(0);
    2171             : 
    2172             :                 /* close stdin, stdout (if not logging to it), but not stderr */
    2173           0 :                 ret = close_low_fd(0);
    2174           0 :                 if (ret != 0) {
    2175           0 :                         DBG_ERR("close_low_fd(0) failed: %s\n", strerror(ret));
    2176           0 :                         return 1;
    2177             :                 }
    2178           0 :                 if (!debug_get_output_is_stdout()) {
    2179           0 :                         ret = close_low_fd(1);
    2180           0 :                         if (ret != 0) {
    2181           0 :                                 DBG_ERR("close_low_fd(1) failed: %s\n",
    2182             :                                         strerror(ret));
    2183           0 :                                 return 1;
    2184             :                         }
    2185             :                 }
    2186             : 
    2187             : #ifdef HAVE_ATEXIT
    2188           0 :                 atexit(killkids);
    2189             : #endif
    2190             : 
    2191             :                 /* Stop zombies */
    2192           0 :                 smbd_setup_sig_chld_handler(parent);
    2193             : 
    2194           0 :                 smbd_process(ev_ctx, msg_ctx, dce_ctx, sock, true);
    2195             : 
    2196           0 :                 exit_server_cleanly(NULL);
    2197             :                 return(0);
    2198             :         }
    2199             : 
    2200          75 :         if (!open_sockets_smbd(parent, ev_ctx, msg_ctx, ports))
    2201           0 :                 exit_server("open_sockets_smbd() failed");
    2202             : 
    2203             :         /* do a printer update now that all messaging has been set up,
    2204             :          * before we allow clients to start connecting */
    2205         150 :         if (!lp__disable_spoolss() &&
    2206          75 :             (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) {
    2207          75 :                 printing_subsystem_update(ev_ctx, msg_ctx, false);
    2208             :         }
    2209             : 
    2210          75 :         TALLOC_FREE(frame);
    2211             :         /* make sure we always have a valid stackframe */
    2212          75 :         frame = talloc_stackframe();
    2213             : 
    2214          75 :         if (!Fork) {
    2215             :                 /* if we are running in the foreground then look for
    2216             :                    EOF on stdin, and exit if it happens. This allows
    2217             :                    us to die if the parent process dies
    2218             :                    Only do this on a pipe or socket, no other device.
    2219             :                 */
    2220             :                 struct stat st;
    2221          75 :                 if (fstat(0, &st) != 0) {
    2222           0 :                         return false;
    2223             :                 }
    2224          75 :                 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
    2225          75 :                         tevent_add_fd(ev_ctx,
    2226             :                                         parent,
    2227             :                                         0,
    2228             :                                         TEVENT_FD_READ,
    2229             :                                         smbd_stdin_handler,
    2230             :                                         NULL);
    2231             :                 }
    2232             :         }
    2233             : 
    2234          75 :         smbd_parent_loop(ev_ctx, parent);
    2235             : 
    2236           0 :         exit_server_cleanly(NULL);
    2237             :         TALLOC_FREE(frame);
    2238             :         return(0);
    2239             : }

Generated by: LCOV version 1.13