LCOV - code coverage report
Current view: top level - source4/samba - server.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 193 354 54.5 %
Date: 2021-09-23 10:06:22 Functions: 13 21 61.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Main SMB server routines
       5             : 
       6             :    Copyright (C) Andrew Tridgell                1992-2005
       7             :    Copyright (C) Martin Pool                    2002
       8             :    Copyright (C) Jelmer Vernooij                2002
       9             :    Copyright (C) James J Myers                  2003 <myersjj@samba.org>
      10             : 
      11             :    This program is free software; you can redistribute it and/or modify
      12             :    it under the terms of the GNU General Public License as published by
      13             :    the Free Software Foundation; either version 3 of the License, or
      14             :    (at your option) any later version.
      15             : 
      16             :    This program is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :    GNU General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU General Public License
      22             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "includes.h"
      26             : #include "lib/events/events.h"
      27             : #include "version.h"
      28             : #include "lib/cmdline/cmdline.h"
      29             : #include "system/dir.h"
      30             : #include "system/filesys.h"
      31             : #include "auth/gensec/gensec.h"
      32             : #include "libcli/auth/schannel.h"
      33             : #include "samba/process_model.h"
      34             : #include "param/secrets.h"
      35             : #include "lib/util/pidfile.h"
      36             : #include "param/param.h"
      37             : #include "dsdb/samdb/samdb.h"
      38             : #include "auth/session.h"
      39             : #include "lib/messaging/irpc.h"
      40             : #include "librpc/gen_ndr/ndr_irpc.h"
      41             : #include "cluster/cluster.h"
      42             : #include "dynconfig/dynconfig.h"
      43             : #include "lib/util/samba_modules.h"
      44             : #include "nsswitch/winbind_client.h"
      45             : #include "libds/common/roles.h"
      46             : #include "lib/util/tfork.h"
      47             : #include "dsdb/samdb/ldb_modules/util.h"
      48             : #include "lib/util/server_id.h"
      49             : #include "server_util.h"
      50             : 
      51             : #ifdef HAVE_PTHREAD
      52             : #include <pthread.h>
      53             : #endif
      54             : 
      55             : struct server_state {
      56             :         struct tevent_context *event_ctx;
      57             :         const char *binary_name;
      58             : };
      59             : 
      60             : /*
      61             :   recursively delete a directory tree
      62             : */
      63          64 : static void recursive_delete(const char *path)
      64             : {
      65             :         DIR *dir;
      66             :         struct dirent *de;
      67             : 
      68          64 :         dir = opendir(path);
      69          64 :         if (!dir) {
      70           0 :                 return;
      71             :         }
      72             : 
      73         192 :         for (de=readdir(dir);de;de=readdir(dir)) {
      74             :                 char *fname;
      75             :                 struct stat st;
      76             : 
      77         128 :                 if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) {
      78         218 :                         continue;
      79             :                 }
      80             : 
      81           0 :                 fname = talloc_asprintf(path, "%s/%s", path, de->d_name);
      82           0 :                 if (stat(fname, &st) != 0) {
      83           0 :                         continue;
      84             :                 }
      85           0 :                 if (S_ISDIR(st.st_mode)) {
      86           0 :                         recursive_delete(fname);
      87           0 :                         talloc_free(fname);
      88           0 :                         continue;
      89             :                 }
      90           0 :                 if (unlink(fname) != 0) {
      91           0 :                         DBG_ERR("Unabled to delete '%s' - %s\n",
      92             :                                  fname, strerror(errno));
      93           0 :                         smb_panic("unable to cleanup tmp files");
      94             :                 }
      95           0 :                 talloc_free(fname);
      96             :         }
      97          64 :         closedir(dir);
      98             : }
      99             : 
     100             : /*
     101             :   cleanup temporary files. This is the new alternative to
     102             :   TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
     103             :   efficient on unix systems due to the lack of scaling of the byte
     104             :   range locking system. So instead of putting the burden on tdb to
     105             :   cleanup tmp files, this function deletes them.
     106             : */
     107          64 : static void cleanup_tmp_files(struct loadparm_context *lp_ctx)
     108             : {
     109             :         char *path;
     110          64 :         TALLOC_CTX *mem_ctx = talloc_new(NULL);
     111          64 :         if (mem_ctx == NULL) {
     112           0 :                 exit_daemon("Failed to create memory context",
     113             :                             ENOMEM);
     114             :         }
     115             : 
     116          64 :         path = smbd_tmp_path(mem_ctx, lp_ctx, NULL);
     117          64 :         if (path == NULL) {
     118           0 :                 exit_daemon("Failed to cleanup temporary files",
     119             :                             EINVAL);
     120             :         }
     121             : 
     122          64 :         recursive_delete(path);
     123          64 :         talloc_free(mem_ctx);
     124          64 : }
     125             : 
     126           0 : static void sig_hup(int sig)
     127             : {
     128           0 :         debug_schedule_reopen_logs();
     129           0 : }
     130             : 
     131           0 : static void sig_term(int sig)
     132             : {
     133             : #ifdef HAVE_GETPGRP
     134           0 :         if (getpgrp() == getpid()) {
     135             :                 /*
     136             :                  * We're the process group leader, send
     137             :                  * SIGTERM to our process group.
     138             :                  */
     139           0 :                 kill(-getpgrp(), SIGTERM);
     140             :         }
     141             : #endif
     142           0 :         _exit(127);
     143             : }
     144             : 
     145           0 : static void sigterm_signal_handler(struct tevent_context *ev,
     146             :                                 struct tevent_signal *se,
     147             :                                 int signum, int count, void *siginfo,
     148             :                                 void *private_data)
     149             : {
     150           0 :         struct server_state *state = talloc_get_type_abort(
     151             :                 private_data, struct server_state);
     152             : 
     153           0 :         DBG_DEBUG("Process %s got SIGTERM\n", state->binary_name);
     154           0 :         TALLOC_FREE(state);
     155           0 :         sig_term(SIGTERM);
     156           0 : }
     157             : 
     158           0 : static void sighup_signal_handler(struct tevent_context *ev,
     159             :                                   struct tevent_signal *se,
     160             :                                   int signum, int count, void *siginfo,
     161             :                                   void *private_data)
     162             : {
     163           0 :         struct server_state *state = talloc_get_type_abort(
     164             :                 private_data, struct server_state);
     165             : 
     166           0 :         DBG_DEBUG("Process %s got SIGHUP\n", state->binary_name);
     167             : 
     168           0 :         reopen_logs_internal();
     169           0 : }
     170             : 
     171             : /*
     172             :   setup signal masks
     173             : */
     174          64 : static void setup_signals(void)
     175             : {
     176             :         /* we are never interested in SIGPIPE */
     177          64 :         BlockSignals(true,SIGPIPE);
     178             : 
     179             : #if defined(SIGFPE)
     180             :         /* we are never interested in SIGFPE */
     181          64 :         BlockSignals(true,SIGFPE);
     182             : #endif
     183             : 
     184             :         /* We are no longer interested in USR1 */
     185          64 :         BlockSignals(true, SIGUSR1);
     186             : 
     187             : #if defined(SIGUSR2)
     188             :         /* We are no longer interested in USR2 */
     189          64 :         BlockSignals(true,SIGUSR2);
     190             : #endif
     191             : 
     192             :         /* POSIX demands that signals are inherited. If the invoking process has
     193             :          * these signals masked, we will have problems,
     194             :          * as we won't receive them. */
     195          64 :         BlockSignals(false, SIGHUP);
     196          64 :         BlockSignals(false, SIGTERM);
     197             : 
     198          64 :         CatchSignal(SIGHUP, sig_hup);
     199          64 :         CatchSignal(SIGTERM, sig_term);
     200          64 : }
     201             : 
     202             : /*
     203             :   handle io on stdin
     204             : */
     205          63 : static void server_stdin_handler(struct tevent_context *event_ctx,
     206             :                                 struct tevent_fd *fde,
     207             :                                 uint16_t flags,
     208             :                                 void *private_data)
     209             : {
     210          63 :         struct server_state *state = talloc_get_type_abort(
     211             :                 private_data, struct server_state);
     212             :         uint8_t c;
     213          63 :         if (read(0, &c, 1) == 0) {
     214          63 :                 DBG_ERR("%s: EOF on stdin - PID %d terminating\n",
     215             :                         state->binary_name, (int)getpid());
     216             : #ifdef HAVE_GETPGRP
     217          63 :                 if (getpgrp() == getpid()) {
     218           0 :                         DBG_ERR("Sending SIGTERM from pid %d\n",
     219             :                                 (int)getpid());
     220           0 :                         kill(-getpgrp(), SIGTERM);
     221             :                 }
     222             : #endif
     223          63 :                 TALLOC_FREE(state);
     224          63 :                 exit(0);
     225             :         }
     226           0 : }
     227             : 
     228             : /*
     229             :   die if the user selected maximum runtime is exceeded
     230             : */
     231           0 : _NORETURN_ static void max_runtime_handler(struct tevent_context *ev,
     232             :                                            struct tevent_timer *te,
     233             :                                            struct timeval t, void *private_data)
     234             : {
     235           0 :         struct server_state *state = talloc_get_type_abort(
     236             :                 private_data, struct server_state);
     237           0 :         DBG_ERR("%s: maximum runtime exceeded - "
     238             :                 "terminating PID %d at %llu, current ts: %llu\n",
     239             :                  state->binary_name,
     240             :                 (int)getpid(),
     241             :                 (unsigned long long)t.tv_sec,
     242             :                 (unsigned long long)time(NULL));
     243           0 :         TALLOC_FREE(state);
     244           0 :         exit(0);
     245             : }
     246             : 
     247             : /*
     248             :  * When doing an in-place upgrade of Samba, the database format may have
     249             :  * changed between versions. E.g. between 4.7 and 4.8 the DB changed from
     250             :  * DN-based indexes to GUID-based indexes, so we have to re-index the DB after
     251             :  * upgrading.
     252             :  * This function handles migrating an older samba DB to a new Samba release.
     253             :  * Note that we have to maintain DB compatibility between *all* older versions
     254             :  * of Samba, not just the ones still under maintenance support.
     255             :  */
     256          64 : static int handle_inplace_db_upgrade(struct ldb_context *ldb_ctx)
     257             : {
     258             :         int ret;
     259             : 
     260             :         /*
     261             :          * The DSDB stack will handle reindexing the DB (if needed) upon the first
     262             :          * DB write. Open and close a transaction on the DB now to trigger a
     263             :          * reindex if required, rather than waiting for the first write.
     264             :          * We do this here to guarantee that the DB will have been re-indexed by
     265             :          * the time the main samba code runs.
     266             :          * Refer to dsdb_schema_set_indices_and_attributes() for the actual reindexing
     267             :          * code, called from
     268             :          * source4/dsdb/samdb/ldb_modules/schema_load.c:schema_load_start_transaction()
     269             :          */
     270          64 :         ret = ldb_transaction_start(ldb_ctx);
     271          64 :         if (ret != LDB_SUCCESS) {
     272           0 :                 return ret;
     273             :         }
     274             : 
     275          64 :         ret = ldb_transaction_commit(ldb_ctx);
     276          64 :         if (ret != LDB_SUCCESS) {
     277           0 :                 return ret;
     278             :         }
     279          64 :         return LDB_SUCCESS;
     280             : }
     281             : 
     282             : /*
     283             :   pre-open the key databases. This saves a lot of time in child
     284             :   processes
     285             :  */
     286          64 : static int prime_ldb_databases(struct tevent_context *event_ctx, bool *am_backup)
     287             : {
     288          64 :         struct ldb_result *res = NULL;
     289          64 :         struct ldb_dn *samba_dsdb_dn = NULL;
     290          64 :         struct ldb_context *ldb_ctx = NULL;
     291          64 :         struct ldb_context *pdb = NULL;
     292             :         static const char *attrs[] = { "backupDate", NULL };
     293          64 :         struct loadparm_context *lp_ctx = samba_cmdline_get_lp_ctx();
     294          64 :         const char *msg = NULL;
     295             :         int ret;
     296          64 :         TALLOC_CTX *db_context = talloc_new(event_ctx);
     297          64 :         if (db_context == NULL) {
     298           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     299             :         }
     300             : 
     301          64 :         *am_backup = false;
     302             : 
     303             :         /* note we deliberately leave these open, which allows them to be
     304             :          * re-used in ldb_wrap_connect() */
     305          64 :         ldb_ctx = samdb_connect(db_context,
     306             :                                 event_ctx,
     307             :                                 lp_ctx,
     308             :                                 system_session(lp_ctx),
     309             :                                 NULL,
     310             :                                 0);
     311          64 :         if (ldb_ctx == NULL) {
     312           0 :                 talloc_free(db_context);
     313           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     314             :         }
     315             : 
     316          64 :         ret = handle_inplace_db_upgrade(ldb_ctx);
     317          64 :         if (ret != LDB_SUCCESS) {
     318           0 :                 talloc_free(db_context);
     319           0 :                 return ret;
     320             :         }
     321             : 
     322          64 :         pdb = privilege_connect(db_context, lp_ctx);
     323          64 :         if (pdb == NULL) {
     324           0 :                 talloc_free(db_context);
     325           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     326             :         }
     327             : 
     328             :         /* check the root DB object to see if it's marked as a backup */
     329          64 :         samba_dsdb_dn = ldb_dn_new(db_context, ldb_ctx, "@SAMBA_DSDB");
     330          64 :         if (!samba_dsdb_dn) {
     331           0 :                 talloc_free(db_context);
     332           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     333             :         }
     334             : 
     335          64 :         ret = dsdb_search_dn(ldb_ctx, db_context, &res, samba_dsdb_dn, attrs,
     336             :                              DSDB_FLAG_AS_SYSTEM);
     337          64 :         if (ret != LDB_SUCCESS) {
     338           0 :                 talloc_free(db_context);
     339           0 :                 return ret;
     340             :         }
     341             : 
     342          64 :         if (res->count > 0) {
     343          64 :                 msg = ldb_msg_find_attr_as_string(res->msgs[0], "backupDate",
     344             :                                                   NULL);
     345          64 :                 if (msg != NULL) {
     346           1 :                         *am_backup = true;
     347             :                 }
     348             :         }
     349          61 :         return LDB_SUCCESS;
     350             : }
     351             : 
     352             : /*
     353             :   called from 'smbcontrol samba shutdown'
     354             :  */
     355           0 : static void samba_parent_shutdown(struct imessaging_context *msg,
     356             :                                   void *private_data,
     357             :                                   uint32_t msg_type,
     358             :                                   struct server_id src,
     359             :                                   size_t num_fds,
     360             :                                   int *fds,
     361             :                                   DATA_BLOB *data)
     362             : {
     363           0 :         struct server_state *state =
     364           0 :                 talloc_get_type_abort(private_data,
     365             :                 struct server_state);
     366             :         struct server_id_buf src_buf;
     367           0 :         struct server_id dst = imessaging_get_server_id(msg);
     368             :         struct server_id_buf dst_buf;
     369             : 
     370           0 :         if (num_fds != 0) {
     371           0 :                 DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
     372           0 :                 return;
     373             :         }
     374             : 
     375           0 :         DBG_ERR("samba_shutdown of %s %s: from %s\n",
     376             :                 state->binary_name,
     377             :                 server_id_str_buf(dst, &dst_buf),
     378             :                 server_id_str_buf(src, &src_buf));
     379             : 
     380           0 :         TALLOC_FREE(state);
     381           0 :         exit(0);
     382             : }
     383             : 
     384             : /*
     385             :   called when a fatal condition occurs in a child task
     386             :  */
     387           0 : static NTSTATUS samba_terminate(struct irpc_message *msg,
     388             :                                 struct samba_terminate *r)
     389             : {
     390           0 :         struct server_state *state = talloc_get_type(msg->private_data,
     391             :                                         struct server_state);
     392           0 :         DBG_ERR("samba_terminate of %s %d: %s\n",
     393             :                 state->binary_name, (int)getpid(), r->in.reason);
     394           0 :         TALLOC_FREE(state);
     395           0 :         exit(1);
     396             : }
     397             : 
     398             : /*
     399             :   setup messaging for the top level samba (parent) task
     400             :  */
     401          63 : static NTSTATUS setup_parent_messaging(struct server_state *state,
     402             :                                        struct loadparm_context *lp_ctx)
     403             : {
     404             :         struct imessaging_context *msg;
     405             :         NTSTATUS status;
     406          63 :         if (state == NULL) {
     407           0 :                 return NT_STATUS_UNSUCCESSFUL;
     408             :         }
     409         107 :         msg = imessaging_init(state->event_ctx,
     410             :                               lp_ctx,
     411          63 :                               cluster_id(getpid(), SAMBA_PARENT_TASKID),
     412             :                               state->event_ctx);
     413          63 :         NT_STATUS_HAVE_NO_MEMORY(msg);
     414             : 
     415          63 :         status = irpc_add_name(msg, "samba");
     416          63 :         if (!NT_STATUS_IS_OK(status)) {
     417           0 :                 return status;
     418             :         }
     419             : 
     420          63 :         status = imessaging_register(msg, state, MSG_SHUTDOWN,
     421             :                                      samba_parent_shutdown);
     422          63 :         if (!NT_STATUS_IS_OK(status)) {
     423           0 :                 return status;
     424             :         }
     425             : 
     426          63 :         status = IRPC_REGISTER(msg, irpc, SAMBA_TERMINATE,
     427             :                                samba_terminate, state);
     428          63 :         if (!NT_STATUS_IS_OK(status)) {
     429           0 :                 return status;
     430             :         }
     431             : 
     432          63 :         return NT_STATUS_OK;
     433             : }
     434             : 
     435             : 
     436             : /*
     437             :   show build info
     438             :  */
     439           0 : static void show_build(void)
     440             : {
     441             : #define CONFIG_OPTION(n) { #n, dyn_ ## n }
     442             :         struct {
     443             :                 const char *name;
     444             :                 const char *value;
     445           0 :         } config_options[] = {
     446             :                 CONFIG_OPTION(BINDIR),
     447             :                 CONFIG_OPTION(SBINDIR),
     448             :                 CONFIG_OPTION(CONFIGFILE),
     449             :                 CONFIG_OPTION(NCALRPCDIR),
     450             :                 CONFIG_OPTION(LOGFILEBASE),
     451             :                 CONFIG_OPTION(LMHOSTSFILE),
     452             :                 CONFIG_OPTION(DATADIR),
     453             :                 CONFIG_OPTION(MODULESDIR),
     454             :                 CONFIG_OPTION(LOCKDIR),
     455             :                 CONFIG_OPTION(STATEDIR),
     456             :                 CONFIG_OPTION(CACHEDIR),
     457             :                 CONFIG_OPTION(PIDDIR),
     458             :                 CONFIG_OPTION(PRIVATE_DIR),
     459             :                 CONFIG_OPTION(CODEPAGEDIR),
     460             :                 CONFIG_OPTION(SETUPDIR),
     461             :                 CONFIG_OPTION(WINBINDD_SOCKET_DIR),
     462             :                 CONFIG_OPTION(NTP_SIGND_SOCKET_DIR),
     463             :                 { NULL, NULL}
     464             :         };
     465             :         int i;
     466             : 
     467           0 :         printf("Samba version: %s\n", SAMBA_VERSION_STRING);
     468           0 :         printf("Build environment:\n");
     469             : 
     470           0 :         printf("Paths:\n");
     471           0 :         for (i=0; config_options[i].name; i++) {
     472           0 :                 printf("   %s: %s\n",
     473             :                         config_options[i].name,
     474             :                         config_options[i].value);
     475             :         }
     476             : 
     477           0 :         exit(0);
     478             : }
     479             : 
     480          64 : static int event_ctx_destructor(struct tevent_context *event_ctx)
     481             : {
     482          64 :         imessaging_dgm_unref_ev(event_ctx);
     483          64 :         return 0;
     484             : }
     485             : 
     486             : #ifdef HAVE_PTHREAD
     487             : static int to_children_fd = -1;
     488       45825 : static void atfork_prepare(void) {
     489       45825 : }
     490       35696 : static void atfork_parent(void) {
     491       35696 : }
     492       10129 : static void atfork_child(void) {
     493       10129 :         if (to_children_fd != -1) {
     494         619 :                 close(to_children_fd);
     495         619 :                 to_children_fd = -1;
     496             :         }
     497       10129 : }
     498             : #endif
     499             : 
     500             : /*
     501             :  main server.
     502             : */
     503          64 : static int binary_smbd_main(TALLOC_CTX *mem_ctx,
     504             :                             const char *binary_name,
     505             :                             int argc,
     506             :                             const char *argv[])
     507             : {
     508          64 :         struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL;
     509          64 :         bool db_is_backup = false;
     510             :         int opt;
     511             :         int ret;
     512             :         poptContext pc;
     513             : #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
     514             :         STATIC_service_MODULES_PROTO;
     515          64 :         init_module_fn static_init[] = { STATIC_service_MODULES };
     516             :         init_module_fn *shared_init;
     517             :         uint16_t stdin_event_flags;
     518             :         NTSTATUS status;
     519          64 :         const char *model = "prefork";
     520          64 :         int max_runtime = 0;
     521             :         struct stat st;
     522             :         enum {
     523             :                 OPT_PROCESS_MODEL = 1000,
     524             :                 OPT_SHOW_BUILD,
     525             :         };
     526         256 :         struct poptOption long_options[] = {
     527             :                 POPT_AUTOHELP
     528             :                 {
     529             :                         .longName   = "model",
     530             :                         .shortName  = 'M',
     531             :                         .argInfo    = POPT_ARG_STRING,
     532             :                         .val        = OPT_PROCESS_MODEL,
     533             :                         .descrip    = "Select process model",
     534             :                         .argDescrip = "MODEL",
     535             :                 },
     536             :                 {
     537             :                         .longName   = "maximum-runtime",
     538             :                         .argInfo    = POPT_ARG_INT,
     539             :                         .arg        = &max_runtime,
     540             :                         .descrip    = "set maximum runtime of the server process, "
     541             :                                       "till autotermination",
     542             :                         .argDescrip = "seconds"
     543             :                 },
     544             :                 {
     545             :                         .longName   = "show-build",
     546             :                         .shortName  = 'b',
     547             :                         .argInfo    = POPT_ARG_NONE,
     548             :                         .val        = OPT_SHOW_BUILD,
     549             :                         .descrip    = "show build info",
     550             :                 },
     551          64 :                 POPT_COMMON_SAMBA
     552          64 :                 POPT_COMMON_DAEMON
     553          64 :                 POPT_COMMON_VERSION
     554             :                 POPT_TABLEEND
     555             :         };
     556          64 :         struct server_state *state = NULL;
     557          64 :         struct tevent_signal *se = NULL;
     558          64 :         struct samba_tevent_trace_state *samba_tevent_trace_state = NULL;
     559          64 :         struct loadparm_context *lp_ctx = NULL;
     560             :         bool ok;
     561             : 
     562          64 :         setproctitle("root process");
     563             : 
     564          64 :         ok = samba_cmdline_init(mem_ctx,
     565             :                                 SAMBA_CMDLINE_CONFIG_SERVER,
     566             :                                 true /* require_smbconf */);
     567          64 :         if (!ok) {
     568           0 :                 DBG_ERR("Failed to init cmdline parser!\n");
     569           0 :                 TALLOC_FREE(mem_ctx);
     570           0 :                 exit(1);
     571             :         }
     572             : 
     573          64 :         cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg();
     574             : 
     575          64 :         pc = samba_popt_get_context(binary_name,
     576             :                                     argc,
     577             :                                     argv,
     578             :                                     long_options,
     579             :                                     0);
     580          64 :         if (pc == NULL) {
     581           0 :                 DBG_ERR("Failed to setup popt context!\n");
     582           0 :                 TALLOC_FREE(mem_ctx);
     583           0 :                 exit(1);
     584             :         }
     585             : 
     586         163 :         while((opt = poptGetNextOpt(pc)) != -1) {
     587          57 :                 switch(opt) {
     588          57 :                 case OPT_PROCESS_MODEL:
     589          57 :                         model = poptGetOptArg(pc);
     590          57 :                         break;
     591           0 :                 case OPT_SHOW_BUILD:
     592           0 :                         show_build();
     593           0 :                         break;
     594           0 :                 default:
     595           0 :                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
     596             :                                   poptBadOption(pc, 0), poptStrerror(opt));
     597           0 :                         poptPrintUsage(pc, stderr, 0);
     598           0 :                         return 1;
     599             :                 }
     600             :         }
     601             : 
     602          64 :         if (cmdline_daemon_cfg->daemon && cmdline_daemon_cfg->interactive) {
     603           0 :                 fprintf(stderr,"\nERROR: "
     604             :                         "Option -i|--interactive is "
     605             :                         "not allowed together with -D|--daemon\n\n");
     606           0 :                 poptPrintUsage(pc, stderr, 0);
     607           0 :                 return 1;
     608          64 :         } else if (!cmdline_daemon_cfg->interactive &&
     609           0 :                    cmdline_daemon_cfg->fork) {
     610             :                 /* default is --daemon */
     611           0 :                 cmdline_daemon_cfg->daemon = true;
     612             :         }
     613             : 
     614          64 :         poptFreeContext(pc);
     615             : 
     616          64 :         lp_ctx = samba_cmdline_get_lp_ctx();
     617             : 
     618          64 :         talloc_enable_null_tracking();
     619             : 
     620          64 :         setup_signals();
     621             : 
     622             :         /* we want total control over the permissions on created files,
     623             :            so set our umask to 0 */
     624          64 :         umask(0);
     625             : 
     626          64 :         DEBUG(0,("%s version %s started.\n",
     627             :                 binary_name,
     628             :                 SAMBA_VERSION_STRING));
     629          64 :         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team"
     630             :                 " 1992-2021\n"));
     631             : 
     632             :         if (sizeof(uint16_t) < 2 ||
     633             :                         sizeof(uint32_t) < 4 ||
     634             :                         sizeof(uint64_t) < 8) {
     635             :                 DEBUG(0,("ERROR: Samba is not configured correctly "
     636             :                         "for the word size on your machine\n"));
     637             :                 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, "
     638             :                         "sizeof(uint64_t) = %u\n",
     639             :                         (unsigned int)sizeof(uint16_t),
     640             :                         (unsigned int)sizeof(uint32_t),
     641             :                         (unsigned int)sizeof(uint64_t)));
     642             :                 return 1;
     643             :         }
     644             : 
     645          64 :         if (cmdline_daemon_cfg->daemon) {
     646           0 :                 DBG_NOTICE("Becoming a daemon.\n");
     647           0 :                 become_daemon(cmdline_daemon_cfg->fork,
     648           0 :                               cmdline_daemon_cfg->no_process_group,
     649             :                               false);
     650          64 :         } else if (!cmdline_daemon_cfg->interactive) {
     651           0 :                 daemon_status("samba", "Starting process...");
     652             :         }
     653             : 
     654             :         /* Create the memory context to hang everything off. */
     655          64 :         state = talloc_zero(mem_ctx, struct server_state);
     656          64 :         if (state == NULL) {
     657           0 :                 exit_daemon("Samba cannot create server state", ENOMEM);
     658             :                 /*
     659             :                  * return is never reached but is here to satisfy static
     660             :                  * checkers
     661             :                  */
     662           0 :                 return 1;
     663             :         };
     664          64 :         state->binary_name = binary_name;
     665             : 
     666          64 :         cleanup_tmp_files(lp_ctx);
     667             : 
     668          64 :         if (!directory_exist(lpcfg_lock_directory(lp_ctx))) {
     669           0 :                 mkdir(lpcfg_lock_directory(lp_ctx), 0755);
     670             :         }
     671             : 
     672          64 :         if (!directory_exist(lpcfg_pid_directory(lp_ctx))) {
     673           0 :                 mkdir(lpcfg_pid_directory(lp_ctx), 0755);
     674             :         }
     675             : 
     676          64 :         pidfile_create(lpcfg_pid_directory(lp_ctx), binary_name);
     677             : 
     678          64 :         if (lpcfg_server_role(lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC) {
     679          58 :                 if (!open_schannel_session_store(state,
     680             :                                 lp_ctx)) {
     681           0 :                         TALLOC_FREE(state);
     682           0 :                         exit_daemon("Samba cannot open schannel store "
     683             :                                 "for secured NETLOGON operations.", EACCES);
     684             :                         /*
     685             :                          * return is never reached but is here to satisfy static
     686             :                          * checkers
     687             :                          */
     688           0 :                         return 1;
     689             :                 }
     690             :         }
     691             : 
     692             :         /* make sure we won't go through nss_winbind */
     693          64 :         if (!winbind_off()) {
     694           0 :                 TALLOC_FREE(state);
     695           0 :                 exit_daemon("Samba failed to disable recusive "
     696             :                         "winbindd calls.", EACCES);
     697             :                 /*
     698             :                  * return is never reached but is here to satisfy static
     699             :                  * checkers
     700             :                  */
     701           0 :                 return 1;
     702             :         }
     703             : 
     704          64 :         gensec_init(); /* FIXME: */
     705             : 
     706          64 :         process_model_init(lp_ctx);
     707             : 
     708          64 :         shared_init = load_samba_modules(mem_ctx, "service");
     709             : 
     710          64 :         run_init_functions(mem_ctx, static_init);
     711          64 :         run_init_functions(mem_ctx, shared_init);
     712             : 
     713          64 :         TALLOC_FREE(shared_init);
     714             : 
     715             :         /* the event context is the top level structure in smbd. Everything else
     716             :            should hang off that */
     717          64 :         state->event_ctx = s4_event_context_init(state);
     718             : 
     719          64 :         if (state->event_ctx == NULL) {
     720           0 :                 TALLOC_FREE(state);
     721           0 :                 exit_daemon("Initializing event context failed", EACCES);
     722             :                 /*
     723             :                  * return is never reached but is here to satisfy static
     724             :                  * checkers
     725             :                  */
     726           0 :                 return 1;
     727             :         }
     728             : 
     729          64 :         talloc_set_destructor(state->event_ctx, event_ctx_destructor);
     730             : 
     731          64 :         samba_tevent_trace_state = create_samba_tevent_trace_state(state);
     732          64 :         if (samba_tevent_trace_state == NULL) {
     733           0 :                 exit_daemon("Samba failed to setup tevent tracing state",
     734             :                             ENOTTY);
     735             :                 /*
     736             :                  * return is never reached but is here to satisfy static
     737             :                  * checkers
     738             :                  */
     739           0 :                 return 1;
     740             :         }
     741             : 
     742          64 :         tevent_set_trace_callback(state->event_ctx,
     743             :                                   samba_tevent_trace_callback,
     744             :                                   samba_tevent_trace_state);
     745             : 
     746          64 :         if (cmdline_daemon_cfg->interactive) {
     747             :                 /* terminate when stdin goes away */
     748          61 :                 stdin_event_flags = TEVENT_FD_READ;
     749             :         } else {
     750             :                 /* stay alive forever */
     751           0 :                 stdin_event_flags = 0;
     752             :         }
     753             : 
     754             : #ifdef HAVE_SETPGID
     755             :         /*
     756             :          * If we're interactive we want to set our own process group for
     757             :          * signal management, unless --no-process-group specified.
     758             :          */
     759         109 :         if (cmdline_daemon_cfg->interactive &&
     760          64 :             !cmdline_daemon_cfg->no_process_group)
     761             :         {
     762           1 :                 setpgid((pid_t)0, (pid_t)0);
     763             :         }
     764             : #endif
     765             : 
     766             :         /* catch EOF on stdin */
     767             : #ifdef SIGTTIN
     768          64 :         signal(SIGTTIN, SIG_IGN);
     769             : #endif
     770             : 
     771          64 :         if (fstat(0, &st) != 0) {
     772           0 :                 TALLOC_FREE(state);
     773           0 :                 exit_daemon("Samba failed to set standard input handler",
     774             :                                 ENOTTY);
     775             :                 /*
     776             :                  * return is never reached but is here to satisfy static
     777             :                  * checkers
     778             :                  */
     779           0 :                 return 1;
     780             :         }
     781             : 
     782          64 :         if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
     783          63 :                 struct tevent_fd *fde = tevent_add_fd(state->event_ctx,
     784             :                                 state->event_ctx,
     785             :                                 0,
     786             :                                 stdin_event_flags,
     787             :                                 server_stdin_handler,
     788             :                                 state);
     789          63 :                 if (fde == NULL) {
     790           0 :                         TALLOC_FREE(state);
     791           0 :                         exit_daemon("Initializing stdin failed", ENOMEM);
     792             :                         /*
     793             :                          * return is never reached but is here to
     794             :                          * satisfy static checkers
     795             :                          */
     796           0 :                         return 1;
     797             :                 }
     798             :         }
     799             : 
     800          64 :         if (max_runtime) {
     801             :                 struct tevent_timer *te;
     802          64 :                 DBG_ERR("%s PID %d was called with maxruntime %d - "
     803             :                         "current ts %llu\n",
     804             :                         binary_name, (int)getpid(),
     805             :                         max_runtime, (unsigned long long) time(NULL));
     806          64 :                 te = tevent_add_timer(state->event_ctx, state->event_ctx,
     807             :                                  timeval_current_ofs(max_runtime, 0),
     808             :                                  max_runtime_handler,
     809             :                                  state);
     810          64 :                 if (te == NULL) {
     811           0 :                         TALLOC_FREE(state);
     812           0 :                         exit_daemon("Maxruntime handler failed", ENOMEM);
     813             :                         /*
     814             :                          * return is never reached but is here to
     815             :                          * satisfy static checkers
     816             :                          */
     817           0 :                         return 1;
     818             :                 }
     819             :         }
     820             : 
     821          64 :         se = tevent_add_signal(state->event_ctx,
     822             :                                 state->event_ctx,
     823             :                                 SIGTERM,
     824             :                                 0,
     825             :                                 sigterm_signal_handler,
     826             :                                 state);
     827          64 :         if (se == NULL) {
     828           0 :                 TALLOC_FREE(state);
     829           0 :                 exit_daemon("Initialize SIGTERM handler failed", ENOMEM);
     830             :                 /*
     831             :                  * return is never reached but is here to satisfy static
     832             :                  * checkers
     833             :                  */
     834           0 :                 return 1;
     835             :         }
     836             : 
     837          64 :         se = tevent_add_signal(state->event_ctx,
     838             :                                 state->event_ctx,
     839             :                                 SIGHUP,
     840             :                                 0,
     841             :                                 sighup_signal_handler,
     842             :                                 state);
     843          64 :         if (se == NULL) {
     844           0 :                 TALLOC_FREE(state);
     845           0 :                 exit_daemon("Initialize SIGHUP handler failed", ENOMEM);
     846             :                 /*
     847             :                  * return is never reached but is here to satisfy static
     848             :                  * checkers
     849             :                  */
     850           0 :                 return 1;
     851             :         }
     852             : 
     853          64 :         if (lpcfg_server_role(lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC
     854           6 :             && !lpcfg_parm_bool(lp_ctx, NULL,
     855             :                         "server role check", "inhibit", false)
     856           6 :             && !str_list_check_ci(lpcfg_server_services(lp_ctx), "smb")
     857           0 :             && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(lp_ctx),
     858             :                         "remote")
     859           0 :             && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(lp_ctx),
     860             :                         "mapiproxy")) {
     861           0 :                 DEBUG(0, ("At this time the 'samba' binary should only be used "
     862             :                         "for either:\n"));
     863           0 :                 DEBUGADD(0, ("'server role = active directory domain "
     864             :                         "controller' or to access the ntvfs file server "
     865             :                         "with 'server services = +smb' or the rpc proxy "
     866             :                         "with 'dcerpc endpoint servers = remote'\n"));
     867           0 :                 DEBUGADD(0, ("You should start smbd/nmbd/winbindd instead for "
     868             :                         "domain member and standalone file server tasks\n"));
     869           0 :                 exit_daemon("Samba detected misconfigured 'server role' "
     870             :                         "and exited. Check logs for details", EINVAL);
     871             :         };
     872             : 
     873          64 :         ret = prime_ldb_databases(state->event_ctx, &db_is_backup);
     874          64 :         if (ret != LDB_SUCCESS) {
     875           0 :                 TALLOC_FREE(state);
     876           0 :                 exit_daemon("Samba failed to prime database", EINVAL);
     877             :                 /*
     878             :                  * return is never reached but is here to satisfy static
     879             :                  * checkers
     880             :                  */
     881           0 :                 return 1;
     882             :         }
     883             : 
     884          64 :         if (db_is_backup) {
     885           1 :                 TALLOC_FREE(state);
     886           1 :                 exit_daemon("Database is a backup. Please run samba-tool domain"
     887             :                             " backup restore", EINVAL);
     888             :                 /*
     889             :                  * return is never reached but is here to satisfy static
     890             :                  * checkers
     891             :                  */
     892           0 :                 return 1;
     893             :         }
     894             : 
     895          63 :         status = setup_parent_messaging(state, lp_ctx);
     896          63 :         if (!NT_STATUS_IS_OK(status)) {
     897           0 :                 TALLOC_FREE(state);
     898           0 :                 exit_daemon("Samba failed to setup parent messaging",
     899           0 :                         NT_STATUS_V(status));
     900             :                 /*
     901             :                  * return is never reached but is here to satisfy static
     902             :                  * checkers
     903             :                  */
     904           0 :                 return 1;
     905             :         }
     906             : 
     907          63 :         DBG_ERR("%s: using '%s' process model\n", binary_name, model);
     908             : 
     909             :         {
     910             :                 int child_pipe[2];
     911             :                 int rc;
     912          63 :                 bool start_services = false;
     913             : 
     914          63 :                 rc = pipe(child_pipe);
     915          63 :                 if (rc < 0) {
     916           0 :                         TALLOC_FREE(state);
     917           0 :                         exit_daemon("Samba failed to open process control pipe",
     918           0 :                                     errno);
     919             :                         /*
     920             :                          * return is never reached but is here to satisfy static
     921             :                          * checkers
     922             :                          */
     923           0 :                         return 1;
     924             :                 }
     925          63 :                 smb_set_close_on_exec(child_pipe[0]);
     926          63 :                 smb_set_close_on_exec(child_pipe[1]);
     927             : 
     928             : #ifdef HAVE_PTHREAD
     929          63 :                 to_children_fd = child_pipe[1];
     930          63 :                 pthread_atfork(atfork_prepare, atfork_parent,
     931             :                                atfork_child);
     932          63 :                 start_services = true;
     933             : #else
     934             :                 pid_t pid;
     935             :                 struct tfork *t = NULL;
     936             :                 t = tfork_create();
     937             :                 if (t == NULL) {
     938             :                         exit_daemon(
     939             :                                 "Samba unable to fork master process",
     940             :                                 0);
     941             :                 }
     942             :                 pid = tfork_child_pid(t);
     943             :                 if (pid == 0) {
     944             :                         start_services = false;
     945             :                 } else {
     946             :                         /* In the child process */
     947             :                         start_services = true;
     948             :                         close(child_pipe[1]);
     949             :                 }
     950             : #endif
     951          61 :                 if (start_services) {
     952          63 :                         status = server_service_startup(
     953             :                                 state->event_ctx, lp_ctx, model,
     954             :                                 lpcfg_server_services(lp_ctx),
     955             :                                 child_pipe[0]);
     956          63 :                         if (!NT_STATUS_IS_OK(status)) {
     957           0 :                                 TALLOC_FREE(state);
     958           0 :                                 exit_daemon("Samba failed to start services",
     959           0 :                                 NT_STATUS_V(status));
     960             :                                 /*
     961             :                                  * return is never reached but is here to
     962             :                                  * satisfy static checkers
     963             :                                  */
     964           0 :                                 return 1;
     965             :                         }
     966             :                 }
     967             :         }
     968             : 
     969          63 :         if (!cmdline_daemon_cfg->interactive) {
     970           0 :                 daemon_ready("samba");
     971             :         }
     972             : 
     973             :         /* wait for events - this is where smbd sits for most of its
     974             :            life */
     975          63 :         tevent_loop_wait(state->event_ctx);
     976             : 
     977             :         /* as everything hangs off this state->event context, freeing state
     978             :            will initiate a clean shutdown of all services */
     979           0 :         TALLOC_FREE(state);
     980             : 
     981           0 :         return 0;
     982             : }
     983             : 
     984          64 : int main(int argc, const char *argv[])
     985             : {
     986          64 :         TALLOC_CTX *mem_ctx = NULL;
     987             :         int rc;
     988             : 
     989          64 :         mem_ctx = talloc_init("samba/server.c#main");
     990          64 :         if (mem_ctx == NULL) {
     991           0 :                 exit(ENOMEM);
     992             :         }
     993             : 
     994          64 :         setproctitle_init(argc, discard_const(argv), environ);
     995             : 
     996          64 :         rc = binary_smbd_main(mem_ctx, "samba", argc, argv);
     997             : 
     998           0 :         TALLOC_FREE(mem_ctx);
     999           0 :         return rc;
    1000             : }

Generated by: LCOV version 1.13