LCOV - code coverage report
Current view: top level - source4/samba - server.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 217 383 56.7 %
Date: 2024-02-28 12:06:22 Functions: 12 21 57.1 %

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