LCOV - code coverage report
Current view: top level - source4/samba - server.c (source / functions) Hit Total Coverage
Test: coverage report for smb2.twrp.listdir_fix f886ca1c Lines: 218 384 56.8 %
Date: 2023-11-07 19:11:32 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       50897 : static void atfork_prepare(void) {
     500       50897 : }
     501       50897 : static void atfork_parent(void) {
     502       50897 : }
     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 :         DEBUG(0,("%s version %s started.\n",
     634             :                 binary_name,
     635             :                 SAMBA_VERSION_STRING));
     636          66 :         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team"
     637             :                 " 1992-2023\n"));
     638             : 
     639           3 :         if (sizeof(uint16_t) < 2 ||
     640             :                         sizeof(uint32_t) < 4 ||
     641             :                         sizeof(uint64_t) < 8) {
     642             :                 DEBUG(0,("ERROR: Samba is not configured correctly "
     643             :                         "for the word size on your machine\n"));
     644             :                 DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, "
     645             :                         "sizeof(uint64_t) = %u\n",
     646             :                         (unsigned int)sizeof(uint16_t),
     647             :                         (unsigned int)sizeof(uint32_t),
     648             :                         (unsigned int)sizeof(uint64_t)));
     649             :                 return 1;
     650             :         }
     651             : 
     652          66 :         if (cmdline_daemon_cfg->daemon) {
     653           0 :                 DBG_NOTICE("Becoming a daemon.\n");
     654           0 :                 become_daemon(cmdline_daemon_cfg->fork,
     655           0 :                               cmdline_daemon_cfg->no_process_group,
     656             :                               false);
     657          66 :         } else if (!cmdline_daemon_cfg->interactive) {
     658           0 :                 daemon_status("samba", "Starting process...");
     659             :         }
     660             : 
     661             :         /* Create the memory context to hang everything off. */
     662          66 :         state = talloc_zero(mem_ctx, struct server_state);
     663          66 :         if (state == NULL) {
     664           0 :                 exit_daemon("Samba cannot create server state", ENOMEM);
     665             :                 /*
     666             :                  * return is never reached but is here to satisfy static
     667             :                  * checkers
     668             :                  */
     669           0 :                 return 1;
     670           3 :         };
     671          66 :         state->binary_name = binary_name;
     672             : 
     673          66 :         cleanup_tmp_files(lp_ctx);
     674             : 
     675          66 :         if (!directory_exist(lpcfg_lock_directory(lp_ctx))) {
     676           0 :                 mkdir(lpcfg_lock_directory(lp_ctx), 0755);
     677             :         }
     678             : 
     679          66 :         if (!directory_exist(lpcfg_pid_directory(lp_ctx))) {
     680           0 :                 mkdir(lpcfg_pid_directory(lp_ctx), 0755);
     681             :         }
     682             : 
     683          66 :         pidfile_create(lpcfg_pid_directory(lp_ctx), binary_name);
     684             : 
     685          66 :         if (lpcfg_server_role(lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC) {
     686          60 :                 if (!open_schannel_session_store(state,
     687             :                                 lp_ctx)) {
     688           0 :                         TALLOC_FREE(state);
     689           0 :                         exit_daemon("Samba cannot open schannel store "
     690             :                                 "for secured NETLOGON operations.", EACCES);
     691             :                         /*
     692             :                          * return is never reached but is here to satisfy static
     693             :                          * checkers
     694             :                          */
     695           0 :                         return 1;
     696             :                 }
     697             :         }
     698             : 
     699             :         /* make sure we won't go through nss_winbind */
     700          66 :         if (!winbind_off()) {
     701           0 :                 TALLOC_FREE(state);
     702           0 :                 exit_daemon("Samba failed to disable recursive "
     703             :                         "winbindd calls.", EACCES);
     704             :                 /*
     705             :                  * return is never reached but is here to satisfy static
     706             :                  * checkers
     707             :                  */
     708           0 :                 return 1;
     709             :         }
     710             : 
     711          66 :         gensec_init(); /* FIXME: */
     712             : 
     713          66 :         process_model_init(lp_ctx);
     714             : 
     715          66 :         samba_service_init();
     716             : 
     717             :         /* the event context is the top level structure in smbd. Everything else
     718             :            should hang off that */
     719          66 :         state->event_ctx = s4_event_context_init(state);
     720             : 
     721          66 :         if (state->event_ctx == NULL) {
     722           0 :                 TALLOC_FREE(state);
     723           0 :                 exit_daemon("Initializing event context failed", EACCES);
     724             :                 /*
     725             :                  * return is never reached but is here to satisfy static
     726             :                  * checkers
     727             :                  */
     728           0 :                 return 1;
     729             :         }
     730             : 
     731          66 :         talloc_set_destructor(state->event_ctx, event_ctx_destructor);
     732             : 
     733          66 :         samba_tevent_trace_state = create_samba_tevent_trace_state(state);
     734          66 :         if (samba_tevent_trace_state == NULL) {
     735           0 :                 exit_daemon("Samba failed to setup tevent tracing state",
     736             :                             ENOTTY);
     737             :                 /*
     738             :                  * return is never reached but is here to satisfy static
     739             :                  * checkers
     740             :                  */
     741           0 :                 return 1;
     742             :         }
     743             : 
     744          66 :         tevent_set_trace_callback(state->event_ctx,
     745             :                                   samba_tevent_trace_callback,
     746             :                                   samba_tevent_trace_state);
     747             : 
     748          66 :         if (cmdline_daemon_cfg->interactive) {
     749             :                 /* terminate when stdin goes away */
     750          63 :                 stdin_event_flags = TEVENT_FD_READ;
     751             :         } else {
     752             :                 /* stay alive forever */
     753           0 :                 stdin_event_flags = 0;
     754             :         }
     755             : 
     756             : #ifdef HAVE_SETPGID
     757             :         /*
     758             :          * If we're interactive we want to set our own process group for
     759             :          * signal management, unless --no-process-group specified.
     760             :          */
     761          66 :         if (cmdline_daemon_cfg->interactive &&
     762          66 :             !cmdline_daemon_cfg->no_process_group)
     763             :         {
     764           1 :                 setpgid((pid_t)0, (pid_t)0);
     765             :         }
     766             : #endif
     767             : 
     768             :         /* catch EOF on stdin */
     769             : #ifdef SIGTTIN
     770          66 :         signal(SIGTTIN, SIG_IGN);
     771             : #endif
     772             : 
     773          66 :         if (fstat(0, &st) != 0) {
     774           0 :                 TALLOC_FREE(state);
     775           0 :                 exit_daemon("Samba failed to set standard input handler",
     776             :                                 ENOTTY);
     777             :                 /*
     778             :                  * return is never reached but is here to satisfy static
     779             :                  * checkers
     780             :                  */
     781           0 :                 return 1;
     782             :         }
     783             : 
     784          66 :         if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
     785          65 :                 struct tevent_fd *fde = tevent_add_fd(state->event_ctx,
     786             :                                 state->event_ctx,
     787             :                                 0,
     788             :                                 stdin_event_flags,
     789             :                                 server_stdin_handler,
     790             :                                 state);
     791          65 :                 if (fde == NULL) {
     792           0 :                         TALLOC_FREE(state);
     793           0 :                         exit_daemon("Initializing stdin failed", ENOMEM);
     794             :                         /*
     795             :                          * return is never reached but is here to
     796             :                          * satisfy static checkers
     797             :                          */
     798           0 :                         return 1;
     799             :                 }
     800             :         }
     801             : 
     802          66 :         if (max_runtime) {
     803           3 :                 struct tevent_timer *te;
     804          66 :                 DBG_ERR("%s PID %d was called with maxruntime %d - "
     805             :                         "current ts %llu\n",
     806             :                         binary_name, (int)getpid(),
     807             :                         max_runtime, (unsigned long long) time(NULL));
     808          66 :                 te = tevent_add_timer(state->event_ctx, state->event_ctx,
     809             :                                  timeval_current_ofs(max_runtime, 0),
     810             :                                  max_runtime_handler,
     811             :                                  state);
     812          66 :                 if (te == NULL) {
     813           0 :                         TALLOC_FREE(state);
     814           0 :                         exit_daemon("Maxruntime handler failed", ENOMEM);
     815             :                         /*
     816             :                          * return is never reached but is here to
     817             :                          * satisfy static checkers
     818             :                          */
     819           0 :                         return 1;
     820             :                 }
     821             :         }
     822             : 
     823          66 :         se = tevent_add_signal(state->event_ctx,
     824             :                                 state->event_ctx,
     825             :                                 SIGTERM,
     826             :                                 0,
     827             :                                 sigterm_signal_handler,
     828             :                                 state);
     829          66 :         if (se == NULL) {
     830           0 :                 TALLOC_FREE(state);
     831           0 :                 exit_daemon("Initialize SIGTERM handler failed", ENOMEM);
     832             :                 /*
     833             :                  * return is never reached but is here to satisfy static
     834             :                  * checkers
     835             :                  */
     836           0 :                 return 1;
     837             :         }
     838             : 
     839          66 :         se = tevent_add_signal(state->event_ctx,
     840             :                                 state->event_ctx,
     841             :                                 SIGHUP,
     842             :                                 0,
     843             :                                 sighup_signal_handler,
     844             :                                 state);
     845          66 :         if (se == NULL) {
     846           0 :                 TALLOC_FREE(state);
     847           0 :                 exit_daemon("Initialize SIGHUP handler failed", ENOMEM);
     848             :                 /*
     849             :                  * return is never reached but is here to satisfy static
     850             :                  * checkers
     851             :                  */
     852           0 :                 return 1;
     853             :         }
     854             : 
     855          66 :         if (lpcfg_server_role(lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC
     856           6 :             && !lpcfg_parm_bool(lp_ctx, NULL,
     857             :                         "server role check", "inhibit", false)
     858           6 :             && !str_list_check_ci(lpcfg_server_services(lp_ctx), "smb")
     859           0 :             && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(lp_ctx),
     860             :                         "remote")
     861           0 :             && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(lp_ctx),
     862             :                         "mapiproxy")) {
     863           0 :                 DEBUG(0, ("At this time the 'samba' binary should only be used "
     864             :                         "for either:\n"));
     865           0 :                 DEBUGADD(0, ("'server role = active directory domain "
     866             :                         "controller' or the rpc proxy "
     867             :                         "with 'dcerpc endpoint servers = remote'\n"));
     868           0 :                 DEBUGADD(0, ("You should start smbd/nmbd/winbindd instead for "
     869             :                         "domain member and standalone file server tasks\n"));
     870           0 :                 exit_daemon("Samba detected misconfigured 'server role' "
     871             :                         "and exited. Check logs for details", EINVAL);
     872           3 :         };
     873             : 
     874          66 :         ret = prime_ldb_databases(state->event_ctx, &db_is_backup);
     875          66 :         if (ret != LDB_SUCCESS) {
     876           0 :                 TALLOC_FREE(state);
     877           0 :                 exit_daemon("Samba failed to prime database", EINVAL);
     878             :                 /*
     879             :                  * return is never reached but is here to satisfy static
     880             :                  * checkers
     881             :                  */
     882           0 :                 return 1;
     883             :         }
     884             : 
     885          66 :         if (db_is_backup) {
     886           1 :                 TALLOC_FREE(state);
     887           1 :                 exit_daemon("Database is a backup. Please run samba-tool domain"
     888             :                             " backup restore", EINVAL);
     889             :                 /*
     890             :                  * return is never reached but is here to satisfy static
     891             :                  * checkers
     892             :                  */
     893           1 :                 return 1;
     894             :         }
     895             : 
     896          65 :         status = setup_parent_messaging(state, lp_ctx);
     897          65 :         if (!NT_STATUS_IS_OK(status)) {
     898           0 :                 TALLOC_FREE(state);
     899           0 :                 exit_daemon("Samba failed to setup parent messaging",
     900           0 :                         NT_STATUS_V(status));
     901             :                 /*
     902             :                  * return is never reached but is here to satisfy static
     903             :                  * checkers
     904             :                  */
     905           0 :                 return 1;
     906             :         }
     907             : 
     908          65 :         DBG_ERR("%s: using '%s' process model\n", binary_name, model);
     909             : 
     910             :         {
     911           2 :                 int child_pipe[2];
     912           2 :                 int rc;
     913          65 :                 bool start_services = false;
     914             : 
     915          65 :                 rc = pipe(child_pipe);
     916          65 :                 if (rc < 0) {
     917           0 :                         TALLOC_FREE(state);
     918           0 :                         exit_daemon("Samba failed to open process control pipe",
     919           0 :                                     errno);
     920             :                         /*
     921             :                          * return is never reached but is here to satisfy static
     922             :                          * checkers
     923             :                          */
     924           0 :                         return 1;
     925             :                 }
     926          65 :                 smb_set_close_on_exec(child_pipe[0]);
     927          65 :                 smb_set_close_on_exec(child_pipe[1]);
     928             : 
     929             : #ifdef HAVE_PTHREAD
     930          65 :                 to_children_fd = child_pipe[1];
     931          65 :                 pthread_atfork(atfork_prepare, atfork_parent,
     932             :                                atfork_child);
     933          65 :                 start_services = true;
     934             : #else
     935             :                 pid_t pid;
     936             :                 struct tfork *t = NULL;
     937             :                 t = tfork_create();
     938             :                 if (t == NULL) {
     939             :                         exit_daemon(
     940             :                                 "Samba unable to fork master process",
     941             :                                 0);
     942             :                 }
     943             :                 pid = tfork_child_pid(t);
     944             :                 if (pid == 0) {
     945             :                         start_services = false;
     946             :                 } else {
     947             :                         /* In the child process */
     948             :                         start_services = true;
     949             :                         close(child_pipe[1]);
     950             :                 }
     951             : #endif
     952          65 :                 if (start_services) {
     953          65 :                         status = server_service_startup(
     954             :                                 state->event_ctx, lp_ctx, model,
     955             :                                 lpcfg_server_services(lp_ctx),
     956             :                                 child_pipe[0]);
     957          65 :                         if (!NT_STATUS_IS_OK(status)) {
     958           0 :                                 TALLOC_FREE(state);
     959           0 :                                 exit_daemon("Samba failed to start services",
     960           0 :                                 NT_STATUS_V(status));
     961             :                                 /*
     962             :                                  * return is never reached but is here to
     963             :                                  * satisfy static checkers
     964             :                                  */
     965           0 :                                 return 1;
     966             :                         }
     967             :                 }
     968             :         }
     969             : 
     970          65 :         if (!cmdline_daemon_cfg->interactive) {
     971           0 :                 daemon_ready("samba");
     972             :         }
     973             : 
     974             :         /* wait for events - this is where smbd sits for most of its
     975             :            life */
     976          65 :         tevent_loop_wait(state->event_ctx);
     977             : 
     978             :         /* as everything hangs off this state->event context, freeing state
     979             :            will initiate a clean shutdown of all services */
     980           0 :         TALLOC_FREE(state);
     981             : 
     982           0 :         return 0;
     983             : }
     984             : 
     985          66 : int main(int argc, const char *argv[])
     986             : {
     987          66 :         TALLOC_CTX *mem_ctx = NULL;
     988           3 :         int rc;
     989             : 
     990          66 :         mem_ctx = talloc_init("samba/server.c#main");
     991          66 :         if (mem_ctx == NULL) {
     992           0 :                 exit(ENOMEM);
     993             :         }
     994             : 
     995          66 :         setproctitle_init(argc, discard_const(argv), environ);
     996             : 
     997          66 :         rc = binary_smbd_main(mem_ctx, "samba", argc, argv);
     998             : 
     999           0 :         TALLOC_FREE(mem_ctx);
    1000           0 :         return rc;
    1001             : }

Generated by: LCOV version 1.14