[Samba] PATCH - smbd/trans2.c to support writing to Unix named pipes(FIFO)

Steve Williams intsteve at genie96.com
Fri Mar 1 15:45:07 GMT 2002


Hi,

We have a simple "Remote Procedure Call" mechanism that we are using to
communicate between Windows computers and our Unix Samba server.

The Windows application is proprietary software (Progress - not ours) and
we have to work within the constraints of it.

We have a Unix named pipe sitting in a Samba shared directory.  We have a
small C program that runs as a Unix daemon, listening for input from the
pipe file and performing tasks based on what is written to the pipe file by
the Windows client.  ( Unix system: mknod some_fifo p )

The windows clients just see a "file" in a share on the Unix box, open it,
write to it, close it, and magic, we have a very simple RPC style API that
works with almost every windows application (including VBScript in MS
Word!).

This has been working for years using Windows 9X clients, talking to Samba
2.0.x, right up to 2.2.3a.  I have avoided NT clients to date, but
unfortunately, I finally must get this working on NT. 

NT seems to do something different that breaks this very simple interface.
( Tested with NT4 as well as NT5/Win2K.. no XP yet!)

Poking into the level 10 logfiles, the problem is in:

[2002/02/28 19:27:11, 3]
smbd/trans2.c:call_trans2qfilepathinfo(1560)           
  call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level =
258                    
[2002/02/28 19:27:11, 3]
lib/system.c:sys_lseek(146)                            
  sys_lseek with fd: 18, offset: 0, whence:
0                                   
  (the sys_lseek above line is something I added in....)
[2002/02/28 19:27:11, 3]
smbd/error.c:error_packet(91)                          
  error string = Illegal
seek                                                   
[2002/02/28 19:27:11, 3]
smbd/error.c:error_packet(103)                         
  error packet at smbd/trans2.c(1604) cmd=50 (SMBtrans2)
NT_STATUS_ACCESS_DENIED
[2002/02/28 19:27:11, 5]
lib/util.c:show_msg(275)                               


The problem is that system is trying to do an lseek on a pipefile, 
which, rightly so returns an error.  I have no idea why Windows 9X 
clients don't do this!

The code in question is in (samba 2.2.3a)
smbd/trans2.c:1603
----------------------------------------------------------------------
call_trans2qfilepathinfo:
----------------------------------------------------------------------
/*
* Original code - this is an open file.                
*/                                                     
CHECK_FSP(fsp,conn);                                    

fname = fsp->fsp_name;                                  
if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {                
        DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum,
strerror(errno)));
        return(UNIXERROR(ERRDOS,ERRbadfid));            
}                                                       
                                                                                
if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
	return(UNIXERROR(ERRDOS,ERRnoaccess));          

delete_pending = fsp->delete_on_close;                  
----------------------------------------------------------------------

The problem is the line that does the vfs_ops.lseek.  The FD is actually a
pipe which causes an error.

I have no idea what what a "TRANSACT2_QFILEINFO: level=258" call is
supposed to do,  but based the fact that it is returning the current offset
in the file, I am offering the following code as a potential enhancement.

I have tested this code, and it completely resolves my problem.  I have not
done any other regression testing, as I figure knowlegeable eyes should
have a look at it first & tell me that I am crazy!  I'll attach the code
snippet as a diff, but here it is inline in the email.

----------------------------------------------------------------------
/*
 * Original code - this is an open file.
 */
CHECK_FSP(fsp,conn);

fname = fsp->fsp_name;
if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
	DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
	return(UNIXERROR(ERRDOS,ERRbadfid));
}

/* If it is a FIFO, it should be safe to assume    
 * that the current position is always "0" in the  
 * file... by the very nature of a FIFO...         
 *                                                 
 * Steve Williams (steve at ware-solutions.com)       
 * Fri Mar  1 15:51:33 MST 2002                    
 */                                                
if(S_ISFIFO(sbuf.st_mode)){
	DEBUG(3,("Is a FIFO, assuming 0 for lseek"));
	pos=0;
} else if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
		return(UNIXERROR(ERRDOS,ERRnoaccess));

delete_pending = fsp->delete_on_close;
----------------------------------------------------------------------

I have used different applications to test my fix, but the simplified one
that I wrote is (compiled with gcc under cygwin on Win2K):

----------------------------------------------------------------------
main(int argc, char *argv[])
{
  int fd;
  
  int pos;

  if (argc != 2) {
    printf("Missing file specification\n");
    exit(1);
  }

  if ( (fd=open(argv[1],2)) < 0 ){
    perror("open");
    printf("unable to open file: %s\n", argv[0]);
    exit(1);
  }

  printf("Got fd: %d\n", fd);

  if ( (pos=lseek(fd,0,0)) == -1) {
    perror("seek");
    printf("Could not seek\n");
    exit(1);
  }

  printf("Got pos=%d\n", pos);

  if(write(fd,"ls\n",3) != 3){
    perror("write");
    printf("could not write\n");
    exit(1);
  }

  printf("Wrote pipefile fine\n");

  close(fd);
  exit(0);
}
----------------------------------------------------------------------
Running un-patched Samba 2.2.3a

$ ./a.exe /cygdrive/p/faxdir/FAXFIFO
Got fd: 3
Got pos=0
write: No space left on device
could not write



Running patched Samba 2.2.3a
$ ./a.exe /cygdrive/q/faxdir/FAXFIFO
Got fd: 3
Got pos=0
Wrote pipefile fine

and the logfile from my daemon on the unix system...

Date 3/1/2002 Time 15:06:15 - Complete string is *ls*
        Token at 0 is *ls*                           

So, the patched one seems to work fine.

As an aside, it's pretty amazing that the lseek itself isn't causing a
problem (maybe it's cached or something!), but the call that is causing the
problem is the WRITE statement???  I checked the samba logfiles & it is
indeed the write that is causing the seek to happen??  Oh well...


What do people think of this patch/issue?

Hopefully I've been clear enough describing this problem.

Thanks,
--                                                                   
        Steve Williams, Calgary, Alberta, Canada                     
        Ware Solutions                                               
        steve at ware-solutions.com                                     
                                                                     
"A man doesn't begin to attain wisdom until he recognizes that he is 
 no longer indispensable."                                           
- Admiral Richard E. Byrd ( 1888-1957 )




More information about the samba mailing list