2001-05-07 05:03:40 +00:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
2001-05-07 05:03:40 +00:00
Winbind daemon - miscellaneous other functions
2002-01-10 11:28:14 +00:00
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Andrew Bartlett 2002
2001-05-07 05:03:40 +00: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 19:25:36 +00:00
the Free Software Foundation ; either version 3 of the License , or
2001-05-07 05:03:40 +00: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 00:52:41 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2001-05-07 05:03:40 +00:00
*/
2003-11-12 01:51:10 +00:00
# include "includes.h"
2001-05-07 05:03:40 +00:00
# include "winbindd.h"
2002-07-15 10:35:28 +00:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2001-05-07 05:03:40 +00:00
/* Check the machine account password is valid */
2005-06-20 13:42:29 +00:00
void winbindd_check_machine_acct ( struct winbindd_cli_state * state )
2005-06-08 22:10:34 +00:00
{
DEBUG ( 3 , ( " [%5lu]: check machine account \n " ,
( unsigned long ) state - > pid ) ) ;
2005-06-20 13:42:29 +00:00
sendto_domain ( state , find_our_domain ( ) ) ;
2005-06-08 22:10:34 +00:00
}
enum winbindd_result winbindd_dual_check_machine_acct ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
2001-05-07 05:03:40 +00:00
{
2001-11-23 00:14:04 +00:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2001-07-25 06:16:27 +00:00
int num_retries = 0 ;
2004-01-05 04:10:28 +00:00
struct winbindd_domain * contact_domain ;
2003-07-22 04:31:20 +00:00
DEBUG ( 3 , ( " [%5lu]: check machine account \n " , ( unsigned long ) state - > pid ) ) ;
2001-05-07 05:03:40 +00:00
/* Get trust account password */
2001-07-25 06:16:27 +00:00
again :
2003-09-05 17:57:45 +00:00
2004-01-08 02:15:46 +00:00
contact_domain = find_our_domain ( ) ;
2004-01-05 04:10:28 +00:00
2001-11-23 00:14:04 +00:00
/* This call does a cli_nt_setup_creds() which implicitly checks
the trust account password . */
2005-06-08 22:10:34 +00:00
invalidate_cm_connection ( & contact_domain - > conn ) ;
{
2005-09-30 17:13:37 +00:00
struct rpc_pipe_client * netlogon_pipe ;
result = cm_connect_netlogon ( contact_domain , & netlogon_pipe ) ;
2005-06-08 22:10:34 +00:00
}
2001-05-07 05:03:40 +00:00
2001-11-23 00:14:04 +00:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 3 , ( " could not open handle to NETLOGON pipe \n " ) ) ;
goto done ;
}
2001-05-07 05:03:40 +00:00
2001-07-25 06:16:27 +00:00
/* There is a race condition between fetching the trust account
2002-03-19 06:36:37 +00:00
password and the periodic machine password change . So it ' s
possible that the trust account password has been changed on us .
We are returned NT_STATUS_ACCESS_DENIED if this happens . */
2001-07-25 06:16:27 +00:00
# define MAX_RETRIES 8
if ( ( num_retries < MAX_RETRIES ) & &
2001-11-23 00:14:04 +00:00
NT_STATUS_V ( result ) = = NT_STATUS_V ( NT_STATUS_ACCESS_DENIED ) ) {
2001-07-25 06:16:27 +00:00
num_retries + + ;
goto again ;
}
2001-05-07 05:03:40 +00:00
/* Pass back result code - zero for success, other values for
specific failures . */
2001-11-23 00:14:04 +00:00
DEBUG ( 3 , ( " secret is %s \n " , NT_STATUS_IS_OK ( result ) ?
" good " : " bad " ) ) ;
2001-05-07 05:03:40 +00:00
done :
2002-07-15 10:35:28 +00:00
state - > response . data . auth . nt_status = NT_STATUS_V ( result ) ;
fstrcpy ( state - > response . data . auth . nt_status_string , nt_errstr ( result ) ) ;
fstrcpy ( state - > response . data . auth . error_string , nt_errstr ( result ) ) ;
state - > response . data . auth . pam_error = nt_status_to_pam ( result ) ;
DEBUG ( NT_STATUS_IS_OK ( result ) ? 5 : 2 , ( " Checking the trust account password returned %s \n " ,
state - > response . data . auth . nt_status_string ) ) ;
2001-11-23 00:14:04 +00:00
2002-07-15 10:35:28 +00:00
return NT_STATUS_IS_OK ( result ) ? WINBINDD_OK : WINBINDD_ERROR ;
2001-05-07 05:03:40 +00:00
}
2008-06-26 14:02:39 -07:00
/* Helpers for listing user and group names */
const char * ent_type_strings [ ] = { " users " ,
" groups " } ;
static const char * get_ent_type_string ( enum ent_type type )
{
return ent_type_strings [ type ] ;
}
struct listent_state {
TALLOC_CTX * mem_ctx ;
struct winbindd_cli_state * cli_state ;
enum ent_type type ;
int domain_count ;
char * extra_data ;
uint32_t extra_data_len ;
} ;
static void listent_recv ( void * private_data , bool success , fstring dom_name ,
char * extra_data ) ;
/* List domain users/groups without mapping to unix ids */
void winbindd_list_ent ( struct winbindd_cli_state * state , enum ent_type type )
{
struct winbindd_domain * domain ;
const char * which_domain ;
struct listent_state * ent_state ;
DEBUG ( 3 , ( " [%5lu]: list %s \n " , ( unsigned long ) state - > pid ,
get_ent_type_string ( type ) ) ) ;
/* Ensure null termination */
state - > request . domain_name [ sizeof ( state - > request . domain_name ) - 1 ] = ' \0 ' ;
which_domain = state - > request . domain_name ;
/* Initialize listent_state */
ent_state = TALLOC_P ( state - > mem_ctx , struct listent_state ) ;
if ( ent_state = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
request_error ( state ) ;
return ;
}
ent_state - > mem_ctx = state - > mem_ctx ;
ent_state - > cli_state = state ;
ent_state - > type = type ;
ent_state - > domain_count = 0 ;
ent_state - > extra_data = NULL ;
ent_state - > extra_data_len = 0 ;
/* Must count the full list of expected domains before we request data
* from any of them . Otherwise it ' s possible for a connection to the
* first domain to fail , call listent_recv ( ) , and return to the
* client without checking any other domains . */
for ( domain = domain_list ( ) ; domain ; domain = domain - > next ) {
/* if we have a domain name restricting the request and this
one in the list doesn ' t match , then just bypass the remainder
of the loop */
if ( * which_domain & & ! strequal ( which_domain , domain - > name ) )
continue ;
ent_state - > domain_count + + ;
}
/* Make sure we're enumerating at least one domain */
if ( ! ent_state - > domain_count ) {
request_ok ( state ) ;
return ;
}
/* Enumerate list of trusted domains and request user/group list from
* each */
for ( domain = domain_list ( ) ; domain ; domain = domain - > next ) {
if ( * which_domain & & ! strequal ( which_domain , domain - > name ) )
continue ;
winbindd_listent_async ( state - > mem_ctx , domain ,
listent_recv , ent_state , type ) ;
}
}
static void listent_recv ( void * private_data , bool success , fstring dom_name ,
char * extra_data )
{
/* extra_data comes to us as a '\0' terminated string of comma
separated users or groups */
struct listent_state * state = talloc_get_type_abort (
private_data , struct listent_state ) ;
/* Append users/groups from one domain onto the whole list */
if ( extra_data ) {
DEBUG ( 5 , ( " listent_recv: %s returned %s. \n " ,
dom_name , get_ent_type_string ( state - > type ) ) ) ;
if ( ! state - > extra_data )
state - > extra_data = talloc_asprintf ( state - > mem_ctx ,
" %s " , extra_data ) ;
else
state - > extra_data = talloc_asprintf_append (
state - > extra_data ,
" ,%s " , extra_data ) ;
/* Add one for the '\0' and each additional ',' */
state - > extra_data_len + = strlen ( extra_data ) + 1 ;
}
else {
DEBUG ( 5 , ( " listent_recv: %s returned no %s. \n " ,
dom_name , get_ent_type_string ( state - > type ) ) ) ;
}
if ( - - state - > domain_count )
/* Still waiting for some child domains to return */
return ;
/* Return list of all users/groups to the client */
if ( state - > extra_data ) {
state - > cli_state - > response . extra_data . data =
SMB_STRDUP ( state - > extra_data ) ;
state - > cli_state - > response . length + = state - > extra_data_len ;
}
request_ok ( state - > cli_state ) ;
}
2008-03-25 16:58:40 -07: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 13:42:29 +00:00
void winbindd_list_trusted_domains ( struct winbindd_cli_state * state )
2001-05-07 05:03:40 +00:00
{
2008-03-25 16:58:40 -07:00
struct winbindd_tdc_domain * dom_list = NULL ;
struct winbindd_tdc_domain * d = NULL ;
size_t num_domains = 0 ;
2007-05-06 19:17:30 +00:00
int extra_data_len = 0 ;
char * extra_data = NULL ;
2008-03-25 16:58:40 -07:00
int i = 0 ;
2007-05-06 19:17:30 +00:00
2005-06-08 22:10:34 +00:00
DEBUG ( 3 , ( " [%5lu]: list trusted domains \n " ,
( unsigned long ) state - > pid ) ) ;
2008-03-25 16:58:40 -07:00
if ( ! wcache_tdc_fetch_list ( & dom_list , & num_domains ) ) {
request_error ( state ) ;
goto done ;
}
for ( i = 0 ; i < num_domains ; i + + ) {
2008-04-22 15:29:53 -05:00
struct winbindd_domain * domain ;
bool is_online = true ;
2008-03-25 16:58:40 -07:00
d = & dom_list [ i ] ;
2008-04-22 15:29:53 -05:00
domain = find_domain_from_name_noinit ( d - > domain_name ) ;
if ( domain ) {
is_online = domain - > online ;
}
2007-05-06 19:17:30 +00:00
if ( ! extra_data ) {
2008-03-25 16:58:40 -07:00
extra_data = talloc_asprintf ( state - > mem_ctx ,
2008-04-22 15:29:53 -05:00
" %s \\ %s \\ %s \\ %s \\ %s \\ %s \\ %s \\ %s " ,
2008-03-25 16:58:40 -07:00
d - > domain_name ,
d - > dns_name ? d - > dns_name : d - > domain_name ,
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 " ,
2008-04-22 15:29:53 -05:00
trust_is_outbound ( d ) ? " Yes " : " No " ,
is_online ? " Online " : " Offline " ) ;
2007-05-06 19:17:30 +00:00
} else {
2008-03-25 16:58:40 -07:00
extra_data = talloc_asprintf ( state - > mem_ctx ,
2008-04-22 15:29:53 -05:00
" %s \n %s \\ %s \\ %s \\ %s \\ %s \\ %s \\ %s \\ %s " ,
2008-03-25 16:58:40 -07:00
extra_data ,
d - > domain_name ,
d - > dns_name ? d - > dns_name : d - > domain_name ,
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 " ,
2008-04-22 15:29:53 -05:00
trust_is_outbound ( d ) ? " Yes " : " No " ,
is_online ? " Online " : " Offline " ) ;
2007-05-06 19:17:30 +00:00
}
}
extra_data_len = 0 ;
if ( extra_data ! = NULL ) {
extra_data_len = strlen ( extra_data ) ;
}
if ( extra_data_len > 0 ) {
state - > response . extra_data . data = SMB_STRDUP ( extra_data ) ;
state - > response . length + = extra_data_len + 1 ;
}
request_ok ( state ) ;
2008-03-25 16:58:40 -07:00
done :
TALLOC_FREE ( dom_list ) ;
TALLOC_FREE ( extra_data ) ;
2005-06-08 22:10:34 +00:00
}
2001-05-07 05:03:40 +00:00
2005-06-08 22:10:34 +00:00
enum winbindd_result winbindd_dual_list_trusted_domains ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
uint32 i , num_domains ;
char * * names , * * alt_names ;
DOM_SID * sids ;
int extra_data_len = 0 ;
char * extra_data ;
NTSTATUS result ;
2007-10-18 17:40:25 -07:00
bool have_own_domain = False ;
2001-05-07 05:03:40 +00:00
2005-06-08 22:10:34 +00:00
DEBUG ( 3 , ( " [%5lu]: list trusted domains \n " ,
( unsigned long ) state - > pid ) ) ;
2001-11-15 03:29:00 +00:00
2005-06-08 22:10:34 +00:00
result = domain - > methods - > trusted_domains ( domain , state - > mem_ctx ,
& num_domains , & names ,
& alt_names , & sids ) ;
2006-06-29 18:01:25 +00: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 16:09:42 +00:00
return WINBINDD_ERROR ;
2006-06-29 18:01:25 +00:00
}
2005-06-08 22:10:34 +00:00
extra_data = talloc_strdup ( state - > mem_ctx , " " ) ;
if ( num_domains > 0 )
2007-12-15 21:49:15 +01:00
extra_data = talloc_asprintf (
state - > mem_ctx , " %s \\ %s \\ %s " ,
names [ 0 ] , alt_names [ 0 ] ? alt_names [ 0 ] : names [ 0 ] ,
sid_string_talloc ( state - > mem_ctx , & sids [ 0 ] ) ) ;
2005-06-08 22:10:34 +00:00
for ( i = 1 ; i < num_domains ; i + + )
2007-12-15 21:49:15 +01:00
extra_data = talloc_asprintf (
state - > mem_ctx , " %s \n %s \\ %s \\ %s " ,
extra_data , names [ i ] ,
alt_names [ i ] ? alt_names [ i ] : names [ i ] ,
sid_string_talloc ( state - > mem_ctx , & sids [ i ] ) ) ;
2006-02-03 22:19:41 +00:00
/* add our primary domain */
for ( i = 0 ; i < num_domains ; i + + ) {
if ( strequal ( names [ i ] , domain - > name ) ) {
have_own_domain = True ;
break ;
}
}
if ( state - > request . data . list_all_domains & & ! have_own_domain ) {
2007-12-15 21:49:15 +01:00
extra_data = talloc_asprintf (
state - > mem_ctx , " %s \n %s \\ %s \\ %s " ,
extra_data , domain - > name ,
domain - > alt_name ? domain - > alt_name : domain - > name ,
sid_string_talloc ( state - > mem_ctx , & domain - > sid ) ) ;
2006-02-03 22:19:41 +00:00
}
2005-06-08 22:10:34 +00:00
/* This is a bit excessive, but the extra data sooner or later will be
talloc ' ed */
2006-06-19 19:41:56 +00:00
extra_data_len = 0 ;
if ( extra_data ! = NULL ) {
extra_data_len = strlen ( extra_data ) ;
}
2005-06-08 22:10:34 +00:00
if ( extra_data_len > 0 ) {
2006-04-12 14:10:39 +00:00
state - > response . extra_data . data = SMB_STRDUP ( extra_data ) ;
2005-06-08 22:10:34 +00:00
state - > response . length + = extra_data_len + 1 ;
2003-01-15 17:39:47 +00:00
}
2002-01-11 05:33:45 +00:00
2005-06-08 22:10:34 +00:00
return WINBINDD_OK ;
}
2005-06-20 13:42:29 +00:00
void winbindd_getdcname ( struct winbindd_cli_state * state )
2005-06-08 22:10:34 +00:00
{
2007-09-21 09:35:53 +00:00
struct winbindd_domain * domain ;
2005-06-08 22:10:34 +00:00
state - > request . domain_name
[ sizeof ( state - > request . domain_name ) - 1 ] = ' \0 ' ;
2001-05-07 05:03:40 +00:00
2005-06-08 22:10:34 +00:00
DEBUG ( 3 , ( " [%5lu]: Get DC name for %s \n " , ( unsigned long ) state - > pid ,
state - > request . domain_name ) ) ;
2001-05-07 05:03:40 +00:00
2007-09-21 09:35:53 +00:00
domain = find_domain_from_name_noinit ( state - > request . domain_name ) ;
if ( domain & & domain - > internal ) {
fstrcpy ( state - > response . data . dc_name , global_myname ( ) ) ;
request_ok ( state ) ;
return ;
}
2005-06-20 13:42:29 +00:00
sendto_domain ( state , find_our_domain ( ) ) ;
2005-06-08 22:10:34 +00:00
}
2001-05-07 05:03:40 +00:00
2005-06-08 22:10:34 +00:00
enum winbindd_result winbindd_dual_getdcname ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
2008-02-07 10:24:18 +01:00
const char * dcname_slash = NULL ;
const char * p ;
2005-09-30 17:13:37 +00:00
struct rpc_pipe_client * netlogon_pipe ;
2005-06-08 22:10:34 +00:00
NTSTATUS result ;
2006-10-06 16:13:10 +00:00
WERROR werr ;
2006-10-12 11:25:37 +00:00
unsigned int orig_timeout ;
2007-09-21 10:25:33 +00:00
struct winbindd_domain * req_domain ;
2001-05-07 05:03:40 +00:00
2005-06-08 22:10:34 +00:00
state - > request . domain_name
[ sizeof ( state - > request . domain_name ) - 1 ] = ' \0 ' ;
2001-05-07 05:03:40 +00:00
2005-06-08 22:10:34 +00:00
DEBUG ( 3 , ( " [%5lu]: Get DC name for %s \n " , ( unsigned long ) state - > pid ,
state - > request . domain_name ) ) ;
2001-05-07 05:03:40 +00:00
2005-09-30 17:13:37 +00:00
result = cm_connect_netlogon ( domain , & netlogon_pipe ) ;
2001-05-07 05:03:40 +00:00
2005-06-08 22:10:34 +00:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2005-12-12 14:08:42 +00:00
DEBUG ( 1 , ( " Can't contact the NETLOGON pipe \n " ) ) ;
2005-06-08 22:10:34 +00:00
return WINBINDD_ERROR ;
2001-05-07 05:03:40 +00:00
}
2006-10-12 11:25:37 +00:00
/* This call can take a long time - allow the server to time out.
35 seconds should do it . */
2008-04-19 23:27:35 +02:00
orig_timeout = rpccli_set_timeout ( netlogon_pipe , 35000 ) ;
2006-10-12 11:25:37 +00:00
2007-09-21 10:25:33 +00:00
req_domain = find_domain_from_name_noinit ( state - > request . domain_name ) ;
if ( req_domain = = domain ) {
2008-02-07 10:24:18 +01:00
result = rpccli_netr_GetDcName ( netlogon_pipe ,
state - > mem_ctx ,
domain - > dcname ,
state - > request . domain_name ,
& dcname_slash ,
& werr ) ;
2007-09-21 10:25:33 +00:00
} else {
2008-02-07 10:24:18 +01:00
result = rpccli_netr_GetAnyDCName ( netlogon_pipe ,
state - > mem_ctx ,
domain - > dcname ,
state - > request . domain_name ,
& dcname_slash ,
& werr ) ;
2007-09-21 10:25:33 +00:00
}
2006-10-12 11:25:37 +00:00
/* And restore our original timeout. */
2008-04-19 23:27:35 +02:00
rpccli_set_timeout ( netlogon_pipe , orig_timeout ) ;
2005-06-08 22:10:34 +00:00
2008-02-07 10:24:18 +01:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 5 , ( " Error requesting DCname for domain %s: %s \n " ,
state - > request . domain_name , nt_errstr ( result ) ) ) ;
return WINBINDD_ERROR ;
}
2006-10-06 16:13:10 +00:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2007-08-22 09:32:37 +00:00
DEBUG ( 5 , ( " Error requesting DCname for domain %s: %s \n " ,
state - > request . domain_name , dos_errstr ( werr ) ) ) ;
2005-06-08 22:10:34 +00:00
return WINBINDD_ERROR ;
2001-05-07 05:03:40 +00:00
}
2005-06-08 22:10:34 +00:00
p = dcname_slash ;
2005-09-30 17:13:37 +00:00
if ( * p = = ' \\ ' ) {
p + = 1 ;
}
if ( * p = = ' \\ ' ) {
p + = 1 ;
}
2005-06-08 22:10:34 +00:00
fstrcpy ( state - > response . data . dc_name , p ) ;
2001-05-07 05:03:40 +00:00
return WINBINDD_OK ;
}
2002-01-10 10:23:54 +00:00
2005-06-08 22:10:34 +00:00
struct sequence_state {
TALLOC_CTX * mem_ctx ;
struct winbindd_cli_state * cli_state ;
struct winbindd_domain * domain ;
struct winbindd_request * request ;
struct winbindd_response * response ;
char * extra_data ;
} ;
2007-10-18 17:40:25 -07:00
static void sequence_recv ( void * private_data , bool success ) ;
2002-01-31 11:49:29 +00:00
2005-06-20 13:42:29 +00:00
void winbindd_show_sequence ( struct winbindd_cli_state * state )
2002-01-31 11:49:29 +00:00
{
2005-06-08 22:10:34 +00:00
struct sequence_state * seq ;
/* Ensure null termination */
state - > request . domain_name [ sizeof ( state - > request . domain_name ) - 1 ] = ' \0 ' ;
if ( strlen ( state - > request . domain_name ) > 0 ) {
struct winbindd_domain * domain ;
domain = find_domain_from_name_noinit (
state - > request . domain_name ) ;
2005-06-20 13:42:29 +00:00
if ( domain = = NULL ) {
request_error ( state ) ;
return ;
}
sendto_domain ( state , domain ) ;
return ;
2005-06-08 22:10:34 +00:00
}
/* Ask all domains in sequence, collect the results in sequence_recv */
2002-01-31 11:49:29 +00:00
2005-06-08 22:10:34 +00:00
seq = TALLOC_P ( state - > mem_ctx , struct sequence_state ) ;
if ( seq = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2005-06-20 13:42:29 +00:00
request_error ( state ) ;
return ;
2005-06-08 22:10:34 +00:00
}
seq - > mem_ctx = state - > mem_ctx ;
seq - > cli_state = state ;
seq - > domain = domain_list ( ) ;
if ( seq - > domain = = NULL ) {
DEBUG ( 0 , ( " domain list empty \n " ) ) ;
2005-06-20 13:42:29 +00:00
request_error ( state ) ;
return ;
2005-06-08 22:10:34 +00:00
}
seq - > request = TALLOC_ZERO_P ( state - > mem_ctx ,
struct winbindd_request ) ;
seq - > response = TALLOC_ZERO_P ( state - > mem_ctx ,
struct winbindd_response ) ;
seq - > extra_data = talloc_strdup ( state - > mem_ctx , " " ) ;
if ( ( seq - > request = = NULL ) | | ( seq - > response = = NULL ) | |
( seq - > extra_data = = NULL ) ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2005-06-20 13:42:29 +00:00
request_error ( state ) ;
return ;
2005-06-08 22:10:34 +00:00
}
seq - > request - > length = sizeof ( * seq - > request ) ;
seq - > request - > cmd = WINBINDD_SHOW_SEQUENCE ;
fstrcpy ( seq - > request - > domain_name , seq - > domain - > name ) ;
async_domain_request ( state - > mem_ctx , seq - > domain ,
seq - > request , seq - > response ,
sequence_recv , seq ) ;
}
2007-10-18 17:40:25 -07:00
static void sequence_recv ( void * private_data , bool success )
2005-06-08 22:10:34 +00:00
{
2006-08-18 14:05:25 +00:00
struct sequence_state * state =
( struct sequence_state * ) private_data ;
2005-06-08 22:10:34 +00:00
uint32 seq = DOM_SEQUENCE_NONE ;
if ( ( success ) & & ( state - > response - > result = = WINBINDD_OK ) )
2007-09-19 19:05:54 +00:00
seq = state - > response - > data . sequence_number ;
2005-06-08 22:10:34 +00:00
if ( seq = = DOM_SEQUENCE_NONE ) {
state - > extra_data = talloc_asprintf ( state - > mem_ctx ,
" %s%s : DISCONNECTED \n " ,
state - > extra_data ,
state - > domain - > name ) ;
} else {
state - > extra_data = talloc_asprintf ( state - > mem_ctx ,
" %s%s : %d \n " ,
state - > extra_data ,
state - > domain - > name , seq ) ;
}
state - > domain - > sequence_number = seq ;
state - > domain = state - > domain - > next ;
if ( state - > domain = = NULL ) {
struct winbindd_cli_state * cli_state = state - > cli_state ;
cli_state - > response . length =
sizeof ( cli_state - > response ) +
strlen ( state - > extra_data ) + 1 ;
2006-04-12 14:10:39 +00:00
cli_state - > response . extra_data . data =
2005-06-08 22:10:34 +00:00
SMB_STRDUP ( state - > extra_data ) ;
2005-06-20 13:42:29 +00:00
request_ok ( cli_state ) ;
2005-06-08 22:10:34 +00:00
return ;
}
/* Ask the next domain */
fstrcpy ( state - > request - > domain_name , state - > domain - > name ) ;
async_domain_request ( state - > mem_ctx , state - > domain ,
state - > request , state - > response ,
sequence_recv , state ) ;
}
/* This is the child-only version of --sequence. It only allows for a single
* domain ( ie " our " one ) to be displayed . */
enum winbindd_result winbindd_dual_show_sequence ( struct winbindd_domain * domain ,
struct winbindd_cli_state * state )
{
2003-07-22 04:31:20 +00:00
DEBUG ( 3 , ( " [%5lu]: show sequence \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-31 11:49:29 +00:00
2003-08-10 22:01:11 +00:00
/* Ensure null termination */
2005-06-08 22:10:34 +00:00
state - > request . domain_name [ sizeof ( state - > request . domain_name ) - 1 ] = ' \0 ' ;
2002-01-31 11:49:29 +00:00
2005-06-08 22:10:34 +00:00
domain - > methods - > sequence_number ( domain , & domain - > sequence_number ) ;
2007-09-19 19:05:54 +00:00
state - > response . data . sequence_number =
2005-06-08 22:10:34 +00:00
domain - > sequence_number ;
2002-01-31 11:49:29 +00:00
return WINBINDD_OK ;
}
2005-06-08 22:10:34 +00:00
struct domain_info_state {
struct winbindd_domain * domain ;
struct winbindd_cli_state * cli_state ;
} ;
2007-10-18 17:40:25 -07:00
static void domain_info_init_recv ( void * private_data , bool success ) ;
2005-06-08 22:10:34 +00:00
2005-06-20 13:42:29 +00:00
void winbindd_domain_info ( struct winbindd_cli_state * state )
2004-01-04 11:51:31 +00:00
{
struct winbindd_domain * domain ;
DEBUG ( 3 , ( " [%5lu]: domain_info [%s] \n " , ( unsigned long ) state - > pid ,
state - > request . domain_name ) ) ;
2005-06-08 22:10:34 +00:00
domain = find_domain_from_name_noinit ( state - > request . domain_name ) ;
2004-01-04 11:51:31 +00:00
if ( domain = = NULL ) {
DEBUG ( 3 , ( " Did not find domain [%s] \n " ,
state - > request . domain_name ) ) ;
2005-06-20 13:42:29 +00:00
request_error ( state ) ;
return ;
2004-01-04 11:51:31 +00:00
}
2005-06-08 22:10:34 +00:00
if ( ! domain - > initialized ) {
struct domain_info_state * istate ;
istate = TALLOC_P ( state - > mem_ctx , struct domain_info_state ) ;
if ( istate = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2005-06-20 13:42:29 +00:00
request_error ( state ) ;
return ;
2005-06-08 22:10:34 +00:00
}
istate - > cli_state = state ;
istate - > domain = domain ;
init_child_connection ( domain , domain_info_init_recv , istate ) ;
2005-06-20 13:42:29 +00:00
return ;
2005-06-08 22:10:34 +00:00
}
fstrcpy ( state - > response . data . domain_info . name ,
domain - > name ) ;
fstrcpy ( state - > response . data . domain_info . alt_name ,
domain - > alt_name ) ;
2007-12-15 22:47:30 +01:00
sid_to_fstring ( state - > response . data . domain_info . sid , & domain - > sid ) ;
2004-01-04 11:51:31 +00:00
2005-06-08 22:10:34 +00:00
state - > response . data . domain_info . native_mode =
domain - > native_mode ;
state - > response . data . domain_info . active_directory =
domain - > active_directory ;
state - > response . data . domain_info . primary =
domain - > primary ;
2004-01-04 11:51:31 +00:00
2005-06-20 13:42:29 +00:00
request_ok ( state ) ;
2004-01-04 11:51:31 +00:00
}
2007-10-18 17:40:25 -07:00
static void domain_info_init_recv ( void * private_data , bool success )
2005-06-08 22:10:34 +00:00
{
2006-08-18 14:05:25 +00:00
struct domain_info_state * istate =
( struct domain_info_state * ) private_data ;
2005-06-08 22:10:34 +00:00
struct winbindd_cli_state * state = istate - > cli_state ;
struct winbindd_domain * domain = istate - > domain ;
DEBUG ( 10 , ( " Got back from child init: %d \n " , success ) ) ;
if ( ( ! success ) | | ( ! domain - > initialized ) ) {
DEBUG ( 5 , ( " Could not init child for domain %s \n " ,
domain - > name ) ) ;
2005-06-20 13:42:29 +00:00
request_error ( state ) ;
2005-06-08 22:10:34 +00:00
return ;
}
fstrcpy ( state - > response . data . domain_info . name ,
domain - > name ) ;
fstrcpy ( state - > response . data . domain_info . alt_name ,
domain - > alt_name ) ;
2007-12-15 22:47:30 +01:00
sid_to_fstring ( state - > response . data . domain_info . sid , & domain - > sid ) ;
2005-06-08 22:10:34 +00:00
state - > response . data . domain_info . native_mode =
domain - > native_mode ;
state - > response . data . domain_info . active_directory =
domain - > active_directory ;
state - > response . data . domain_info . primary =
domain - > primary ;
2005-06-20 13:42:29 +00:00
request_ok ( state ) ;
2005-06-08 22:10:34 +00:00
}
2005-06-20 13:42:29 +00:00
void winbindd_ping ( struct winbindd_cli_state * state )
2002-01-10 10:23:54 +00:00
{
2003-07-22 04:31:20 +00:00
DEBUG ( 3 , ( " [%5lu]: ping \n " , ( unsigned long ) state - > pid ) ) ;
2005-06-20 13:42:29 +00:00
request_ok ( state ) ;
2002-01-10 10:23:54 +00:00
}
2002-01-10 11:28:14 +00:00
/* List various tidbits of information */
2005-06-20 13:42:29 +00:00
void winbindd_info ( struct winbindd_cli_state * state )
2002-01-10 11:28:14 +00:00
{
2003-07-22 04:31:20 +00:00
DEBUG ( 3 , ( " [%5lu]: request misc info \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-10 11:28:14 +00:00
state - > response . data . info . winbind_separator = * lp_winbind_separator ( ) ;
2003-08-20 17:13:38 +00:00
fstrcpy ( state - > response . data . info . samba_version , SAMBA_VERSION_STRING ) ;
2005-06-20 13:42:29 +00:00
request_ok ( state ) ;
2002-01-10 11:28:14 +00:00
}
2002-01-26 09:52:55 +00:00
/* Tell the client the current interface version */
2002-01-10 11:28:14 +00:00
2005-06-20 13:42:29 +00:00
void winbindd_interface_version ( struct winbindd_cli_state * state )
2002-01-10 11:28:14 +00:00
{
2005-06-20 13:42:29 +00:00
DEBUG ( 3 , ( " [%5lu]: request interface version \n " ,
( unsigned long ) state - > pid ) ) ;
2002-01-10 11:28:14 +00:00
state - > response . data . interface_version = WINBIND_INTERFACE_VERSION ;
2005-06-20 13:42:29 +00:00
request_ok ( state ) ;
2002-01-10 11:28:14 +00:00
}
2002-01-26 09:52:55 +00:00
/* What domain are we a member of? */
2005-06-20 13:42:29 +00:00
void winbindd_domain_name ( struct winbindd_cli_state * state )
2002-01-26 09:52:55 +00:00
{
2003-07-22 04:31:20 +00:00
DEBUG ( 3 , ( " [%5lu]: request domain name \n " , ( unsigned long ) state - > pid ) ) ;
2002-01-26 09:52:55 +00:00
fstrcpy ( state - > response . data . domain_name , lp_workgroup ( ) ) ;
2005-06-20 13:42:29 +00:00
request_ok ( state ) ;
2002-01-26 09:52:55 +00:00
}
2003-01-28 12:07:02 +00:00
/* What's my name again? */
2005-06-20 13:42:29 +00:00
void winbindd_netbios_name ( struct winbindd_cli_state * state )
2003-01-28 12:07:02 +00:00
{
2005-06-20 13:42:29 +00:00
DEBUG ( 3 , ( " [%5lu]: request netbios name \n " ,
( unsigned long ) state - > pid ) ) ;
2003-01-28 12:07:02 +00:00
fstrcpy ( state - > response . data . netbios_name , global_myname ( ) ) ;
2005-06-20 13:42:29 +00:00
request_ok ( state ) ;
2003-01-28 12:07:02 +00:00
}
2003-03-24 09:54:13 +00:00
2003-04-21 14:09:03 +00:00
/* Where can I find the privilaged pipe? */
2003-03-24 09:54:13 +00:00
2005-06-20 13:42:29 +00:00
void winbindd_priv_pipe_dir ( struct winbindd_cli_state * state )
2003-03-24 09:54:13 +00:00
{
2005-06-20 13:42:29 +00:00
DEBUG ( 3 , ( " [%5lu]: request location of privileged pipe \n " ,
( unsigned long ) state - > pid ) ) ;
2003-03-24 09:54:13 +00:00
2006-04-12 14:10:39 +00:00
state - > response . extra_data . data = SMB_STRDUP ( get_winbind_priv_pipe_dir ( ) ) ;
if ( ! state - > response . extra_data . data ) {
2005-06-20 13:42:29 +00:00
DEBUG ( 0 , ( " malloc failed \n " ) ) ;
request_error ( state ) ;
return ;
}
2003-03-24 09:54:13 +00:00
/* must add one to length to copy the 0 for string termination */
2005-06-20 13:42:29 +00:00
state - > response . length + =
2006-04-12 14:10:39 +00:00
strlen ( ( char * ) state - > response . extra_data . data ) + 1 ;
2003-03-24 09:54:13 +00:00
2005-06-20 13:42:29 +00:00
request_ok ( state ) ;
2003-03-24 09:54:13 +00:00
}
2007-08-29 12:43:23 +00:00