2001-01-03 08:19:21 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-01-03 08:19:21 +03:00
client dgram calls
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Richard Sharpe 2001
Copyright ( C ) John Terpstra 2001
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2001-01-03 08:19:21 +03:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2001-01-03 08:19:21 +03:00
*/
# include "includes.h"
/*
* cli_send_mailslot , send a mailslot for client code . . .
*/
2007-10-19 04:40:25 +04:00
bool cli_send_mailslot ( struct messaging_context * msg_ctx ,
bool unique , const char * mailslot ,
2005-06-09 02:10:34 +04:00
uint16 priority ,
char * buf , int len ,
2007-10-25 01:16:54 +04:00
const char * srcname , int src_type ,
2005-06-09 02:10:34 +04:00
const char * dstname , int dest_type ,
2007-10-25 01:16:54 +04:00
const struct sockaddr_storage * dest_ss )
2001-01-03 08:19:21 +03:00
{
2005-06-09 02:10:34 +04:00
struct packet_struct p ;
struct dgram_packet * dgram = & p . packet . dgram ;
char * ptr , * p2 ;
char tmp [ 4 ] ;
pid_t nmbd_pid ;
2007-10-25 01:16:54 +04:00
char addr [ INET6_ADDRSTRLEN ] ;
2005-06-09 02:10:34 +04:00
if ( ( nmbd_pid = pidfile_pid ( " nmbd " ) ) = = 0 ) {
DEBUG ( 3 , ( " No nmbd found \n " ) ) ;
return False ;
}
2007-10-25 01:16:54 +04:00
if ( dest_ss - > ss_family ! = AF_INET ) {
DEBUG ( 3 , ( " cli_send_mailslot: can't send to IPv6 address. \n " ) ) ;
return false ;
}
2005-06-09 02:10:34 +04:00
memset ( ( char * ) & p , ' \0 ' , sizeof ( p ) ) ;
/*
* Next , build the DGRAM . . .
*/
/* DIRECT GROUP or UNIQUE datagram. */
2007-10-25 01:16:54 +04:00
dgram - > header . msg_type = unique ? 0x10 : 0x11 ;
2005-06-09 02:10:34 +04:00
dgram - > header . flags . node_type = M_NODE ;
dgram - > header . flags . first = True ;
dgram - > header . flags . more = False ;
dgram - > header . dgm_id = ( ( unsigned ) time ( NULL ) % ( unsigned ) 0x7FFF ) +
( ( unsigned ) sys_getpid ( ) % ( unsigned ) 100 ) ;
/* source ip is filled by nmbd */
dgram - > header . dgm_length = 0 ; /* Let build_dgram() handle this. */
dgram - > header . packet_offset = 0 ;
2007-10-25 01:16:54 +04:00
2005-06-09 02:10:34 +04:00
make_nmb_name ( & dgram - > source_name , srcname , src_type ) ;
make_nmb_name ( & dgram - > dest_name , dstname , dest_type ) ;
ptr = & dgram - > data [ 0 ] ;
/* Setup the smb part. */
ptr - = 4 ; /* XXX Ugliness because of handling of tcp SMB length. */
memcpy ( tmp , ptr , 4 ) ;
2007-10-11 00:34:30 +04:00
set_message ( ptr , 17 , strlen ( mailslot ) + 1 + len , True ) ;
2005-06-09 02:10:34 +04:00
memcpy ( ptr , tmp , 4 ) ;
SCVAL ( ptr , smb_com , SMBtrans ) ;
SSVAL ( ptr , smb_vwv1 , len ) ;
SSVAL ( ptr , smb_vwv11 , len ) ;
SSVAL ( ptr , smb_vwv12 , 70 + strlen ( mailslot ) ) ;
SSVAL ( ptr , smb_vwv13 , 3 ) ;
SSVAL ( ptr , smb_vwv14 , 1 ) ;
SSVAL ( ptr , smb_vwv15 , priority ) ;
SSVAL ( ptr , smb_vwv16 , 2 ) ;
p2 = smb_buf ( ptr ) ;
fstrcpy ( p2 , mailslot ) ;
2007-04-03 00:10:21 +04:00
p2 = skip_string ( ptr , MAX_DGRAM_SIZE , p2 ) ;
2007-03-31 02:25:08 +04:00
if ( ! p2 ) {
return False ;
}
2005-06-09 02:10:34 +04:00
memcpy ( p2 , buf , len ) ;
p2 + = len ;
dgram - > datasize = PTR_DIFF ( p2 , ptr + 4 ) ; /* +4 for tcp length. */
p . packet_type = DGRAM_PACKET ;
2007-10-25 01:16:54 +04:00
p . ip = ( ( const struct sockaddr_in * ) & dest_ss ) - > sin_addr ;
2005-06-09 02:10:34 +04:00
p . timestamp = time ( NULL ) ;
DEBUG ( 4 , ( " send_mailslot: Sending to mailslot %s from %s " ,
mailslot , nmb_namestr ( & dgram - > source_name ) ) ) ;
2007-10-25 01:16:54 +04:00
print_sockaddr ( addr , sizeof ( addr ) , dest_ss ) ;
DEBUGADD ( 4 , ( " to %s IP %s \n " , nmb_namestr ( & dgram - > dest_name ) , addr ) ) ;
2005-06-09 02:10:34 +04:00
2007-05-15 17:56:00 +04:00
return NT_STATUS_IS_OK ( messaging_send_buf ( msg_ctx ,
pid_to_procid ( nmbd_pid ) ,
MSG_SEND_PACKET ,
( uint8 * ) & p , sizeof ( p ) ) ) ;
2001-01-03 08:19:21 +03:00
}
/*
* cli_get_response : Get a response . . .
*/
2007-10-19 04:40:25 +04:00
bool cli_get_response ( const char * mailslot , char * buf , int bufsiz )
2001-01-03 08:19:21 +03:00
{
2005-06-09 02:10:34 +04:00
struct packet_struct * p ;
2001-01-03 08:19:21 +03:00
2005-06-09 02:10:34 +04:00
p = receive_unexpected ( DGRAM_PACKET , 0 , mailslot ) ;
2001-01-03 08:19:21 +03:00
2005-06-09 02:10:34 +04:00
if ( p = = NULL )
return False ;
2001-01-03 08:19:21 +03:00
2005-06-09 02:10:34 +04:00
memcpy ( buf , & p - > packet . dgram . data [ 92 ] ,
MIN ( bufsiz , p - > packet . dgram . datasize - 92 ) ) ;
2001-02-26 14:53:22 +03:00
2005-06-09 02:10:34 +04:00
return True ;
2001-01-03 08:19:21 +03:00
}
/*
* cli_get_backup_list : Send a get backup list request . . .
*/
static char cli_backup_list [ 1024 ] ;
2007-05-15 17:56:00 +04:00
int cli_get_backup_list ( struct messaging_context * msg_ctx ,
const char * myname , const char * send_to_name )
2001-01-03 08:19:21 +03:00
{
2005-06-09 02:10:34 +04:00
pstring outbuf ;
char * p ;
2007-10-25 01:16:54 +04:00
struct sockaddr_storage sendto_ss ;
2001-02-19 05:17:27 +03:00
2007-10-25 01:16:54 +04:00
if ( ! resolve_name ( send_to_name , & sendto_ss , 0x1d ) ) {
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
DEBUG ( 0 , ( " Could not resolve name: %s<1D> \n " , send_to_name ) ) ;
return False ;
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
}
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
memset ( cli_backup_list , ' \0 ' , sizeof ( cli_backup_list ) ) ;
memset ( outbuf , ' \0 ' , sizeof ( outbuf ) ) ;
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
p = outbuf ;
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
SCVAL ( p , 0 , ANN_GetBackupListReq ) ;
p + + ;
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
SCVAL ( p , 0 , 1 ) ; /* Count pointer ... */
p + + ;
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
SIVAL ( p , 0 , 1 ) ; /* The sender's token ... */
p + = 4 ;
2001-02-19 05:17:27 +03:00
2007-05-15 17:56:00 +04:00
cli_send_mailslot ( msg_ctx , True , " \\ MAILSLOT \\ BROWSE " , 1 , outbuf ,
2005-06-09 02:10:34 +04:00
PTR_DIFF ( p , outbuf ) , myname , 0 , send_to_name ,
2007-10-25 01:16:54 +04:00
0x1d , & sendto_ss ) ;
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
/* We should check the error and return if we got one */
2001-02-19 05:17:27 +03:00
2005-06-09 02:10:34 +04:00
/* Now, get the response ... */
2001-01-03 08:19:21 +03:00
2005-06-09 02:10:34 +04:00
cli_get_response ( " \\ MAILSLOT \\ BROWSE " ,
cli_backup_list , sizeof ( cli_backup_list ) ) ;
2001-01-03 08:19:21 +03:00
2005-06-09 02:10:34 +04:00
return True ;
2001-02-26 14:53:22 +03:00
2001-01-03 08:19:21 +03:00
}
/*
* cli_get_backup_server : Get the backup list and retrieve a server from it
*/
2007-05-15 17:56:00 +04:00
int cli_get_backup_server ( struct messaging_context * msg_ctx ,
char * my_name , char * target , char * servername ,
int namesize )
2001-01-03 08:19:21 +03:00
{
/* Get the backup list first. We could pull this from the cache later */
2007-05-15 17:56:00 +04:00
cli_get_backup_list ( msg_ctx , my_name , target ) ; /* FIXME: Check the response */
2001-01-03 08:19:21 +03:00
2001-02-19 05:17:27 +03:00
if ( ! cli_backup_list [ 0 ] ) { /* Empty list ... try again */
2007-05-15 17:56:00 +04:00
cli_get_backup_list ( msg_ctx , my_name , target ) ;
2001-02-19 05:17:27 +03:00
}
2001-01-03 08:19:21 +03:00
strncpy ( servername , cli_backup_list , MIN ( 16 , namesize ) ) ;
2001-02-26 14:53:22 +03:00
return True ;
2001-01-03 08:19:21 +03:00
}