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

Generated by: LCOV version 1.14