1996-08-15 19:11:34 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
Pipe SMB reply routines
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1992 - 1998
Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1998
Copyright ( C ) Paul Ashton 1997 - 1998.
1996-08-15 19:11:34 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/*
This file handles reply_ calls on named pipes that the server
makes to handle specific protocols
*/
# include "includes.h"
# include "trans2.h"
# define PIPE "\\PIPE\\"
# define PIPELEN strlen(PIPE)
# define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
/* look in server.c for some explanation of these variables */
extern int Protocol ;
extern int DEBUGLEVEL ;
extern char magic_char ;
extern BOOL case_sensitive ;
extern pstring sesssetup_user ;
extern int Client ;
1997-10-30 04:05:13 +03:00
# define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
# define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open)
# define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
/* this macro should always be used to extract an pnum (smb_fid) from
a packet to ensure chaining works correctly */
# define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where))
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
extern struct pipe_id_info pipe_names [ ] ;
1996-08-15 19:11:34 +04:00
1997-10-30 04:05:13 +03:00
/****************************************************************************
reply to an open and X on a named pipe
1996-08-15 19:11:34 +04:00
This code is basically stolen from reply_open_and_X with some
wrinkles to handle pipes .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int reply_open_pipe_and_X ( char * inbuf , char * outbuf , int length , int bufsize )
{
pstring fname ;
1998-03-12 00:11:04 +03:00
uint16 cnum = SVAL ( inbuf , smb_tid ) ;
uint16 vuid = SVAL ( inbuf , smb_uid ) ;
1997-10-30 04:05:13 +03:00
int pnum = - 1 ;
1996-08-15 19:11:34 +04:00
int smb_ofun = SVAL ( inbuf , smb_vwv8 ) ;
int size = 0 , fmode = 0 , mtime = 0 , rmode = 0 ;
int i ;
/* XXXX we need to handle passed times, sattr and flags */
1997-09-26 22:55:29 +04:00
pstrcpy ( fname , smb_buf ( inbuf ) ) ;
1996-08-15 19:11:34 +04:00
/* If the name doesn't start \PIPE\ then this is directed */
/* at a mailslot or something we really, really don't understand, */
/* not just something we really don't understand. */
if ( strncmp ( fname , PIPE , PIPELEN ) ! = 0 )
return ( ERROR ( ERRSRV , ERRaccess ) ) ;
DEBUG ( 4 , ( " Opening pipe %s. \n " , fname ) ) ;
/* See if it is one we want to handle. */
1998-03-12 00:11:04 +03:00
for ( i = 0 ; pipe_names [ i ] . client_pipe ; i + + )
if ( strcmp ( fname , pipe_names [ i ] . client_pipe ) = = 0 )
1996-08-15 19:11:34 +04:00
break ;
1998-03-12 00:11:04 +03:00
if ( pipe_names [ i ] . client_pipe = = NULL )
1996-08-15 19:11:34 +04:00
return ( ERROR ( ERRSRV , ERRaccess ) ) ;
1998-03-12 00:11:04 +03:00
/* Strip \PIPE\ off the name. */
pstrcpy ( fname , smb_buf ( inbuf ) + PIPELEN ) ;
1996-08-15 19:11:34 +04:00
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
/* can be opened and add it in after the open. */
DEBUG ( 3 , ( " Known pipe %s opening. \n " , fname ) ) ;
smb_ofun | = 0x10 ; /* Add Create it not exists flag */
1998-03-12 00:11:04 +03:00
pnum = open_rpc_pipe_hnd ( fname , cnum , vuid ) ;
1997-10-30 04:05:13 +03:00
if ( pnum < 0 ) return ( ERROR ( ERRSRV , ERRnofids ) ) ;
1996-08-15 19:11:34 +04:00
/* Prepare the reply */
1996-08-19 15:17:29 +04:00
set_message ( outbuf , 15 , 0 , True ) ;
1996-08-15 19:11:34 +04:00
/* Mark the opened file as an existing named pipe in message mode. */
SSVAL ( outbuf , smb_vwv9 , 2 ) ;
SSVAL ( outbuf , smb_vwv10 , 0xc700 ) ;
1997-10-30 04:05:13 +03:00
1996-08-15 19:11:34 +04:00
if ( rmode = = 2 )
{
DEBUG ( 4 , ( " Resetting open result to open from create. \n " ) ) ;
rmode = 1 ;
}
1997-10-30 04:05:13 +03:00
SSVAL ( outbuf , smb_vwv2 , pnum + 0x800 ) ; /* mark file handle up into high range */
1996-08-15 19:11:34 +04:00
SSVAL ( outbuf , smb_vwv3 , fmode ) ;
put_dos_date3 ( outbuf , smb_vwv4 , mtime ) ;
SIVAL ( outbuf , smb_vwv6 , size ) ;
SSVAL ( outbuf , smb_vwv8 , rmode ) ;
1997-10-30 04:05:13 +03:00
SSVAL ( outbuf , smb_vwv11 , 0 ) ;
1996-08-15 19:11:34 +04:00
1996-08-19 15:17:29 +04:00
return chain_reply ( inbuf , outbuf , length , bufsize ) ;
1996-08-15 19:11:34 +04:00
}
1997-10-30 04:05:13 +03:00
/****************************************************************************
1998-03-12 00:11:04 +03:00
reply to a read and X
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
This code is basically stolen from reply_read_and_X with some
wrinkles to handle pipes .
1996-08-15 19:11:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-03-12 00:11:04 +03:00
int reply_pipe_read_and_X ( char * inbuf , char * outbuf , int length , int bufsize )
1996-08-15 19:11:34 +04:00
{
1998-03-12 00:11:04 +03:00
int pnum = get_rpc_pipe_num ( inbuf , smb_vwv2 ) ;
uint32 smb_offs = IVAL ( inbuf , smb_vwv3 ) ;
int smb_maxcnt = SVAL ( inbuf , smb_vwv5 ) ;
int smb_mincnt = SVAL ( inbuf , smb_vwv6 ) ;
int cnum ;
int nread = - 1 ;
char * data ;
BOOL ok = False ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
cnum = SVAL ( inbuf , smb_tid ) ;
1997-10-31 00:51:15 +03:00
1998-03-12 00:11:04 +03:00
/*
CHECK_FNUM ( fnum , cnum ) ;
CHECK_READ ( fnum ) ;
CHECK_ERROR ( fnum ) ;
*/
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
set_message ( outbuf , 12 , 0 , True ) ;
data = smb_buf ( outbuf ) ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
nread = read_pipe ( pnum , data , smb_offs , smb_maxcnt ) ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
ok = True ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
if ( nread < 0 )
return ( UNIXERROR ( ERRDOS , ERRnoaccess ) ) ;
SSVAL ( outbuf , smb_vwv5 , nread ) ;
SSVAL ( outbuf , smb_vwv6 , smb_offset ( data , outbuf ) ) ;
SSVAL ( smb_buf ( outbuf ) , - 2 , nread ) ;
DEBUG ( 3 , ( " %s readX pnum=%04x cnum=%d min=%d max=%d nread=%d \n " ,
timestring ( ) , pnum , cnum ,
smb_mincnt , smb_maxcnt , nread ) ) ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
set_chain_pnum ( pnum ) ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
return chain_reply ( inbuf , outbuf , length , bufsize ) ;
1996-08-15 19:11:34 +04:00
}
1998-03-12 00:11:04 +03:00
/****************************************************************************
reply to a close
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int reply_pipe_close ( char * inbuf , char * outbuf )
1996-08-15 19:11:34 +04:00
{
1998-03-12 00:11:04 +03:00
int pnum = get_rpc_pipe_num ( inbuf , smb_vwv0 ) ;
int cnum = SVAL ( inbuf , smb_tid ) ;
int outsize = set_message ( outbuf , 0 , 0 , True ) ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
DEBUG ( 5 , ( " reply_pipe_close: pnum:%x cnum:%x \n " , pnum , cnum ) ) ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
if ( ! close_rpc_pipe_hnd ( pnum , cnum ) ) return ( ERROR ( ERRDOS , ERRbadfid ) ) ;
1996-08-15 19:11:34 +04:00
1998-03-12 00:11:04 +03:00
return ( outsize ) ;
1996-08-15 19:11:34 +04:00
}
1997-10-15 20:51:03 +04:00