2005-02-06 08:25:53 +00:00
/*
Unix SMB / CIFS implementation .
wins client name registration and refresh
Copyright ( C ) Andrew Tridgell 2005
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"
# include "nbt_server/nbt_server.h"
# include "libcli/raw/libcliraw.h"
# include "libcli/composite/composite.h"
# include "lib/events/events.h"
# include "smbd/service_task.h"
2005-02-08 01:09:21 +00:00
/* we send WINS client requests using our primary network interface
*/
static struct nbt_name_socket * wins_socket ( struct nbtd_interface * iface )
{
struct nbtd_server * nbtsrv = iface - > nbtsrv ;
return nbtsrv - > interfaces - > nbtsock ;
}
static void nbtd_wins_refresh ( struct event_context * ev , struct timed_event * te ,
struct timeval t , void * private ) ;
2005-02-06 08:25:53 +00:00
/*
2005-02-08 01:09:21 +00:00
retry a WINS name registration
2005-02-06 08:25:53 +00:00
*/
2005-02-08 01:09:21 +00:00
static void nbtd_wins_register_retry ( struct event_context * ev , struct timed_event * te ,
struct timeval t , void * private )
2005-02-06 08:25:53 +00:00
{
struct nbtd_iface_name * iname = talloc_get_type ( private , struct nbtd_iface_name ) ;
2005-02-08 01:09:21 +00:00
nbtd_winsclient_register ( iname ) ;
2005-02-06 08:25:53 +00:00
}
2005-02-08 01:09:21 +00:00
2005-02-06 08:25:53 +00:00
/*
called when a wins name refresh has completed
*/
2005-02-08 01:09:21 +00:00
static void nbtd_wins_refresh_handler ( struct composite_context * c )
2005-02-06 08:25:53 +00:00
{
NTSTATUS status ;
struct nbt_name_refresh_wins io ;
struct nbtd_iface_name * iname = talloc_get_type ( c - > async . private ,
struct nbtd_iface_name ) ;
TALLOC_CTX * tmp_ctx = talloc_new ( iname ) ;
status = nbt_name_refresh_wins_recv ( c , tmp_ctx , & io ) ;
2005-02-08 01:09:21 +00:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_IO_TIMEOUT ) ) {
/* our WINS server is dead - start registration over
from scratch */
DEBUG ( 2 , ( " Failed to refresh %s<%02x> with WINS server %s \n " ,
iname - > name . name , iname - > name . type , iname - > wins_server ) ) ;
nbtd_winsclient_register ( iname ) ;
return ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " Name refresh failure with WINS for %s<%02x> - %s \n " ,
iname - > name . name , iname - > name . type , nt_errstr ( status ) ) ) ;
talloc_free ( tmp_ctx ) ;
return ;
}
if ( io . out . rcode ! = 0 ) {
DEBUG ( 1 , ( " WINS server %s rejected name refresh of %s<%02x> - %s \n " ,
io . out . wins_server , iname - > name . name , iname - > name . type ,
nt_errstr ( nbt_rcode_to_ntstatus ( io . out . rcode ) ) ) ) ;
iname - > nb_flags | = NBT_NM_CONFLICT ;
talloc_free ( tmp_ctx ) ;
return ;
}
DEBUG ( 4 , ( " Refreshed name %s<%02x> with WINS server %s \n " ,
iname - > name . name , iname - > name . type , iname - > wins_server ) ) ;
/* success - start a periodic name refresh */
iname - > nb_flags | = NBT_NM_ACTIVE ;
if ( iname - > wins_server ) {
talloc_free ( iname - > wins_server ) ;
}
iname - > wins_server = talloc_steal ( iname , io . out . wins_server ) ;
iname - > registration_time = timeval_current ( ) ;
event_add_timed ( iname - > iface - > nbtsrv - > task - > event_ctx ,
iname ,
timeval_add ( & iname - > registration_time , iname - > ttl / 2 , 0 ) ,
nbtd_wins_refresh ,
iname ) ;
talloc_free ( tmp_ctx ) ;
}
/*
refresh a WINS name registration
*/
static void nbtd_wins_refresh ( struct event_context * ev , struct timed_event * te ,
struct timeval t , void * private )
{
struct nbtd_iface_name * iname = talloc_get_type ( private , struct nbtd_iface_name ) ;
struct nbtd_interface * iface = iname - > iface ;
struct nbt_name_refresh_wins io ;
struct composite_context * c ;
TALLOC_CTX * tmp_ctx = talloc_new ( iname ) ;
/* setup a wins name refresh request */
io . in . name = iname - > name ;
io . in . wins_servers = str_list_make ( tmp_ctx , iname - > wins_server , NULL ) ;
io . in . addresses = nbtd_address_list ( iface , tmp_ctx ) ;
io . in . nb_flags = iname - > nb_flags ;
io . in . ttl = iname - > ttl ;
c = nbt_name_refresh_wins_send ( wins_socket ( iface ) , & io ) ;
if ( c = = NULL ) {
talloc_free ( tmp_ctx ) ;
return ;
}
talloc_steal ( c , io . in . addresses ) ;
c - > async . fn = nbtd_wins_refresh_handler ;
c - > async . private = iname ;
talloc_free ( tmp_ctx ) ;
}
/*
called when a wins name register has completed
*/
static void nbtd_wins_register_handler ( struct composite_context * c )
{
NTSTATUS status ;
struct nbt_name_register_wins io ;
struct nbtd_iface_name * iname = talloc_get_type ( c - > async . private ,
struct nbtd_iface_name ) ;
TALLOC_CTX * tmp_ctx = talloc_new ( iname ) ;
status = nbt_name_register_wins_recv ( c , tmp_ctx , & io ) ;
2005-02-06 08:25:53 +00:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_IO_TIMEOUT ) ) {
/* none of the WINS servers responded - try again
periodically */
2005-02-08 01:09:21 +00:00
int wins_retry_time = lp_parm_int ( - 1 , " nbtd " , " wins_retry " , 300 ) ;
2005-02-06 08:25:53 +00:00
event_add_timed ( iname - > iface - > nbtsrv - > task - > event_ctx ,
iname ,
timeval_current_ofs ( wins_retry_time , 0 ) ,
2005-02-08 01:09:21 +00:00
nbtd_wins_register_retry ,
2005-02-06 08:25:53 +00:00
iname ) ;
talloc_free ( tmp_ctx ) ;
return ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-02-08 01:09:21 +00:00
DEBUG ( 1 , ( " Name register failure with WINS for %s<%02x> - %s \n " ,
2005-02-06 08:25:53 +00:00
iname - > name . name , iname - > name . type , nt_errstr ( status ) ) ) ;
talloc_free ( tmp_ctx ) ;
return ;
}
if ( io . out . rcode ! = 0 ) {
2005-02-08 01:09:21 +00:00
DEBUG ( 1 , ( " WINS server %s rejected name register of %s<%02x> - %s \n " ,
io . out . wins_server , iname - > name . name , iname - > name . type ,
nt_errstr ( nbt_rcode_to_ntstatus ( io . out . rcode ) ) ) ) ;
2005-02-06 08:25:53 +00:00
iname - > nb_flags | = NBT_NM_CONFLICT ;
talloc_free ( tmp_ctx ) ;
return ;
}
/* success - start a periodic name refresh */
iname - > nb_flags | = NBT_NM_ACTIVE ;
if ( iname - > wins_server ) {
talloc_free ( iname - > wins_server ) ;
}
iname - > wins_server = talloc_steal ( iname , io . out . wins_server ) ;
iname - > registration_time = timeval_current ( ) ;
event_add_timed ( iname - > iface - > nbtsrv - > task - > event_ctx ,
iname ,
timeval_add ( & iname - > registration_time , iname - > ttl / 2 , 0 ) ,
2005-02-08 01:09:21 +00:00
nbtd_wins_refresh ,
2005-02-06 08:25:53 +00:00
iname ) ;
2005-02-08 01:09:21 +00:00
DEBUG ( 3 , ( " Registered %s<%02x> with WINS server %s \n " ,
iname - > name . name , iname - > name . type , iname - > wins_server ) ) ;
2005-02-06 08:25:53 +00:00
talloc_free ( tmp_ctx ) ;
}
/*
2005-02-08 01:09:21 +00:00
register a name with our WINS servers
2005-02-06 08:25:53 +00:00
*/
2005-02-08 01:09:21 +00:00
void nbtd_winsclient_register ( struct nbtd_iface_name * iname )
2005-02-06 08:25:53 +00:00
{
struct nbtd_interface * iface = iname - > iface ;
2005-02-08 01:09:21 +00:00
struct nbt_name_register_wins io ;
2005-02-06 08:25:53 +00:00
struct composite_context * c ;
2005-02-08 01:09:21 +00:00
/* setup a wins name register request */
2005-02-06 08:25:53 +00:00
io . in . name = iname - > name ;
io . in . wins_servers = lp_wins_server_list ( ) ;
2005-02-07 11:49:55 +00:00
io . in . addresses = nbtd_address_list ( iface , iname ) ;
2005-02-06 08:25:53 +00:00
io . in . nb_flags = iname - > nb_flags ;
io . in . ttl = iname - > ttl ;
2005-02-08 01:09:21 +00:00
c = nbt_name_register_wins_send ( wins_socket ( iface ) , & io ) ;
2005-02-06 08:25:53 +00:00
if ( c = = NULL ) {
talloc_free ( io . in . addresses ) ;
return ;
}
talloc_steal ( c , io . in . addresses ) ;
2005-02-08 01:09:21 +00:00
c - > async . fn = nbtd_wins_register_handler ;
2005-02-06 08:25:53 +00:00
c - > async . private = iname ;
}