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
2017-12-13 10:53:16 +03:00
static char * get_trust_type_string ( TALLOC_CTX * mem_ctx ,
struct winbindd_tdc_domain * tdc ,
struct winbindd_domain * domain )
{
enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL ;
char * s = NULL ;
2008-03-26 02:58:40 +03:00
2017-12-13 10:53:16 +03:00
if ( domain ! = NULL ) {
secure_channel_type = domain - > secure_channel_type ;
}
2008-03-26 02:58:40 +03:00
2017-12-13 10:53:16 +03:00
switch ( secure_channel_type ) {
case SEC_CHAN_NULL : {
if ( domain = = NULL ) {
DBG_ERR ( " Missing domain [%s] \n " ,
tdc - > domain_name ) ;
return NULL ;
}
if ( domain - > routing_domain = = NULL ) {
DBG_ERR ( " Missing routing for domain [%s] \n " ,
tdc - > domain_name ) ;
return NULL ;
}
s = talloc_asprintf ( mem_ctx , " Routed (via %s) " ,
domain - > routing_domain - > name ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
}
2008-03-26 02:58:40 +03:00
2017-12-13 10:53:16 +03:00
case SEC_CHAN_LOCAL :
s = talloc_strdup ( mem_ctx , " Local " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
2008-03-26 02:58:40 +03:00
2017-12-13 10:53:16 +03:00
case SEC_CHAN_WKSTA :
s = talloc_strdup ( mem_ctx , " Workstation " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
case SEC_CHAN_BDC : {
int role = lp_server_role ( ) ;
if ( role = = ROLE_DOMAIN_PDC ) {
s = talloc_strdup ( mem_ctx , " PDC " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
}
if ( role = = ROLE_DOMAIN_BDC ) {
s = talloc_strdup ( mem_ctx , " BDC " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
}
s = talloc_strdup ( mem_ctx , " RWDC " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
}
case SEC_CHAN_RODC :
s = talloc_strdup ( mem_ctx , " RODC " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
case SEC_CHAN_DNS_DOMAIN :
if ( tdc - > trust_attribs & LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN ) {
s = talloc_strdup ( mem_ctx , " External " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
}
if ( tdc - > trust_attribs & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST ) {
s = talloc_strdup ( mem_ctx , " In Forest " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
}
if ( tdc - > trust_attribs & LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL ) {
s = talloc_strdup ( mem_ctx , " External " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
}
if ( tdc - > trust_attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE ) {
s = talloc_strdup ( mem_ctx , " Forest " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
}
s = talloc_strdup ( mem_ctx , " External " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
case SEC_CHAN_DOMAIN :
s = talloc_strdup ( mem_ctx , " External " ) ;
if ( s = = NULL ) {
return NULL ;
}
break ;
default :
DBG_ERR ( " Unhandled secure_channel_type %d for domain[%s] \n " ,
secure_channel_type , tdc - > domain_name ) ;
return NULL ;
}
return s ;
2008-03-26 02:58:40 +03:00
}
static bool trust_is_inbound ( struct winbindd_tdc_domain * domain )
{
2017-11-28 19:44:41 +03:00
if ( domain - > trust_flags & NETR_TRUST_FLAG_INBOUND ) {
return true ;
}
return false ;
2008-03-26 02:58:40 +03:00
}
static bool trust_is_outbound ( struct winbindd_tdc_domain * domain )
{
2017-11-28 19:46:03 +03:00
if ( domain - > trust_flags & NETR_TRUST_FLAG_OUTBOUND ) {
return true ;
}
return false ;
2008-03-26 02:58:40 +03:00
}
static bool trust_is_transitive ( struct winbindd_tdc_domain * domain )
{
2017-11-28 19:32:59 +03:00
bool transitive = false ;
/*
* Beware : order matters
*/
if ( domain - > trust_attribs & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST ) {
transitive = true ;
}
if ( domain - > trust_attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE ) {
transitive = true ;
}
if ( domain - > trust_attribs & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE ) {
transitive = false ;
}
if ( domain - > trust_attribs & LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN ) {
transitive = false ;
}
if ( domain - > trust_flags & NETR_TRUST_FLAG_PRIMARY ) {
transitive = true ;
}
return transitive ;
2008-03-26 02:58:40 +03:00
}
2018-05-04 22:19:06 +03:00
bool 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 ;
size_t num_domains = 0 ;
2007-05-06 23:17:30 +04:00
int extra_data_len = 0 ;
char * extra_data = NULL ;
2018-05-04 22:07:35 +03:00
size_t i = 0 ;
2018-05-04 22:19:06 +03:00
bool ret = false ;
2009-12-21 17:11:55 +03:00
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s (%u)]: list trusted domains \n " ,
state - > client_name ,
( unsigned int ) state - > pid ) ;
2005-06-09 02:10:34 +04:00
2008-03-26 02:58:40 +03:00
if ( ! wcache_tdc_fetch_list ( & dom_list , & num_domains ) ) {
goto done ;
}
2009-12-28 15:49:01 +03:00
extra_data = talloc_strdup ( state - > mem_ctx , " " ) ;
if ( extra_data = = NULL ) {
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 ;
2016-02-22 17:18:26 +03:00
struct winbindd_tdc_domain * d = NULL ;
2017-12-13 10:53:16 +03:00
char * trust_type = NULL ;
2018-12-10 14:32:12 +03:00
struct dom_sid_buf buf ;
2008-04-23 00:29:53 +04:00
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 ;
}
2017-12-13 10:53:16 +03:00
trust_type = get_trust_type_string ( talloc_tos ( ) , d , domain ) ;
if ( trust_type = = NULL ) {
continue ;
}
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 : " " ,
2018-12-10 14:32:12 +03:00
dom_sid_str_buf ( & d - > sid , & buf ) ,
2017-12-13 10:53:16 +03:00
trust_type ,
2009-12-28 15:49:01 +03:00
trust_is_transitive ( d ) ? " Yes " : " No " ,
trust_is_inbound ( d ) ? " Yes " : " No " ,
trust_is_outbound ( d ) ? " Yes " : " No " ,
is_online ? " Online " : " Offline " ) ;
2017-12-13 10:53:16 +03:00
TALLOC_FREE ( trust_type ) ;
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
}
2018-05-04 22:19:06 +03:00
ret = true ;
2008-03-26 02:58:40 +03:00
done :
TALLOC_FREE ( dom_list ) ;
2018-05-04 22:19:06 +03:00
return ret ;
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 )
{
2018-05-04 22:07:35 +03:00
uint32_t 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
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s %u]: list trusted domains \n " ,
state - > client_name ,
( unsigned int ) state - > pid ) ;
2001-11-15 06:29:00 +03:00
2016-10-08 02:31:40 +03:00
result = wb_cache_trusted_domains ( domain , state - > mem_ctx , & 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 + + ) {
2018-12-10 14:32:12 +03:00
struct dom_sid_buf buf ;
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 (
2016-02-10 01:38:11 +03:00
extra_data , " %s \\ %s \\ %s \\ %u \\ %u \\ %u \n " ,
trusts . array [ i ] . netbios_name , trusts . array [ i ] . dns_name ,
2018-12-10 14:32:12 +03:00
dom_sid_str_buf ( trusts . array [ i ] . sid , & buf ) ,
2016-02-10 01:38:11 +03:00
trusts . array [ i ] . trust_flags ,
( uint32_t ) trusts . array [ i ] . trust_type ,
trusts . array [ i ] . trust_attributes ) ;
2009-12-28 17:51:36 +03:00
}
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 ) {
2018-12-10 14:32:12 +03:00
struct dom_sid_buf buf ;
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 ,
2018-12-10 14:32:12 +03:00
dom_sid_str_buf ( & domain - > sid , & buf ) ) ;
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 ;
2016-03-10 14:17:43 +03:00
state - > response - > length + = extra_data_len ;
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
2018-05-02 19:27:23 +03:00
bool winbindd_dc_info ( struct winbindd_cli_state * cli )
2011-01-10 19:25:00 +03:00
{
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
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s (%u)]: domain_info [%s] \n " ,
cli - > client_name ,
( unsigned int ) cli - > pid ,
cli - > request - > domain_name ) ;
2011-01-10 19:25:00 +03:00
if ( cli - > request - > domain_name [ 0 ] ! = ' \0 ' ) {
2017-11-30 15:04:56 +03:00
domain = find_trust_from_name_noinit (
2011-01-10 19:25:00 +03:00
cli - > request - > domain_name ) ;
if ( domain = = NULL ) {
2017-06-23 17:25:27 +03:00
DEBUG ( 10 , ( " Could not find domain %s \n " ,
cli - > request - > domain_name ) ) ;
2018-05-02 19:27:23 +03:00
return false ;
2011-01-10 19:25:00 +03:00
}
} 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 ) ) ;
2018-05-02 19:27:23 +03:00
return false ;
2011-01-10 19:25:00 +03:00
}
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 ) {
2018-05-02 19:27:23 +03:00
return false ;
2011-01-10 19:25:00 +03:00
}
/* must add one to length to copy the 0 for string termination */
cli - > response - > length + =
strlen ( ( char * ) cli - > response - > extra_data . data ) + 1 ;
2018-05-02 19:27:23 +03:00
return true ;
2011-01-10 19:25:00 +03:00
}
2018-05-02 17:38:14 +03:00
bool winbindd_ping ( struct winbindd_cli_state * state )
2018-04-18 18:29:51 +03:00
{
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s (%u)]: ping \n " ,
state - > client_name ,
( unsigned int ) state - > pid ) ;
2018-05-02 17:38:14 +03:00
return true ;
2018-04-18 18:29:51 +03:00
}
2002-01-10 14:28:14 +03:00
/* List various tidbits of information */
2018-05-02 17:36:49 +03:00
bool winbindd_info ( struct winbindd_cli_state * state )
2002-01-10 14:28:14 +03:00
{
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s (%u)]: request misc info \n " ,
state - > client_name ,
( unsigned int ) 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 ( ) ) ;
2018-05-02 17:36:49 +03:00
return true ;
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
2018-05-02 16:26:55 +03:00
bool winbindd_interface_version ( struct winbindd_cli_state * state )
2002-01-10 14:28:14 +03:00
{
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s (%u)]: request interface version (version = %d) \n " ,
state - > client_name ,
( unsigned int ) state - > pid ,
WINBIND_INTERFACE_VERSION ) ;
2009-12-21 17:11:55 +03:00
2009-06-14 14:41:46 +04:00
state - > response - > data . interface_version = WINBIND_INTERFACE_VERSION ;
2018-05-02 16:26:55 +03:00
return true ;
2002-01-10 14:28:14 +03:00
}
2002-01-26 12:52:55 +03:00
/* What domain are we a member of? */
2018-05-02 17:39:20 +03:00
bool winbindd_domain_name ( struct winbindd_cli_state * state )
2002-01-26 12:52:55 +03:00
{
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s (%u)]: request domain name \n " ,
state - > client_name ,
( unsigned int ) 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 ( ) ) ;
2018-05-02 17:39:20 +03:00
return true ;
2002-01-26 12:52:55 +03:00
}
2003-01-28 15:07:02 +03:00
/* What's my name again? */
2018-05-02 19:25:00 +03:00
bool winbindd_netbios_name ( struct winbindd_cli_state * state )
2003-01-28 15:07:02 +03:00
{
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s (%u)]: request netbios name \n " ,
state - > client_name ,
( unsigned int ) 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 ( ) ) ;
2018-05-02 19:25:00 +03:00
return true ;
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
2018-05-02 21:27:43 +03:00
bool 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 ;
2018-11-05 13:55:46 +03:00
DBG_NOTICE ( " [%s (%u)]: request location of privileged pipe \n " ,
state - > client_name ,
( unsigned int ) 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
2018-05-02 21:27:43 +03:00
return true ;
2003-03-24 12:54:13 +03:00
}