svn commit: samba r10550 - in trunk/source/smbd: .

jra at samba.org jra at samba.org
Tue Sep 27 17:41:58 GMT 2005


Author: jra
Date: 2005-09-27 17:41:56 +0000 (Tue, 27 Sep 2005)
New Revision: 10550

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=10550

Log:
We need to check if the source path is a parent directory of the destination
(ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
refuse the rename with a sharing violation. Under UNIX the above call can
*succeed* if /foo/bar/baz is a symlink to another area in the share. We
probably need to check that the client is a Windows one before disallowing
this as a UNIX client (one with UNIX extensions) can know the source is a
symlink and make this decision intelligently. Found by an excellent bug
report from <AndyLiebman at aol.com>.
Jeremy.

Modified:
   trunk/source/smbd/reply.c


Changeset:
Modified: trunk/source/smbd/reply.c
===================================================================
--- trunk/source/smbd/reply.c	2005-09-27 16:58:37 UTC (rev 10549)
+++ trunk/source/smbd/reply.c	2005-09-27 17:41:56 UTC (rev 10550)
@@ -4066,6 +4066,35 @@
 }
 
 /****************************************************************************
+ We need to check if the source path is a parent directory of the destination
+ (ie. a rename of /foo/bar/baz -> /foo/bar/baz/bibble/bobble. If so we must
+ refuse the rename with a sharing violation. Under UNIX the above call can
+ *succeed* if /foo/bar/baz is a symlink to another area in the share. We
+ probably need to check that the client is a Windows one before disallowing
+ this as a UNIX client (one with UNIX extensions) can know the source is a
+ symlink and make this decision intelligently. Found by an excellent bug
+ report from <AndyLiebman at aol.com>.
+****************************************************************************/
+
+static BOOL rename_path_prefix_equal(const char *src, const char *dest)
+{
+	const char *psrc = src;
+	const char *pdst = dest;
+	size_t slen;
+
+	if (psrc[0] == '.' && psrc[1] == '/') {
+		psrc += 2;
+	}
+	if (pdst[0] == '.' && pdst[1] == '/') {
+		pdst += 2;
+	}
+	if ((slen = strlen(psrc)) > strlen(pdst)) {
+		return False;
+	}
+	return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/');
+}
+
+/****************************************************************************
  Rename an open file - given an fsp.
 ****************************************************************************/
 
@@ -4160,6 +4189,10 @@
 		return error;
 	}
 
+	if (rename_path_prefix_equal(fsp->fsp_name, newname)) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
 		DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
 			fsp->fsp_name,newname));
@@ -4381,6 +4414,10 @@
 			return NT_STATUS_OBJECT_NAME_COLLISION;
 		}
 
+		if (rename_path_prefix_equal(directory, newname)) {
+			return NT_STATUS_SHARING_VIOLATION;
+		}
+
 		if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
 			DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
 				directory,newname));
@@ -4479,6 +4516,10 @@
 					continue;
 				}
 				
+				if (rename_path_prefix_equal(fname, destname)) {
+					return NT_STATUS_SHARING_VIOLATION;
+				}
+
 				if (!SMB_VFS_RENAME(conn,fname,destname)) {
 					rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
 					count++;



More information about the samba-cvs mailing list