1997-10-21 13:12:41 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
SMB client generic functions
1999-12-13 16:27:58 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
1997-10-21 13:12:41 +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 .
*/
1998-07-29 07:08:05 +04:00
# define NO_SYSLOG
1997-10-21 13:12:41 +04:00
# include "includes.h"
1999-12-13 16:27:58 +03:00
/*
* Change the port number used to call on
*/
1999-01-25 04:46:14 +03:00
int cli_set_port ( struct cli_state * cli , int port )
{
2001-08-25 00:11:09 +04:00
cli - > port = port ;
return port ;
1999-01-25 04:46:14 +03:00
}
1998-10-19 06:48:57 +04:00
1999-10-08 02:10:29 +04:00
/****************************************************************************
1999-12-13 16:27:58 +03:00
recv an smb
1999-10-08 02:10:29 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-25 18:04:06 +04:00
BOOL cli_receive_smb ( struct cli_state * cli )
1999-10-08 02:10:29 +04:00
{
1999-12-13 16:27:58 +03:00
BOOL ret ;
again :
ret = client_receive_smb ( cli - > fd , cli - > inbuf , cli - > timeout ) ;
if ( ret ) {
/* it might be an oplock break request */
2000-01-10 16:40:27 +03:00
if ( ! ( CVAL ( cli - > inbuf , smb_flg ) & FLAG_REPLY ) & &
CVAL ( cli - > inbuf , smb_com ) = = SMBlockingX & &
1999-12-13 16:27:58 +03:00
SVAL ( cli - > inbuf , smb_vwv6 ) = = 0 & &
SVAL ( cli - > inbuf , smb_vwv7 ) = = 0 ) {
2001-06-18 12:26:15 +04:00
if ( cli - > oplock_handler ) {
int fnum = SVAL ( cli - > inbuf , smb_vwv2 ) ;
unsigned char level = CVAL ( cli - > inbuf , smb_vwv3 + 1 ) ;
if ( ! cli - > oplock_handler ( cli , fnum , level ) ) return False ;
}
1999-12-13 16:27:58 +03:00
/* try to prevent loops */
CVAL ( cli - > inbuf , smb_com ) = 0xFF ;
goto again ;
1999-10-08 02:10:29 +04:00
}
}
1999-12-13 16:27:58 +03:00
return ret ;
1998-11-09 06:45:49 +03:00
}
1998-10-19 06:48:57 +04:00
/****************************************************************************
send an smb to a fd and re - establish if necessary
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-25 18:04:06 +04:00
BOOL cli_send_smb ( struct cli_state * cli )
1998-10-19 06:48:57 +04:00
{
size_t len ;
size_t nwritten = 0 ;
ssize_t ret ;
BOOL reestablished = False ;
1999-08-19 00:10:12 +04:00
len = smb_len ( cli - > outbuf ) + 4 ;
1998-10-19 06:48:57 +04:00
while ( nwritten < len ) {
ret = write_socket ( cli - > fd , cli - > outbuf + nwritten , len - nwritten ) ;
1999-12-13 16:27:58 +03:00
if ( ret < = 0 & & errno = = EPIPE & & ! reestablished ) {
1998-10-19 06:48:57 +04:00
if ( cli_reestablish_connection ( cli ) ) {
reestablished = True ;
nwritten = 0 ;
continue ;
}
}
if ( ret < = 0 ) {
2000-04-11 17:55:53 +04:00
DEBUG ( 0 , ( " Error writing %d bytes to client. %d \n " ,
1999-12-13 16:27:58 +03:00
( int ) len , ( int ) ret ) ) ;
2000-04-11 17:55:53 +04:00
return False ;
1998-10-19 06:48:57 +04:00
}
nwritten + = ret ;
}
return True ;
}
1999-12-13 16:27:58 +03:00
/****************************************************************************
setup basics in a outgoing packet
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-25 18:04:06 +04:00
void cli_setup_packet ( struct cli_state * cli )
1999-12-13 16:27:58 +03:00
{
cli - > rap_error = 0 ;
SSVAL ( cli - > outbuf , smb_pid , cli - > pid ) ;
SSVAL ( cli - > outbuf , smb_uid , cli - > vuid ) ;
SSVAL ( cli - > outbuf , smb_mid , cli - > mid ) ;
if ( cli - > protocol > PROTOCOL_CORE ) {
2001-02-20 11:09:06 +03:00
uint16 flags2 ;
1999-12-13 16:27:58 +03:00
SCVAL ( cli - > outbuf , smb_flg , 0x8 ) ;
2001-02-20 11:09:06 +03:00
flags2 = FLAGS2_LONG_PATH_COMPONENTS ;
2001-02-21 06:40:20 +03:00
if ( cli - > capabilities & CAP_UNICODE ) {
2001-02-20 11:09:06 +03:00
flags2 | = FLAGS2_UNICODE_STRINGS ;
}
2001-08-27 12:19:43 +04:00
if ( cli - > capabilities & CAP_STATUS32 ) {
flags2 | = FLAGS2_32_BIT_ERROR_CODES ;
}
2001-10-22 10:48:35 +04:00
if ( cli - > use_spnego ) {
flags2 | = FLAGS2_EXTENDED_SECURITY ;
}
2001-02-20 11:09:06 +03:00
SSVAL ( cli - > outbuf , smb_flg2 , flags2 ) ;
1999-12-13 16:27:58 +03:00
}
1999-06-24 22:58:08 +04:00
}
2001-02-20 15:45:50 +03:00
/****************************************************************************
setup the bcc length of the packet from a pointer to the end of the data
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void cli_setup_bcc ( struct cli_state * cli , void * p )
{
set_message_bcc ( cli - > outbuf , PTR_DIFF ( p , smb_buf ( cli - > outbuf ) ) ) ;
}
1999-12-13 16:27:58 +03:00
1999-06-24 22:58:08 +04:00
2000-07-03 08:24:31 +04:00
/****************************************************************************
initialise a client structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void cli_init_creds ( struct cli_state * cli , const struct ntuser_creds * usr )
{
/* copy_nt_creds(&cli->usr, usr); */
safe_strcpy ( cli - > domain , usr - > domain , sizeof ( usr - > domain ) - 1 ) ;
safe_strcpy ( cli - > user_name , usr - > user_name , sizeof ( usr - > user_name ) - 1 ) ;
memcpy ( & cli - > pwd , & usr - > pwd , sizeof ( usr - > pwd ) ) ;
cli - > ntlmssp_flags = usr - > ntlmssp_flags ;
cli - > ntlmssp_cli_flgs = usr ! = NULL ? usr - > ntlmssp_flags : 0 ;
DEBUG ( 10 , ( " cli_init_creds: user %s domain %s flgs: %x \n ntlmssp_cli_flgs:%x \n " ,
cli - > user_name , cli - > domain ,
cli - > ntlmssp_flags , cli - > ntlmssp_cli_flgs ) ) ;
}
1999-12-13 16:27:58 +03:00
1998-04-24 00:12:17 +04:00
/****************************************************************************
2000-04-25 18:04:06 +04:00
initialise a client structure
1998-04-24 00:12:17 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-25 18:04:06 +04:00
struct cli_state * cli_initialise ( struct cli_state * cli )
1998-04-24 00:12:17 +04:00
{
2001-08-07 03:29:25 +04:00
BOOL alloced_cli = False ;
2001-10-31 04:52:34 +03:00
/* Check the effective uid - make sure we are not setuid */
if ( is_setuid_root ( ) ) {
DEBUG ( 0 , ( " libsmb based programs must *NOT* be setuid root. \n " ) ) ;
return NULL ;
}
2000-04-25 18:04:06 +04:00
if ( ! cli ) {
cli = ( struct cli_state * ) malloc ( sizeof ( * cli ) ) ;
if ( ! cli )
return NULL ;
ZERO_STRUCTP ( cli ) ;
2001-08-07 03:29:25 +04:00
alloced_cli = True ;
Makefile.in :
- added srvsvc client files
clientgen.c :
- replaced cli_error(cli, int *cls, int *err) with
cli_error(cli, uint8 cls, uint32 *err). this version detects
32 bit status messages. the DOS error "MORE_DATA", the
equivalent of the 32 bit *warning* 0x8000 0005
(STATUS_BUFFER_OVERFLOW), was being processed as an error,
terminating the cli_receive_trans() call.
cli_pipe.c :
- replaced calls that had been incorrectly modified from
32 bit warnings (0x8000 0005 - STATUS_BUFFER_OVERFLOW)
to 8 bit DOS errors (0x01 0xEA - MORE_DATA).
the use of the old version of cli_error (DOS only)
instead of the new one (DOS and 32 bit) caused the
dce/rpc client code to fail.
- replaced 2 space indentation with tab indentation in all functions.
cli_srvsvc.c :
cmd_srvsvc.c :
- added these files back in, fixing them up to use jeremy's
modified versions of the dce/rpc client functions.
parse_srv.c :
- added back in some "unused" functions required by dce/rpc
client-side code. it would be helpful if all such "unused"
functions could be added back in.
rpcclient.c :
- added "session", "file", "share", "connection" enumeration
functions back in. these are equivalent to nt's "NetXXXXXEnum"
Win32 (MSDN) functions.
- added "srvinfo" function back in. this is equivalent to
nt's NetServerGetInfo Win32 (MSDN) function.
(This used to be commit bcf39ffdcc64e049bca2d70a394a99976291e81d)
1998-10-03 01:09:23 +04:00
}
1998-04-24 02:59:19 +04:00
2000-04-25 18:04:06 +04:00
if ( cli - > initialised ) {
cli_shutdown ( cli ) ;
1999-06-24 22:58:08 +04:00
}
1999-10-08 02:10:29 +04:00
2000-04-25 18:04:06 +04:00
ZERO_STRUCTP ( cli ) ;
1999-12-13 16:27:58 +03:00
2000-04-25 18:04:06 +04:00
cli - > port = 0 ;
cli - > fd = - 1 ;
cli - > cnum = - 1 ;
2000-05-02 06:23:41 +04:00
cli - > pid = ( uint16 ) sys_getpid ( ) ;
2000-04-25 18:04:06 +04:00
cli - > mid = 1 ;
cli - > vuid = UID_FIELD_INVALID ;
cli - > protocol = PROTOCOL_NT1 ;
cli - > timeout = 20000 ; /* Timeout is in milliseconds. */
cli - > bufsize = CLI_BUFFER_SIZE + 4 ;
cli - > max_xmit = cli - > bufsize ;
cli - > outbuf = ( char * ) malloc ( cli - > bufsize ) ;
cli - > inbuf = ( char * ) malloc ( cli - > bufsize ) ;
2001-06-18 12:26:15 +04:00
cli - > oplock_handler = cli_oplock_ack ;
2001-10-22 10:48:35 +04:00
cli - > use_spnego = True ;
2001-06-18 12:26:15 +04:00
2000-04-25 18:04:06 +04:00
if ( ! cli - > outbuf | | ! cli - > inbuf )
2001-08-06 06:18:40 +04:00
goto error ;
1997-10-26 10:32:02 +03:00
2001-08-06 06:18:40 +04:00
if ( ( cli - > mem_ctx = talloc_init ( ) ) = = NULL )
goto error ;
2000-07-27 04:47:19 +04:00
2001-08-06 06:18:40 +04:00
memset ( cli - > outbuf , 0 , cli - > bufsize ) ;
memset ( cli - > inbuf , 0 , cli - > bufsize ) ;
1997-10-26 10:32:02 +03:00
2001-05-04 11:28:41 +04:00
cli - > nt_pipe_fnum = 0 ;
2000-04-25 18:04:06 +04:00
cli - > initialised = 1 ;
1997-10-26 10:32:02 +03:00
2000-04-25 18:04:06 +04:00
return cli ;
2001-08-06 06:18:40 +04:00
/* Clean up after malloc() error */
error :
2001-09-17 07:33:37 +04:00
SAFE_FREE ( cli - > inbuf ) ;
SAFE_FREE ( cli - > outbuf ) ;
2001-08-06 06:18:40 +04:00
2001-08-07 03:29:25 +04:00
if ( alloced_cli )
2001-09-17 07:33:37 +04:00
SAFE_FREE ( cli ) ;
2001-08-07 03:29:25 +04:00
2001-08-06 06:18:40 +04:00
return NULL ;
1997-10-26 10:32:02 +03:00
}
1997-10-21 13:12:41 +04:00
/****************************************************************************
2000-04-25 18:04:06 +04:00
shutdown a client structure
1997-10-21 13:12:41 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-25 18:04:06 +04:00
void cli_shutdown ( struct cli_state * cli )
1997-10-21 13:12:41 +04:00
{
2001-09-17 07:33:37 +04:00
SAFE_FREE ( cli - > outbuf ) ;
SAFE_FREE ( cli - > inbuf ) ;
2000-07-27 04:47:19 +04:00
2001-10-17 12:54:19 +04:00
data_blob_free ( & cli - > secblob ) ;
2001-10-11 11:42:52 +04:00
2000-07-27 04:47:19 +04:00
if ( cli - > mem_ctx )
talloc_destroy ( cli - > mem_ctx ) ;
2000-04-25 18:04:06 +04:00
# ifdef WITH_SSL
2001-10-11 11:42:52 +04:00
if ( cli - > fd ! = - 1 )
sslutil_disconnect ( cli - > fd ) ;
2000-04-25 18:04:06 +04:00
# endif /* WITH_SSL */
if ( cli - > fd ! = - 1 )
2001-10-11 11:42:52 +04:00
close ( cli - > fd ) ;
2000-04-25 18:04:06 +04:00
memset ( cli , 0 , sizeof ( * cli ) ) ;
1997-10-21 13:12:41 +04:00
}
/****************************************************************************
2000-04-25 18:04:06 +04:00
set socket options on a open connection
1997-10-21 13:12:41 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-25 18:04:06 +04:00
void cli_sockopt ( struct cli_state * cli , char * options )
1997-10-21 13:12:41 +04:00
{
2000-04-25 18:04:06 +04:00
set_socket_options ( cli - > fd , options ) ;
1997-10-21 13:12:41 +04:00
}
1997-11-30 05:58:34 +03:00
/****************************************************************************
2000-04-25 18:04:06 +04:00
set the PID to use for smb messages . Return the old pid .
1997-11-30 05:58:34 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-04-25 18:04:06 +04:00
uint16 cli_setpid ( struct cli_state * cli , uint16 pid )
1997-11-30 05:58:34 +03:00
{
2000-04-25 18:04:06 +04:00
uint16 ret = cli - > pid ;
cli - > pid = pid ;
return ret ;
1997-11-30 05:58:34 +03:00
}