BUG/PATCH: Samba 2.0.7pre3

Mattias Gronlund Mattias.Gronlund at sa.erisoft.se
Wed Apr 12 16:05:30 GMT 2000


Hello,

There is a bug in SAMBA that can make smbd to write the log-disk full. The "max log size"
limit should be checked periodically if you read the man page, but the the code skips all these
tests if smbd is not running as root when the check should be done.
This is a real problem, we had a few disk-full problems before this patch.

To make things worse, there is a likely senario:
1. One process write a lot to the log, but always when run as the user.
2. Another smbd-process move:s the inode to .old and creates a new log-file.
3. The second log-file fills up
4. Another smbd-process unliks the .old inode, and creates a new .old and a new log-file.

The problem here is that the first and probably large log-file is still allocated on disk as there
is a process that has an open handle to it. And it gets very hard to find out where that disk
is allocated.

So, here is a patch that we have been using for a long time with older versions of SAMBA that
you might want to include into the 2.0.7 release.

/Mattias

-------------- next part --------------
diff -ru ./source/include/smb.h ../samba-2.0.7pre3-epl2/source/include/smb.h
--- ./source/include/smb.h	Thu Mar 16 23:59:13 2000
+++ ../samba-2.0.7pre3-epl2/source/include/smb.h	Tue Apr 11 12:55:53 2000
@@ -84,6 +84,9 @@
 BOOL dbgtext();
 #endif
 
+BOOL need_to_check_log_size();
+void check_log_size();
+
 /* If we have these macros, we can add additional info to the header. */
 #ifdef HAVE_FILE_MACRO
 #define FILE_MACRO (__FILE__)
@@ -1461,7 +1464,7 @@
 #ifdef HAVE_STDARG_H
 int slprintf(char *str, int n, char *format, ...)
 #ifdef __GNUC__
-     __attribute__ ((format (printf, 3, 4)))
+     __attribute__ ((format (__printf__, 3, 4)))
 #endif
 ;
 #else
diff -ru ./source/lib/debug.c ../samba-2.0.7pre3-epl2/source/lib/debug.c
--- ./source/lib/debug.c	Thu Mar 16 23:59:14 2000
+++ ../samba-2.0.7pre3-epl2/source/lib/debug.c	Tue Apr 11 10:44:51 2000
@@ -244,20 +244,44 @@
   } /* force_check_log_size */
 
 /* ************************************************************************** **
+ * Check to see if there is any need to check if the logfile has grown too big
+ * ************************************************************************** **
+ */
+BOOL need_to_check_log_size( void )
+{
+  int         maxlog;
+  if( debug_count++ < 100 )
+    return( False );
+
+  maxlog = lp_max_log_size() * 1024;
+  if( !dbf || maxlog <= 0 ) 
+    {
+    debug_count = 0;
+    return(False);
+    }
+  return( True );
+} /* need_to_check_log_size */
+
+/* ************************************************************************** **
  * Check to see if the log has grown to be too big.
  * ************************************************************************** **
  */
-static void check_log_size( void )
+void check_log_size( void )
 {
   int         maxlog;
   SMB_STRUCT_STAT st;
 
-  if( debug_count++ < 100 || geteuid() != 0 )
+  if( !need_to_check_log_size() )
     return;
 
-  maxlog = lp_max_log_size() * 1024;
-  if( !dbf || maxlog <= 0 )
+  /*
+   *  We need to be root to check/change log-file, skip this and let the main
+   *  loop check do a new chech as root.
+   */
+  if( geteuid() != 0 )
     return;
+
+  maxlog = lp_max_log_size() * 1024;
 
   if( sys_fstat( fileno( dbf ), &st ) == 0 && st.st_size > maxlog )
     {
diff -ru ./source/smbd/process.c ../samba-2.0.7pre3-epl2/source/smbd/process.c
--- ./source/smbd/process.c	Thu Mar 16 23:59:49 2000
+++ ../samba-2.0.7pre3-epl2/source/smbd/process.c	Tue Apr 11 10:44:52 2000
@@ -1014,6 +1014,16 @@
       do_read_prediction();
 #endif
 
+    if(need_to_check_log_size()) {
+      if ( geteuid() != 0 ) {
+        become_root(False);
+        check_log_size();
+	unbecome_root(False);
+      } else {
+        check_log_size();
+      }
+    }
+
     errno = 0;      
 
     /* free up temporary memory */


More information about the samba-technical mailing list