LCOV - code coverage report
Current view: top level - source3/smbd - server.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 366 832 44.0 %
Date: 2024-06-13 04:01:37 Functions: 21 45 46.7 %

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

Generated by: LCOV version 1.13