1997-12-13 17:16:07 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1997-12-13 17:16:07 +03:00
NBT netbios routines and daemon - version 2
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Luke Kenneth Casson Leighton 1994 - 1998
2003-08-27 05:25:01 +04:00
Copyright ( C ) Jeremy Allison 1994 - 2003
1997-12-13 17:16:07 +03: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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1997-12-13 17:16:07 +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/>.
1997-12-13 17:16:07 +03:00
*/
# include "includes.h"
2010-08-03 00:48:16 +04:00
# include "../librpc/gen_ndr/svcctl.h"
2010-08-18 17:22:09 +04:00
# include "nmbd/nmbd.h"
1997-12-13 17:16:07 +03:00
2015-04-30 06:14:34 +03:00
extern uint16_t samba_nb_type ; /* Samba's NetBIOS type. */
1997-12-13 17:16:07 +03:00
/****************************************************************************
Fail to become a Logon server on a subnet .
2003-08-27 05:25:01 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-12-13 17:16:07 +03:00
static void become_logon_server_fail ( struct subnet_record * subrec ,
struct response_record * rrec ,
struct nmb_name * fail_name )
{
2004-03-16 00:45:45 +03:00
unstring failname ;
2003-08-27 05:25:01 +04:00
struct work_record * work ;
struct server_record * servrec ;
2004-03-13 05:16:21 +03:00
pull_ascii_nstring ( failname , sizeof ( failname ) , fail_name - > name ) ;
2003-08-27 05:25:01 +04:00
work = find_workgroup_on_subnet ( subrec , failname ) ;
if ( ! work ) {
DEBUG ( 0 , ( " become_logon_server_fail: Error - cannot find \
workgroup % s on subnet % s \ n " , failname, subrec->subnet_name));
return ;
}
2011-06-09 09:31:03 +04:00
if ( ( servrec = find_server_in_workgroup ( work , lp_netbios_name ( ) ) ) = = NULL ) {
2003-08-27 05:25:01 +04:00
DEBUG ( 0 , ( " become_logon_server_fail: Error - cannot find server %s \
1997-12-13 17:16:07 +03:00
in workgroup % s on subnet % s \ n " ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , failname , subrec - > subnet_name ) ) ;
2003-08-27 05:25:01 +04:00
work - > log_state = LOGON_NONE ;
return ;
}
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
/* Set the state back to LOGON_NONE. */
work - > log_state = LOGON_NONE ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
servrec - > serv . type & = ~ SV_TYPE_DOMAIN_CTRL ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
DEBUG ( 0 , ( " become_logon_server_fail: Failed to become a domain master for \
1997-12-13 17:16:07 +03:00
workgroup % s on subnet % s . Couldn ' t register name % s . \ n " ,
2003-08-27 05:25:01 +04:00
work - > work_group , subrec - > subnet_name , nmb_namestr ( fail_name ) ) ) ;
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Become a Logon server on a subnet .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void become_logon_server_success ( struct subnet_record * subrec ,
struct userdata_struct * userdata ,
struct nmb_name * registered_name ,
2015-04-30 06:14:34 +03:00
uint16_t nb_flags ,
1997-12-13 17:16:07 +03:00
int ttl , struct in_addr registered_ip )
{
2004-03-16 00:45:45 +03:00
unstring reg_name ;
2003-08-27 05:25:01 +04:00
struct work_record * work ;
struct server_record * servrec ;
2004-03-13 05:16:21 +03:00
pull_ascii_nstring ( reg_name , sizeof ( reg_name ) , registered_name - > name ) ;
2003-08-27 05:25:01 +04:00
work = find_workgroup_on_subnet ( subrec , reg_name ) ;
if ( ! work ) {
DEBUG ( 0 , ( " become_logon_server_success: Error - cannot find \
workgroup % s on subnet % s \ n " , reg_name, subrec->subnet_name));
return ;
}
2011-06-09 09:31:03 +04:00
if ( ( servrec = find_server_in_workgroup ( work , lp_netbios_name ( ) ) ) = = NULL ) {
2003-08-27 05:25:01 +04:00
DEBUG ( 0 , ( " become_logon_server_success: Error - cannot find server %s \
1997-12-13 17:16:07 +03:00
in workgroup % s on subnet % s \ n " ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , reg_name , subrec - > subnet_name ) ) ;
2003-08-27 05:25:01 +04:00
work - > log_state = LOGON_NONE ;
return ;
}
/* Set the state in the workgroup structure. */
work - > log_state = LOGON_SRV ; /* Become domain master. */
/* Update our server status. */
servrec - > serv . type | = ( SV_TYPE_NT | SV_TYPE_DOMAIN_MEMBER ) ;
/* To allow Win95 policies to load we need to set type domain
controller .
*/
servrec - > serv . type | = SV_TYPE_DOMAIN_CTRL ;
/* Tell the namelist writer to write out a change. */
subrec - > work_changed = True ;
/*
* Add the WORKGROUP < 1 C > name to the UNICAST subnet with the IP address
* for this subnet so we will respond to queries on this name .
*/
{
struct nmb_name nmbname ;
make_nmb_name ( & nmbname , lp_workgroup ( ) , 0x1c ) ;
insert_permanent_name_into_unicast ( subrec , & nmbname , 0x1c ) ;
}
DEBUG ( 0 , ( " become_logon_server_success: Samba is now a logon server \
1997-12-13 17:16:07 +03:00
for workgroup % s on subnet % s \ n " , work->work_group, subrec->subnet_name));
}
/*******************************************************************
Become a logon server by attempting to register the WORKGROUP < 1 c >
group name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void become_logon_server ( struct subnet_record * subrec ,
struct work_record * work )
{
2003-08-27 05:25:01 +04:00
DEBUG ( 2 , ( " become_logon_server: Atempting to become logon server for workgroup %s \
1997-12-13 17:16:07 +03:00
on subnet % s \ n " , work->work_group,subrec->subnet_name));
2003-08-27 05:25:01 +04:00
DEBUG ( 3 , ( " become_logon_server: go to first stage: register %s<1c> name \n " ,
work - > work_group ) ) ;
work - > log_state = LOGON_WAIT ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
register_name ( subrec , work - > work_group , 0x1c , samba_nb_type | NB_GROUP ,
become_logon_server_success ,
become_logon_server_fail , NULL ) ;
1997-12-13 17:16:07 +03:00
}
/*****************************************************************************
Add the internet group < 1 c > logon names by unicast and broadcast .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-27 05:25:01 +04:00
1997-12-13 17:16:07 +03:00
void add_logon_names ( void )
{
2003-08-27 05:25:01 +04:00
struct subnet_record * subrec ;
for ( subrec = FIRST_SUBNET ; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST ( subrec ) ) {
struct work_record * work = find_workgroup_on_subnet ( subrec , lp_workgroup ( ) ) ;
if ( work & & ( work - > log_state = = LOGON_NONE ) ) {
struct nmb_name nmbname ;
make_nmb_name ( & nmbname , lp_workgroup ( ) , 0x1c ) ;
if ( find_name_on_subnet ( subrec , & nmbname , FIND_SELF_NAME ) = = NULL ) {
if ( DEBUGLVL ( 0 ) ) {
dbgtext ( " add_domain_logon_names: \n " ) ;
dbgtext ( " Attempting to become logon server " ) ;
dbgtext ( " for workgroup %s " , lp_workgroup ( ) ) ;
dbgtext ( " on subnet %s \n " , subrec - > subnet_name ) ;
}
become_logon_server ( subrec , work ) ;
}
}
}
1997-12-13 17:16:07 +03:00
}