LCOV - code coverage report
Current view: top level - source3/smbd - server.c (source / functions) Hit Total Coverage
Test: coverage report for master 7edf5467 Lines: 81 899 9.0 %
Date: 2024-03-23 18:40:31 Functions: 8 44 18.2 %

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

Generated by: LCOV version 1.14