2003-08-13 01:53:07 +00:00
/*
Unix SMB / CIFS implementation .
SMB client socket context management functions
2003-11-19 23:17:55 +00:00
Copyright ( C ) Andrew Tridgell 1994 - 2003
2003-08-13 01:53:07 +00:00
Copyright ( C ) James Myers 2003 < myersjj @ samba . org >
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 .
*/
# include "includes.h"
2004-11-01 01:03:22 +00:00
# include "libcli/raw/libcliraw.h"
2003-08-13 01:53:07 +00:00
/*
2004-08-04 13:23:35 +00:00
create a smbcli_socket context
2003-08-13 01:53:07 +00:00
*/
2004-09-28 05:44:59 +00:00
struct smbcli_socket * smbcli_sock_init ( TALLOC_CTX * mem_ctx )
2003-08-13 01:53:07 +00:00
{
2004-08-04 13:23:35 +00:00
struct smbcli_socket * sock ;
2003-08-13 01:53:07 +00:00
2004-09-28 05:44:59 +00:00
sock = talloc_p ( mem_ctx , struct smbcli_socket ) ;
2003-08-13 01:53:07 +00:00
if ( ! sock ) {
return NULL ;
}
2004-08-21 07:43:29 +00:00
ZERO_STRUCTP ( sock ) ;
2004-10-28 08:15:12 +00:00
sock - > sock = NULL ;
2003-11-26 21:57:29 +00:00
sock - > port = 0 ;
2004-09-26 11:30:20 +00:00
2003-08-13 01:53:07 +00:00
/* 20 second default timeout */
sock - > timeout = 20000 ;
2004-07-13 05:14:59 +00:00
sock - > hostname = NULL ;
2003-08-13 01:53:07 +00:00
return sock ;
}
/*
2004-08-04 13:23:35 +00:00
connect a smbcli_socket context to an IP / port pair
2003-08-13 01:53:07 +00:00
if port is 0 then choose 445 then 139
*/
2004-11-01 22:48:25 +00:00
BOOL smbcli_sock_connect ( struct smbcli_socket * sock , struct ipv4_addr * ip , int port )
2003-08-13 01:53:07 +00:00
{
2004-10-28 08:15:12 +00:00
NTSTATUS status ;
2003-08-13 01:53:07 +00:00
if ( port = = 0 ) {
2004-08-14 05:56:12 +00:00
int i ;
const char * * ports = lp_smb_ports ( ) ;
for ( i = 0 ; ports [ i ] ; i + + ) {
2004-08-19 11:37:36 +00:00
port = atoi ( ports [ i ] ) ;
2004-08-14 05:56:12 +00:00
if ( port ! = 0 & & smbcli_sock_connect ( sock , ip , port ) ) {
return True ;
}
}
return False ;
2003-08-13 01:53:07 +00:00
}
2004-10-28 08:15:12 +00:00
status = socket_create ( " ip " , SOCKET_TYPE_STREAM , & sock - > sock , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2004-07-23 06:40:49 +00:00
return False ;
}
2004-10-28 08:15:12 +00:00
talloc_steal ( sock , sock - > sock ) ;
2004-07-23 06:40:49 +00:00
2004-11-01 22:48:25 +00:00
status = socket_connect ( sock - > sock , NULL , 0 , sys_inet_ntoa ( * ip ) , port , 0 ) ;
2004-10-28 08:15:12 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( sock - > sock ) ;
sock - > sock = NULL ;
return False ;
}
sock - > dest_ip = * ip ;
sock - > port = port ;
socket_set_option ( sock - > sock , lp_socket_options ( ) , NULL ) ;
2004-07-23 06:40:49 +00:00
return True ;
2003-08-13 01:53:07 +00:00
}
2004-04-23 04:21:22 +00:00
/****************************************************************************
mark the socket as dead
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-08-04 13:23:35 +00:00
void smbcli_sock_dead ( struct smbcli_socket * sock )
2004-04-23 04:21:22 +00:00
{
2004-10-28 08:15:12 +00:00
if ( sock - > sock ! = NULL ) {
talloc_free ( sock - > sock ) ;
sock - > sock = NULL ;
2004-04-23 04:21:22 +00:00
}
}
2003-08-13 01:53:07 +00:00
/****************************************************************************
Set socket options on a open connection .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-08-04 13:23:35 +00:00
void smbcli_sock_set_options ( struct smbcli_socket * sock , const char * options )
2003-08-13 01:53:07 +00:00
{
2004-10-28 08:15:12 +00:00
socket_set_option ( sock - > sock , options , NULL ) ;
2003-08-13 01:53:07 +00:00
}
/****************************************************************************
Write to socket . Return amount written .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-12-04 13:56:25 +00:00
ssize_t smbcli_sock_write ( struct smbcli_socket * sock , const uint8_t * data , size_t len )
2003-08-13 01:53:07 +00:00
{
2004-10-28 08:15:12 +00:00
NTSTATUS status ;
DATA_BLOB blob ;
size_t nsent ;
if ( sock - > sock = = NULL ) {
2004-04-23 04:21:22 +00:00
errno = EIO ;
return - 1 ;
}
2004-10-28 08:15:12 +00:00
blob . data = discard_const ( data ) ;
blob . length = len ;
status = socket_send ( sock - > sock , & blob , & nsent , 0 ) ;
if ( NT_STATUS_IS_ERR ( status ) ) {
return - 1 ;
}
return nsent ;
2003-08-13 01:53:07 +00:00
}
/****************************************************************************
Read from socket . return amount read
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-12-04 13:56:25 +00:00
ssize_t smbcli_sock_read ( struct smbcli_socket * sock , uint8_t * data , size_t len )
2003-08-13 01:53:07 +00:00
{
2004-10-28 08:15:12 +00:00
NTSTATUS status ;
size_t nread ;
if ( sock - > sock = = NULL ) {
2004-04-23 04:21:22 +00:00
errno = EIO ;
return - 1 ;
}
2004-10-28 08:15:12 +00:00
status = socket_recv ( sock - > sock , data , len , & nread , 0 ) ;
if ( NT_STATUS_IS_ERR ( status ) ) {
return - 1 ;
}
return nread ;
2003-08-13 01:53:07 +00:00
}
/****************************************************************************
resolve a hostname and connect
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-08-04 13:23:35 +00:00
BOOL smbcli_sock_connect_byname ( struct smbcli_socket * sock , const char * host , int port )
2003-08-13 01:53:07 +00:00
{
int name_type = 0x20 ;
2004-11-01 22:48:25 +00:00
struct ipv4_addr ip ;
2003-08-13 01:53:07 +00:00
char * name , * p ;
2004-07-13 05:14:59 +00:00
BOOL ret ;
2003-08-13 01:53:07 +00:00
2004-10-28 08:15:12 +00:00
#if 0
2003-08-13 01:53:07 +00:00
if ( getenv ( " LIBSMB_PROG " ) ) {
sock - > fd = sock_exec ( getenv ( " LIBSMB_PROG " ) ) ;
return sock - > fd ! = - 1 ;
}
2004-10-28 08:15:12 +00:00
# endif
2003-08-13 01:53:07 +00:00
2004-08-21 07:43:29 +00:00
name = talloc_strdup ( sock , host ) ;
2003-08-13 01:53:07 +00:00
/* allow hostnames of the form NAME#xx and do a netbios lookup */
if ( ( p = strchr ( name , ' # ' ) ) ) {
name_type = strtol ( p + 1 , NULL , 16 ) ;
* p = 0 ;
}
2004-08-21 07:43:29 +00:00
if ( ! resolve_name ( name , name , & ip , name_type ) ) {
talloc_free ( name ) ;
2003-08-13 01:53:07 +00:00
return False ;
}
2004-08-04 13:23:35 +00:00
ret = smbcli_sock_connect ( sock , & ip , port ) ;
2004-07-13 05:14:59 +00:00
if ( ret ) {
2004-08-21 07:43:29 +00:00
sock - > hostname = talloc_steal ( sock , name ) ;
2004-08-25 02:07:53 +00:00
} else {
talloc_free ( name ) ;
2004-07-13 05:14:59 +00:00
}
return ret ;
2003-08-13 01:53:07 +00:00
}