samba resetting permissions on extant files on NT_TRANSACT_CREATE

Buck Huppmann cjh at frb.gov
Fri Dec 14 17:24:02 GMT 2001


one of our diligent users discovered this. i'm less diligent, so please
rebuke me gently

seems that if samba gets a request to create a file and the file already
exists, it will reset the perms on the file. this isn't what NT (4, SP6a)
seems to do, and it's not what UNIX does, so i'm having trouble grokking
it. at any rate, since it potentially impacts on security, i'm hoping
either that someone can hack on this or to be made to understand it

thanks

--- demo ---

(D: is mapped to an NT4SP6a server share; G: is mapped to a samba 2.2.2
share with ``inherit permissions'', though i think that's irrelevant to
the behavioral course exhibited)

	G:\>for %i in (d g) do ( cacls %i:\foo\bar & type nul > %i:\foo\bar
	More? cacls %i:\ foo\bar )

	G:\>(cacls d:\foo\bar   & type nul   1>d:\foo\bar  & cacls d:\foo\bar  )
	d:\foo\bar US\me:F

	d:\foo\bar US\me:F


	G:\>(cacls g:\foo\bar   & type nul   1>g:\foo\bar  & cacls g:\foo\bar  )
	g:\foo\bar Everyone:(special access:)
			    WRITE_OWNER

		   US\someof:(special access:)
			    WRITE_OWNER

		   US\me:F

	g:\foo\bar Everyone:(special access:)
			    WRITE_OWNER

		   US\me:F
		   US\someof:(special access:)
			    READ_CONTROL
			    SYNCHRONIZE
			    FILE_GENERIC_READ
			    FILE_READ_DATA
			    FILE_READ_EA
			    FILE_READ_ATTRIBUTES

--- example patch ---

the second hunk is from the 

	if(!VALID_STAT(*psbuf)) {
		if (vfs_fstat(fsp,fsp->fd,psbuf) == -1) {

which is the same logic that open_file_shared() uses higher up in the
stack to determine whether it's creating the file, using the same
*psbuf contents. i'm unsure if the same sort of check should also be made
in nttrans.c:call_nt_transact_create() before set_sd() is called also, since
i don't have any ready way to test this (so i have a hard time trying to
force myself to study that code, which is too close to the actual SMBs for
my comfort)

--- samba-2.2.2/source/smbd/open.c.orig	Sat Oct 13 17:09:39 2001
+++ samba-2.2.2/source/smbd/open.c	Fri Dec 14 19:47:53 2001
@@ -95,6 +95,10 @@
 	pstring fname;
 	int accmode = (flags & O_ACCMODE);
 	int local_flags = flags;
+	/* flag whether we create a new file so modes can be reset if so
+	 * (but not otherwise)
+	 */
+	BOOL created;
 
 	fsp->fd = -1;
 	fsp->oplock_type = NO_OPLOCK;
@@ -167,7 +171,17 @@
 			fd_close(conn, fsp);
 			return False;
 		}
+		created = True; /* maybe. if we're in a race and have owner-
+				 * ship, we'll end up resetting the perms, so
+				 * hope we like whatever we chose this time */
 	}
+	else
+		created = False; /* maybe--unless it got unlinked out from
+				  * under us. it'd be nice to do another
+				  * fstat() here and make sure we're still
+				  * looking at the same inode, but that's
+				  * probably not buying much security, and
+				  * i'm not sure how sure we could get */
 
 	/*
 	 * POSIX allows read-only opens of directories. We don't
@@ -218,9 +232,10 @@
 
 	/*
 	 * Take care of inherited ACLs on created files. JRA.
+	 * IF we just created the file
 	 */
 
-	if ((flags & O_CREAT) && (conn->vfs_ops.fchmod_acl != NULL)) {
+	if (created && (conn->vfs_ops.fchmod_acl != NULL)) {
 		int saved_errno = errno; /* We might get ENOSYS in the next call.. */
 		if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
 			errno = saved_errno; /* Ignore ENOSYS */




More information about the samba-technical mailing list