LCOV - code coverage report
Current view: top level - source3/smbd - server.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 448 866 51.7 %
Date: 2021-09-23 10:06:22 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         184 : 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         184 :         struct tevent_context *ev_ctx =
     117           0 :                 talloc_get_type_abort(private_data, struct tevent_context);
     118             :         bool ok;
     119             : 
     120         184 :         DEBUG(10,("smbd_parent_conf_updated: Got message saying smb.conf was "
     121             :                   "updated. Reloading.\n"));
     122         184 :         change_to_root_user();
     123         184 :         reload_services(NULL, NULL, false);
     124         184 :         printing_subsystem_update(ev_ctx, msg, false);
     125             : 
     126         184 :         ok = reinit_guest_session_info(NULL);
     127         184 :         if (!ok) {
     128           0 :                 DBG_ERR("Failed to reinit guest info\n");
     129             :         }
     130         184 :         messaging_send_to_children(msg, MSG_SMB_CONF_UPDATED, NULL);
     131         184 : }
     132             : 
     133             : /*******************************************************************
     134             :  Delete a statcache entry.
     135             :  ********************************************************************/
     136             : 
     137       15787 : 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       15787 :         const char *name = (const char *)data->data;
     144       15787 :         DEBUG(10,("smb_stat_cache_delete: delete name %s\n", name));
     145       15787 :         stat_cache_delete(name);
     146       15787 : }
     147             : 
     148             : /****************************************************************************
     149             :   Send a SIGTERM to our process group.
     150             : *****************************************************************************/
     151             : 
     152       27288 : static void  killkids(void)
     153             : {
     154       27288 :         if(am_parent) kill(0,SIGTERM);
     155       27288 : }
     156             : 
     157           8 : 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           8 :         DEBUG(3, ("got a SHUTDOWN message\n"));
     164           8 :         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         418 : static NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx,
     232             :                                            uint32_t msg_type, DATA_BLOB* data)
     233             : {
     234             :         NTSTATUS status;
     235         418 :         struct smbd_parent_context *parent = am_parent;
     236             :         struct smbd_child_pid *child;
     237             : 
     238         418 :         if (parent == NULL) {
     239         145 :                 return NT_STATUS_INTERNAL_ERROR;
     240             :         }
     241             : 
     242        1972 :         for (child = parent->children; child != NULL; child = child->next) {
     243        1699 :                 status = messaging_send(parent->msg_ctx,
     244             :                                         pid_to_procid(child->pid),
     245             :                                         msg_type, data);
     246        1699 :                 if (!NT_STATUS_IS_OK(status)) {
     247          14 :                         DBG_DEBUG("messaging_send(%d) failed: %s\n",
     248             :                                   (int)child->pid, nt_errstr(status));
     249             :                 }
     250             :         }
     251         273 :         return NT_STATUS_OK;
     252             : }
     253             : 
     254          86 : 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          86 :         messaging_send_to_children(ctx, msg_type, msg_data);
     261          86 : }
     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         148 : 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         148 :         id_cache_delete_message(ctx, data, msg_type, srv_id, msg_data);
     307             : 
     308         148 :         messaging_send_to_children(ctx, msg_type, msg_data);
     309         148 : }
     310             : 
     311       23719 : static void add_child_pid(struct smbd_parent_context *parent,
     312             :                           pid_t pid)
     313             : {
     314             :         struct smbd_child_pid *child;
     315             : 
     316       23719 :         child = talloc_zero(parent, struct smbd_child_pid);
     317       23719 :         if (child == NULL) {
     318           0 :                 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
     319           0 :                 return;
     320             :         }
     321       23719 :         child->pid = pid;
     322       23719 :         DLIST_ADD(parent->children, child);
     323       23719 :         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          63 : static bool smbd_notifyd_init(struct messaging_context *msg, bool interactive,
     408             :                               struct server_id *ppid)
     409             : {
     410          63 :         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          63 :         if (interactive) {
     418           0 :                 req = notifyd_req(msg, ev);
     419           0 :                 return (req != NULL);
     420             :         }
     421             : 
     422          63 :         pid = fork();
     423          63 :         if (pid == -1) {
     424           0 :                 DEBUG(1, ("%s: fork failed: %s\n", __func__,
     425             :                           strerror(errno)));
     426           0 :                 return false;
     427             :         }
     428             : 
     429          63 :         if (pid != 0) {
     430          63 :                 if (am_parent != NULL) {
     431          63 :                         add_child_pid(am_parent, pid);
     432             :                 }
     433          63 :                 *ppid = pid_to_procid(pid);
     434          63 :                 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         117 : static bool cleanupd_init(struct messaging_context *msg, bool interactive,
     575             :                           struct server_id *ppid)
     576             : {
     577         117 :         struct tevent_context *ev = messaging_tevent_context(msg);
     578         117 :         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         117 :         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         117 :         ret = pipe(up_pipe);
     595         117 :         if (ret == -1) {
     596           0 :                 DBG_WARNING("pipe failed: %s\n", strerror(errno));
     597           0 :                 return false;
     598             :         }
     599             : 
     600         117 :         pid = fork();
     601         114 :         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         114 :         if (pid != 0) {
     609             : 
     610         114 :                 close(up_pipe[1]);
     611         114 :                 rwret = sys_read(up_pipe[0], &c, 1);
     612         114 :                 close(up_pipe[0]);
     613             : 
     614         114 :                 if (rwret == -1) {
     615           0 :                         DBG_WARNING("sys_read failed: %s\n", strerror(errno));
     616           0 :                         return false;
     617             :                 }
     618         114 :                 if (rwret == 0) {
     619           0 :                         DBG_WARNING("cleanupd could not start\n");
     620           0 :                         return false;
     621             :                 }
     622         114 :                 if (c != 0) {
     623           0 :                         DBG_WARNING("cleanupd returned %d\n", (int)c);
     624           0 :                         return false;
     625             :                 }
     626             : 
     627         114 :                 DBG_DEBUG("Started cleanupd pid=%d\n", (int)pid);
     628             : 
     629         114 :                 if (am_parent != NULL) {
     630         114 :                         add_child_pid(am_parent, pid);
     631             :                 }
     632             : 
     633         114 :                 *ppid = pid_to_procid(pid);
     634         114 :                 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       23611 : 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       36097 :         for (child = parent->children; child != NULL; child = child->next) {
     804       36034 :                 if (child->pid == pid) {
     805       23548 :                         struct smbd_child_pid *tmp = child;
     806       23548 :                         DLIST_REMOVE(parent->children, child);
     807       23548 :                         TALLOC_FREE(tmp);
     808       23548 :                         parent->num_children -= 1;
     809       23548 :                         break;
     810             :                 }
     811             :         }
     812             : 
     813       23611 :         if (child == NULL) {
     814             :                 /* not all forked child processes are added to the children list */
     815          63 :                 DEBUG(2, ("Could not find child %d -- ignoring\n", (int)pid));
     816         180 :                 return;
     817             :         }
     818             : 
     819       23548 :         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       23494 :         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       23494 :         ok = cleanupdb_store_child(pid, unclean_shutdown);
     858       23494 :         if (!ok) {
     859           0 :                 DBG_ERR("cleanupdb_store_child failed\n");
     860           0 :                 return;
     861             :         }
     862             : 
     863       23494 :         if (!server_id_is_disconnected(&parent->cleanupd)) {
     864       23492 :                 status = messaging_send(parent->msg_ctx,
     865             :                                         parent->cleanupd,
     866             :                                         MSG_SMB_NOTIFY_CLEANUP,
     867             :                                         &data_blob_null);
     868       23492 :                 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       23051 : static bool allowable_number_of_smbd_processes(struct smbd_parent_context *parent)
     880             : {
     881       23581 :         int max_processes = lp_max_smbd_processes();
     882             : 
     883       23581 :         if (!max_processes)
     884       23051 :                 return True;
     885             : 
     886           0 :         return parent->num_children < max_processes;
     887             : }
     888             : 
     889       23248 : 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       23248 :         struct smbd_parent_context *parent =
     899           0 :                 talloc_get_type_abort(private_data,
     900             :                 struct smbd_parent_context);
     901             : 
     902       70107 :         while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
     903       23611 :                 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       23611 :                 if (WIFEXITED(status)) {
     910       23554 :                         unclean_shutdown = WEXITSTATUS(status);
     911             :                 }
     912             :                 /* If the child terminated due to a signal
     913             :                    we always assume it was unclean.
     914             :                 */
     915       23611 :                 if (WIFSIGNALED(status)) {
     916          57 :                         unclean_shutdown = True;
     917             :                 }
     918       23611 :                 remove_child_pid(parent, pid, unclean_shutdown);
     919             :         }
     920       23248 : }
     921             : 
     922          60 : static void smbd_setup_sig_chld_handler(struct smbd_parent_context *parent)
     923             : {
     924             :         struct tevent_signal *se;
     925             : 
     926          60 :         se = tevent_add_signal(parent->ev_ctx,
     927             :                                parent, /* mem_ctx */
     928             :                                SIGCHLD, 0,
     929             :                                smbd_sig_chld_handler,
     930             :                                parent);
     931          60 :         if (!se) {
     932           0 :                 exit_server("failed to setup SIGCHLD handler");
     933             :         }
     934          60 : }
     935             : 
     936      109080 : 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      109080 :         close(fd);
     943      109080 : }
     944             : 
     945       23581 : static void smbd_accept_connection(struct tevent_context *ev,
     946             :                                    struct tevent_fd *fde,
     947             :                                    uint16_t flags,
     948             :                                    void *private_data)
     949             : {
     950       23581 :         struct smbd_open_socket *s = talloc_get_type_abort(private_data,
     951             :                                      struct smbd_open_socket);
     952       23581 :         struct messaging_context *msg_ctx = s->parent->msg_ctx;
     953       23581 :         struct dcesrv_context *dce_ctx = s->parent->dce_ctx;
     954             :         struct sockaddr_storage addr;
     955       23581 :         socklen_t in_addrlen = sizeof(addr);
     956             :         int fd;
     957       23581 :         pid_t pid = 0;
     958             : 
     959       23581 :         fd = accept(s->fd, (struct sockaddr *)(void *)&addr,&in_addrlen);
     960       23581 :         if (fd == -1 && errno == EINTR)
     961           0 :                 return;
     962             : 
     963       23581 :         if (fd == -1) {
     964           0 :                 DEBUG(0,("accept: %s\n",
     965             :                          strerror(errno)));
     966           0 :                 return;
     967             :         }
     968       23581 :         smb_set_close_on_exec(fd);
     969             : 
     970       23581 :         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       23581 :         if (!allowable_number_of_smbd_processes(s->parent)) {
     978           0 :                 close(fd);
     979           0 :                 return;
     980             :         }
     981             : 
     982       23581 :         pid = fork();
     983       50809 :         if (pid == 0) {
     984       27267 :                 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       27267 :                 talloc_free(s->parent);
     991       27267 :                 s = NULL;
     992             : 
     993             :                 /* Stop zombies, the parent explicitly handles
     994             :                  * them, counting worker smbds. */
     995       27267 :                 CatchChild();
     996             : 
     997       27267 :                 status = smbd_reinit_after_fork(msg_ctx, ev, true, NULL);
     998       27267 :                 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       27267 :                 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       23542 :         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       23542 :         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       23014 :         if (pid != 0) {
    1044       23542 :                 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       23542 :         force_check_log_size();
    1062             : }
    1063             : 
    1064         240 : 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         240 :         s = talloc(parent, struct smbd_open_socket);
    1072         240 :         if (!s) {
    1073           0 :                 return false;
    1074             :         }
    1075             : 
    1076         240 :         s->parent = parent;
    1077             : 
    1078         240 :         s->fd = open_socket_in(SOCK_STREAM, ifss, port, true);
    1079         240 :         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         240 :         set_socket_options(s->fd, "SO_KEEPALIVE");
    1091         240 :         set_socket_options(s->fd, lp_socket_options());
    1092             : 
    1093             :         /* Set server socket to
    1094             :          * non-blocking for the accept. */
    1095         240 :         set_blocking(s->fd, False);
    1096             : 
    1097         240 :         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         240 :         s->fde = tevent_add_fd(ev_ctx,
    1106             :                                s,
    1107             :                                s->fd, TEVENT_FD_READ,
    1108             :                                smbd_accept_connection,
    1109             :                                s);
    1110         240 :         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         240 :         tevent_fd_set_close_fn(s->fde, smbd_open_socket_close_fn);
    1119             : 
    1120         240 :         DLIST_ADD_END(parent->sockets, s);
    1121             : 
    1122         232 :         return true;
    1123             : }
    1124             : 
    1125             : /****************************************************************************
    1126             :  Open the socket communication.
    1127             : ****************************************************************************/
    1128             : 
    1129          60 : 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          60 :         int num_interfaces = iface_count();
    1135             :         int i,j;
    1136             :         const char **ports;
    1137          60 :         unsigned dns_port = 0;
    1138             : 
    1139             : #ifdef HAVE_ATEXIT
    1140          60 :         atexit(killkids);
    1141             : #endif
    1142             : 
    1143             :         /* Stop zombies */
    1144          60 :         smbd_setup_sig_chld_handler(parent);
    1145             : 
    1146          60 :         ports = lp_smb_ports();
    1147             : 
    1148             :         /* use a reasonable default set of ports - listing on 445 and 139 */
    1149          60 :         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         180 :         for (j = 0; ports && ports[j]; j++) {
    1156         124 :                 unsigned port = atoi(ports[j]);
    1157             : 
    1158         120 :                 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          88 :         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          84 :                 for(i = 0; i < num_interfaces; i++) {
    1173          56 :                         const struct sockaddr_storage *ifss =
    1174           0 :                                         iface_n_sockaddr_storage(i);
    1175          56 :                         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         168 :                         for (j = 0; ports && ports[j]; j++) {
    1183         112 :                                 unsigned port = atoi(ports[j]);
    1184             : 
    1185             :                                 /* Keep the first port for mDNS service
    1186             :                                  * registration.
    1187             :                                  */
    1188         112 :                                 if (dns_port == 0) {
    1189          28 :                                         dns_port = port;
    1190             :                                 }
    1191             : 
    1192         112 :                                 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          32 :                 sock_addr = "::,0.0.0.0";
    1210             : #else
    1211             :                 sock_addr = "0.0.0.0";
    1212             : #endif
    1213             : 
    1214         128 :                 for (sock_ptr=sock_addr;
    1215          96 :                      next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) {
    1216         188 :                         for (j = 0; ports && ports[j]; j++) {
    1217             :                                 struct sockaddr_storage ss;
    1218         136 :                                 unsigned port = atoi(ports[j]);
    1219             : 
    1220             :                                 /* Keep the first port for mDNS service
    1221             :                                  * registration.
    1222             :                                  */
    1223         120 :                                 if (dns_port == 0) {
    1224          30 :                                         dns_port = port;
    1225             :                                 }
    1226             : 
    1227             :                                 /* open an incoming socket */
    1228         128 :                                 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         128 :                                 (void)smbd_open_one_socket(parent,
    1240             :                                                   ev_ctx,
    1241             :                                                   &ss,
    1242             :                                                   port);
    1243             :                         }
    1244             :                 }
    1245             :         }
    1246             : 
    1247          60 :         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          60 :         messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server);
    1256          60 :         messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED,
    1257             :                            smbd_parent_conf_updated);
    1258          60 :         messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE,
    1259             :                            smb_stat_cache_delete);
    1260          60 :         messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug);
    1261          60 :         messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS,
    1262             :                            smb_parent_send_to_children);
    1263          60 :         messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS_DENIED,
    1264             :                            smb_parent_send_to_children);
    1265          60 :         messaging_register(msg_ctx, NULL, MSG_SMB_KILL_CLIENT_IP,
    1266             :                            smb_parent_send_to_children);
    1267          60 :         messaging_register(msg_ctx, NULL, MSG_SMB_TELL_NUM_CHILDREN,
    1268             :                            smb_tell_num_children);
    1269             : 
    1270          60 :         messaging_register(msg_ctx, NULL,
    1271             :                            ID_CACHE_DELETE, smbd_parent_id_cache_delete);
    1272          60 :         messaging_register(msg_ctx, NULL,
    1273             :                            ID_CACHE_KILL, smbd_parent_id_cache_kill);
    1274          60 :         messaging_register(msg_ctx, NULL, MSG_SMB_NOTIFY_STARTED,
    1275             :                            smb_parent_send_to_children);
    1276             : 
    1277             : #ifdef DEVELOPER
    1278          60 :         messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT,
    1279             :                            msg_inject_fault);
    1280             : #endif
    1281             : 
    1282             : #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
    1283          60 :         messaging_register(msg_ctx, NULL, MSG_SMB_SLEEP, msg_sleep);
    1284             : #endif
    1285             : 
    1286          60 :         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           0 :                 avahi_conn = avahi_start_register(ev_ctx,
    1295             :                                                   ev_ctx,
    1296             :                                                   dns_port);
    1297           0 :                 if (avahi_conn == NULL) {
    1298           0 :                         DEBUG(10, ("avahi_start_register failed\n"));
    1299             :                 }
    1300             : #endif
    1301             :         }
    1302             : 
    1303          60 :         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      365442 : static void smbd_parent_tevent_trace_callback(enum tevent_trace_point point,
    1328             :                                               void *private_data)
    1329             : {
    1330      365442 :         struct smbd_parent_tevent_trace_state *state =
    1331             :                 (struct smbd_parent_tevent_trace_state *)private_data;
    1332             : 
    1333      365442 :         switch (point) {
    1334       78957 :         case TEVENT_TRACE_BEFORE_WAIT:
    1335       78957 :                 break;
    1336       78957 :         case TEVENT_TRACE_AFTER_WAIT:
    1337       78957 :                 break;
    1338      102315 :         case TEVENT_TRACE_BEFORE_LOOP_ONCE:
    1339      102315 :                 TALLOC_FREE(state->frame);
    1340      102315 :                 state->frame = talloc_stackframe();
    1341      102315 :                 break;
    1342      102255 :         case TEVENT_TRACE_AFTER_LOOP_ONCE:
    1343      102255 :                 TALLOC_FREE(state->frame);
    1344      100593 :                 break;
    1345             :         }
    1346             : 
    1347      365442 :         errno = 0;
    1348      365442 : }
    1349             : 
    1350          60 : static void smbd_parent_loop(struct tevent_context *ev_ctx,
    1351             :                              struct smbd_parent_context *parent)
    1352             : {
    1353          60 :         struct smbd_parent_tevent_trace_state trace_state = {
    1354             :                 .frame = NULL,
    1355             :         };
    1356          60 :         int ret = 0;
    1357             : 
    1358          60 :         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          60 :         DEBUG(2,("waiting for connections\n"));
    1364             : 
    1365          60 :         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          61 : 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          63 :         if (!secrets_init())
    1389           0 :                 return False;
    1390             : 
    1391          61 :         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           0 :                 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         107 :  int main(int argc,const char *argv[])
    1539             : {
    1540             :         /* shall I run as a daemon */
    1541         107 :         struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL;
    1542         107 :         bool log_stdout = false;
    1543         107 :         char *ports = NULL;
    1544         107 :         char *profile_level = NULL;
    1545             :         int opt;
    1546             :         poptContext pc;
    1547         107 :         bool print_build_options = False;
    1548         107 :         bool serving_printers = false;
    1549         107 :         struct server_id main_server_id = {0};
    1550         428 :         struct poptOption long_options[] = {
    1551             :                 POPT_AUTOHELP
    1552             :                 {
    1553             :                         .longName   = "build-options",
    1554             :                         .shortName  = 'b',
    1555             :                         .argInfo    = POPT_ARG_NONE,
    1556             :                         .arg        = NULL,
    1557             :                         .val        = 'b',
    1558             :                         .descrip    = "Print build options" ,
    1559             :                 },
    1560             :                 {
    1561             :                         .longName   = "port",
    1562             :                         .shortName  = 'p',
    1563             :                         .argInfo    = POPT_ARG_STRING,
    1564             :                         .arg        = &ports,
    1565             :                         .val        = 0,
    1566             :                         .descrip    = "Listen on the specified ports",
    1567             :                 },
    1568             :                 {
    1569             :                         .longName   = "profiling-level",
    1570             :                         .shortName  = 'P',
    1571             :                         .argInfo    = POPT_ARG_STRING,
    1572             :                         .arg        = &profile_level,
    1573             :                         .val        = 0,
    1574             :                         .descrip    = "Set profiling level","PROFILE_LEVEL",
    1575             :                 },
    1576         107 :                 POPT_COMMON_SAMBA
    1577         107 :                 POPT_COMMON_DAEMON
    1578         107 :                 POPT_COMMON_VERSION
    1579             :                 POPT_TABLEEND
    1580             :         };
    1581         107 :         struct smbd_parent_context *parent = NULL;
    1582             :         TALLOC_CTX *frame;
    1583             :         NTSTATUS status;
    1584             :         struct tevent_context *ev_ctx;
    1585             :         struct messaging_context *msg_ctx;
    1586         107 :         struct dcesrv_context *dce_ctx = NULL;
    1587             :         struct server_id server_id;
    1588             :         struct tevent_signal *se;
    1589             :         int profiling_level;
    1590         107 :         char *np_dir = NULL;
    1591          91 :         const struct loadparm_substitution *lp_sub =
    1592          16 :                 loadparm_s3_global_substitution();
    1593             :         static const struct smbd_shim smbd_shim_fns =
    1594             :         {
    1595             :                 .send_stat_cache_delete_message = smbd_send_stat_cache_delete_message,
    1596             :                 .change_to_root_user = smbd_change_to_root_user,
    1597             :                 .become_authenticated_pipe_user = smbd_become_authenticated_pipe_user,
    1598             :                 .unbecome_authenticated_pipe_user = smbd_unbecome_authenticated_pipe_user,
    1599             : 
    1600             :                 .contend_level2_oplocks_begin = smbd_contend_level2_oplocks_begin,
    1601             :                 .contend_level2_oplocks_end = smbd_contend_level2_oplocks_end,
    1602             : 
    1603             :                 .become_root = smbd_become_root,
    1604             :                 .unbecome_root = smbd_unbecome_root,
    1605             : 
    1606             :                 .exit_server = smbd_exit_server,
    1607             :                 .exit_server_cleanly = smbd_exit_server_cleanly,
    1608             :         };
    1609             :         bool ok;
    1610             : 
    1611             :         /*
    1612             :          * Do this before any other talloc operation
    1613             :          */
    1614         107 :         talloc_enable_null_tracking();
    1615         107 :         frame = talloc_stackframe();
    1616             : 
    1617         107 :         smb_init_locale();
    1618             : 
    1619         107 :         set_smbd_shim(&smbd_shim_fns);
    1620             : 
    1621         107 :         smbd_init_globals();
    1622             : 
    1623         107 :         TimeInit();
    1624             : 
    1625             : #ifdef HAVE_SET_AUTH_PARAMETERS
    1626             :         set_auth_parameters(argc,argv);
    1627             : #endif
    1628             : 
    1629         107 :         ok = samba_cmdline_init(frame,
    1630             :                                 SAMBA_CMDLINE_CONFIG_SERVER,
    1631             :                                 true /* require_smbconf */);
    1632         107 :         if (!ok) {
    1633           0 :                 DBG_ERR("Failed to setup cmdline parser!\n");
    1634           0 :                 exit(ENOMEM);
    1635             :         }
    1636             : 
    1637         107 :         cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg();
    1638             : 
    1639         107 :         pc = samba_popt_get_context(getprogname(),
    1640             :                                     argc,
    1641             :                                     argv,
    1642             :                                     long_options,
    1643             :                                     0);
    1644         107 :         if (pc == NULL) {
    1645           0 :                 DBG_ERR("Failed to get popt context!\n");
    1646           0 :                 exit(ENOMEM);
    1647             :         }
    1648             : 
    1649         238 :         while((opt = poptGetNextOpt(pc)) != -1) {
    1650          44 :                 switch (opt)  {
    1651          42 :                 case 'b':
    1652          42 :                         print_build_options = True;
    1653          42 :                         break;
    1654           0 :                 default:
    1655           0 :                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1656             :                                   poptBadOption(pc, 0), poptStrerror(opt));
    1657           0 :                         poptPrintUsage(pc, stderr, 0);
    1658           0 :                         exit(1);
    1659             :                 }
    1660             :         }
    1661         107 :         poptFreeContext(pc);
    1662             : 
    1663         107 :         log_stdout = (debug_get_log_type() == DEBUG_STDOUT);
    1664             : 
    1665         107 :         if (cmdline_daemon_cfg->interactive) {
    1666           0 :                 log_stdout = True;
    1667             :         }
    1668             : 
    1669         107 :         if (print_build_options) {
    1670          44 :                 build_options(True); /* Display output to screen as well as debug */
    1671          44 :                 exit(0);
    1672             :         }
    1673             : 
    1674             : #ifdef HAVE_SETLUID
    1675             :         /* needed for SecureWare on SCO */
    1676             :         setluid(0);
    1677             : #endif
    1678             : 
    1679          63 :         set_remote_machine_name("smbd", False);
    1680             : 
    1681          63 :         if (cmdline_daemon_cfg->interactive && (DEBUGLEVEL >= 9)) {
    1682           0 :                 talloc_enable_leak_report();
    1683             :         }
    1684             : 
    1685          63 :         if (log_stdout && cmdline_daemon_cfg->fork) {
    1686           0 :                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
    1687           0 :                 exit(1);
    1688             :         }
    1689             : 
    1690             :         /*
    1691             :          * We want to die early if we can't open /dev/urandom
    1692             :          */
    1693          63 :         generate_random_buffer(NULL, 0);
    1694             : 
    1695             :         /* get initial effective uid and gid */
    1696          63 :         sec_init();
    1697             : 
    1698             :         /* make absolutely sure we run as root - to handle cases where people
    1699             :            are crazy enough to have it setuid */
    1700          63 :         gain_root_privilege();
    1701          63 :         gain_root_group_privilege();
    1702             : 
    1703          63 :         dump_core_setup("smbd", lp_logfile(talloc_tos(), lp_sub));
    1704             : 
    1705             :         /* we are never interested in SIGPIPE */
    1706          63 :         BlockSignals(True,SIGPIPE);
    1707             : 
    1708             : #if defined(SIGFPE)
    1709             :         /* we are never interested in SIGFPE */
    1710          63 :         BlockSignals(True,SIGFPE);
    1711             : #endif
    1712             : 
    1713             : #if defined(SIGUSR2)
    1714             :         /* We are no longer interested in USR2 */
    1715          63 :         BlockSignals(True,SIGUSR2);
    1716             : #endif
    1717             : 
    1718             :         /*
    1719             :          * POSIX demands that signals are inherited. If the invoking
    1720             :          * process has these signals masked, we will have problems, as
    1721             :          * we won't receive them.
    1722             :          */
    1723          63 :         BlockSignals(False, SIGHUP);
    1724          63 :         BlockSignals(False, SIGUSR1);
    1725          63 :         BlockSignals(False, SIGTERM);
    1726             : 
    1727             :         /* Ensure we leave no zombies until we
    1728             :          * correctly set up child handling below. */
    1729             : 
    1730          63 :         CatchChild();
    1731             : 
    1732             :         /* we want total control over the permissions on created files,
    1733             :            so set our umask to 0 */
    1734          63 :         umask(0);
    1735             : 
    1736          63 :         reopen_logs();
    1737             : 
    1738          63 :         DEBUG(0,("smbd version %s started.\n", samba_version_string()));
    1739          63 :         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
    1740             : 
    1741          63 :         DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
    1742             :                  (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
    1743             : 
    1744             :         /* Output the build options to the debug log */ 
    1745          63 :         build_options(False);
    1746             : 
    1747             :         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4) {
    1748             :                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
    1749             :                 exit(1);
    1750             :         }
    1751             : 
    1752             :         /*
    1753             :          * This calls unshare(CLONE_FS); on linux
    1754             :          * in order to check if the running kernel/container
    1755             :          * environment supports it.
    1756             :          */
    1757          63 :         per_thread_cwd_check();
    1758             : 
    1759          63 :         if (!cluster_probe_ok()) {
    1760           0 :                 exit(1);
    1761             :         }
    1762             : 
    1763             :         /* Init the security context and global current_user */
    1764          63 :         init_sec_ctx();
    1765             : 
    1766             :         /*
    1767             :          * Initialize the event context. The event context needs to be
    1768             :          * initialized before the messaging context, cause the messaging
    1769             :          * context holds an event context.
    1770             :          */
    1771          63 :         ev_ctx = global_event_context();
    1772          63 :         if (ev_ctx == NULL) {
    1773           0 :                 exit(1);
    1774             :         }
    1775             : 
    1776             :         /*
    1777             :          * Init the messaging context
    1778             :          * FIXME: This should only call messaging_init()
    1779             :          */
    1780          63 :         msg_ctx = global_messaging_context();
    1781          63 :         if (msg_ctx == NULL) {
    1782           0 :                 exit(1);
    1783             :         }
    1784             : 
    1785          63 :         dce_ctx = global_dcesrv_context();
    1786          63 :         if (dce_ctx == NULL) {
    1787           0 :                 exit(1);
    1788             :         }
    1789             : 
    1790             :         /*
    1791             :          * Reloading of the printers will not work here as we don't have a
    1792             :          * server info and rpc services set up. It will be called later.
    1793             :          */
    1794          63 :         if (!reload_services(NULL, NULL, false)) {
    1795           0 :                 exit(1);
    1796             :         }
    1797             : 
    1798          63 :         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
    1799          35 :                 if (!lp_parm_bool(-1, "server role check", "inhibit", false)) {
    1800           0 :                         DBG_ERR("server role = 'active directory domain controller' not compatible with running smbd standalone. \n");
    1801           0 :                         DEBUGADD(0, ("You should start 'samba' instead, and it will control starting smbd if required\n"));
    1802           0 :                         exit(1);
    1803             :                 }
    1804             :                 /* Main 'samba' daemon will notify */
    1805          35 :                 daemon_sd_notifications(false);
    1806             :         }
    1807             : 
    1808             :         /* ...NOTE... Log files are working from this point! */
    1809             : 
    1810          63 :         DEBUG(3,("loaded services\n"));
    1811             : 
    1812          61 :         init_structs();
    1813             : 
    1814          63 :         if (!profile_setup(msg_ctx, False)) {
    1815           0 :                 DEBUG(0,("ERROR: failed to setup profiling\n"));
    1816           0 :                 return -1;
    1817             :         }
    1818             : 
    1819          63 :         if (profile_level != NULL) {
    1820           0 :                 profiling_level = atoi(profile_level);
    1821             :         } else {
    1822          63 :                 profiling_level = lp_smbd_profiling_level();
    1823             :         }
    1824          63 :         main_server_id = messaging_server_id(msg_ctx);
    1825          63 :         set_profile_level(profiling_level, &main_server_id);
    1826             : 
    1827          63 :         if (!cmdline_daemon_cfg->daemon && !is_a_socket(0)) {
    1828          28 :                 if (!cmdline_daemon_cfg->interactive) {
    1829          28 :                         DEBUG(3, ("Standard input is not a socket, "
    1830             :                                   "assuming -D option\n"));
    1831             :                 }
    1832             : 
    1833             :                 /*
    1834             :                  * Setting "daemon" here prevents us from eventually calling
    1835             :                  * the open_sockets_inetd()
    1836             :                  */
    1837             : 
    1838          28 :                 cmdline_daemon_cfg->daemon = true;
    1839             :         }
    1840             : 
    1841          63 :         if (cmdline_daemon_cfg->daemon && !cmdline_daemon_cfg->interactive) {
    1842          63 :                 DEBUG(3, ("Becoming a daemon.\n"));
    1843         126 :                 become_daemon(cmdline_daemon_cfg->fork,
    1844          63 :                               cmdline_daemon_cfg->no_process_group,
    1845             :                               log_stdout);
    1846             :         } else {
    1847           0 :                 daemon_status("smbd", "Starting process ...");
    1848             :         }
    1849             : 
    1850             : #ifdef HAVE_SETPGID
    1851             :         /*
    1852             :          * If we're interactive we want to set our own process group for
    1853             :          * signal management.
    1854             :          */
    1855          63 :         if (cmdline_daemon_cfg->interactive &&
    1856           0 :             !cmdline_daemon_cfg->no_process_group)
    1857             :         {
    1858           0 :                 setpgid( (pid_t)0, (pid_t)0);
    1859             :         }
    1860             : #endif
    1861             : 
    1862          63 :         if (!directory_exist(lp_lock_directory()))
    1863           0 :                 mkdir(lp_lock_directory(), 0755);
    1864             : 
    1865          63 :         if (!directory_exist(lp_pid_directory()))
    1866           0 :                 mkdir(lp_pid_directory(), 0755);
    1867             : 
    1868          63 :         if (cmdline_daemon_cfg->daemon)
    1869          63 :                 pidfile_create(lp_pid_directory(), "smbd");
    1870             : 
    1871          63 :         status = reinit_after_fork(msg_ctx, ev_ctx, false, NULL);
    1872          63 :         if (!NT_STATUS_IS_OK(status)) {
    1873           0 :                 exit_daemon("reinit_after_fork() failed", map_errno_from_nt_status(status));
    1874             :         }
    1875             : 
    1876          63 :         if (!cmdline_daemon_cfg->interactive) {
    1877             :                 /*
    1878             :                  * Do not initialize the parent-child-pipe before becoming a
    1879             :                  * daemon: this is used to detect a died parent in the child
    1880             :                  * process.
    1881             :                  */
    1882          63 :                 status = init_before_fork();
    1883          63 :                 if (!NT_STATUS_IS_OK(status)) {
    1884           0 :                         exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
    1885             :                 }
    1886             :         }
    1887             : 
    1888          63 :         parent = talloc_zero(ev_ctx, struct smbd_parent_context);
    1889          63 :         if (!parent) {
    1890           0 :                 exit_server("talloc(struct smbd_parent_context) failed");
    1891             :         }
    1892          63 :         parent->interactive = cmdline_daemon_cfg->interactive;
    1893          63 :         parent->ev_ctx = ev_ctx;
    1894          63 :         parent->msg_ctx = msg_ctx;
    1895          63 :         parent->dce_ctx = dce_ctx;
    1896          63 :         am_parent = parent;
    1897             : 
    1898          63 :         se = tevent_add_signal(parent->ev_ctx,
    1899             :                                parent,
    1900             :                                SIGTERM, 0,
    1901             :                                smbd_parent_sig_term_handler,
    1902             :                                parent);
    1903          63 :         if (!se) {
    1904           0 :                 exit_server("failed to setup SIGTERM handler");
    1905             :         }
    1906          63 :         se = tevent_add_signal(parent->ev_ctx,
    1907             :                                parent,
    1908             :                                SIGHUP, 0,
    1909             :                                smbd_parent_sig_hup_handler,
    1910             :                                parent);
    1911          63 :         if (!se) {
    1912           0 :                 exit_server("failed to setup SIGHUP handler");
    1913             :         }
    1914             : 
    1915             :         /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
    1916             : 
    1917          63 :         if (smbd_memcache() == NULL) {
    1918           0 :                 exit_daemon("no memcache available", EACCES);
    1919             :         }
    1920             : 
    1921          63 :         memcache_set_global(smbd_memcache());
    1922             : 
    1923             :         /* Initialise the password backed before the global_sam_sid
    1924             :            to ensure that we fetch from ldap before we make a domain sid up */
    1925             : 
    1926          63 :         if(!initialize_password_db(false, ev_ctx))
    1927           0 :                 exit(1);
    1928             : 
    1929          63 :         if (!secrets_init()) {
    1930           0 :                 exit_daemon("smbd can not open secrets.tdb", EACCES);
    1931             :         }
    1932             : 
    1933          63 :         if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
    1934           8 :                 struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
    1935           8 :                 if (!open_schannel_session_store(NULL, lp_ctx)) {
    1936           0 :                         exit_daemon("ERROR: Samba cannot open schannel store for secured NETLOGON operations.", EACCES);
    1937             :                 }
    1938           8 :                 TALLOC_FREE(lp_ctx);
    1939             :         }
    1940             : 
    1941          63 :         if(!get_global_sam_sid()) {
    1942           0 :                 exit_daemon("Samba cannot create a SAM SID", EACCES);
    1943             :         }
    1944             : 
    1945          63 :         server_id = messaging_server_id(msg_ctx);
    1946          63 :         status = smbXsrv_version_global_init(&server_id);
    1947          63 :         if (!NT_STATUS_IS_OK(status)) {
    1948           0 :                 exit_daemon("Samba cannot init server context", EACCES);
    1949             :         }
    1950             : 
    1951          63 :         status = smbXsrv_client_global_init();
    1952          63 :         if (!NT_STATUS_IS_OK(status)) {
    1953           0 :                 exit_daemon("Samba cannot init clients context", EACCES);
    1954             :         }
    1955             : 
    1956          63 :         status = smbXsrv_session_global_init(msg_ctx);
    1957          63 :         if (!NT_STATUS_IS_OK(status)) {
    1958           0 :                 exit_daemon("Samba cannot init session context", EACCES);
    1959             :         }
    1960             : 
    1961          63 :         status = smbXsrv_tcon_global_init();
    1962          63 :         if (!NT_STATUS_IS_OK(status)) {
    1963           0 :                 exit_daemon("Samba cannot init tcon context", EACCES);
    1964             :         }
    1965             : 
    1966          63 :         if (!locking_init())
    1967           0 :                 exit_daemon("Samba cannot init locking", EACCES);
    1968             : 
    1969          63 :         if (!leases_db_init(false)) {
    1970           0 :                 exit_daemon("Samba cannot init leases", EACCES);
    1971             :         }
    1972             : 
    1973         126 :         if (!smbd_notifyd_init(
    1974             :                     msg_ctx,
    1975          63 :                     cmdline_daemon_cfg->interactive,
    1976             :                     &parent->notifyd)) {
    1977           0 :                 exit_daemon("Samba cannot init notification", EACCES);
    1978             :         }
    1979             : 
    1980         126 :         if (!cleanupd_init(
    1981             :                     msg_ctx,
    1982          63 :                     cmdline_daemon_cfg->interactive,
    1983             :                     &parent->cleanupd)) {
    1984           0 :                 exit_daemon("Samba cannot init the cleanupd", EACCES);
    1985             :         }
    1986             : 
    1987          60 :         if (!messaging_parent_dgm_cleanup_init(msg_ctx)) {
    1988           0 :                 exit(1);
    1989             :         }
    1990             : 
    1991          60 :         if (!smbd_scavenger_init(NULL, msg_ctx, ev_ctx)) {
    1992           0 :                 exit_daemon("Samba cannot init scavenging", EACCES);
    1993             :         }
    1994             : 
    1995          60 :         if (!W_ERROR_IS_OK(registry_init_full()))
    1996           0 :                 exit_daemon("Samba cannot init registry", EACCES);
    1997             : 
    1998             :         /* Open the share_info.tdb here, so we don't have to open
    1999             :            after the fork on every single connection.  This is a small
    2000             :            performance improvment and reduces the total number of system
    2001             :            fds used. */
    2002          60 :         status = share_info_db_init();
    2003          60 :         if (!NT_STATUS_IS_OK(status)) {
    2004           0 :                 exit_daemon("ERROR: failed to load share info db.", EACCES);
    2005             :         }
    2006             : 
    2007          60 :         status = init_system_session_info(NULL);
    2008          60 :         if (!NT_STATUS_IS_OK(status)) {
    2009           0 :                 DEBUG(1, ("ERROR: failed to setup system user info: %s.\n",
    2010             :                           nt_errstr(status)));
    2011           0 :                 return -1;
    2012             :         }
    2013             : 
    2014          60 :         if (!init_guest_session_info(NULL)) {
    2015           0 :                 DEBUG(0,("ERROR: failed to setup guest info.\n"));
    2016           0 :                 return -1;
    2017             :         }
    2018             : 
    2019          60 :         if (!file_init_global()) {
    2020           0 :                 DEBUG(0, ("ERROR: file_init_global() failed\n"));
    2021           0 :                 return -1;
    2022             :         }
    2023          60 :         status = smbXsrv_open_global_init();
    2024          60 :         if (!NT_STATUS_IS_OK(status)) {
    2025           0 :                 exit_daemon("Samba cannot init global open", map_errno_from_nt_status(status));
    2026             :         }
    2027             : 
    2028          60 :         if (lp_clustering() && !lp_allow_unsafe_cluster_upgrade()) {
    2029           0 :                 status = smbd_claim_version(msg_ctx, samba_version_string());
    2030           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2031           0 :                         DBG_ERR("Could not claim version: %s\n",
    2032             :                                     nt_errstr(status));
    2033           0 :                         return -1;
    2034             :                 }
    2035             :         }
    2036             : 
    2037             :         /* This MUST be done before start_epmd() because otherwise
    2038             :          * start_epmd() forks and races against dcesrv_ep_setup() to
    2039             :          * call directory_create_or_exist() */
    2040          60 :         if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) {
    2041           0 :                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
    2042             :                           lp_ncalrpc_dir(), strerror(errno)));
    2043           0 :                 return -1;
    2044             :         }
    2045             : 
    2046          60 :         np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir());
    2047          60 :         if (!np_dir) {
    2048           0 :                 DEBUG(0, ("%s: Out of memory\n", __location__));
    2049           0 :                 return -1;
    2050             :         }
    2051             : 
    2052          60 :         if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) {
    2053           0 :                 DEBUG(0, ("Failed to create pipe directory %s - %s\n",
    2054             :                           np_dir, strerror(errno)));
    2055           0 :                 return -1;
    2056             :         }
    2057             : 
    2058          60 :         status = dcesrv_init(ev_ctx, ev_ctx, msg_ctx, dce_ctx);
    2059          60 :         if (!NT_STATUS_IS_OK(status)) {
    2060           0 :                 DBG_ERR("Failed to setup RPC server: %s\n", nt_errstr(status));
    2061           0 :                 exit_daemon("Samba cannot setup ep pipe", EACCES);
    2062             :         }
    2063             : 
    2064          60 :         if (!cmdline_daemon_cfg->interactive) {
    2065          60 :                 daemon_ready("smbd");
    2066             :         }
    2067             : 
    2068         120 :         serving_printers = (!lp__disable_spoolss() &&
    2069          60 :                             (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED));
    2070             : 
    2071             :         /* only start other daemons if we are running as a daemon
    2072             :          * -- bad things will happen if smbd is launched via inetd
    2073             :          *  and we fork a copy of ourselves here */
    2074          60 :         if (cmdline_daemon_cfg->daemon && !cmdline_daemon_cfg->interactive) {
    2075             : 
    2076          60 :                 if (rpc_epmapper_daemon() == RPC_DAEMON_FORK) {
    2077           9 :                         start_epmd(ev_ctx, msg_ctx, dce_ctx);
    2078             :                 }
    2079             : 
    2080          60 :                 if (rpc_lsasd_daemon() == RPC_DAEMON_FORK) {
    2081           9 :                         start_lsasd(ev_ctx, msg_ctx, dce_ctx);
    2082             :                 }
    2083             : 
    2084          60 :                 if (rpc_fss_daemon() == RPC_DAEMON_FORK) {
    2085           6 :                         start_fssd(ev_ctx, msg_ctx, dce_ctx);
    2086             :                 }
    2087             : 
    2088          60 :                 if (serving_printers) {
    2089          60 :                         bool bgq = lp_parm_bool(-1, "smbd", "backgroundqueue", true);
    2090          60 :                         ok = printing_subsystem_init(ev_ctx,
    2091             :                                                      msg_ctx,
    2092             :                                                      dce_ctx,
    2093             :                                                      true,
    2094             :                                                      bgq);
    2095          60 :                         if (!ok) {
    2096           0 :                                 exit_daemon("Samba failed to init printing subsystem", EACCES);
    2097             :                         }
    2098             :                 }
    2099             : 
    2100             : #ifdef WITH_SPOTLIGHT
    2101         150 :                 if ((rpc_mdssvc_mode() == RPC_SERVICE_MODE_EXTERNAL) &&
    2102          32 :                     (rpc_mdssd_daemon() == RPC_DAEMON_FORK)) {
    2103           0 :                         start_mdssd(ev_ctx, msg_ctx, dce_ctx);
    2104             :                 }
    2105             : #endif
    2106           0 :         } else if (serving_printers) {
    2107           0 :                 ok = printing_subsystem_init(ev_ctx,
    2108             :                                              msg_ctx,
    2109             :                                              dce_ctx,
    2110             :                                              false,
    2111             :                                              false);
    2112           0 :                 if (!ok) {
    2113           0 :                         exit(1);
    2114             :                 }
    2115             :         }
    2116             : 
    2117          60 :         if (!cmdline_daemon_cfg->daemon) {
    2118             :                 int ret, sock;
    2119             : 
    2120             :                 /* inetd mode */
    2121           0 :                 TALLOC_FREE(frame);
    2122             : 
    2123             :                 /* Started from inetd. fd 0 is the socket. */
    2124             :                 /* We will abort gracefully when the client or remote system
    2125             :                    goes away */
    2126           0 :                 sock = dup(0);
    2127             : 
    2128             :                 /* close stdin, stdout (if not logging to it), but not stderr */
    2129           0 :                 ret = close_low_fd(0);
    2130           0 :                 if (ret != 0) {
    2131           0 :                         DBG_ERR("close_low_fd(0) failed: %s\n", strerror(ret));
    2132           0 :                         return 1;
    2133             :                 }
    2134           0 :                 if (!debug_get_output_is_stdout()) {
    2135           0 :                         ret = close_low_fd(1);
    2136           0 :                         if (ret != 0) {
    2137           0 :                                 DBG_ERR("close_low_fd(1) failed: %s\n",
    2138             :                                         strerror(ret));
    2139           0 :                                 return 1;
    2140             :                         }
    2141             :                 }
    2142             : 
    2143             : #ifdef HAVE_ATEXIT
    2144           0 :                 atexit(killkids);
    2145             : #endif
    2146             : 
    2147             :                 /* Stop zombies */
    2148           0 :                 smbd_setup_sig_chld_handler(parent);
    2149             : 
    2150           0 :                 smbd_process(ev_ctx, msg_ctx, dce_ctx, sock, true);
    2151             : 
    2152           0 :                 exit_server_cleanly(NULL);
    2153             :                 return(0);
    2154             :         }
    2155             : 
    2156          60 :         if (!open_sockets_smbd(parent, ev_ctx, msg_ctx, ports))
    2157           0 :                 exit_server("open_sockets_smbd() failed");
    2158             : 
    2159             :         /* do a printer update now that all messaging has been set up,
    2160             :          * before we allow clients to start connecting */
    2161         120 :         if (!lp__disable_spoolss() &&
    2162          60 :             (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) {
    2163          60 :                 printing_subsystem_update(ev_ctx, msg_ctx, false);
    2164             :         }
    2165             : 
    2166          60 :         TALLOC_FREE(frame);
    2167             :         /* make sure we always have a valid stackframe */
    2168          60 :         frame = talloc_stackframe();
    2169             : 
    2170          60 :         if (!cmdline_daemon_cfg->fork) {
    2171             :                 /* if we are running in the foreground then look for
    2172             :                    EOF on stdin, and exit if it happens. This allows
    2173             :                    us to die if the parent process dies
    2174             :                    Only do this on a pipe or socket, no other device.
    2175             :                 */
    2176             :                 struct stat st;
    2177          60 :                 if (fstat(0, &st) != 0) {
    2178           0 :                         return false;
    2179             :                 }
    2180          60 :                 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
    2181          60 :                         tevent_add_fd(ev_ctx,
    2182             :                                         parent,
    2183             :                                         0,
    2184             :                                         TEVENT_FD_READ,
    2185             :                                         smbd_stdin_handler,
    2186             :                                         NULL);
    2187             :                 }
    2188             :         }
    2189             : 
    2190          60 :         smbd_parent_loop(ev_ctx, parent);
    2191             : 
    2192           0 :         exit_server_cleanly(NULL);
    2193             :         TALLOC_FREE(frame);
    2194             :         return(0);
    2195             : }

Generated by: LCOV version 1.13