fault: get fault.c ready for use by s4
authorAndrew Tridgell <tridge@samba.org>
Tue, 22 Mar 2011 05:17:39 +0000 (16:17 +1100)
committerAndrew Tridgell <tridge@samba.org>
Wed, 23 Mar 2011 00:03:57 +0000 (11:03 +1100)
this moves the s3 specific dumpcore code into source3/lib/dumpcore.c,
and uses a function pointer to setup which smb_panic call to use

lib/util/fault.c
lib/util/util.h
source3/Makefile.in
source3/include/proto.h
source3/lib/dumpcore.c [new file with mode: 0644]
source3/lib/util.c
source3/nmbd/nmbd.c
source3/param/loadparm.c
source3/smbd/server.c
source3/winbindd/winbindd.c
source3/wscript_build

index 2ffd5dbd6d17dc1d1033681d333f3516b8018aef..086dc33545d780457c57808ce961df777ba2a8fa 100644 (file)
@@ -19,6 +19,8 @@
 */
 
 #include "includes.h"
 */
 
 #include "includes.h"
+#include "system/filesys.h"
+#include "version.h"
 
 #ifdef HAVE_SYS_SYSCTL_H
 #include <sys/sysctl.h>
 
 #ifdef HAVE_SYS_SYSCTL_H
 #include <sys/sysctl.h>
 #include <sys/prctl.h>
 #endif
 
 #include <sys/prctl.h>
 #endif
 
-static char *corepath;
+static struct {
+       bool disabled;
+       smb_panic_handler_t panic_handler;
+} fault_state;
+
+
+/*******************************************************************
+setup variables used for fault handling
+********************************************************************/
+void fault_configure(smb_panic_handler_t panic_handler)
+{
+       fault_state.panic_handler = panic_handler;
+}
+
+
+/**
+   disable setting up fault handlers
+   This is used for the bind9 dlz module, as we
+   don't want a Samba module in bind9 to override the bind
+   fault handling
+**/
+_PUBLIC_ void fault_setup_disable(void)
+{
+       fault_state.disabled = true;
+}
+
 
 /*******************************************************************
 report a fault
 
 /*******************************************************************
 report a fault
@@ -43,9 +70,8 @@ static void fault_report(int sig)
        counter++;
 
        DEBUGSEP(0);
        counter++;
 
        DEBUGSEP(0);
-       DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),samba_version_string()));
-       DEBUG(0,("\nPlease read the Trouble-Shooting section of the Samba3-HOWTO\n"));
-       DEBUG(0,("\nFrom: http://www.samba.org/samba/docs/Samba3-HOWTO.pdf\n"));
+       DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),SAMBA_VERSION_STRING));
+       DEBUG(0,("\nPlease read the Trouble-Shooting section of the Samba HOWTO\n"));
        DEBUGSEP(0);
 
        smb_panic("internal error");
        DEBUGSEP(0);
 
        smb_panic("internal error");
@@ -67,6 +93,9 @@ setup our fault handlers
 ********************************************************************/
 void fault_setup(void)
 {
 ********************************************************************/
 void fault_setup(void)
 {
+       if (fault_state.disabled) {
+               return;
+       }
 #ifdef SIGSEGV
        CatchSignal(SIGSEGV, sig_fault);
 #endif
 #ifdef SIGSEGV
        CatchSignal(SIGSEGV, sig_fault);
 #endif
@@ -78,303 +107,48 @@ void fault_setup(void)
 #endif
 }
 
 #endif
 }
 
-/**
- * Build up the default corepath as "<logbase>/cores/<progname>"
- */
-static char *get_default_corepath(const char *logbase, const char *progname)
-{
-       char *tmp_corepath;
-
-       /* Setup core dir in logbase. */
-       tmp_corepath = talloc_asprintf(NULL, "%s/cores", logbase);
-       if (!tmp_corepath)
-               return NULL;
-
-       if ((mkdir(tmp_corepath, 0700) == -1) && errno != EEXIST)
-               goto err_out;
-
-       if (chmod(tmp_corepath, 0700) == -1)
-               goto err_out;
-
-       talloc_free(tmp_corepath);
-
-       /* Setup progname-specific core subdir */
-       tmp_corepath = talloc_asprintf(NULL, "%s/cores/%s", logbase, progname);
-       if (!tmp_corepath)
-               return NULL;
-
-       if (mkdir(tmp_corepath, 0700) == -1 && errno != EEXIST)
-               goto err_out;
+_PUBLIC_ const char *panic_action = NULL;
 
 
-       if (chown(tmp_corepath, getuid(), getgid()) == -1)
-               goto err_out;
-
-       if (chmod(tmp_corepath, 0700) == -1)
-               goto err_out;
-
-       return tmp_corepath;
-
- err_out:
-       talloc_free(tmp_corepath);
-       return NULL;
-}
-
-/**
- * Get the FreeBSD corepath.
- *
- * On FreeBSD the current working directory is ignored when creating a core
- * file.  Instead the core directory is controlled via sysctl.  This consults
- * the value of "kern.corefile" so the correct corepath can be printed out
- * before dump_core() calls abort.
- */
-#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
-static char *get_freebsd_corepath(void)
+/*
+   default smb_panic() implementation
+*/
+static void smb_panic_default(const char *why)
 {
 {
-       char *tmp_corepath = NULL;
-       char *end = NULL;
-       size_t len = 128;
-       int ret;
-
-       /* Loop with increasing sizes so we don't allocate too much. */
-       do {
-               if (len > 1024)  {
-                       goto err_out;
-               }
-
-               tmp_corepath = (char *)talloc_realloc(NULL, tmp_corepath,
-                                                     char, len);
-               if (!tmp_corepath) {
-                       return NULL;
-               }
+       int result;
+
+       if (panic_action && *panic_action) {
+               char pidstr[20];
+               char cmdstring[200];
+               safe_strcpy(cmdstring, panic_action, sizeof(cmdstring)-1);
+               snprintf(pidstr, sizeof(pidstr), "%d", (int) getpid());
+               all_string_sub(cmdstring, "%PID%", pidstr, sizeof(cmdstring));
+               DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring));
+               result = system(cmdstring);
+
+               if (result == -1)
+                       DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
+                                 strerror(errno)));
+               else
+                       DEBUG(0, ("smb_panic(): action returned status %d\n",
+                                 WEXITSTATUS(result)));
+       }
+       DEBUG(0,("PANIC: %s\n", why));
 
 
-               ret = sysctlbyname("kern.corefile", tmp_corepath, &len, NULL,
-                                  0);
-               if (ret == -1) {
-                       if (errno != ENOMEM) {
-                               DEBUG(0, ("sysctlbyname failed getting "
-                                         "kern.corefile %s\n",
-                                         strerror(errno)));
-                               goto err_out;
-                       }
-
-                       /* Not a large enough array, try a bigger one. */
-                       len = len << 1;
-               }
-       } while (ret == -1);
-
-       /* Strip off the common filename expansion */
-       if ((end = strrchr_m(tmp_corepath, '/'))) {
-               *end = '\0';
-       }
-
-       return tmp_corepath;
-
- err_out:
-       if (tmp_corepath) {
-               talloc_free(tmp_corepath);
-       }
-       return NULL;
-}
+#ifdef SIGABRT
+       CatchSignal(SIGABRT, SIG_DFL);
 #endif
 #endif
-
-#if defined(HAVE_SYS_KERNEL_PROC_CORE_PATTERN)
-
-/**
- * Get the Linux corepath.
- *
- * On Linux the contents of /proc/sys/kernel/core_pattern indicates the
- * location of the core path.
- */
-static char *get_linux_corepath(void)
-{
-       char *end;
-       int fd;
-       char *result;
-
-       fd = open("/proc/sys/kernel/core_pattern", O_RDONLY, 0);
-       if (fd == -1) {
-               return NULL;
-       }
-
-       result = afdgets(fd, NULL, 0);
-       close(fd);
-
-       if (result == NULL) {
-               return NULL;
-       }
-
-       if (result[0] != '/') {
-               /*
-                * No absolute path, use the default (cwd)
-                */
-               TALLOC_FREE(result);
-               return NULL;
-       }
-       /* Strip off the common filename expansion */
-
-       end = strrchr_m(result, '/');
-
-       if ((end != result) /* this would be the only / */
-           && (end != NULL)) {
-               *end = '\0';
-       }
-       return result;
+       abort();
 }
 }
-#endif
 
 
 /**
 
 
 /**
- * Try getting system-specific corepath if one exists.
- *
- * If the system doesn't define a corepath, then the default is used.
- */
-static char *get_corepath(const char *logbase, const char *progname)
-{
-#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
-       char *tmp_corepath = NULL;
-       tmp_corepath = get_freebsd_corepath();
-
-       /* If this has been set correctly, we're done. */
-       if (tmp_corepath) {
-               return tmp_corepath;
-       }
-#endif
-
-#if defined(HAVE_SYS_KERNEL_PROC_CORE_PATTERN)
-       char *tmp_corepath = NULL;
-       tmp_corepath = get_linux_corepath();
-
-       /* If this has been set correctly, we're done. */
-       if (tmp_corepath) {
-               return tmp_corepath;
-       }
-#endif
-
-       /* Fall back to the default. */
-       return get_default_corepath(logbase, progname);
-}
-
-/*******************************************************************
-make all the preparations to safely dump a core file
-********************************************************************/
-
-void dump_core_setup(const char *progname)
-{
-       char *logbase = NULL;
-       char *end = NULL;
-
-       if (lp_logfile() && *lp_logfile()) {
-               if (asprintf(&logbase, "%s", lp_logfile()) < 0) {
-                       return;
-               }
-               if ((end = strrchr_m(logbase, '/'))) {
-                       *end = '\0';
-               }
-       } else {
-               /* We will end up here if the log file is given on the command
-                * line by the -l option but the "log file" option is not set
-                * in smb.conf.
-                */
-               if (asprintf(&logbase, "%s", get_dyn_LOGFILEBASE()) < 0) {
-                       return;
-               }
-       }
-
-       SMB_ASSERT(progname != NULL);
-
-       corepath = get_corepath(logbase, progname);
-       if (!corepath) {
-               DEBUG(0, ("Unable to setup corepath for %s: %s\n", progname,
-                         strerror(errno)));
-               goto out;
-       }
-
-
-#ifdef HAVE_GETRLIMIT
-#ifdef RLIMIT_CORE
-       {
-               struct rlimit rlp;
-               getrlimit(RLIMIT_CORE, &rlp);
-               rlp.rlim_cur = MAX(16*1024*1024,rlp.rlim_cur);
-               setrlimit(RLIMIT_CORE, &rlp);
-               getrlimit(RLIMIT_CORE, &rlp);
-               DEBUG(3,("Maximum core file size limits now %d(soft) %d(hard)\n",
-                        (int)rlp.rlim_cur,(int)rlp.rlim_max));
-       }
-#endif
-#endif
-
-       /* FIXME: if we have a core-plus-pid facility, configurably set
-        * this up here.
-        */
- out:
-       SAFE_FREE(logbase);
-}
-
- void dump_core(void)
+   Something really nasty happened - panic !
+**/
+_PUBLIC_ void smb_panic(const char *why)
 {
 {
-       static bool called;
-
-       if (called) {
-               DEBUG(0, ("dump_core() called recursive\n"));
-               exit(1);
-       }
-       called = true;
-
-       /* Note that even if core dumping has been disabled, we still set up
-        * the core path. This is to handle the case where core dumping is
-        * turned on in smb.conf and the relevant daemon is not restarted.
-        */
-       if (!lp_enable_core_files()) {
-               DEBUG(0, ("Exiting on internal error (core file administratively disabled)\n"));
-               exit(1);
-       }
-
-#if DUMP_CORE
-       /* If we're running as non root we might not be able to dump the core
-        * file to the corepath.  There must not be an unbecome_root() before
-        * we call abort(). */
-       if (geteuid() != sec_initial_uid()) {
-               become_root();
-       }
-
-       if (corepath == NULL) {
-               DEBUG(0, ("Can not dump core: corepath not set up\n"));
-               exit(1);
-       }
-
-       if (*corepath != '\0') {
-               /* The chdir might fail if we dump core before we finish
-                * processing the config file.
-                */
-               if (chdir(corepath) != 0) {
-                       DEBUG(0, ("unable to change to %s\n", corepath));
-                       DEBUGADD(0, ("refusing to dump core\n"));
-                       exit(1);
-               }
-
-               DEBUG(0,("dumping core in %s\n", corepath));
+       if (fault_state.panic_handler) {
+               fault_state.panic_handler(why);
+               _exit(1);
        }
        }
-
-       umask(~(0700));
-       dbgflush();
-
-#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
-       /* On Linux we lose the ability to dump core when we change our user
-        * ID. We know how to dump core safely, so let's make sure we have our
-        * dumpable flag set.
-        */
-       prctl(PR_SET_DUMPABLE, 1);
-#endif
-
-       /* Ensure we don't have a signal handler for abort. */
-#ifdef SIGABRT
-       CatchSignal(SIGABRT, SIG_DFL);
-#endif
-
-       abort();
-
-#else /* DUMP_CORE */
-       exit(1);
-#endif /* DUMP_CORE */
+       smb_panic_default(why);
 }
 }
index 78071ad3ca8ea7f1bb8bbd6f84c4dda384a65610..b143e4e9919a46ec70c24ea817581b19cdca8a3c 100644 (file)
@@ -73,13 +73,14 @@ _PUBLIC_ void call_backtrace(void);
 **/
 _PUBLIC_ _NORETURN_ void smb_panic(const char *why);
 
 **/
 _PUBLIC_ _NORETURN_ void smb_panic(const char *why);
 
-#if _SAMBA_BUILD_ == 4
-/**
-setup our fault handlers
-**/
-_PUBLIC_ void fault_setup(const char *pname);
+typedef void (*smb_panic_handler_t)(const char *why);
+
+_PUBLIC_ void fault_configure(smb_panic_handler_t panic_handler);
+_PUBLIC_ void fault_setup(void);
 _PUBLIC_ void fault_setup_disable(void);
 _PUBLIC_ void fault_setup_disable(void);
-#endif
+_PUBLIC_ void dump_core_setup(const char *progname, const char *logfile);
+_PUBLIC_ void smb_panic(const char *reason);
+
 
 /**
   register a fault handler. 
 
 /**
   register a fault handler. 
index 7ba8332eb0a7153aea9b846aaa5c9eb07fd58cd8..065f0cbad77be15933c0f1ff5c047bb585f990c9 100644 (file)
@@ -443,7 +443,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
          lib/addrchange.o \
          $(TDB_LIB_OBJ) \
          $(VERSION_OBJ) lib/charcnv.o ../lib/util/debug.o ../lib/util/debug_s3.o ../lib/util/fault.o \
          lib/addrchange.o \
          $(TDB_LIB_OBJ) \
          $(VERSION_OBJ) lib/charcnv.o ../lib/util/debug.o ../lib/util/debug_s3.o ../lib/util/fault.o \
-         lib/interface.o lib/pidfile.o \
+         lib/interface.o lib/pidfile.o lib/dumpcore.o \
          lib/system.o lib/sendfile.o lib/recvfile.o lib/time.o \
          lib/username.o \
          ../libds/common/flag_mapping.o \
          lib/system.o lib/sendfile.o lib/recvfile.o lib/time.o \
          lib/username.o \
          ../libds/common/flag_mapping.o \
index b5b35a46237e53c58a471f6121c1e3c1897a473e..bb9241c893df3c83d55f03cc7f14be7cc9cc760e 100644 (file)
@@ -515,10 +515,6 @@ void display_set_stderr(void);
 NTSTATUS map_nt_error_from_unix(int unix_error);
 int map_errno_from_nt_status(NTSTATUS status);
 
 NTSTATUS map_nt_error_from_unix(int unix_error);
 int map_errno_from_nt_status(NTSTATUS status);
 
-/* The following definitions come from lib/fault.c  */
-void fault_setup(void);
-void dump_core_setup(const char *progname);
-
 /* The following definitions come from lib/file_id.c  */
 
 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf);
 /* The following definitions come from lib/file_id.c  */
 
 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf);
@@ -1095,7 +1091,7 @@ const char *uidtoname(uid_t uid);
 char *gidtoname(gid_t gid);
 uid_t nametouid(const char *name);
 gid_t nametogid(const char *name);
 char *gidtoname(gid_t gid);
 uid_t nametouid(const char *name);
 gid_t nametogid(const char *name);
-void smb_panic(const char *const why);
+void smb_panic_s3(const char *why);
 void log_stack_trace(void);
 const char *readdirname(SMB_STRUCT_DIR *p);
 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive);
 void log_stack_trace(void);
 const char *readdirname(SMB_STRUCT_DIR *p);
 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive);
diff --git a/source3/lib/dumpcore.c b/source3/lib/dumpcore.c
new file mode 100644 (file)
index 0000000..8a1c43a
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+   Unix SMB/CIFS implementation.
+   Samba utility functions
+
+   Copyright (C) Andrew Tridgell 1992-2011
+
+   based on old fault.c code, which had:
+
+   Copyright (C) Jeremy Allison 2001-2007
+   Copyright (C) Simo Sorce 2001
+   Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+   Copyright (C) James Peach 2006
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+
+static char *corepath;
+
+/**
+ * Build up the default corepath as "<logbase>/cores/<progname>"
+ */
+static char *get_default_corepath(const char *logbase, const char *progname)
+{
+       char *tmp_corepath;
+
+       /* Setup core dir in logbase. */
+       tmp_corepath = talloc_asprintf(NULL, "%s/cores", logbase);
+       if (!tmp_corepath)
+               return NULL;
+
+       if ((mkdir(tmp_corepath, 0700) == -1) && errno != EEXIST)
+               goto err_out;
+
+       if (chmod(tmp_corepath, 0700) == -1)
+               goto err_out;
+
+       talloc_free(tmp_corepath);
+
+       /* Setup progname-specific core subdir */
+       tmp_corepath = talloc_asprintf(NULL, "%s/cores/%s", logbase, progname);
+       if (!tmp_corepath)
+               return NULL;
+
+       if (mkdir(tmp_corepath, 0700) == -1 && errno != EEXIST)
+               goto err_out;
+
+       if (chown(tmp_corepath, getuid(), getgid()) == -1)
+               goto err_out;
+
+       if (chmod(tmp_corepath, 0700) == -1)
+               goto err_out;
+
+       return tmp_corepath;
+
+ err_out:
+       talloc_free(tmp_corepath);
+       return NULL;
+}
+
+
+/**
+ * Get the FreeBSD corepath.
+ *
+ * On FreeBSD the current working directory is ignored when creating a core
+ * file.  Instead the core directory is controlled via sysctl.  This consults
+ * the value of "kern.corefile" so the correct corepath can be printed out
+ * before dump_core() calls abort.
+ */
+#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
+static char *get_freebsd_corepath(void)
+{
+       char *tmp_corepath = NULL;
+       char *end = NULL;
+       size_t len = 128;
+       int ret;
+
+       /* Loop with increasing sizes so we don't allocate too much. */
+       do {
+               if (len > 1024)  {
+                       goto err_out;
+               }
+
+               tmp_corepath = (char *)talloc_realloc(NULL, tmp_corepath,
+                                                     char, len);
+               if (!tmp_corepath) {
+                       return NULL;
+               }
+
+               ret = sysctlbyname("kern.corefile", tmp_corepath, &len, NULL,
+                                  0);
+               if (ret == -1) {
+                       if (errno != ENOMEM) {
+                               DEBUG(0, ("sysctlbyname failed getting "
+                                         "kern.corefile %s\n",
+                                         strerror(errno)));
+                               goto err_out;
+                       }
+
+                       /* Not a large enough array, try a bigger one. */
+                       len = len << 1;
+               }
+       } while (ret == -1);
+
+       /* Strip off the common filename expansion */
+       if ((end = strrchr_m(tmp_corepath, '/'))) {
+               *end = '\0';
+       }
+
+       return tmp_corepath;
+
+ err_out:
+       if (tmp_corepath) {
+               talloc_free(tmp_corepath);
+       }
+       return NULL;
+}
+#endif
+
+#if defined(HAVE_SYS_KERNEL_PROC_CORE_PATTERN)
+
+/**
+ * Get the Linux corepath.
+ *
+ * On Linux the contents of /proc/sys/kernel/core_pattern indicates the
+ * location of the core path.
+ */
+static char *get_linux_corepath(void)
+{
+       char *end;
+       int fd;
+       char *result;
+
+       fd = open("/proc/sys/kernel/core_pattern", O_RDONLY, 0);
+       if (fd == -1) {
+               return NULL;
+       }
+
+       result = afdgets(fd, NULL, 0);
+       close(fd);
+
+       if (result == NULL) {
+               return NULL;
+       }
+
+       if (result[0] != '/') {
+               /*
+                * No absolute path, use the default (cwd)
+                */
+               TALLOC_FREE(result);
+               return NULL;
+       }
+       /* Strip off the common filename expansion */
+
+       end = strrchr_m(result, '/');
+
+       if ((end != result) /* this would be the only / */
+           && (end != NULL)) {
+               *end = '\0';
+       }
+       return result;
+}
+#endif
+
+
+/**
+ * Try getting system-specific corepath if one exists.
+ *
+ * If the system doesn't define a corepath, then the default is used.
+ */
+static char *get_corepath(const char *logbase, const char *progname)
+{
+#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
+       char *tmp_corepath = NULL;
+       tmp_corepath = get_freebsd_corepath();
+
+       /* If this has been set correctly, we're done. */
+       if (tmp_corepath) {
+               return tmp_corepath;
+       }
+#endif
+
+#if defined(HAVE_SYS_KERNEL_PROC_CORE_PATTERN)
+       char *tmp_corepath = NULL;
+       tmp_corepath = get_linux_corepath();
+
+       /* If this has been set correctly, we're done. */
+       if (tmp_corepath) {
+               return tmp_corepath;
+       }
+#endif
+
+       /* Fall back to the default. */
+       return get_default_corepath(logbase, progname);
+}
+
+/*******************************************************************
+make all the preparations to safely dump a core file
+********************************************************************/
+
+void dump_core_setup(const char *progname, const char *logfile)
+{
+       char *logbase = NULL;
+       char *end = NULL;
+
+       if (logfile && *logfile) {
+               if (asprintf(&logbase, "%s", logfile) < 0) {
+                       return;
+               }
+               if ((end = strrchr_m(logbase, '/'))) {
+                       *end = '\0';
+               }
+       } else {
+               /* We will end up here if the log file is given on the command
+                * line by the -l option but the "log file" option is not set
+                * in smb.conf.
+                */
+               if (asprintf(&logbase, "%s", get_dyn_LOGFILEBASE()) < 0) {
+                       return;
+               }
+       }
+
+       SMB_ASSERT(progname != NULL);
+
+       corepath = get_corepath(logbase, progname);
+       if (!corepath) {
+               DEBUG(0, ("Unable to setup corepath for %s: %s\n", progname,
+                         strerror(errno)));
+               goto out;
+       }
+
+
+#ifdef HAVE_GETRLIMIT
+#ifdef RLIMIT_CORE
+       {
+               struct rlimit rlp;
+               getrlimit(RLIMIT_CORE, &rlp);
+               rlp.rlim_cur = MAX(16*1024*1024,rlp.rlim_cur);
+               setrlimit(RLIMIT_CORE, &rlp);
+               getrlimit(RLIMIT_CORE, &rlp);
+               DEBUG(3,("Maximum core file size limits now %d(soft) %d(hard)\n",
+                        (int)rlp.rlim_cur,(int)rlp.rlim_max));
+       }
+#endif
+#endif
+
+       /* FIXME: if we have a core-plus-pid facility, configurably set
+        * this up here.
+        */
+ out:
+       SAFE_FREE(logbase);
+}
+
+ void dump_core(void)
+{
+       static bool called;
+
+       if (called) {
+               DEBUG(0, ("dump_core() called recursive\n"));
+               exit(1);
+       }
+       called = true;
+
+       /* Note that even if core dumping has been disabled, we still set up
+        * the core path. This is to handle the case where core dumping is
+        * turned on in smb.conf and the relevant daemon is not restarted.
+        */
+       if (!lp_enable_core_files()) {
+               DEBUG(0, ("Exiting on internal error (core file administratively disabled)\n"));
+               exit(1);
+       }
+
+#if DUMP_CORE
+       /* If we're running as non root we might not be able to dump the core
+        * file to the corepath.  There must not be an unbecome_root() before
+        * we call abort(). */
+       if (geteuid() != sec_initial_uid()) {
+               become_root();
+       }
+
+       if (corepath == NULL) {
+               DEBUG(0, ("Can not dump core: corepath not set up\n"));
+               exit(1);
+       }
+
+       if (*corepath != '\0') {
+               /* The chdir might fail if we dump core before we finish
+                * processing the config file.
+                */
+               if (chdir(corepath) != 0) {
+                       DEBUG(0, ("unable to change to %s\n", corepath));
+                       DEBUGADD(0, ("refusing to dump core\n"));
+                       exit(1);
+               }
+
+               DEBUG(0,("dumping core in %s\n", corepath));
+       }
+
+       umask(~(0700));
+       dbgflush();
+
+#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
+       /* On Linux we lose the ability to dump core when we change our user
+        * ID. We know how to dump core safely, so let's make sure we have our
+        * dumpable flag set.
+        */
+       prctl(PR_SET_DUMPABLE, 1);
+#endif
+
+       /* Ensure we don't have a signal handler for abort. */
+#ifdef SIGABRT
+       CatchSignal(SIGABRT, SIG_DFL);
+#endif
+
+       abort();
+
+#else /* DUMP_CORE */
+       exit(1);
+#endif /* DUMP_CORE */
+}
index b6128feaf6591f3fe6a434ab6484d144cd27bf5f..79b10fda5ee12dea917d30771bf34534e30502e5 100644 (file)
@@ -1344,7 +1344,7 @@ gid_t nametogid(const char *name)
  Something really nasty happened - panic !
 ********************************************************************/
 
  Something really nasty happened - panic !
 ********************************************************************/
 
-void smb_panic(const char *const why)
+void smb_panic_s3(const char *why)
 {
        char *cmd;
        int result;
 {
        char *cmd;
        int result;
index 1735c90576e163a4b88d77c325d1217161d9a417..2aa896476f74e2f92f65bf962a54368250b33d14 100644 (file)
@@ -812,7 +812,7 @@ static bool open_sockets(bool isdaemon, int port)
        }
        
        fault_setup();
        }
        
        fault_setup();
-       dump_core_setup("nmbd");
+       dump_core_setup("nmbd", lp_logfile());
        
        /* POSIX demands that signals are inherited. If the invoking process has
         * these signals masked, we will have problems, as we won't receive them. */
        
        /* POSIX demands that signals are inherited. If the invoking process has
         * these signals masked, we will have problems, as we won't receive them. */
index a82d21cdb1a8a5d91a3b278e43e84a3a1560326b..ba3cd3c6c5205a25858e5a3983c9714f9a893bd8 100644 (file)
@@ -9541,6 +9541,8 @@ static bool lp_load_ex(const char *pszFname,
 
        init_iconv();
 
 
        init_iconv();
 
+       fault_configure(smb_panic_s3);
+
        bAllowIncludeRegistry = true;
 
        return (bRetval);
        bAllowIncludeRegistry = true;
 
        return (bRetval);
index 2c09dd26c5b2b4d06d8325557386ddbc2dd00aa8..37c97049b813a15253991f5554b3a7b0b063c616 100644 (file)
@@ -987,7 +987,7 @@ extern void build_options(bool screen);
        gain_root_group_privilege();
 
        fault_setup();
        gain_root_group_privilege();
 
        fault_setup();
-       dump_core_setup("smbd");
+       dump_core_setup("smbd", lp_logfile());
 
        /* we are never interested in SIGPIPE */
        BlockSignals(True,SIGPIPE);
 
        /* we are never interested in SIGPIPE */
        BlockSignals(True,SIGPIPE);
index 99e98ac2b0ac39eaf05d07666572ec6e69342662..47d8be617839eb1fbd7e94010d7070040b6e94c1 100644 (file)
@@ -1230,7 +1230,7 @@ int main(int argc, char **argv, char **envp)
        CatchSignal(SIGUSR2, SIG_IGN);
 
        fault_setup();
        CatchSignal(SIGUSR2, SIG_IGN);
 
        fault_setup();
-       dump_core_setup("winbindd");
+       dump_core_setup("winbindd", lp_logfile());
 
        load_case_tables();
 
 
        load_case_tables();
 
index fd9e4f488b736318ae6b5b7a40409f11c905cbf0..cb3bbc29be452f35f495f917548aac7bb852a67b 100755 (executable)
@@ -69,7 +69,8 @@ LIB_SRC = '''
           lib/util_transfer_file.c
           lib/addrchange.c
           ${TDB_LIB_SRC}
           lib/util_transfer_file.c
           lib/addrchange.c
           ${TDB_LIB_SRC}
-          ../lib/util/debug_s3.c ../lib/util/fault.c
+          ../lib/util/debug_s3.c
+          lib/dumpcore.c
           lib/interface.c lib/pidfile.c
           lib/system.c lib/sendfile.c lib/recvfile.c lib/time.c
           lib/username.c
           lib/interface.c lib/pidfile.c
           lib/system.c lib/sendfile.c lib/recvfile.c lib/time.c
           lib/username.c