LCOV - code coverage report
Current view: top level - source4/samba - server.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 190 350 54.3 %
Date: 2024-06-13 04:01:37 Functions: 13 21 61.9 %

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

Generated by: LCOV version 1.13