samba3-3.4-honor-all-loopback-ips.patch
samba-3.5-crossrename.patch

commit b6afe7ef236a454d8a6abf104b8846f817378f73
Author: Björn Jacke <bj@sernet.de>
Date:   Thu Oct 15 02:02:30 2009 +0200

    util: cope the all loopback addresses IPv4 knows
    
    The fact that we just recogniced 127.0.0.1 as loopback IP address and not the
    rest of the 127.0.0.0/8 IP address range we used the lo interface for sending
    packages even though we should send them to some more physical interface. This
    way we ended up with failing WINS registration and so on like in #6348.
    On the lo interface sendto() returned "Invalid Argument" (EINVAL).

diff --git a/lib/util/util_net.c b/lib/util/util_net.c
index 0ce495e..0511a28 100644
--- a/lib/util/util_net.c
+++ b/lib/util/util_net.c
@@ -351,13 +351,11 @@ bool is_broadcast_addr(const struct sockaddr *pss)
 }
 
 /**
- * Check if an IPv7 is 127.0.0.1
+ * Check if an IPv4 is in IN_LOOPBACKNET (127.0.0.0/8)
  */
 bool is_loopback_ip_v4(struct in_addr ip)
 {
-	struct in_addr a;
-	a.s_addr = htonl(INADDR_LOOPBACK);
-	return(ip.s_addr == a.s_addr);
+	return ((ntohl(ip.s_addr) & IN_CLASSA_NET) == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT));
 }
 
 /**
From 433d1b5816a9a2befdf86c806f1ae79f7d35bef4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de>
Date: Mon, 8 Mar 2010 12:52:13 +0100
Subject: [PATCH 1/3] s3: remove cross-device rename support from vfs_default

cross-device rename support has some major limitations:

- on huge files clients will timeout or hang
- ACLs and EA information is not retained

Usually a client will have to handle this. A Windows Server with a reparse
point will also just return NT_STATUS_NOT_SAME_DEVICE. We will now by default
do the same.

I will add a vfs module which will restore the old cross-device renames.
---
 source3/modules/vfs_default.c |  116 -----------------------------------------
 1 files changed, 0 insertions(+), 116 deletions(-)

diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 6e2a571..faca292 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -475,117 +475,6 @@ static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
 	return result;
 }
 
-/*********************************************************
- For rename across filesystems Patch from Warren Birnbaum
- <warrenb@hpcvscdp.cv.hp.com>
-**********************************************************/
-
-static int copy_reg(const char *source, const char *dest)
-{
-	SMB_STRUCT_STAT source_stats;
-	int saved_errno;
-	int ifd = -1;
-	int ofd = -1;
-
-	if (sys_lstat(source, &source_stats, false) == -1)
-		return -1;
-
-	if (!S_ISREG (source_stats.st_ex_mode))
-		return -1;
-
-	if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
-		return -1;
-
-	if (unlink (dest) && errno != ENOENT)
-		return -1;
-
-#ifdef O_NOFOLLOW
-	if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
-#else
-	if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
-#endif
-		goto err;
-
-	if (transfer_file(ifd, ofd, (size_t)-1) == -1)
-		goto err;
-
-	/*
-	 * Try to preserve ownership.  For non-root it might fail, but that's ok.
-	 * But root probably wants to know, e.g. if NFS disallows it.
-	 */
-
-#ifdef HAVE_FCHOWN
-	if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
-#else
-	if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
-#endif
-		goto err;
-
-	/*
-	 * fchown turns off set[ug]id bits for non-root,
-	 * so do the chmod last.
-	 */
-
-#if defined(HAVE_FCHMOD)
-	if (fchmod (ofd, source_stats.st_ex_mode & 07777))
-#else
-	if (chmod (dest, source_stats.st_ex_mode & 07777))
-#endif
-		goto err;
-
-	if (close (ifd) == -1)
-		goto err;
-
-	if (close (ofd) == -1)
-		return -1;
-
-	/* Try to copy the old file's modtime and access time.  */
-#if defined(HAVE_UTIMENSAT)
-	{
-		struct timespec ts[2];
-
-		ts[0] = source_stats.st_ex_atime;
-		ts[1] = source_stats.st_ex_mtime;
-		utimensat(AT_FDCWD, dest, ts, AT_SYMLINK_NOFOLLOW);
-	}
-#elif defined(HAVE_UTIMES)
-	{
-		struct timeval tv[2];
-
-		tv[0] = convert_timespec_to_timeval(source_stats.st_ex_atime);
-		tv[1] = convert_timespec_to_timeval(source_stats.st_ex_mtime);
-#ifdef HAVE_LUTIMES
-		lutimes(dest, tv);
-#else
-		utimes(dest, tv);
-#endif
-	}
-#elif defined(HAVE_UTIME)
-	{
-		struct utimbuf tv;
-
-		tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime);
-		tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime);
-		utime(dest, &tv);
-	}
-#endif
-
-	if (unlink (source) == -1)
-		return -1;
-
-	return 0;
-
-  err:
-
-	saved_errno = errno;
-	if (ifd != -1)
-		close(ifd);
-	if (ofd != -1)
-		close(ofd);
-	errno = saved_errno;
-	return -1;
-}
-
 static int vfswrap_rename(vfs_handle_struct *handle,
 			  const struct smb_filename *smb_fname_src,
 			  const struct smb_filename *smb_fname_dst)
@@ -600,11 +489,6 @@ static int vfswrap_rename(vfs_handle_struct *handle,
 	}
 
 	result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
-	if ((result == -1) && (errno == EXDEV)) {
-		/* Rename across filesystems needed. */
-		result = copy_reg(smb_fname_src->base_name,
-				  smb_fname_dst->base_name);
-	}
 
  out:
 	END_PROFILE(syscall_rename);
-- 
1.6.6.1


From 6dc931b27daf06aa1f4cdca19dae44ffef0bc3fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de>
Date: Mon, 8 Mar 2010 18:18:59 +0100
Subject: [PATCH 2/3] s3: add vfs_crossrename

this module adds optional server-side support for limited rename operations
beyond filesystem boundaries, which was the previously the default.
---
 source3/Makefile.in               |    5 +
 source3/configure.in              |    3 +-
 source3/modules/vfs_crossrename.c |  200 +++++++++++++++++++++++++++++++++++++
 3 files changed, 207 insertions(+), 1 deletions(-)
 create mode 100644 source3/modules/vfs_crossrename.c

diff --git a/source3/Makefile.in b/source3/Makefile.in
index f84ed20..2b90958 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -741,6 +741,7 @@ PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o
 PERFCOUNT_TEST_OBJ = modules/perfcount_test.o
 VFS_DIRSORT_OBJ = modules/vfs_dirsort.o
 VFS_SCANNEDONLY_OBJ = modules/vfs_scannedonly.o
+VFS_CROSSRENAME_OBJ = modules/vfs_crossrename.o
 
 PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
 
@@ -2846,6 +2847,10 @@ bin/scannedonly.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SCANNEDONLY_OBJ)
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) $(VFS_SCANNEDONLY_OBJ)
 
+bin/crossrename.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_CROSSRENAME_OBJ)
+	@echo "Building plugin $@"
+	@$(SHLD_MODULE) $(VFS_CROSSRENAME_OBJ)
+
 #########################################################
 ## IdMap NSS plugins
 
diff --git a/source3/configure.in b/source3/configure.in
index 0529a69..dbbc5be 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -387,7 +387,7 @@ dnl These have to be built static:
 default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template"
 
 dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen vfs_catia vfs_scannedonly"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer vfs_preopen vfs_catia vfs_scannedonly vfs_crossrename"
 
 if test "x$developer" = xyes; then
    default_static_modules="$default_static_modules rpc_rpcecho pdb_ads"
@@ -6571,6 +6571,7 @@ SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_onefs_shadow_copy, \$(VFS_ONEFS_SHADOW_COPY), "bin/onefs_shadow_copy.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_dirsort, \$(VFS_DIRSORT_OBJ), "bin/dirsort.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_scannedonly, \$(VFS_SCANNEDONLY_OBJ), "bin/scannedonly.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_crossrename, \$(VFS_CROSSRENAME_OBJ), "bin/crossrename.$SHLIBEXT", VFS)
 
 SMB_SUBSYSTEM(VFS,smbd/vfs.o)
 
diff --git a/source3/modules/vfs_crossrename.c b/source3/modules/vfs_crossrename.c
new file mode 100644
index 0000000..323ceb1
--- /dev/null
+++ b/source3/modules/vfs_crossrename.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) Björn Jacke 2010
+ *
+ * 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"
+
+
+#define MODULE "crossrename"
+static SMB_OFF_T module_sizelimit;
+
+static int crossrename_connect(
+                struct vfs_handle_struct *  handle,
+                const char *                service,
+                const char *                user)
+{
+	int ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
+
+	if (ret < 0) {
+		return ret;
+	}
+
+	module_sizelimit = (SMB_OFF_T) lp_parm_int(SNUM(handle->conn),
+					MODULE, "sizelimit", 20);
+	/* convert from MiB to byte: */
+	module_sizelimit *= 1048576;
+
+	return 0;
+}
+
+/*********************************************************
+ For rename across filesystems initial Patch from Warren Birnbaum
+ <warrenb@hpcvscdp.cv.hp.com>
+**********************************************************/
+
+static int copy_reg(const char *source, const char *dest)
+{
+	SMB_STRUCT_STAT source_stats;
+	int saved_errno;
+	int ifd = -1;
+	int ofd = -1;
+
+	if (sys_lstat(source, &source_stats, false) == -1)
+		return -1;
+
+	if (!S_ISREG (source_stats.st_ex_mode))
+		return -1;
+
+	if (source_stats.st_ex_size > module_sizelimit) {
+		DEBUG(5,
+			("%s: size of %s larger than sizelimit (%lld > %lld), rename prohititted\n",
+			MODULE, source,
+			(long long)source_stats.st_ex_size,
+			(long long)module_sizelimit));
+		return -1;
+	}
+
+	if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
+		return -1;
+
+	if (unlink (dest) && errno != ENOENT)
+		return -1;
+
+#ifdef O_NOFOLLOW
+	if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
+#else
+	if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
+#endif
+		goto err;
+
+	if (transfer_file(ifd, ofd, (size_t)-1) == -1)
+		goto err;
+
+	/*
+	 * Try to preserve ownership.  For non-root it might fail, but that's ok.
+	 * But root probably wants to know, e.g. if NFS disallows it.
+	 */
+
+#ifdef HAVE_FCHOWN
+	if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
+#else
+	if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
+#endif
+		goto err;
+
+	/*
+	 * fchown turns off set[ug]id bits for non-root,
+	 * so do the chmod last.
+	 */
+
+#if defined(HAVE_FCHMOD)
+	if (fchmod (ofd, source_stats.st_ex_mode & 07777))
+#else
+	if (chmod (dest, source_stats.st_ex_mode & 07777))
+#endif
+		goto err;
+
+	if (close (ifd) == -1)
+		goto err;
+
+	if (close (ofd) == -1)
+		return -1;
+
+	/* Try to copy the old file's modtime and access time.  */
+#if defined(HAVE_UTIMENSAT)
+	{
+		struct timespec ts[2];
+
+		ts[0] = source_stats.st_ex_atime;
+		ts[1] = source_stats.st_ex_mtime;
+		utimensat(AT_FDCWD, dest, ts, AT_SYMLINK_NOFOLLOW);
+	}
+#elif defined(HAVE_UTIMES)
+	{
+		struct timeval tv[2];
+
+		tv[0] = convert_timespec_to_timeval(source_stats.st_ex_atime);
+		tv[1] = convert_timespec_to_timeval(source_stats.st_ex_mtime);
+#ifdef HAVE_LUTIMES
+		lutimes(dest, tv);
+#else
+		utimes(dest, tv);
+#endif
+	}
+#elif defined(HAVE_UTIME)
+	{
+		struct utimbuf tv;
+
+		tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime);
+		tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime);
+		utime(dest, &tv);
+	}
+#endif
+
+	if (unlink (source) == -1)
+		return -1;
+
+	return 0;
+
+  err:
+
+	saved_errno = errno;
+	if (ifd != -1)
+		close(ifd);
+	if (ofd != -1)
+		close(ofd);
+	errno = saved_errno;
+	return -1;
+}
+
+
+static int crossrename_rename(vfs_handle_struct *handle,
+			  const struct smb_filename *smb_fname_src,
+			  const struct smb_filename *smb_fname_dst)
+{
+	int result = -1;
+
+	START_PROFILE(syscall_rename);
+
+	if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
+		errno = ENOENT;
+		goto out;
+	}
+
+	result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
+	if ((result == -1) && (errno == EXDEV)) {
+		/* Rename across filesystems needed. */
+		result = copy_reg(smb_fname_src->base_name,
+				  smb_fname_dst->base_name);
+	}
+
+ out:
+	END_PROFILE(syscall_rename);
+	return result;
+}
+
+static struct vfs_fn_pointers vfs_crossrename_fns = {
+	.connect_fn = crossrename_connect,
+	.rename = crossrename_rename
+};
+
+NTSTATUS vfs_crossrename_init(void);
+NTSTATUS vfs_crossrename_init(void)
+{
+	return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE,
+				&vfs_crossrename_fns);
+}
+
-- 
1.6.6.1


From 555acebc72c2827691e91648f697212ffa6725d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de>
Date: Mon, 8 Mar 2010 12:38:38 +0100
Subject: [PATCH 3/3] s3: add man page for vfs_crossrename

---
 docs-xml/manpages-3/vfs_crossrename.8.xml |  115 +++++++++++++++++++++++++++++
 1 files changed, 115 insertions(+), 0 deletions(-)
 create mode 100644 docs-xml/manpages-3/vfs_crossrename.8.xml

diff --git a/docs-xml/manpages-3/vfs_crossrename.8.xml b/docs-xml/manpages-3/vfs_crossrename.8.xml
new file mode 100644
index 0000000..675c92e
--- /dev/null
+++ b/docs-xml/manpages-3/vfs_crossrename.8.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<refentry id="vfs_crossrename.8">
+
+<refmeta>
+	<refentrytitle>vfs_crossrename</refentrytitle>
+	<manvolnum>8</manvolnum>
+	<refmiscinfo class="source">Samba</refmiscinfo>
+	<refmiscinfo class="manual">System Administration tools</refmiscinfo>
+	<refmiscinfo class="version">3.6</refmiscinfo>
+</refmeta>
+
+
+<refnamediv>
+	<refname>vfs_crossrename</refname>
+	<refpurpose>server side rename files across filesystem boundaries</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+	<cmdsynopsis>
+		<command>vfs objects = crossrename</command>
+	</cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+	<title>DESCRIPTION</title>
+
+	<para>This VFS module is part of the
+	<citerefentry><refentrytitle>samba</refentrytitle>
+	<manvolnum>7</manvolnum></citerefentry> suite.</para>
+
+	<para>The <command>vfs_crossrename</command> VFS module allows
+	server side rename operations even if source and target are on
+	differen physical devices. A "move" in Explorer is usually a
+	rename operation if it is inside of a single share or device.
+	Usually such a rename operation returns
+	NT_STATUS_NOT_SAME_DEVICE and the client has to move the file by
+	manual copy and delete operations. If the rename by copy is done by the
+	server this can be much more efficient. vfs_crossrename tries to do
+	this server-side cross-device rename operation. There are however
+	limitations that this module currently does not solve:
+
+	<variablelist>
+		<varlistentry>
+		the ACLs of files are not preserved
+		</varlistentry>
+		<varlistentry>
+		meta data in EAs are not preserved
+		</varlistentry>
+		<varlistentry>
+		renames of whole subdirectories cannot be done recursively,
+		in that case we still return STATUS_NOT_SAME_DEVICE and
+		let the client decide what to do
+		</varlistentry>
+		<varlistentry>
+		rename operations of huge files can cause hangs on the
+		client because clients expect a rename operation to
+		return fast
+		</varlistentry>
+	</variablelist>
+	</para>
+
+	<para>This module is stackable.</para>
+
+</refsect1>
+
+
+<refsect1>
+	<title>OPTIONS</title>
+
+	<variablelist>
+
+		<varlistentry>
+		<term>crossrename:sizelimit = BYTES</term>
+		<listitem>
+		<para>server-side cross-device-renames are only done
+		for files if the filesize is not larger than the defined
+		size in MiB to prevent timeouts. The default sizelimit is
+		20 (MiB)
+		</para>
+		</varlistentry>
+	</variablelist>
+</refsect1>
+
+<refsect1>
+	<title>EXAMPLES</title>
+
+	<para>To add server-side cross-device renames inside of a share
+	for all files sized up to 50MB:</para>
+
+<programlisting>
+        <smbconfsection name="[testshare]"/>
+	<smbconfoption name="path">/data/mounts</smbconfoption>
+	<smbconfoption name="vfs objects">crossrename</smbconfoption>
+	<smbconfoption name="crossrename:sizelimit">50</smbconfoption>
+</programlisting>
+</refsect1>
+
+<refsect1>
+	<title>VERSION</title>
+	<para>This man page is correct for version 3.6.0 of the Samba suite.
+	</para>
+</refsect1>
+
+<refsect1>
+	<title>AUTHOR</title>
+
+	<para>The original Samba software and related utilities
+	were created by Andrew Tridgell. Samba is now developed
+	by the Samba Team as an Open Source project similar
+	to the way the Linux kernel is developed.</para>
+
+</refsect1>
+
+</refentry>
-- 
1.6.6.1

From 36f4541d92b7ae588743ce206514d27419d478df Mon Sep 17 00:00:00 2001
From: Torsten Kurbad <samba-technical@tk-webart.de>
Date: Thu, 25 Mar 2010 17:58:27 +0100
Subject: [PATCH] s3: Fix a missing </listitem> in vfs_crossrename.8.xml

---
 docs-xml/manpages-3/vfs_crossrename.8.xml |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/docs-xml/manpages-3/vfs_crossrename.8.xml b/docs-xml/manpages-3/vfs_crossrename.8.xml
index 675c92e..f5a4444 100644
--- a/docs-xml/manpages-3/vfs_crossrename.8.xml
+++ b/docs-xml/manpages-3/vfs_crossrename.8.xml
@@ -78,6 +78,7 @@
 		size in MiB to prevent timeouts. The default sizelimit is
 		20 (MiB)
 		</para>
+		</listitem>
 		</varlistentry>
 	</variablelist>
 </refsect1>
-- 
1.7.0.2

