Bug & fix: call_trans2open returns some parameter fields wrong, causing client operations to fail

samba.10.maazl at spamgourmet.com samba.10.maazl at spamgourmet.com
Sat Aug 6 11:04:50 GMT 2005


To: samba-technical at samba.org, jra at samba.org


Symptom:

OS/2 Client application (e.g. FC/2) sometimes fails to create a new file 
on a samba share reporting "access denied".


Reason:

The (final) reply to trans2open leaves the parameter fileds open_access 
(offset 12) and open_type (offset 14) uninitialized. So the original 
values from the initial request are returned.


Fix:

- Return open_mode (=deny_mode) as open_access like Windows does.
- Clear open_type. This seems to be right for plain files. Most likely 
we must return something different here when opening sequential devices 
like pipes or character devices.

See attached diff.

You may ignore the first patch block, which is only a optimizition to 
keep the file system's fragmentation level low and to avoid late disk 
full or quota errors after several 100MB of data have been written. It 
did not find the way into the svn code so far.


Marcel
-------------- next part --------------
Index: smbd/trans2.c
===================================================================
--- smbd/trans2.c	(revision 9124)
+++ smbd/trans2.c	(working copy)
@@ -858,7 +858,25 @@
 		return(ERROR_DOS(ERRDOS,ERRnoaccess));
 	}
 
-	if (total_data && smb_action == FILE_WAS_CREATED) {
+   /* allocate space for the file if a size hint is supplied */
+	if (smb_action != FILE_WAS_OPENED && open_size && (open_size > size)) /* in case of create or overwrite only */
+	{
+		fsp->initial_allocation_size = smb_roundup(fsp->conn, open_size);
+		
+		if (fsp->is_directory) {
+			close_file(fsp,False);
+			END_PROFILE(SMBntcreateX);
+			/* Can't set allocation size on a directory. */
+			return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+		}
+		if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
+			close_file(fsp,False);
+			return ERROR_NT(NT_STATUS_DISK_FULL);
+		}
+	} else
+		fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)size);
+
+	if (total_data && smb_action != FILE_WAS_OPENED) { /* in case of create or overwrite only */
 		status = set_ea(conn, fsp, fname, ea_list);
 		talloc_destroy(ctx);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -878,8 +896,9 @@
 	SSVAL(params,2,open_attr);
 	put_dos_date2(params,4, mtime);
 	SIVAL(params,8, (uint32)size);
-	SSVAL(params,12,open_ofun);
-	SSVAL(params,16,0); /* Padding. */
+	SSVAL(params,12,deny_mode); /* I think open_ofun is not identical to the reply parameter open_access. Windows seems to return open_mode aka deny_mode here. */ 
+	SSVAL(params,14,0); /* open_type. 0 for ordinary files. I think we have to look for that again when opening something like pipes. */
+	SSVAL(params,16,0); /* open_state. 0 for ordinary files. I think we have to look for that again when opening something like pipes. */
 
 	if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
 		smb_action |= EXTENDED_OPLOCK_GRANTED;


More information about the samba-technical mailing list