2001-05-07 09:03:40 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-05-07 09:03:40 +04:00
Winbind daemon - miscellaneous other functions
2002-01-10 14:28:14 +03:00
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Andrew Bartlett 2002
2009-12-21 17:11:55 +03:00
2001-05-07 09:03:40 +04: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
2001-05-07 09:03:40 +04:00
( at your option ) any later version .
2009-12-21 17:11:55 +03:00
2001-05-07 09:03:40 +04:00
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 .
2009-12-21 17:11:55 +03:00
2001-05-07 09:03:40 +04:00
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-05-07 09:03:40 +04:00
*/
2003-11-12 04:51:10 +03:00
# include "includes.h"
2001-05-07 09:03:40 +04:00
# include "winbindd.h"
2011-08-17 14:05:26 +04:00
# include "libcli/security/dom_sid.h"
2001-05-07 09:03:40 +04:00
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2008-03-26 02:58:40 +03:00
/* Constants and helper functions for determining domain trust types */
enum trust_type {
EXTERNAL = 0 ,
FOREST ,
IN_FOREST ,
NONE ,
} ;
const char * trust_type_strings [ ] = { " External " ,
" Forest " ,
" In Forest " ,
" None " } ;
static enum trust_type get_trust_type ( struct winbindd_tdc_domain * domain )
{
if ( domain - > trust_attribs = = NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN )
return EXTERNAL ;
else if ( domain - > trust_attribs = = NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE )
return FOREST ;
else if ( ( ( domain - > trust_flags & NETR_TRUST_FLAG_IN_FOREST ) = = NETR_TRUST_FLAG_IN_FOREST ) & &
( ( domain - > trust_flags & NETR_TRUST_FLAG_PRIMARY ) = = 0x0 ) )
return IN_FOREST ;
return NONE ;
}
static const char * get_trust_type_string ( struct winbindd_tdc_domain * domain )
{
return trust_type_strings [ get_trust_type ( domain ) ] ;
}
static bool trust_is_inbound ( struct winbindd_tdc_domain * domain )
{
return ( domain - > trust_flags = = 0x0 ) | |
( ( domain - > trust_flags & NETR_TRUST_FLAG_IN_FOREST ) = =
NETR_TRUST_FLAG_IN_FOREST ) | |
( ( domain - > trust_flags & NETR_TRUST_FLAG_INBOUND ) = =
NETR_TRUST_FLAG_INBOUND ) ;
}
static bool trust_is_outbound ( struct winbindd_tdc_domain * domain )
{
return ( domain - > trust_flags = = 0x0 ) | |
( ( domain - > trust_flags & NETR_TRUST_FLAG_IN_FOREST ) = =
NETR_TRUST_FLAG_IN_FOREST ) | |
( ( domain - > trust_flags & NETR_TRUST_FLAG_OUTBOUND ) = =
NETR_TRUST_FLAG_OUTBOUND ) ;
}
static bool trust_is_transitive ( struct winbindd_tdc_domain * domain )
{
if ( ( domain - > trust_attribs = = NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE ) | |
( domain - > trust_attribs = = NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN ) | |
( domain - > trust_attribs = = NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL ) )
return False ;
return True ;
}
2005-06-20 17:42:29 +04:00
void winbindd_list_trusted_domains ( struct winbindd_cli_state * state )
2001-05-07 09:03:40 +04:00
{
2008-03-26 02:58:40 +03:00
struct winbindd_tdc_domain * dom_list = NULL ;
struct winbindd_tdc_domain * d = NULL ;
size_t num_domains = 0 ;
2007-05-06 23:17:30 +04:00
int extra_data_len = 0 ;
char * extra_data = NULL ;
2008-03-26 02:58:40 +03:00
int i = 0 ;
2009-12-21 17:11:55 +03:00
2005-06-09 02:10:34 +04:00
DEBUG ( 3 , ( " [%5lu]: list trusted domains \n " ,
( unsigned long ) state - > pid ) ) ;
2008-03-26 02:58:40 +03:00
if ( ! wcache_tdc_fetch_list ( & dom_list , & num_domains ) ) {
request_error ( state ) ;
goto done ;
}
2009-12-28 15:49:01 +03:00
extra_data = talloc_strdup ( state - > mem_ctx , " " ) ;
if ( extra_data = = NULL ) {
request_error ( state ) ;
goto done ;
}
2008-03-26 02:58:40 +03:00
for ( i = 0 ; i < num_domains ; i + + ) {
2008-04-23 00:29:53 +04:00
struct winbindd_domain * domain ;
bool is_online = true ;
2008-03-26 02:58:40 +03:00
d = & dom_list [ i ] ;
2008-04-23 00:29:53 +04:00
domain = find_domain_from_name_noinit ( d - > domain_name ) ;
if ( domain ) {
is_online = domain - > online ;
}
2009-12-28 15:49:01 +03:00
extra_data = talloc_asprintf_append_buffer (
extra_data ,
" %s \\ %s \\ %s \\ %s \\ %s \\ %s \\ %s \\ %s \n " ,
d - > domain_name ,
2013-02-21 15:14:55 +04:00
d - > dns_name ? d - > dns_name : " " ,
2009-12-28 15:49:01 +03:00
sid_string_talloc ( state - > mem_ctx , & d - > sid ) ,
get_trust_type_string ( d ) ,
trust_is_transitive ( d ) ? " Yes " : " No " ,
trust_is_inbound ( d ) ? " Yes " : " No " ,
trust_is_outbound ( d ) ? " Yes " : " No " ,
is_online ? " Online " : " Offline " ) ;
2007-05-06 23:17:30 +04:00
}
2010-04-03 16:16:19 +04:00
state - > response - > data . num_entries = num_domains ;
2009-12-28 15:49:01 +03:00
extra_data_len = strlen ( extra_data ) ;
2007-05-06 23:17:30 +04:00
if ( extra_data_len > 0 ) {
2009-12-28 15:49:01 +03:00
/* Strip the last \n */
extra_data [ extra_data_len - 1 ] = ' \0 ' ;
2009-06-14 14:41:46 +04:00
state - > response - > extra_data . data = extra_data ;
2009-12-28 15:49:01 +03:00
state - > response - > length + = extra_data_len ;
2007-05-06 23:17:30 +04:00
}
request_ok ( state ) ;
2008-03-26 02:58:40 +03:00
done :
TALLOC_FREE ( dom_list ) ;
2005-06-09 02:10:34 +04:00
}
2001-05-07 09:03:40 +04:00
2005-06-09 02:10:34 +04:00
enum winbindd_result winbindd_dual_list_trusted_domains ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
2009-12-28 17:51:36 +03:00
int i ;
2005-06-09 02:10:34 +04:00
int extra_data_len = 0 ;
char * extra_data ;
NTSTATUS result ;
2007-10-19 04:40:25 +04:00
bool have_own_domain = False ;
2009-12-28 17:51:36 +03:00
struct netr_DomainTrustList trusts ;
2001-05-07 09:03:40 +04:00
2005-06-09 02:10:34 +04:00
DEBUG ( 3 , ( " [%5lu]: list trusted domains \n " ,
( unsigned long ) state - > pid ) ) ;
2001-11-15 06:29:00 +03:00
2005-06-09 02:10:34 +04:00
result = domain - > methods - > trusted_domains ( domain , state - > mem_ctx ,
2009-12-28 17:51:36 +03:00
& trusts ) ;
2005-06-09 02:10:34 +04:00
2006-06-29 22:01:25 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 3 , ( " winbindd_dual_list_trusted_domains: trusted_domains returned %s \n " ,
nt_errstr ( result ) ) ) ;
2006-10-18 20:09:42 +04:00
return WINBINDD_ERROR ;
2006-06-29 22:01:25 +04:00
}
2005-06-09 02:10:34 +04:00
extra_data = talloc_strdup ( state - > mem_ctx , " " ) ;
2009-12-28 17:51:36 +03:00
for ( i = 0 ; i < trusts . count ; i + + ) {
2011-07-25 14:38:27 +04:00
if ( trusts . array [ i ] . sid = = NULL ) {
continue ;
}
2011-08-17 14:05:26 +04:00
if ( dom_sid_equal ( trusts . array [ i ] . sid , & global_sid_NULL ) ) {
continue ;
}
2011-07-25 14:38:27 +04:00
2009-12-28 17:51:36 +03:00
extra_data = talloc_asprintf_append_buffer (
extra_data , " %s \\ %s \\ %s \n " ,
trusts . array [ i ] . netbios_name ,
trusts . array [ i ] . dns_name ,
sid_string_talloc ( state - > mem_ctx ,
trusts . array [ i ] . sid ) ) ;
}
2007-12-15 23:49:15 +03:00
2006-02-04 01:19:41 +03:00
/* add our primary domain */
2009-12-21 17:11:55 +03:00
2009-12-28 17:51:36 +03:00
for ( i = 0 ; i < trusts . count ; i + + ) {
if ( strequal ( trusts . array [ i ] . netbios_name , domain - > name ) ) {
2006-02-04 01:19:41 +03:00
have_own_domain = True ;
break ;
}
}
2009-05-08 00:46:27 +04:00
if ( state - > request - > data . list_all_domains & & ! have_own_domain ) {
2009-12-28 17:51:36 +03:00
extra_data = talloc_asprintf_append_buffer (
extra_data , " %s \\ %s \\ %s \n " , domain - > name ,
2013-02-25 12:31:12 +04:00
domain - > alt_name ! = NULL ?
domain - > alt_name :
domain - > name ,
2007-12-15 23:49:15 +03:00
sid_string_talloc ( state - > mem_ctx , & domain - > sid ) ) ;
2006-02-04 01:19:41 +03:00
}
2005-06-09 02:10:34 +04:00
2009-12-28 17:51:36 +03:00
extra_data_len = strlen ( extra_data ) ;
if ( extra_data_len > 0 ) {
2005-06-09 02:10:34 +04:00
2009-12-28 17:51:36 +03:00
/* Strip the last \n */
extra_data [ extra_data_len - 1 ] = ' \0 ' ;
2005-06-09 02:10:34 +04:00
2009-06-14 14:41:46 +04:00
state - > response - > extra_data . data = extra_data ;
state - > response - > length + = extra_data_len + 1 ;
2003-01-15 20:39:47 +03:00
}
2002-01-11 08:33:45 +03:00
2005-06-09 02:10:34 +04:00
return WINBINDD_OK ;
2001-05-07 09:03:40 +04:00
}
2002-01-10 13:23:54 +03:00
2005-06-09 02:10:34 +04:00
struct domain_info_state {
struct winbindd_domain * domain ;
2009-05-16 16:20:30 +04:00
struct winbindd_cli_state * cli ;
struct winbindd_request ping_request ;
2005-06-09 02:10:34 +04:00
} ;
2009-05-16 16:20:30 +04:00
static void domain_info_done ( struct tevent_req * req ) ;
2005-06-09 02:10:34 +04:00
2009-05-16 16:20:30 +04:00
void winbindd_domain_info ( struct winbindd_cli_state * cli )
2004-01-04 14:51:31 +03:00
{
2009-05-16 16:20:30 +04:00
struct domain_info_state * state ;
2004-01-04 14:51:31 +03:00
struct winbindd_domain * domain ;
2009-05-16 16:20:30 +04:00
struct tevent_req * req ;
2004-01-04 14:51:31 +03:00
2009-05-16 16:20:30 +04:00
DEBUG ( 3 , ( " [%5lu]: domain_info [%s] \n " , ( unsigned long ) cli - > pid ,
cli - > request - > domain_name ) ) ;
2004-01-04 14:51:31 +03:00
2009-05-16 16:20:30 +04:00
domain = find_domain_from_name_noinit ( cli - > request - > domain_name ) ;
2004-01-04 14:51:31 +03:00
if ( domain = = NULL ) {
DEBUG ( 3 , ( " Did not find domain [%s] \n " ,
2009-05-16 16:20:30 +04:00
cli - > request - > domain_name ) ) ;
request_error ( cli ) ;
2005-06-20 17:42:29 +04:00
return ;
2004-01-04 14:51:31 +03:00
}
2009-05-16 16:20:30 +04:00
if ( domain - > initialized ) {
2009-06-14 14:41:46 +04:00
fstrcpy ( cli - > response - > data . domain_info . name ,
2009-05-16 16:20:30 +04:00
domain - > name ) ;
2009-06-14 14:41:46 +04:00
fstrcpy ( cli - > response - > data . domain_info . alt_name ,
2009-05-16 16:20:30 +04:00
domain - > alt_name ) ;
2009-06-14 14:41:46 +04:00
sid_to_fstring ( cli - > response - > data . domain_info . sid ,
2009-05-16 16:20:30 +04:00
& domain - > sid ) ;
2009-06-14 14:41:46 +04:00
cli - > response - > data . domain_info . native_mode =
2009-05-16 16:20:30 +04:00
domain - > native_mode ;
2009-06-14 14:41:46 +04:00
cli - > response - > data . domain_info . active_directory =
2009-05-16 16:20:30 +04:00
domain - > active_directory ;
2009-06-14 14:41:46 +04:00
cli - > response - > data . domain_info . primary =
2009-05-16 16:20:30 +04:00
domain - > primary ;
request_ok ( cli ) ;
return ;
}
2005-06-09 02:10:34 +04:00
2009-05-16 16:20:30 +04:00
state = talloc_zero ( cli - > mem_ctx , struct domain_info_state ) ;
if ( state = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
request_error ( cli ) ;
2005-06-20 17:42:29 +04:00
return ;
2005-06-09 02:10:34 +04:00
}
2009-05-16 16:20:30 +04:00
state - > cli = cli ;
state - > domain = domain ;
state - > ping_request . cmd = WINBINDD_PING ;
2004-01-04 14:51:31 +03:00
2009-05-16 16:20:30 +04:00
/*
* Send a ping down . This implicitly initializes the domain .
*/
req = wb_domain_request_send ( state , winbind_event_context ( ) ,
domain , & state - > ping_request ) ;
if ( req = = NULL ) {
DEBUG ( 3 , ( " wb_domain_request_send failed \n " ) ) ;
request_error ( cli ) ;
2009-09-04 09:59:51 +04:00
return ;
2009-05-16 16:20:30 +04:00
}
tevent_req_set_callback ( req , domain_info_done , state ) ;
2004-01-04 14:51:31 +03:00
}
2009-05-16 16:20:30 +04:00
static void domain_info_done ( struct tevent_req * req )
2005-06-09 02:10:34 +04:00
{
2009-05-16 16:20:30 +04:00
struct domain_info_state * state = tevent_req_callback_data (
req , struct domain_info_state ) ;
struct winbindd_response * response ;
int ret , err ;
2005-06-09 02:10:34 +04:00
2009-05-16 16:20:30 +04:00
ret = wb_domain_request_recv ( req , req , & response , & err ) ;
TALLOC_FREE ( req ) ;
if ( ret = = - 1 ) {
DEBUG ( 10 , ( " wb_domain_request failed: %s \n " , strerror ( errno ) ) ) ;
request_error ( state - > cli ) ;
return ;
}
if ( ! state - > domain - > initialized ) {
DEBUG ( 5 , ( " wb_domain_request did not initialize domain %s \n " ,
state - > domain - > name ) ) ;
request_error ( state - > cli ) ;
2005-06-09 02:10:34 +04:00
return ;
}
2009-06-14 14:41:46 +04:00
fstrcpy ( state - > cli - > response - > data . domain_info . name ,
2009-05-16 16:20:30 +04:00
state - > domain - > name ) ;
2009-06-14 14:41:46 +04:00
fstrcpy ( state - > cli - > response - > data . domain_info . alt_name ,
2009-05-16 16:20:30 +04:00
state - > domain - > alt_name ) ;
2009-06-14 14:41:46 +04:00
sid_to_fstring ( state - > cli - > response - > data . domain_info . sid ,
2009-05-16 16:20:30 +04:00
& state - > domain - > sid ) ;
2005-06-09 02:10:34 +04:00
2009-06-14 14:41:46 +04:00
state - > cli - > response - > data . domain_info . native_mode =
2009-05-16 16:20:30 +04:00
state - > domain - > native_mode ;
2009-06-14 14:41:46 +04:00
state - > cli - > response - > data . domain_info . active_directory =
2009-05-16 16:20:30 +04:00
state - > domain - > active_directory ;
2009-06-14 14:41:46 +04:00
state - > cli - > response - > data . domain_info . primary =
2009-05-16 16:20:30 +04:00
state - > domain - > primary ;
request_ok ( state - > cli ) ;
2005-06-09 02:10:34 +04:00
}
2011-01-10 19:25:00 +03:00
void winbindd_dc_info ( struct winbindd_cli_state * cli )
{
struct winbindd_domain * domain ;
char * dc_name , * dc_ip ;
2011-03-16 19:55:37 +03:00
cli - > request - > domain_name [ sizeof ( cli - > request - > domain_name ) - 1 ] = ' \0 ' ;
2011-01-10 19:25:00 +03:00
DEBUG ( 3 , ( " [%5lu]: domain_info [%s] \n " , ( unsigned long ) cli - > pid ,
cli - > request - > domain_name ) ) ;
if ( cli - > request - > domain_name [ 0 ] ! = ' \0 ' ) {
domain = find_domain_from_name_noinit (
cli - > request - > domain_name ) ;
DEBUG ( 10 , ( " Could not find domain %s \n " ,
cli - > request - > domain_name ) ) ;
if ( domain = = NULL ) {
request_error ( cli ) ;
return ;
}
} else {
domain = find_our_domain ( ) ;
}
if ( ! fetch_current_dc_from_gencache (
talloc_tos ( ) , domain - > name , & dc_name , & dc_ip ) ) {
DEBUG ( 10 , ( " fetch_current_dc_from_gencache(%s) failed \n " ,
domain - > name ) ) ;
request_error ( cli ) ;
return ;
}
cli - > response - > data . num_entries = 1 ;
cli - > response - > extra_data . data = talloc_asprintf (
cli - > mem_ctx , " %s \n %s \n " , dc_name , dc_ip ) ;
TALLOC_FREE ( dc_name ) ;
TALLOC_FREE ( dc_ip ) ;
if ( cli - > response - > extra_data . data = = NULL ) {
request_error ( cli ) ;
return ;
}
/* must add one to length to copy the 0 for string termination */
cli - > response - > length + =
strlen ( ( char * ) cli - > response - > extra_data . data ) + 1 ;
request_ok ( cli ) ;
}
2002-01-10 14:28:14 +03:00
/* List various tidbits of information */
2005-06-20 17:42:29 +04:00
void winbindd_info ( struct winbindd_cli_state * state )
2002-01-10 14:28:14 +03:00
{
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: request misc info \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-10 14:28:14 +03:00
2009-06-14 14:41:46 +04:00
state - > response - > data . info . winbind_separator = * lp_winbind_separator ( ) ;
fstrcpy ( state - > response - > data . info . samba_version , samba_version_string ( ) ) ;
2005-06-20 17:42:29 +04:00
request_ok ( state ) ;
2002-01-10 14:28:14 +03:00
}
2002-01-26 12:52:55 +03:00
/* Tell the client the current interface version */
2002-01-10 14:28:14 +03:00
2005-06-20 17:42:29 +04:00
void winbindd_interface_version ( struct winbindd_cli_state * state )
2002-01-10 14:28:14 +03:00
{
2005-06-20 17:42:29 +04:00
DEBUG ( 3 , ( " [%5lu]: request interface version \n " ,
( unsigned long ) state - > pid ) ) ;
2009-12-21 17:11:55 +03:00
2009-06-14 14:41:46 +04:00
state - > response - > data . interface_version = WINBIND_INTERFACE_VERSION ;
2005-06-20 17:42:29 +04:00
request_ok ( state ) ;
2002-01-10 14:28:14 +03:00
}
2002-01-26 12:52:55 +03:00
/* What domain are we a member of? */
2005-06-20 17:42:29 +04:00
void winbindd_domain_name ( struct winbindd_cli_state * state )
2002-01-26 12:52:55 +03:00
{
2003-07-22 08:31:20 +04:00
DEBUG ( 3 , ( " [%5lu]: request domain name \n " , ( unsigned long ) state - > pid ) ) ;
2009-12-21 17:11:55 +03:00
2009-06-14 14:41:46 +04:00
fstrcpy ( state - > response - > data . domain_name , lp_workgroup ( ) ) ;
2005-06-20 17:42:29 +04:00
request_ok ( state ) ;
2002-01-26 12:52:55 +03:00
}
2003-01-28 15:07:02 +03:00
/* What's my name again? */
2005-06-20 17:42:29 +04:00
void winbindd_netbios_name ( struct winbindd_cli_state * state )
2003-01-28 15:07:02 +03:00
{
2005-06-20 17:42:29 +04:00
DEBUG ( 3 , ( " [%5lu]: request netbios name \n " ,
( unsigned long ) state - > pid ) ) ;
2009-12-21 17:11:55 +03:00
2011-06-09 09:31:03 +04:00
fstrcpy ( state - > response - > data . netbios_name , lp_netbios_name ( ) ) ;
2005-06-20 17:42:29 +04:00
request_ok ( state ) ;
2003-01-28 15:07:02 +03:00
}
2003-03-24 12:54:13 +03:00
2009-10-19 11:47:33 +04:00
/* Where can I find the privileged pipe? */
2003-03-24 12:54:13 +03:00
2005-06-20 17:42:29 +04:00
void winbindd_priv_pipe_dir ( struct winbindd_cli_state * state )
2003-03-24 12:54:13 +03:00
{
2009-05-12 19:47:22 +04:00
char * priv_dir ;
2005-06-20 17:42:29 +04:00
DEBUG ( 3 , ( " [%5lu]: request location of privileged pipe \n " ,
( unsigned long ) state - > pid ) ) ;
2009-12-21 17:11:55 +03:00
2009-05-12 19:47:22 +04:00
priv_dir = get_winbind_priv_pipe_dir ( ) ;
2009-06-14 14:41:46 +04:00
state - > response - > extra_data . data = talloc_move ( state - > mem_ctx ,
2009-05-12 19:47:22 +04:00
& priv_dir ) ;
2003-03-24 12:54:13 +03:00
/* must add one to length to copy the 0 for string termination */
2009-06-14 14:41:46 +04:00
state - > response - > length + =
strlen ( ( char * ) state - > response - > extra_data . data ) + 1 ;
2003-03-24 12:54:13 +03:00
2005-06-20 17:42:29 +04:00
request_ok ( state ) ;
2003-03-24 12:54:13 +03:00
}
2007-08-29 16:43:23 +04:00