2001-12-20 10:42:00 +03:00
/*
Samba Unix / Linux SMB client library
net lookup command
Copyright ( C ) 2001 Andrew Tridgell ( tridge @ 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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2001-12-20 10:42:00 +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-12-20 10:42:00 +03:00
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2001-12-20 10:42:00 +03:00
int net_lookup_usage ( int argc , const char * * argv )
{
d_printf (
2003-09-05 08:40:10 +04:00
" net lookup [host] HOSTNAME[#<type>] \n \t gives IP for a hostname \n \n "
2002-07-15 14:35:28 +04:00
" net lookup ldap [domain] \n \t gives IP of domain's ldap server \n \n "
" net lookup kdc [realm] \n \t gives IP of realm's kerberos KDC \n \n "
2007-08-28 19:01:23 +04:00
" net lookup pdc [domain|realm] \n \t gives IP of realm's kerberos KDC \n \n "
2002-07-15 14:35:28 +04:00
" net lookup dc [domain] \n \t gives IP of domains Domain Controllers \n \n "
" net lookup master [domain|wg] \n \t give IP of master browser \n \n "
2006-02-04 01:19:41 +03:00
" net lookup name [name] \n \t Lookup name's sid and type \n \n "
" net lookup sid [sid] \n \t Give sid's name and type \n \n "
2007-08-28 19:01:23 +04:00
" net lookup dsgetdcname [name] [flags] [sitename] \n \n "
2002-07-15 14:35:28 +04:00
) ;
2001-12-20 10:42:00 +03:00
return - 1 ;
}
/* lookup a hostname giving an IP */
static int net_lookup_host ( int argc , const char * * argv )
{
struct in_addr ip ;
int name_type = 0x20 ;
2003-09-05 08:40:10 +04:00
const char * name = argv [ 0 ] ;
char * p ;
2001-12-20 10:42:00 +03:00
2003-09-05 08:40:10 +04:00
if ( argc = = 0 )
return net_lookup_usage ( argc , argv ) ;
2001-12-20 10:42:00 +03:00
2003-09-05 08:40:10 +04:00
p = strchr_m ( name , ' # ' ) ;
if ( p ) {
* p = ' \0 ' ;
sscanf ( + + p , " %x " , & name_type ) ;
}
if ( ! resolve_name ( name , & ip , name_type ) ) {
2001-12-20 10:42:00 +03:00
/* we deliberately use DEBUG() here to send it to stderr
so scripts aren ' t mucked up */
2003-09-05 08:40:10 +04:00
DEBUG ( 0 , ( " Didn't find %s#%02x \n " , name , name_type ) ) ;
2001-12-20 10:42:00 +03:00
return - 1 ;
}
d_printf ( " %s \n " , inet_ntoa ( ip ) ) ;
return 0 ;
}
2006-05-05 23:24:48 +04:00
# ifdef HAVE_ADS
static void print_ldap_srvlist ( struct dns_rr_srv * dclist , int numdcs )
2002-07-15 14:35:28 +04:00
{
struct in_addr ip ;
2006-05-05 23:24:48 +04:00
int i ;
for ( i = 0 ; i < numdcs ; i + + ) {
if ( resolve_name ( dclist [ i ] . hostname , & ip , 0x20 ) ) {
d_printf ( " %s:%d \n " , inet_ntoa ( ip ) , dclist [ i ] . port ) ;
}
}
2002-07-15 14:35:28 +04:00
}
2005-10-20 21:33:17 +04:00
# endif
2002-07-15 14:35:28 +04:00
static int net_lookup_ldap ( int argc , const char * * argv )
{
2005-11-22 22:48:33 +03:00
# ifdef HAVE_ADS
2002-08-17 18:45:04 +04:00
const char * domain ;
2002-11-06 08:14:15 +03:00
struct in_addr addr ;
2002-07-15 14:35:28 +04:00
struct hostent * hostent ;
2006-05-05 23:24:48 +04:00
struct dns_rr_srv * dcs = NULL ;
int numdcs = 0 ;
2007-01-18 12:58:57 +03:00
char * sitename ;
2006-05-05 23:24:48 +04:00
TALLOC_CTX * ctx ;
NTSTATUS status ;
2002-07-15 14:35:28 +04:00
if ( argc > 0 )
domain = argv [ 0 ] ;
else
domain = opt_target_workgroup ;
2007-01-18 12:58:57 +03:00
sitename = sitename_fetch ( domain ) ;
2006-05-05 23:24:48 +04:00
if ( ( ctx = talloc_init ( " net_lookup_ldap " ) ) = = NULL ) {
2007-08-28 19:01:23 +04:00
d_fprintf ( stderr , " net_lookup_ldap: talloc_init() failed! \n " ) ;
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2006-05-05 23:24:48 +04:00
return - 1 ;
}
2002-07-15 14:35:28 +04:00
DEBUG ( 9 , ( " Lookup up ldap for domain %s \n " , domain ) ) ;
2006-05-05 23:24:48 +04:00
2007-01-17 21:25:35 +03:00
status = ads_dns_query_dcs ( ctx , domain , sitename , & dcs , & numdcs ) ;
2006-05-05 23:24:48 +04:00
if ( NT_STATUS_IS_OK ( status ) & & numdcs ) {
print_ldap_srvlist ( dcs , numdcs ) ;
TALLOC_FREE ( ctx ) ;
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2002-07-15 14:35:28 +04:00
return 0 ;
}
2007-08-28 19:01:23 +04:00
DEBUG ( 9 , ( " Looking up PDC for domain %s \n " , domain ) ) ;
2006-05-05 23:24:48 +04:00
if ( ! get_pdc_ip ( domain , & addr ) ) {
TALLOC_FREE ( ctx ) ;
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2002-07-15 14:35:28 +04:00
return - 1 ;
2006-05-05 23:24:48 +04:00
}
2002-07-15 14:35:28 +04:00
2002-11-06 08:14:15 +03:00
hostent = gethostbyaddr ( ( char * ) & addr . s_addr , sizeof ( addr . s_addr ) ,
2002-07-15 14:35:28 +04:00
AF_INET ) ;
2006-05-05 23:24:48 +04:00
if ( ! hostent ) {
TALLOC_FREE ( ctx ) ;
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2002-07-15 14:35:28 +04:00
return - 1 ;
2006-05-05 23:24:48 +04:00
}
2002-07-15 14:35:28 +04:00
2007-08-28 19:01:23 +04:00
DEBUG ( 9 , ( " Found PDC with DNS name %s \n " , hostent - > h_name ) ) ;
2002-07-15 14:35:28 +04:00
domain = strchr ( hostent - > h_name , ' . ' ) ;
2006-05-05 23:24:48 +04:00
if ( ! domain ) {
TALLOC_FREE ( ctx ) ;
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2002-07-15 14:35:28 +04:00
return - 1 ;
2006-05-05 23:24:48 +04:00
}
2002-07-15 14:35:28 +04:00
domain + + ;
DEBUG ( 9 , ( " Looking up ldap for domain %s \n " , domain ) ) ;
2006-05-05 23:24:48 +04:00
2007-01-17 21:25:35 +03:00
status = ads_dns_query_dcs ( ctx , domain , sitename , & dcs , & numdcs ) ;
2006-05-05 23:24:48 +04:00
if ( NT_STATUS_IS_OK ( status ) & & numdcs ) {
print_ldap_srvlist ( dcs , numdcs ) ;
TALLOC_FREE ( ctx ) ;
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2002-07-15 14:35:28 +04:00
return 0 ;
}
2006-05-05 23:24:48 +04:00
TALLOC_FREE ( ctx ) ;
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2006-05-05 23:24:48 +04:00
2002-07-15 14:35:28 +04:00
return - 1 ;
# endif
2005-11-22 22:48:33 +03:00
DEBUG ( 1 , ( " No ADS support \n " ) ) ;
2002-07-15 14:35:28 +04:00
return - 1 ;
}
static int net_lookup_dc ( int argc , const char * * argv )
{
2003-06-25 21:41:05 +04:00
struct ip_service * ip_list ;
struct in_addr addr ;
2002-07-15 14:35:28 +04:00
char * pdc_str = NULL ;
2007-08-28 19:01:23 +04:00
const char * domain = NULL ;
2007-01-17 21:25:35 +03:00
char * sitename = NULL ;
2002-07-15 14:35:28 +04:00
int count , i ;
2007-08-28 19:01:23 +04:00
BOOL sec_ads = ( lp_security ( ) = = SEC_ADS ) ;
if ( sec_ads ) {
domain = lp_realm ( ) ;
} else {
domain = opt_target_workgroup ;
}
2002-07-15 14:35:28 +04:00
if ( argc > 0 )
domain = argv [ 0 ] ;
/* first get PDC */
2002-11-06 08:14:15 +03:00
if ( ! get_pdc_ip ( domain , & addr ) )
2002-07-15 14:35:28 +04:00
return - 1 ;
2002-11-06 08:14:15 +03:00
asprintf ( & pdc_str , " %s " , inet_ntoa ( addr ) ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " %s \n " , pdc_str ) ;
2001-12-20 10:42:00 +03:00
2007-01-18 12:58:57 +03:00
sitename = sitename_fetch ( domain ) ;
2007-08-28 19:01:23 +04:00
if ( ! NT_STATUS_IS_OK ( get_sorted_dc_list ( domain , sitename , & ip_list , & count , sec_ads ) ) ) {
2002-07-15 14:35:28 +04:00
SAFE_FREE ( pdc_str ) ;
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2002-07-15 14:35:28 +04:00
return 0 ;
}
2007-01-17 21:25:35 +03:00
SAFE_FREE ( sitename ) ;
2002-07-15 14:35:28 +04:00
for ( i = 0 ; i < count ; i + + ) {
2003-06-25 21:41:05 +04:00
char * dc_str = inet_ntoa ( ip_list [ i ] . ip ) ;
2002-07-15 14:35:28 +04:00
if ( ! strequal ( pdc_str , dc_str ) )
d_printf ( " %s \n " , dc_str ) ;
}
SAFE_FREE ( pdc_str ) ;
return 0 ;
}
2007-08-28 19:01:23 +04:00
static int net_lookup_pdc ( int argc , const char * * argv )
{
struct in_addr addr ;
char * pdc_str = NULL ;
const char * domain ;
if ( lp_security ( ) = = SEC_ADS ) {
domain = lp_realm ( ) ;
} else {
domain = opt_target_workgroup ;
}
if ( argc > 0 )
domain = argv [ 0 ] ;
/* first get PDC */
if ( ! get_pdc_ip ( domain , & addr ) )
return - 1 ;
asprintf ( & pdc_str , " %s " , inet_ntoa ( addr ) ) ;
d_printf ( " %s \n " , pdc_str ) ;
SAFE_FREE ( pdc_str ) ;
return 0 ;
}
2002-07-15 14:35:28 +04:00
static int net_lookup_master ( int argc , const char * * argv )
{
struct in_addr master_ip ;
2002-08-17 18:45:04 +04:00
const char * domain = opt_target_workgroup ;
2002-07-15 14:35:28 +04:00
if ( argc > 0 )
domain = argv [ 0 ] ;
if ( ! find_master_ip ( domain , & master_ip ) )
return - 1 ;
d_printf ( " %s \n " , inet_ntoa ( master_ip ) ) ;
return 0 ;
}
static int net_lookup_kdc ( int argc , const char * * argv )
{
# ifdef HAVE_KRB5
krb5_error_code rc ;
krb5_context ctx ;
struct sockaddr_in * addrs ;
int num_kdcs , i ;
krb5_data realm ;
char * * realms ;
2005-11-07 17:16:50 +03:00
initialize_krb5_error_table ( ) ;
2002-07-15 14:35:28 +04:00
rc = krb5_init_context ( & ctx ) ;
if ( rc ) {
DEBUG ( 1 , ( " krb5_init_context failed (%s) \n " ,
error_message ( rc ) ) ) ;
return - 1 ;
}
if ( argc > 0 ) {
2006-09-04 23:47:48 +04:00
realm . data = CONST_DISCARD ( char * , argv [ 0 ] ) ;
2002-07-15 14:35:28 +04:00
realm . length = strlen ( argv [ 0 ] ) ;
} else if ( lp_realm ( ) & & * lp_realm ( ) ) {
2006-09-04 23:47:48 +04:00
realm . data = lp_realm ( ) ;
2006-10-20 01:47:11 +04:00
realm . length = strlen ( ( const char * ) realm . data ) ;
2002-07-15 14:35:28 +04:00
} else {
rc = krb5_get_host_realm ( ctx , NULL , & realms ) ;
if ( rc ) {
DEBUG ( 1 , ( " krb5_gethost_realm failed (%s) \n " ,
error_message ( rc ) ) ) ;
return - 1 ;
}
2006-09-04 23:47:48 +04:00
realm . data = ( char * ) * realms ;
2006-10-20 01:47:11 +04:00
realm . length = strlen ( ( const char * ) realm . data ) ;
2002-07-15 14:35:28 +04:00
}
2007-03-28 23:47:59 +04:00
rc = smb_krb5_locate_kdc ( ctx , & realm , ( struct sockaddr * * ) ( void * ) & addrs , & num_kdcs , 0 ) ;
2002-07-15 14:35:28 +04:00
if ( rc ) {
2007-03-28 23:47:59 +04:00
DEBUG ( 1 , ( " smb_krb5_locate_kdc failed (%s) \n " , error_message ( rc ) ) ) ;
2002-07-15 14:35:28 +04:00
return - 1 ;
}
for ( i = 0 ; i < num_kdcs ; i + + )
if ( addrs [ i ] . sin_family = = AF_INET )
d_printf ( " %s:%hd \n " , inet_ntoa ( addrs [ i ] . sin_addr ) ,
ntohs ( addrs [ i ] . sin_port ) ) ;
return 0 ;
# endif
DEBUG ( 1 , ( " No kerberos support \n " ) ) ;
return - 1 ;
}
2002-08-17 18:45:04 +04:00
2006-02-04 01:19:41 +03:00
static int net_lookup_name ( int argc , const char * * argv )
{
const char * dom , * name ;
DOM_SID sid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ;
2006-02-04 01:19:41 +03:00
if ( argc ! = 1 ) {
d_printf ( " usage: net lookup name <name> \n " ) ;
return - 1 ;
}
if ( ! lookup_name ( tmp_talloc_ctx ( ) , argv [ 0 ] , LOOKUP_NAME_ALL ,
& dom , & name , & sid , & type ) ) {
d_printf ( " Could not lookup name %s \n " , argv [ 0 ] ) ;
return - 1 ;
}
d_printf ( " %s %d (%s) %s \\ %s \n " , sid_string_static ( & sid ) ,
type , sid_type_lookup ( type ) , dom , name ) ;
return 0 ;
}
static int net_lookup_sid ( int argc , const char * * argv )
{
const char * dom , * name ;
DOM_SID sid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ;
2006-02-04 01:19:41 +03:00
if ( argc ! = 1 ) {
d_printf ( " usage: net lookup sid <sid> \n " ) ;
return - 1 ;
}
if ( ! string_to_sid ( & sid , argv [ 0 ] ) ) {
d_printf ( " Could not convert %s to SID \n " , argv [ 0 ] ) ;
return - 1 ;
}
if ( ! lookup_sid ( tmp_talloc_ctx ( ) , & sid ,
& dom , & name , & type ) ) {
d_printf ( " Could not lookup name %s \n " , argv [ 0 ] ) ;
return - 1 ;
}
d_printf ( " %s %d (%s) %s \\ %s \n " , sid_string_static ( & sid ) ,
type , sid_type_lookup ( type ) , dom , name ) ;
return 0 ;
}
2002-08-17 18:45:04 +04:00
2007-08-28 19:01:23 +04:00
static int net_lookup_dsgetdcname ( int argc , const char * * argv )
{
NTSTATUS status ;
const char * domain_name = NULL ;
char * site_name = NULL ;
uint32_t flags = 0 ;
struct DS_DOMAIN_CONTROLLER_INFO * info = NULL ;
TALLOC_CTX * mem_ctx ;
if ( argc < 1 | | argc > 3 ) {
d_printf ( " usage: net lookup dsgetdcname "
" <name> <flags> <sitename> \n " ) ;
return - 1 ;
}
mem_ctx = talloc_init ( " net_lookup_dsgetdcname " ) ;
if ( ! mem_ctx ) {
return - 1 ;
}
domain_name = argv [ 0 ] ;
if ( argc > = 2 )
sscanf ( argv [ 1 ] , " %x " , & flags ) ;
if ( ! flags ) {
flags | = DS_DIRECTORY_SERVICE_REQUIRED ;
}
if ( argc = = 3 ) {
site_name = SMB_STRDUP ( argv [ 2 ] ) ;
if ( ! site_name ) {
TALLOC_FREE ( mem_ctx ) ;
return - 1 ;
}
}
if ( ! site_name ) {
site_name = sitename_fetch ( domain_name ) ;
}
status = DsGetDcName ( mem_ctx , NULL , domain_name , NULL , site_name ,
flags , & info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed with: %s \n " , nt_errstr ( status ) ) ;
SAFE_FREE ( site_name ) ;
TALLOC_FREE ( mem_ctx ) ;
return - 1 ;
}
display_ds_domain_controller_info ( mem_ctx , info ) ;
SAFE_FREE ( site_name ) ;
TALLOC_FREE ( mem_ctx ) ;
return 0 ;
}
2001-12-20 10:42:00 +03:00
/* lookup hosts or IP addresses using internal samba lookup fns */
int net_lookup ( int argc , const char * * argv )
{
2003-09-05 08:40:10 +04:00
int i ;
struct functable table [ ] = {
2001-12-20 10:42:00 +03:00
{ " HOST " , net_lookup_host } ,
2002-07-15 14:35:28 +04:00
{ " LDAP " , net_lookup_ldap } ,
{ " DC " , net_lookup_dc } ,
2007-08-28 19:01:23 +04:00
{ " PDC " , net_lookup_pdc } ,
2002-07-15 14:35:28 +04:00
{ " MASTER " , net_lookup_master } ,
{ " KDC " , net_lookup_kdc } ,
2006-02-04 01:19:41 +03:00
{ " NAME " , net_lookup_name } ,
{ " SID " , net_lookup_sid } ,
2007-08-28 19:01:23 +04:00
{ " DSGETDCNAME " , net_lookup_dsgetdcname } ,
2001-12-20 10:42:00 +03:00
{ NULL , NULL }
} ;
2003-09-05 08:40:10 +04:00
if ( argc < 1 ) {
d_printf ( " \n Usage: \n " ) ;
return net_lookup_usage ( argc , argv ) ;
}
for ( i = 0 ; table [ i ] . funcname ; i + + ) {
if ( StrCaseCmp ( argv [ 0 ] , table [ i ] . funcname ) = = 0 )
return table [ i ] . fn ( argc - 1 , argv + 1 ) ;
}
/* Default to lookup a hostname so 'net lookup foo#1b' can be
used instead of ' net lookup host foo # 1 b ' . The host syntax
is a bit confusing as non # 00 names can ' t really be
considered hosts as such . */
return net_lookup_host ( argc , argv ) ;
2001-12-20 10:42:00 +03:00
}