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

Generated by: LCOV version 1.14