1996-08-15 19:11:34 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
Pipe SMB reply routines
1997-10-07 18:58:07 +04:00
Copyright ( C ) Andrew Tridgell 1992 - 1997 ,
1997-10-09 19:48:40 +04:00
Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1997.
Copyright ( C ) Paul Ashton 1997.
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-05-20 04:32:51 +04:00
extern fstring myworkgroup ;
1996-08-15 19:11:34 +04:00
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
char * known_pipes [ ] =
{
1997-10-12 23:02:55 +04:00
" lsarpc " ,
1997-10-09 20:14:53 +04:00
# if NTDOMAIN
1997-10-07 18:58:07 +04:00
" NETLOGON " ,
1997-10-15 20:51:03 +04:00
" srvsvc " ,
following a cvs error, i am rewriting this monster-commit. with bad grace.
Modified Files:
---------------
Makefile:
adding extra files
ipc.c :
send_trans_reply() - alignment issue. this makes the alignment
the same as that in NT. this should be looked at by people who
understand the SMB stuff better than i.
api_fd_commands[] - added samr and wkssvc pipes.
loadparm.c :
lp_domain_controller() changed to mean "samba is a domain controller".
it's a "yes/no" parameter, now. no, it isn't used _anywhere_.
namedbwork.c nameelect.c :
if "domain controller = yes" then add SV_TYPE_DOMAIN_CTRL to the
host _and_ workgroup announcements. yes, you must do both: nt does.
namelogon.c :
important NETLOGON bug in SAMLOGON request parsing, which may be
the source of some people's problems with logging on to the Samba PDC.
password.c :
get_smbpwnam() renamed to get_smbpwd_entry().
pipes.c :
added samr and wkssvc pipes.
proto.h :
usual. can we actually _remove_ proto.h from the cvs tree, and
have it as one of the Makefile dependencies, or something?
reply.c :
get_smbpwnam() renamed to get_smbpwd_entry() - also changed response
error code when logging in from a WORKSTATION$ account. yes, paul
is right: we need to know when to return the right error code, and why.
server.c :
added call to reset_chain_pnum().
#ifdef NTDOMAIN added call to init_lsa_policy_hnd() #endif. jeremy,
you'd be proud: i did a compile without NTDOMAIN, and caught a link
error for this function.
smb.h :
defines and structures for samr and wkssvc pipes.
smbpass.c :
modified get_smbpwnam() to get_smbpwd_entry() and it now takes
two arguments. one for the name; if this is null, it looks up
by smb_userid instead.
oh, by the way, smb_userids are actually domain relative ids
(RIDs). concatenate a RID with the domain SID, and you have
an internet globally unique way of identifying a user.
we're using RIDs in the wrong way....
added mod_smbpwnam() function. this was based on code in smbpasswd.c
rpc_pipes/lsaparse.c :
added enum trusted domain parsing. this is incomplete: i need
a packet trace to write it properly.
rpc_pipes/pipe_hnd.c :
added reset_chain_pnum() function.
rpc_pipes/pipenetlog.c :
get_smbpwnam() function renamed to get_smbpwd_entry().
arcfour() issues.
removed capability of get_md4pw() function to automatically add
workstation accounts. this should either be done using
smbpasswd -add MACHINE$, or by using \PIPE\samr.
rpc_pipes/pipe_util.c :
create_pol_hnd() - creates a unique LSA Policy Handle. overkill
function: uses a 64 bit sequence number; current unix time and
the smbd pid.
rpc_pipes/smbparse.c :
arcfour() issues.
smb_io_unistr2() should advance by uni_str_len not uni_max_len.
smb_io_smb_hdr_rb() - request bind uses uint16 for the context
id, and uint8 for the num_syntaxes. oops, i put these both as
uint32s.
Added Files:
------------
rpc_pipes/lsa_hnd.c :
on the samr pipe, allocate and associate an LSA Policy Handle
with a SID. you receive queries with the LSA Policy Handle,
and have to turn this back into a SID in order to answer the
query...
rpc_pipes/pipesamr.c rpc_pipes/samrparse.c
\PIPE\samr processing. samr i presume is the SAM Replication pipe.
rpc_pipes/pipewkssvc.c rpc_pipes/wksparse.c
\PIPE\wkssvc processing. the Workstation Service pipe?
holy cow.
(This used to be commit 1bd084b3e690eb26a1006d616075e53d711ecd2f)
1997-11-07 02:03:58 +03:00
" wkssvc " ,
" samr " ,
1997-10-07 18:58:07 +04:00
# endif
1996-08-15 19:11:34 +04:00
NULL
} ;
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 ;
int cnum = SVAL ( inbuf , smb_tid ) ;
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 ) ) ;
/* Strip \PIPE\ off the name. */
1997-09-26 22:55:29 +04:00
pstrcpy ( fname , smb_buf ( inbuf ) + PIPELEN ) ;
1996-08-15 19:11:34 +04:00
/* See if it is one we want to handle. */
for ( i = 0 ; known_pipes [ i ] ; i + + )
if ( strcmp ( fname , known_pipes [ i ] ) = = 0 )
break ;
if ( known_pipes [ i ] = = NULL )
return ( ERROR ( ERRSRV , ERRaccess ) ) ;
/* 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 */
1997-10-30 20:08:42 +03:00
pnum = open_rpc_pipe_hnd ( fname , cnum ) ;
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
/****************************************************************************
reply to a close
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int reply_pipe_close ( char * inbuf , char * outbuf )
{
1997-10-30 20:08:42 +03:00
int pnum = get_rpc_pipe_num ( inbuf , smb_vwv0 ) ;
1997-10-30 04:05:13 +03:00
int cnum = SVAL ( inbuf , smb_tid ) ;
int outsize = set_message ( outbuf , 0 , 0 , True ) ;
following a cvs error, i am rewriting this monster-commit. with bad grace.
Modified Files:
---------------
Makefile:
adding extra files
ipc.c :
send_trans_reply() - alignment issue. this makes the alignment
the same as that in NT. this should be looked at by people who
understand the SMB stuff better than i.
api_fd_commands[] - added samr and wkssvc pipes.
loadparm.c :
lp_domain_controller() changed to mean "samba is a domain controller".
it's a "yes/no" parameter, now. no, it isn't used _anywhere_.
namedbwork.c nameelect.c :
if "domain controller = yes" then add SV_TYPE_DOMAIN_CTRL to the
host _and_ workgroup announcements. yes, you must do both: nt does.
namelogon.c :
important NETLOGON bug in SAMLOGON request parsing, which may be
the source of some people's problems with logging on to the Samba PDC.
password.c :
get_smbpwnam() renamed to get_smbpwd_entry().
pipes.c :
added samr and wkssvc pipes.
proto.h :
usual. can we actually _remove_ proto.h from the cvs tree, and
have it as one of the Makefile dependencies, or something?
reply.c :
get_smbpwnam() renamed to get_smbpwd_entry() - also changed response
error code when logging in from a WORKSTATION$ account. yes, paul
is right: we need to know when to return the right error code, and why.
server.c :
added call to reset_chain_pnum().
#ifdef NTDOMAIN added call to init_lsa_policy_hnd() #endif. jeremy,
you'd be proud: i did a compile without NTDOMAIN, and caught a link
error for this function.
smb.h :
defines and structures for samr and wkssvc pipes.
smbpass.c :
modified get_smbpwnam() to get_smbpwd_entry() and it now takes
two arguments. one for the name; if this is null, it looks up
by smb_userid instead.
oh, by the way, smb_userids are actually domain relative ids
(RIDs). concatenate a RID with the domain SID, and you have
an internet globally unique way of identifying a user.
we're using RIDs in the wrong way....
added mod_smbpwnam() function. this was based on code in smbpasswd.c
rpc_pipes/lsaparse.c :
added enum trusted domain parsing. this is incomplete: i need
a packet trace to write it properly.
rpc_pipes/pipe_hnd.c :
added reset_chain_pnum() function.
rpc_pipes/pipenetlog.c :
get_smbpwnam() function renamed to get_smbpwd_entry().
arcfour() issues.
removed capability of get_md4pw() function to automatically add
workstation accounts. this should either be done using
smbpasswd -add MACHINE$, or by using \PIPE\samr.
rpc_pipes/pipe_util.c :
create_pol_hnd() - creates a unique LSA Policy Handle. overkill
function: uses a 64 bit sequence number; current unix time and
the smbd pid.
rpc_pipes/smbparse.c :
arcfour() issues.
smb_io_unistr2() should advance by uni_str_len not uni_max_len.
smb_io_smb_hdr_rb() - request bind uses uint16 for the context
id, and uint8 for the num_syntaxes. oops, i put these both as
uint32s.
Added Files:
------------
rpc_pipes/lsa_hnd.c :
on the samr pipe, allocate and associate an LSA Policy Handle
with a SID. you receive queries with the LSA Policy Handle,
and have to turn this back into a SID in order to answer the
query...
rpc_pipes/pipesamr.c rpc_pipes/samrparse.c
\PIPE\samr processing. samr i presume is the SAM Replication pipe.
rpc_pipes/pipewkssvc.c rpc_pipes/wksparse.c
\PIPE\wkssvc processing. the Workstation Service pipe?
holy cow.
(This used to be commit 1bd084b3e690eb26a1006d616075e53d711ecd2f)
1997-11-07 02:03:58 +03:00
DEBUG ( 5 , ( " reply_pipe_close: pnum:%x cnum:%x \n " , pnum , cnum ) ) ;
1997-10-30 20:08:42 +03:00
if ( ! close_rpc_pipe_hnd ( pnum , cnum ) ) return ( ERROR ( ERRDOS , ERRbadfid ) ) ;
1997-10-30 04:05:13 +03:00
return ( outsize ) ;
}
1996-08-15 19:11:34 +04:00
/****************************************************************************
api_LsarpcSNPHS
1997-10-31 00:51:15 +03:00
SetNamedPipeHandleState on \ PIPE \ lsarpc .
1996-08-15 19:11:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-10-31 00:51:15 +03:00
BOOL api_LsarpcSNPHS ( int pnum , int cnum , char * param )
1996-08-15 19:11:34 +04:00
{
uint16 id ;
1997-10-31 00:51:15 +03:00
if ( ! param ) return False ;
1996-08-15 19:11:34 +04:00
id = param [ 0 ] + ( param [ 1 ] < < 8 ) ;
DEBUG ( 4 , ( " lsarpc SetNamedPipeHandleState to code %x \n " , id ) ) ;
1997-10-31 00:51:15 +03:00
return set_rpc_pipe_hnd_state ( pnum , cnum , id ) ;
1996-08-15 19:11:34 +04:00
}
/****************************************************************************
api_LsarpcTNP
TransactNamedPipe on \ PIPE \ lsarpc .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-10-29 03:04:14 +03:00
static void LsarpcTNP1 ( char * data , char * * rdata , int * rdata_len )
1996-08-15 19:11:34 +04:00
{
uint32 dword1 , dword2 ;
char pname [ ] = " \\ PIPE \\ lsass " ;
/* All kinds of mysterious numbers here */
* rdata_len = 68 ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
dword1 = IVAL ( data , 0xC ) ;
dword2 = IVAL ( data , 0x10 ) ;
SIVAL ( * rdata , 0 , 0xc0005 ) ;
SIVAL ( * rdata , 4 , 0x10 ) ;
SIVAL ( * rdata , 8 , 0x44 ) ;
SIVAL ( * rdata , 0xC , dword1 ) ;
SIVAL ( * rdata , 0x10 , dword2 ) ;
SIVAL ( * rdata , 0x14 , 0x15 ) ;
SSVAL ( * rdata , 0x18 , sizeof ( pname ) ) ;
strcpy ( * rdata + 0x1a , pname ) ;
SIVAL ( * rdata , 0x28 , 1 ) ;
memcpy ( * rdata + 0x30 , data + 0x34 , 0x14 ) ;
}
static void LsarpcTNP2 ( char * data , char * * rdata , int * rdata_len )
{
uint32 dword1 ;
/* All kinds of mysterious numbers here */
* rdata_len = 48 ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
dword1 = IVAL ( data , 0xC ) ;
SIVAL ( * rdata , 0 , 0x03020005 ) ;
SIVAL ( * rdata , 4 , 0x10 ) ;
SIVAL ( * rdata , 8 , 0x30 ) ;
SIVAL ( * rdata , 0xC , dword1 ) ;
SIVAL ( * rdata , 0x10 , 0x18 ) ;
SIVAL ( * rdata , 0x1c , 0x44332211 ) ;
SIVAL ( * rdata , 0x20 , 0x88776655 ) ;
SIVAL ( * rdata , 0x24 , 0xCCBBAA99 ) ;
SIVAL ( * rdata , 0x28 , 0x11FFEEDD ) ;
}
static void LsarpcTNP3 ( char * data , char * * rdata , int * rdata_len )
{
uint32 dword1 ;
uint16 word1 ;
1997-05-20 04:32:51 +04:00
char * workgroup = myworkgroup ;
1996-10-02 19:41:30 +04:00
int wglen = strlen ( workgroup ) ;
1996-08-15 19:11:34 +04:00
int i ;
/* All kinds of mysterious numbers here */
* rdata_len = 90 + 2 * wglen ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
dword1 = IVAL ( data , 0xC ) ;
word1 = SVAL ( data , 0x2C ) ;
SIVAL ( * rdata , 0 , 0x03020005 ) ;
SIVAL ( * rdata , 4 , 0x10 ) ;
SIVAL ( * rdata , 8 , 0x60 ) ;
SIVAL ( * rdata , 0xC , dword1 ) ;
SIVAL ( * rdata , 0x10 , 0x48 ) ;
SSVAL ( * rdata , 0x18 , 0x5988 ) ; /* This changes */
SSVAL ( * rdata , 0x1A , 0x15 ) ;
SSVAL ( * rdata , 0x1C , word1 ) ;
SSVAL ( * rdata , 0x20 , 6 ) ;
SSVAL ( * rdata , 0x22 , 8 ) ;
SSVAL ( * rdata , 0x24 , 0x8E8 ) ; /* So does this */
SSVAL ( * rdata , 0x26 , 0x15 ) ;
SSVAL ( * rdata , 0x28 , 0x4D48 ) ; /* And this */
SSVAL ( * rdata , 0x2A , 0x15 ) ;
SIVAL ( * rdata , 0x2C , 4 ) ;
SIVAL ( * rdata , 0x34 , wglen ) ;
for ( i = 0 ; i < wglen ; i + + )
1996-10-02 19:41:30 +04:00
( * rdata ) [ 0x38 + i * 2 ] = workgroup [ i ] ;
1996-08-15 19:11:34 +04:00
/* Now fill in the rest */
i = 0x38 + wglen * 2 ;
SSVAL ( * rdata , i , 0x648 ) ;
SIVAL ( * rdata , i + 2 , 4 ) ;
SIVAL ( * rdata , i + 6 , 0x401 ) ;
SSVAL ( * rdata , i + 0xC , 0x500 ) ;
SIVAL ( * rdata , i + 0xE , 0x15 ) ;
SIVAL ( * rdata , i + 0x12 , 0x2372FE1 ) ;
SIVAL ( * rdata , i + 0x16 , 0x7E831BEF ) ;
SIVAL ( * rdata , i + 0x1A , 0x4B454B2 ) ;
}
static void LsarpcTNP4 ( char * data , char * * rdata , int * rdata_len )
{
uint32 dword1 ;
/* All kinds of mysterious numbers here */
* rdata_len = 48 ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
dword1 = IVAL ( data , 0xC ) ;
SIVAL ( * rdata , 0 , 0x03020005 ) ;
SIVAL ( * rdata , 4 , 0x10 ) ;
SIVAL ( * rdata , 8 , 0x30 ) ;
SIVAL ( * rdata , 0xC , dword1 ) ;
SIVAL ( * rdata , 0x10 , 0x18 ) ;
}
BOOL api_LsarpcTNP ( int cnum , int uid , char * param , char * data ,
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len )
{
uint32 id , id2 ;
id = IVAL ( data , 0 ) ;
DEBUG ( 4 , ( " lsarpc TransactNamedPipe id %lx \n " , id ) ) ;
switch ( id )
{
case 0xb0005 :
LsarpcTNP1 ( data , rdata , rdata_len ) ;
break ;
case 0x03000005 :
id2 = IVAL ( data , 8 ) ;
DEBUG ( 4 , ( " \t - Suboperation %lx \n " , id2 ) ) ;
switch ( id2 & 0xF )
{
case 8 :
LsarpcTNP2 ( data , rdata , rdata_len ) ;
break ;
case 0xC :
LsarpcTNP4 ( data , rdata , rdata_len ) ;
break ;
case 0xE :
LsarpcTNP3 ( data , rdata , rdata_len ) ;
break ;
}
break ;
}
return ( True ) ;
}
1997-10-15 20:51:03 +04:00