svn commit: samba r20342 - in branches/SAMBA_3_0/source/smbd: .

vlendec at samba.org vlendec at samba.org
Sun Dec 24 15:11:04 GMT 2006


Author: vlendec
Date: 2006-12-24 15:11:03 +0000 (Sun, 24 Dec 2006)
New Revision: 20342

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

Log:
Move the lstat into mkdir_internal, for the FILE_OPEN case in open_directory
we want to follow symlinks.

Volker

Modified:
   branches/SAMBA_3_0/source/smbd/open.c


Changeset:
Modified: branches/SAMBA_3_0/source/smbd/open.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/open.c	2006-12-24 15:09:47 UTC (rev 20341)
+++ branches/SAMBA_3_0/source/smbd/open.c	2006-12-24 15:11:03 UTC (rev 20342)
@@ -1851,9 +1851,9 @@
 	return ret;
 }
 
-static NTSTATUS mkdir_internal(connection_struct *conn, const char *name)
+static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
+			       SMB_STRUCT_STAT *psbuf)
 {
-	SMB_STRUCT_STAT sbuf;
 	int ret= -1;
 	mode_t mode;
 
@@ -1873,6 +1873,21 @@
 		return map_nt_error_from_unix(errno);
 	}
 
+	/* Ensure we're checking for a symlink here.... */
+	/* We don't want to get caught by a symlink racer. */
+
+	if (SMB_VFS_LSTAT(conn, name, psbuf) == -1) {
+		DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
+			  name, strerror(errno)));
+		return map_nt_error_from_unix(errno);
+	}
+
+	if (!S_ISDIR(psbuf->st_mode)) {
+		DEBUG(0, ("Directory just '%s' created is not a directory\n",
+			  name));
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	if (lp_inherit_perms(SNUM(conn))) {
 		inherit_access_acl(conn, name, mode);
 	}
@@ -1883,11 +1898,9 @@
 	 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
 	 * dir.
 	 */
-	if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)
-	    && (SMB_VFS_STAT(conn, name, &sbuf) == 0)
-	    && (mode & ~sbuf.st_mode)) {
+	if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_mode)) {
 		SMB_VFS_CHMOD(conn, name,
-			      sbuf.st_mode | (mode & ~sbuf.st_mode));
+			      psbuf->st_mode | (mode & ~psbuf->st_mode));
 	}
 
 	return NT_STATUS_OK;
@@ -1929,11 +1942,17 @@
 
 	switch( create_disposition ) {
 		case FILE_OPEN:
+
+			info = FILE_WAS_OPENED;
+
 			/*
-			 * Don't do anything. The check for existence is done
-			 * futher down.
+			 * We want to follow symlinks here.
 			 */
-			info = FILE_WAS_OPENED;
+
+			if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
+				return map_nt_error_from_unix(errno);
+			}
+				
 			break;
 
 		case FILE_CREATE:
@@ -1941,7 +1960,7 @@
 			/* If directory exists error. If directory doesn't
 			 * exist create. */
 
-			status = mkdir_internal(conn, fname);
+			status = mkdir_internal(conn, fname, psbuf);
 			if (!NT_STATUS_IS_OK(status)) {
 				DEBUG(2, ("open_directory: unable to create "
 					  "%s. Error was %s\n", fname,
@@ -1958,7 +1977,7 @@
 			 * exist create.
 			 */
 
-			status = mkdir_internal(conn, fname);
+			status = mkdir_internal(conn, fname, psbuf);
 
 			if (NT_STATUS_IS_OK(status)) {
 				info = FILE_WAS_CREATED;
@@ -1982,13 +2001,6 @@
 			return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	/* Ensure we're checking for a symlink here.... */
-	/* We don't want to get caught by a symlink racer. */
-
-	if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) {
-		return map_nt_error_from_unix(errno);
-	}
-
 	if(!S_ISDIR(psbuf->st_mode)) {
 		DEBUG(5,("open_directory: %s is not a directory !\n",
 			 fname ));



More information about the samba-cvs mailing list