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)
extern int DEBUGLEVEL ;
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-14 21:38:29 +04:00
int reply_open_pipe_and_X ( connection_struct * conn ,
char * inbuf , char * outbuf , int length , int bufsize )
1996-08-15 19:11:34 +04:00
{
1998-08-17 07:06:20 +04:00
pstring fname ;
uint16 vuid = SVAL ( inbuf , smb_uid ) ;
pipes_struct * p ;
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 */
pstrcpy ( fname , smb_buf ( inbuf ) ) ;
/* 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. */
for ( i = 0 ; pipe_names [ i ] . client_pipe ; i + + )
if ( strequal ( fname , pipe_names [ i ] . client_pipe ) )
break ;
if ( pipe_names [ i ] . client_pipe = = NULL )
return ( ERROR ( ERRSRV , ERRaccess ) ) ;
/* Strip \PIPE\ off the name. */
pstrcpy ( fname , smb_buf ( inbuf ) + PIPELEN ) ;
/* 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 */
p = open_rpc_pipe_p ( fname , conn , vuid ) ;
if ( ! p ) return ( ERROR ( ERRSRV , ERRnofids ) ) ;
/* Prepare the reply */
set_message ( outbuf , 15 , 0 , True ) ;
/* Mark the opened file as an existing named pipe in message mode. */
SSVAL ( outbuf , smb_vwv9 , 2 ) ;
SSVAL ( outbuf , smb_vwv10 , 0xc700 ) ;
if ( rmode = = 2 ) {
DEBUG ( 4 , ( " Resetting open result to open from create. \n " ) ) ;
rmode = 1 ;
}
SSVAL ( outbuf , smb_vwv2 , p - > pnum ) ;
SSVAL ( outbuf , smb_vwv3 , fmode ) ;
put_dos_date3 ( outbuf , smb_vwv4 , mtime ) ;
SIVAL ( outbuf , smb_vwv6 , size ) ;
SSVAL ( outbuf , smb_vwv8 , rmode ) ;
SSVAL ( outbuf , smb_vwv11 , 0 ) ;
return chain_reply ( inbuf , outbuf , length , bufsize ) ;
1996-08-15 19:11:34 +04:00
}
1998-10-07 19:22:49 +04:00
/****************************************************************************
reply to a write and X
This code is basically stolen from reply_write_and_X with some
wrinkles to handle pipes .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int reply_pipe_write_and_X ( char * inbuf , char * outbuf , int length , int bufsize )
{
pipes_struct * p = get_rpc_pipe_p ( inbuf , smb_vwv2 ) ;
uint32 smb_offs = IVAL ( inbuf , smb_vwv3 ) ;
size_t numtowrite = SVAL ( inbuf , smb_vwv10 ) ;
int nwritten = - 1 ;
int smb_doff = SVAL ( inbuf , smb_vwv11 ) ;
char * data ;
if ( ! p ) return ( ERROR ( ERRDOS , ERRbadfid ) ) ;
1998-10-08 01:42:24 +04:00
data = smb_base ( inbuf ) + smb_doff ;
1998-10-07 19:22:49 +04:00
if ( numtowrite = = 0 )
{
nwritten = 0 ;
}
else
{
nwritten = write_pipe ( p , data , numtowrite ) ;
}
if ( ( nwritten = = 0 & & numtowrite ! = 0 ) | | ( nwritten < 0 ) )
{
return ( UNIXERROR ( ERRDOS , ERRnoaccess ) ) ;
}
set_message ( outbuf , 6 , 0 , True ) ;
SSVAL ( outbuf , smb_vwv2 , nwritten ) ;
DEBUG ( 3 , ( " writeX-IPC pnum=%04x nwritten=%d \n " ,
p - > pnum , nwritten ) ) ;
return chain_reply ( inbuf , outbuf , length , bufsize ) ;
}
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-08-17 07:06:20 +04:00
pipes_struct * p = get_rpc_pipe_p ( 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 nread = - 1 ;
char * data ;
1996-08-15 19:11:34 +04:00
1998-09-01 05:10:01 +04:00
if ( ! p ) return ( ERROR ( ERRDOS , ERRbadfid ) ) ;
1998-08-17 07:06:20 +04:00
set_message ( outbuf , 12 , 0 , True ) ;
data = smb_buf ( outbuf ) ;
1996-08-15 19:11:34 +04:00
1998-08-17 07:06:20 +04:00
nread = read_pipe ( p , data , smb_offs , smb_maxcnt ) ;
1996-08-15 19:11:34 +04:00
1998-08-17 07:06:20 +04:00
if ( nread < 0 )
return ( UNIXERROR ( ERRDOS , ERRnoaccess ) ) ;
1998-03-12 00:11:04 +03:00
1998-08-17 07:06:20 +04:00
SSVAL ( outbuf , smb_vwv5 , nread ) ;
SSVAL ( outbuf , smb_vwv6 , smb_offset ( data , outbuf ) ) ;
SSVAL ( smb_buf ( outbuf ) , - 2 , nread ) ;
1998-03-12 00:11:04 +03:00
1998-10-07 19:22:49 +04:00
DEBUG ( 3 , ( " readX-IPC pnum=%04x min=%d max=%d nread=%d \n " ,
1998-08-17 07:06:20 +04:00
p - > pnum , smb_mincnt , smb_maxcnt , nread ) ) ;
1996-08-15 19:11:34 +04:00
1998-08-17 07:06:20 +04:00
return chain_reply ( inbuf , outbuf , length , bufsize ) ;
1996-08-15 19:11:34 +04:00
}
1998-10-07 19:22:49 +04:00
1998-03-12 00:11:04 +03:00
/****************************************************************************
reply to a close
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-14 21:38:29 +04:00
int reply_pipe_close ( connection_struct * conn , char * inbuf , char * outbuf )
1996-08-15 19:11:34 +04:00
{
1998-08-17 07:06:20 +04:00
pipes_struct * p = get_rpc_pipe_p ( inbuf , smb_vwv0 ) ;
int outsize = set_message ( outbuf , 0 , 0 , True ) ;
1996-08-15 19:11:34 +04:00
1998-09-01 05:10:01 +04:00
if ( ! p ) return ( ERROR ( ERRDOS , ERRbadfid ) ) ;
1998-08-17 07:06:20 +04:00
DEBUG ( 5 , ( " reply_pipe_close: pnum:%x \n " , p - > pnum ) ) ;
1996-08-15 19:11:34 +04:00
1998-08-17 07:06:20 +04:00
if ( ! close_rpc_pipe_hnd ( p , conn ) ) return ( ERROR ( ERRDOS , ERRbadfid ) ) ;
1996-08-15 19:11:34 +04:00
1998-08-17 07:06:20 +04:00
return ( outsize ) ;
1996-08-15 19:11:34 +04:00
}
1997-10-15 20:51:03 +04:00