2001-10-05 04:20:06 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-10-05 04:20:06 +04:00
Winbind daemon connection manager
Copyright ( C ) Tim Potter 2001
2002-07-15 14:35:28 +04:00
Copyright ( C ) Andrew Bartlett 2002
2001-10-05 04:20:06 +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
the Free Software Foundation ; either version 2 of the License , or
( 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
2001-11-28 02:48:44 +03:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2001-10-05 04:20:06 +04:00
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/*
We need to manage connections to domain controllers without having to
mess up the main winbindd code with other issues . The aim of the
connection manager is to :
- make connections to domain controllers and cache them
- re - establish connections when networks or servers go down
- centralise the policy on connection timeouts , domain controller
2001-11-28 02:48:44 +03:00
selection etc
2001-10-05 04:20:06 +04:00
- manage re - entrancy for when winbindd becomes able to handle
2001-11-28 02:48:44 +03:00
multiple outstanding rpc requests
2001-10-05 04:20:06 +04:00
Why not have connection management as part of the rpc layer like tng ?
Good question . This code may morph into libsmb / rpc_cache . c or something
2001-11-28 02:48:44 +03:00
like that but at the moment it ' s simply staying as part of winbind . I
2001-10-05 04:20:06 +04:00
think the TNG architecture of forcing every user of the rpc layer to use
2001-11-28 02:48:44 +03:00
the connection caching system is a bad idea . It should be an optional
2001-11-15 09:55:56 +03:00
method of using the routines .
2001-10-05 04:20:06 +04:00
The TNG design is quite good but I disagree with some aspects of the
implementation . - tpot
*/
/*
TODO :
- I ' m pretty annoyed by all the make_nmb_name ( ) stuff . It should be
moved down into another function .
- There needs to be a utility function in libsmb / namequery . c that does
2001-10-08 04:34:14 +04:00
cm_get_dc_name ( )
- Take care when destroying cli_structs as they can be shared between
various sam handles .
2001-10-05 04:20:06 +04:00
*/
# include "winbindd.h"
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2001-11-28 02:48:44 +03:00
/* Global list of connections. Initially a DLIST but can become a hash
2001-11-14 09:18:13 +03:00
table or whatever later . */
2001-10-05 04:20:06 +04:00
struct winbindd_cm_conn {
2001-11-15 22:40:00 +03:00
struct winbindd_cm_conn * prev , * next ;
fstring domain ;
fstring controller ;
fstring pipe_name ;
2003-01-16 23:08:26 +03:00
size_t mutex_ref_count ;
2001-11-15 22:40:00 +03:00
struct cli_state * cli ;
POLICY_HND pol ;
2001-10-05 04:20:06 +04:00
} ;
2001-12-01 15:31:43 +03:00
static struct winbindd_cm_conn * cm_conns = NULL ;
2001-10-05 04:20:06 +04:00
2001-11-15 06:33:12 +03:00
/* Get a domain controller name. Cache positive and negative lookups so we
don ' t go to the network too often when something is badly broken . */
2001-10-05 04:20:06 +04:00
2001-11-15 06:33:12 +03:00
# define GET_DC_NAME_CACHE_TIMEOUT 30 /* Seconds between dc lookups */
struct get_dc_name_cache {
2001-11-15 22:40:00 +03:00
fstring domain_name ;
fstring srv_name ;
time_t lookup_time ;
struct get_dc_name_cache * prev , * next ;
2001-11-15 06:33:12 +03:00
} ;
2002-08-17 21:00:51 +04:00
/*
find the DC for a domain using methods appropriate for a ADS domain
*/
static BOOL cm_ads_find_dc ( const char * domain , struct in_addr * dc_ip , fstring srv_name )
{
ADS_STRUCT * ads ;
const char * realm = domain ;
2003-01-16 03:27:27 +03:00
if ( strcasecmp ( realm , lp_workgroup ( ) ) = = 0 )
2002-08-17 21:00:51 +04:00
realm = lp_realm ( ) ;
ads = ads_init ( realm , domain , NULL ) ;
2003-01-16 03:27:27 +03:00
if ( ! ads )
2002-08-17 21:00:51 +04:00
return False ;
/* we don't need to bind, just connect */
2002-09-25 19:19:00 +04:00
ads - > auth . flags | = ADS_AUTH_NO_BIND ;
2002-08-17 21:00:51 +04:00
DEBUG ( 4 , ( " cm_ads_find_dc: domain=%s \n " , domain ) ) ;
# ifdef HAVE_ADS
/* a full ads_connect() is actually overkill, as we don't srictly need
to do the SASL auth in order to get the info we need , but libads
doesn ' t offer a better way right now */
ads_connect ( ads ) ;
# endif
2003-01-16 03:27:27 +03:00
if ( ! ads - > config . realm )
2002-08-17 21:00:51 +04:00
return False ;
fstrcpy ( srv_name , ads - > config . ldap_server_name ) ;
strupper ( srv_name ) ;
* dc_ip = ads - > ldap_ip ;
ads_destroy ( & ads ) ;
DEBUG ( 4 , ( " cm_ads_find_dc: using server='%s' IP=%s \n " ,
srv_name , inet_ntoa ( * dc_ip ) ) ) ;
return True ;
}
2002-02-15 16:28:59 +03:00
static BOOL cm_get_dc_name ( const char * domain , fstring srv_name , struct in_addr * ip_out )
2001-10-05 04:20:06 +04:00
{
2001-11-15 22:40:00 +03:00
static struct get_dc_name_cache * get_dc_name_cache ;
struct get_dc_name_cache * dcc ;
2002-08-17 21:00:51 +04:00
struct in_addr dc_ip ;
BOOL ret ;
2001-10-05 04:20:06 +04:00
2001-11-15 22:40:00 +03:00
/* Check the cache for previous lookups */
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
for ( dcc = get_dc_name_cache ; dcc ; dcc = dcc - > next ) {
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
if ( ! strequal ( domain , dcc - > domain_name ) )
continue ; /* Not our domain */
2001-11-15 06:33:12 +03:00
2001-11-28 02:48:44 +03:00
if ( ( time ( NULL ) - dcc - > lookup_time ) >
GET_DC_NAME_CACHE_TIMEOUT ) {
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
/* Cache entry has expired, delete it */
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
DEBUG ( 10 , ( " get_dc_name_cache entry expired for %s \n " , domain ) ) ;
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
DLIST_REMOVE ( get_dc_name_cache , dcc ) ;
SAFE_FREE ( dcc ) ;
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
break ;
}
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
/* Return a positive or negative lookup for this domain */
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
if ( dcc - > srv_name [ 0 ] ) {
2001-11-28 02:48:44 +03:00
DEBUG ( 10 , ( " returning positive get_dc_name_cache entry for %s \n " , domain ) ) ;
2001-11-15 22:40:00 +03:00
fstrcpy ( srv_name , dcc - > srv_name ) ;
return True ;
} else {
2001-11-28 02:48:44 +03:00
DEBUG ( 10 , ( " returning negative get_dc_name_cache entry for %s \n " , domain ) ) ;
2001-11-15 22:40:00 +03:00
return False ;
}
}
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
/* Add cache entry for this lookup. */
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
DEBUG ( 10 , ( " Creating get_dc_name_cache entry for %s \n " , domain ) ) ;
2001-11-15 06:33:12 +03:00
2001-11-28 02:48:44 +03:00
if ( ! ( dcc = ( struct get_dc_name_cache * )
malloc ( sizeof ( struct get_dc_name_cache ) ) ) )
2001-11-15 22:40:00 +03:00
return False ;
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
ZERO_STRUCTP ( dcc ) ;
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
fstrcpy ( dcc - > domain_name , domain ) ;
dcc - > lookup_time = time ( NULL ) ;
DLIST_ADD ( get_dc_name_cache , dcc ) ;
2001-11-15 06:33:12 +03:00
2002-08-17 21:00:51 +04:00
zero_ip ( & dc_ip ) ;
2002-01-25 08:24:07 +03:00
2002-08-17 21:00:51 +04:00
ret = False ;
2003-01-16 03:27:27 +03:00
if ( lp_security ( ) = = SEC_ADS )
2002-08-17 21:00:51 +04:00
ret = cm_ads_find_dc ( domain , & dc_ip , srv_name ) ;
2003-01-16 03:27:27 +03:00
2002-08-17 21:00:51 +04:00
if ( ! ret ) {
/* fall back on rpc methods if the ADS methods fail */
2002-12-13 05:07:05 +03:00
ret = rpc_find_dc ( domain , srv_name , & dc_ip ) ;
2001-11-29 08:50:32 +03:00
}
2003-01-16 03:27:27 +03:00
if ( ! ret )
2002-08-17 21:00:51 +04:00
return False ;
2001-10-05 04:20:06 +04:00
2001-11-15 22:40:00 +03:00
/* We have a name so make the cache entry positive now */
fstrcpy ( dcc - > srv_name , srv_name ) ;
2001-11-15 06:33:12 +03:00
2002-02-28 04:05:15 +03:00
DEBUG ( 3 , ( " cm_get_dc_name: Returning DC %s (%s) for domain %s \n " , srv_name ,
2002-01-25 08:24:07 +03:00
inet_ntoa ( dc_ip ) , domain ) ) ;
2002-02-15 16:28:59 +03:00
* ip_out = dc_ip ;
2001-10-05 04:20:06 +04:00
return True ;
}
2001-12-11 08:19:15 +03:00
/* Choose between anonymous or authenticated connections. We need to use
an authenticated connection if DCs have the RestrictAnonymous registry
entry set > 0 , or the " Additional restrictions for anonymous
2002-02-15 16:28:59 +03:00
connections " set in the win2k Local Security Policy.
Caller to free ( ) result in domain , username , password
*/
2001-12-11 08:19:15 +03:00
2002-02-15 16:28:59 +03:00
static void cm_get_ipc_userpass ( char * * username , char * * domain , char * * password )
2001-12-11 08:19:15 +03:00
{
2002-02-15 16:28:59 +03:00
* username = secrets_fetch ( SECRETS_AUTH_USER , NULL ) ;
* domain = secrets_fetch ( SECRETS_AUTH_DOMAIN , NULL ) ;
* password = secrets_fetch ( SECRETS_AUTH_PASSWORD , NULL ) ;
if ( * username & & * * username ) {
2002-11-02 04:06:10 +03:00
if ( ! * domain | | ! * * domain )
2002-02-15 16:28:59 +03:00
* domain = smb_xstrdup ( lp_workgroup ( ) ) ;
2002-11-02 04:06:10 +03:00
if ( ! * password | | ! * * password )
* password = smb_xstrdup ( " " ) ;
DEBUG ( 3 , ( " IPC$ connections done by user %s \\ %s \n " ,
* domain , * username ) ) ;
2002-02-15 16:28:59 +03:00
} else {
2001-12-11 08:19:15 +03:00
DEBUG ( 3 , ( " IPC$ connections done anonymously \n " ) ) ;
2002-02-15 16:28:59 +03:00
* username = smb_xstrdup ( " " ) ;
* domain = smb_xstrdup ( " " ) ;
* password = smb_xstrdup ( " " ) ;
}
2001-12-11 08:19:15 +03:00
}
2001-11-15 06:33:12 +03:00
/* Open a new smb pipe connection to a DC on a given domain. Cache
negative creation attempts so we don ' t try and connect to broken
machines too often . */
2002-02-15 16:28:59 +03:00
# define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
2001-11-15 06:33:12 +03:00
2002-02-15 16:28:59 +03:00
struct failed_connection_cache {
2001-11-15 22:40:00 +03:00
fstring domain_name ;
fstring controller ;
time_t lookup_time ;
2002-02-15 16:28:59 +03:00
NTSTATUS nt_status ;
struct failed_connection_cache * prev , * next ;
2001-11-15 06:33:12 +03:00
} ;
2001-10-05 04:20:06 +04:00
2002-02-15 16:28:59 +03:00
static struct failed_connection_cache * failed_connection_cache ;
/* Add an entry to the failed conneciton cache */
2002-08-17 21:00:51 +04:00
static void add_failed_connection_entry ( struct winbindd_cm_conn * new_conn ,
NTSTATUS result )
{
2002-02-15 16:28:59 +03:00
struct failed_connection_cache * fcc ;
SMB_ASSERT ( ! NT_STATUS_IS_OK ( result ) ) ;
2002-08-17 21:00:51 +04:00
/* Check we already aren't in the cache */
for ( fcc = failed_connection_cache ; fcc ; fcc = fcc - > next ) {
if ( strequal ( fcc - > domain_name , new_conn - > domain ) ) {
DEBUG ( 10 , ( " domain %s already tried and failed \n " ,
fcc - > domain_name ) ) ;
return ;
}
}
2002-02-15 16:28:59 +03:00
/* Create negative lookup cache entry for this domain and controller */
if ( ! ( fcc = ( struct failed_connection_cache * )
malloc ( sizeof ( struct failed_connection_cache ) ) ) ) {
DEBUG ( 0 , ( " malloc failed in add_failed_connection_entry! \n " ) ) ;
return ;
}
ZERO_STRUCTP ( fcc ) ;
fstrcpy ( fcc - > domain_name , new_conn - > domain ) ;
fstrcpy ( fcc - > controller , new_conn - > controller ) ;
fcc - > lookup_time = time ( NULL ) ;
fcc - > nt_status = result ;
DLIST_ADD ( failed_connection_cache , fcc ) ;
}
/* Open a connction to the remote server, cache failures for 30 seconds */
2002-10-05 01:46:11 +04:00
static NTSTATUS cm_open_connection ( const char * domain , const int pipe_index ,
2003-03-18 02:06:12 +03:00
struct winbindd_cm_conn * new_conn )
2001-10-05 04:20:06 +04:00
{
2002-02-15 16:28:59 +03:00
struct failed_connection_cache * fcc ;
NTSTATUS result ;
char * ipc_username , * ipc_domain , * ipc_password ;
struct in_addr dc_ip ;
2002-10-17 21:10:24 +04:00
int i ;
BOOL retry = True ;
2002-02-15 16:28:59 +03:00
ZERO_STRUCT ( dc_ip ) ;
2001-11-15 22:40:00 +03:00
fstrcpy ( new_conn - > domain , domain ) ;
2002-10-05 01:42:04 +04:00
fstrcpy ( new_conn - > pipe_name , get_pipe_name_from_index ( pipe_index ) ) ;
2001-11-28 02:48:44 +03:00
2002-10-02 03:07:12 +04:00
/* Look for a domain controller for this domain. Negative results
are cached so don ' t bother applying the caching for this
function just yet . */
if ( ! cm_get_dc_name ( domain , new_conn - > controller , & dc_ip ) ) {
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND ;
add_failed_connection_entry ( new_conn , result ) ;
return result ;
}
2001-11-15 22:40:00 +03:00
/* Return false if we have tried to look up this domain and netbios
2002-01-25 08:24:07 +03:00
name before and failed . */
2001-11-15 06:33:12 +03:00
2002-02-15 16:28:59 +03:00
for ( fcc = failed_connection_cache ; fcc ; fcc = fcc - > next ) {
2001-11-28 02:48:44 +03:00
2002-02-15 16:28:59 +03:00
if ( ! ( strequal ( domain , fcc - > domain_name ) & &
strequal ( new_conn - > controller , fcc - > controller ) ) )
2001-11-15 22:40:00 +03:00
continue ; /* Not our domain */
2001-11-15 06:33:12 +03:00
2002-02-15 16:28:59 +03:00
if ( ( time ( NULL ) - fcc - > lookup_time ) >
FAILED_CONNECTION_CACHE_TIMEOUT ) {
2001-11-28 02:48:44 +03:00
2001-11-15 22:40:00 +03:00
/* Cache entry has expired, delete it */
2001-11-15 06:33:12 +03:00
2001-11-28 02:48:44 +03:00
DEBUG ( 10 , ( " cm_open_connection cache entry expired for %s, %s \n " , domain , new_conn - > controller ) ) ;
2001-11-15 06:33:12 +03:00
2002-02-15 16:28:59 +03:00
DLIST_REMOVE ( failed_connection_cache , fcc ) ;
free ( fcc ) ;
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
break ;
}
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
/* The timeout hasn't expired yet so return false */
2001-11-15 06:33:12 +03:00
2001-11-28 02:48:44 +03:00
DEBUG ( 10 , ( " returning negative open_connection_cache entry for %s, %s \n " , domain , new_conn - > controller ) ) ;
2001-11-15 06:33:12 +03:00
2002-02-15 16:28:59 +03:00
result = fcc - > nt_status ;
SMB_ASSERT ( ! NT_STATUS_IS_OK ( result ) ) ;
return result ;
2001-11-15 22:40:00 +03:00
}
2001-11-15 06:33:12 +03:00
2001-11-15 22:40:00 +03:00
/* Initialise SMB connection */
2001-10-05 04:20:06 +04:00
2002-02-15 16:28:59 +03:00
cm_get_ipc_userpass ( & ipc_username , & ipc_domain , & ipc_password ) ;
2001-10-05 04:20:06 +04:00
2002-02-15 16:28:59 +03:00
DEBUG ( 5 , ( " connecting to %s from %s with username [%s] \\ [%s] \n " ,
2002-11-13 02:20:50 +03:00
new_conn - > controller , global_myname ( ) , ipc_domain , ipc_username ) ) ;
2001-10-05 04:20:06 +04:00
2002-10-17 21:10:24 +04:00
for ( i = 0 ; retry & & ( i < 3 ) ; i + + ) {
2003-03-18 02:06:12 +03:00
BOOL got_mutex ;
if ( ! ( got_mutex = secrets_named_mutex ( new_conn - > controller , WINBIND_SERVER_MUTEX_WAIT_TIME ) ) ) {
2003-01-16 23:08:26 +03:00
DEBUG ( 0 , ( " cm_open_connection: mutex grab failed for %s \n " , new_conn - > controller ) ) ;
result = NT_STATUS_POSSIBLE_DEADLOCK ;
continue ;
}
2002-11-13 02:20:50 +03:00
result = cli_full_connection ( & new_conn - > cli , global_myname ( ) , new_conn - > controller ,
2002-10-17 21:10:24 +04:00
& dc_ip , 0 , " IPC$ " , " IPC " , ipc_username , ipc_domain ,
2003-03-18 02:06:12 +03:00
ipc_password , CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK , & retry ) ;
secrets_named_mutex_release ( new_conn - > controller ) ;
2002-10-17 21:10:24 +04:00
if ( NT_STATUS_IS_OK ( result ) )
break ;
}
2001-10-05 04:20:06 +04:00
2002-02-15 16:28:59 +03:00
SAFE_FREE ( ipc_username ) ;
SAFE_FREE ( ipc_domain ) ;
SAFE_FREE ( ipc_password ) ;
2001-11-15 06:33:12 +03:00
2002-02-15 16:28:59 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
add_failed_connection_entry ( new_conn , result ) ;
return result ;
2001-11-15 22:40:00 +03:00
}
2002-02-15 16:28:59 +03:00
2002-10-05 01:42:04 +04:00
if ( ! cli_nt_session_open ( new_conn - > cli , pipe_index ) ) {
2002-02-15 16:28:59 +03:00
result = NT_STATUS_PIPE_NOT_AVAILABLE ;
2002-10-08 22:32:42 +04:00
/*
* only cache a failure if we are not trying to open the
* * * win2k * * specific lsarpc UUID . This could be an NT PDC
* and therefore a failure is normal . This should probably
* be abstracted to a check for 2 k specific pipes and wondering
* if the PDC is an NT4 box . but since there is only one 2 k
* specific UUID right now , i ' m not going to bother . - - jerry
*/
if ( ! is_win2k_pipe ( pipe_index ) )
2003-01-16 03:27:27 +03:00
add_failed_connection_entry ( new_conn , result ) ;
2001-11-15 22:40:00 +03:00
cli_shutdown ( new_conn - > cli ) ;
2002-02-15 16:28:59 +03:00
return result ;
}
2001-11-15 22:40:00 +03:00
2002-02-15 16:28:59 +03:00
return NT_STATUS_OK ;
2001-10-05 04:20:06 +04:00
}
2001-10-27 08:48:22 +04:00
/* Return true if a connection is still alive */
static BOOL connection_ok ( struct winbindd_cm_conn * conn )
{
2002-02-15 16:28:59 +03:00
if ( ! conn ) {
smb_panic ( " Invalid paramater passed to conneciton_ok(): conn was NULL! \n " ) ;
return False ;
}
2002-03-18 13:53:02 +03:00
if ( ! conn - > cli ) {
2002-03-19 09:36:37 +03:00
DEBUG ( 0 , ( " Connection to %s for domain %s (pipe %s) has NULL conn->cli! \n " ,
2002-03-18 13:53:02 +03:00
conn - > controller , conn - > domain , conn - > pipe_name ) ) ;
2002-03-19 09:36:37 +03:00
smb_panic ( " connection_ok: conn->cli was null! " ) ;
2002-03-18 13:53:02 +03:00
return False ;
}
if ( ! conn - > cli - > initialised ) {
2002-03-19 09:36:37 +03:00
DEBUG ( 0 , ( " Connection to %s for domain %s (pipe %s) was never initialised! \n " ,
2002-02-11 04:29:07 +03:00
conn - > controller , conn - > domain , conn - > pipe_name ) ) ;
2002-03-19 09:36:37 +03:00
smb_panic ( " connection_ok: conn->cli->initialised is False! " ) ;
2001-11-15 22:40:00 +03:00
return False ;
2002-02-11 04:29:07 +03:00
}
2001-10-27 08:48:22 +04:00
2002-02-11 04:29:07 +03:00
if ( conn - > cli - > fd = = - 1 ) {
DEBUG ( 3 , ( " Connection to %s for domain %s (pipe %s) has died or was never started (fd == -1) \n " ,
conn - > controller , conn - > domain , conn - > pipe_name ) ) ;
2001-11-15 22:40:00 +03:00
return False ;
2002-02-11 04:29:07 +03:00
}
2001-10-27 08:48:22 +04:00
2001-11-15 22:40:00 +03:00
return True ;
2001-10-27 08:48:22 +04:00
}
2002-02-15 16:28:59 +03:00
/* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
2001-10-05 04:20:06 +04:00
2003-01-16 23:08:26 +03:00
static NTSTATUS get_connection_from_cache ( const char * domain , const char * pipe_name ,
2003-03-18 02:06:12 +03:00
struct winbindd_cm_conn * * conn_out )
2001-10-05 04:20:06 +04:00
{
2002-02-15 16:28:59 +03:00
struct winbindd_cm_conn * conn , conn_temp ;
2001-11-15 22:40:00 +03:00
NTSTATUS result ;
2001-10-05 04:20:06 +04:00
2001-11-15 22:40:00 +03:00
for ( conn = cm_conns ; conn ; conn = conn - > next ) {
2001-11-28 02:48:44 +03:00
if ( strequal ( conn - > domain , domain ) & &
2002-02-15 16:28:59 +03:00
strequal ( conn - > pipe_name , pipe_name ) ) {
2001-11-15 22:40:00 +03:00
if ( ! connection_ok ( conn ) ) {
2003-01-16 03:27:27 +03:00
if ( conn - > cli )
2002-02-15 16:28:59 +03:00
cli_shutdown ( conn - > cli ) ;
2002-03-23 11:28:19 +03:00
ZERO_STRUCT ( conn_temp ) ;
2002-02-15 16:28:59 +03:00
conn_temp . next = conn - > next ;
2001-11-15 22:40:00 +03:00
DLIST_REMOVE ( cm_conns , conn ) ;
2002-02-11 04:29:07 +03:00
SAFE_FREE ( conn ) ;
2002-02-15 16:28:59 +03:00
conn = & conn_temp ; /* Just to keep the loop moving */
} else {
break ;
2001-11-15 22:40:00 +03:00
}
}
}
2002-02-15 16:28:59 +03:00
if ( ! conn ) {
2002-03-23 11:28:19 +03:00
if ( ! ( conn = malloc ( sizeof ( * conn ) ) ) )
2002-02-15 16:28:59 +03:00
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( conn ) ;
2003-03-18 02:06:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = cm_open_connection ( domain , get_pipe_index ( pipe_name ) , conn ) ) ) {
2002-02-15 16:28:59 +03:00
DEBUG ( 3 , ( " Could not open a connection to %s for %s (%s) \n " ,
2002-03-17 07:36:35 +03:00
domain , pipe_name , nt_errstr ( result ) ) ) ;
2002-02-15 16:28:59 +03:00
SAFE_FREE ( conn ) ;
return result ;
}
DLIST_ADD ( cm_conns , conn ) ;
}
* conn_out = conn ;
return NT_STATUS_OK ;
}
2001-10-05 04:20:06 +04:00
2002-10-05 01:42:04 +04:00
/**********************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cm_check_for_native_mode_win2k ( const char * domain )
{
NTSTATUS result ;
struct winbindd_cm_conn conn ;
DS_DOMINFO_CTR ctr ;
BOOL ret = False ;
ZERO_STRUCT ( conn ) ;
ZERO_STRUCT ( ctr ) ;
2003-03-18 02:06:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = cm_open_connection ( domain , PI_LSARPC_DS , & conn ) ) ) {
2002-10-08 22:32:42 +04:00
DEBUG ( 5 , ( " cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s) \n " ,
2002-10-05 01:42:04 +04:00
domain , nt_errstr ( result ) ) ) ;
return False ;
}
if ( conn . cli ) {
if ( ! NT_STATUS_IS_OK ( cli_ds_getprimarydominfo ( conn . cli ,
2003-01-16 03:27:27 +03:00
conn . cli - > mem_ctx , DsRolePrimaryDomainInfoBasic , & ctr ) ) ) {
2002-10-05 01:42:04 +04:00
ret = False ;
goto done ;
}
}
if ( ( ctr . basic - > flags & DSROLE_PRIMARY_DS_RUNNING )
2003-01-16 03:27:27 +03:00
& & ! ( ctr . basic - > flags & DSROLE_PRIMARY_DS_MIXED_MODE ) )
2002-10-05 01:42:04 +04:00
ret = True ;
done :
if ( conn . cli )
cli_shutdown ( conn . cli ) ;
return ret ;
}
2002-02-15 16:28:59 +03:00
/* Return a LSA policy handle on a domain */
2001-10-05 04:20:06 +04:00
2002-11-13 02:20:50 +03:00
CLI_POLICY_HND * cm_get_lsa_handle ( const char * domain )
2002-02-15 16:28:59 +03:00
{
struct winbindd_cm_conn * conn ;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED ;
NTSTATUS result ;
static CLI_POLICY_HND hnd ;
2001-10-05 04:20:06 +04:00
2002-02-15 16:28:59 +03:00
/* Look for existing connections */
2001-10-08 04:34:14 +04:00
2003-03-18 02:06:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = get_connection_from_cache ( domain , PIPE_LSARPC , & conn ) ) )
2001-11-15 22:40:00 +03:00
return NULL ;
2002-04-04 06:39:57 +04:00
/* This *shitty* code needs scrapping ! JRA */
if ( policy_handle_is_valid ( & conn - > pol ) ) {
hnd . pol = conn - > pol ;
hnd . cli = conn - > cli ;
return & hnd ;
}
2002-02-15 16:28:59 +03:00
2001-11-28 02:48:44 +03:00
result = cli_lsa_open_policy ( conn - > cli , conn - > cli - > mem_ctx , False ,
des_access , & conn - > pol ) ;
2001-10-05 04:20:06 +04:00
2002-02-15 16:28:59 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
/* Hit the cache code again. This cleans out the old connection and gets a new one */
if ( conn - > cli - > fd = = - 1 ) { /* Try again, if the remote host disapeared */
2003-03-18 02:06:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = get_connection_from_cache ( domain , PIPE_LSARPC , & conn ) ) )
2002-02-15 16:28:59 +03:00
return NULL ;
2001-10-05 04:20:06 +04:00
2002-02-15 16:28:59 +03:00
result = cli_lsa_open_policy ( conn - > cli , conn - > cli - > mem_ctx , False ,
des_access , & conn - > pol ) ;
}
2001-10-05 04:20:06 +04:00
2002-02-15 16:28:59 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
cli_shutdown ( conn - > cli ) ;
DLIST_REMOVE ( cm_conns , conn ) ;
SAFE_FREE ( conn ) ;
return NULL ;
}
}
2001-10-05 04:20:06 +04:00
2001-11-15 22:40:00 +03:00
hnd . pol = conn - > pol ;
hnd . cli = conn - > cli ;
2001-10-05 04:20:06 +04:00
2001-11-15 22:40:00 +03:00
return & hnd ;
2001-10-05 04:20:06 +04:00
}
/* Return a SAM policy handle on a domain */
CLI_POLICY_HND * cm_get_sam_handle ( char * domain )
{
2001-11-15 22:40:00 +03:00
struct winbindd_cm_conn * conn ;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED ;
NTSTATUS result ;
static CLI_POLICY_HND hnd ;
2001-10-08 04:34:14 +04:00
2001-11-15 22:40:00 +03:00
/* Look for existing connections */
2001-10-08 04:34:14 +04:00
2003-03-18 02:06:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = get_connection_from_cache ( domain , PIPE_SAMR , & conn ) ) )
2001-11-15 22:40:00 +03:00
return NULL ;
2002-02-15 16:28:59 +03:00
2002-04-04 06:39:57 +04:00
/* This *shitty* code needs scrapping ! JRA */
if ( policy_handle_is_valid ( & conn - > pol ) ) {
hnd . pol = conn - > pol ;
hnd . cli = conn - > cli ;
return & hnd ;
}
2001-11-28 02:48:44 +03:00
result = cli_samr_connect ( conn - > cli , conn - > cli - > mem_ctx ,
des_access , & conn - > pol ) ;
2001-10-08 04:34:14 +04:00
2002-02-15 16:28:59 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
/* Hit the cache code again. This cleans out the old connection and gets a new one */
if ( conn - > cli - > fd = = - 1 ) { /* Try again, if the remote host disapeared */
2003-03-18 02:06:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = get_connection_from_cache ( domain , PIPE_SAMR , & conn ) ) )
2002-02-15 16:28:59 +03:00
return NULL ;
2001-10-08 04:34:14 +04:00
2002-02-15 16:28:59 +03:00
result = cli_samr_connect ( conn - > cli , conn - > cli - > mem_ctx ,
des_access , & conn - > pol ) ;
}
2001-10-08 04:34:14 +04:00
2002-02-15 16:28:59 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
cli_shutdown ( conn - > cli ) ;
DLIST_REMOVE ( cm_conns , conn ) ;
SAFE_FREE ( conn ) ;
return NULL ;
}
}
2001-10-08 04:34:14 +04:00
2001-11-15 22:40:00 +03:00
hnd . pol = conn - > pol ;
hnd . cli = conn - > cli ;
2001-10-08 04:34:14 +04:00
2002-02-15 16:28:59 +03:00
return & hnd ;
2001-10-05 04:20:06 +04:00
}
2002-02-15 16:28:59 +03:00
#if 0 /* This code now *well* out of date */
2001-11-15 09:55:56 +03:00
2001-10-05 04:20:06 +04:00
/* Return a SAM domain policy handle on a domain */
2001-10-08 04:34:14 +04:00
CLI_POLICY_HND * cm_get_sam_dom_handle ( char * domain , DOM_SID * domain_sid )
2001-10-05 04:20:06 +04:00
{
2001-11-28 02:48:44 +03:00
struct winbindd_cm_conn * conn , * basic_conn = NULL ;
static CLI_POLICY_HND hnd ;
NTSTATUS result ;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
/* Look for existing connections */
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
for ( conn = cm_conns ; conn ; conn = conn - > next ) {
if ( strequal ( conn - > domain , domain ) & &
strequal ( conn - > pipe_name , PIPE_SAMR ) & &
conn - > pipe_data . samr . pipe_type = = SAM_PIPE_DOM ) {
2001-10-27 08:48:22 +04:00
2001-11-28 02:48:44 +03:00
if ( ! connection_ok ( conn ) ) {
2002-02-11 04:29:07 +03:00
/* Shutdown cli? Free conn? Allow retry of DC? */
2001-11-28 02:48:44 +03:00
DLIST_REMOVE ( cm_conns , conn ) ;
return NULL ;
}
2001-10-27 08:48:22 +04:00
2001-11-28 02:48:44 +03:00
goto ok ;
}
}
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
/* Create a basic handle to open a domain handle from */
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
if ( ! cm_get_sam_handle ( domain ) )
return False ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
for ( conn = cm_conns ; conn ; conn = conn - > next ) {
if ( strequal ( conn - > domain , domain ) & &
strequal ( conn - > pipe_name , PIPE_SAMR ) & &
conn - > pipe_data . samr . pipe_type = = SAM_PIPE_BASIC )
basic_conn = conn ;
}
if ( ! ( conn = ( struct winbindd_cm_conn * )
malloc ( sizeof ( struct winbindd_cm_conn ) ) ) )
return NULL ;
ZERO_STRUCTP ( conn ) ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
fstrcpy ( conn - > domain , basic_conn - > domain ) ;
fstrcpy ( conn - > controller , basic_conn - > controller ) ;
fstrcpy ( conn - > pipe_name , basic_conn - > pipe_name ) ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
conn - > pipe_data . samr . pipe_type = SAM_PIPE_DOM ;
conn - > cli = basic_conn - > cli ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
result = cli_samr_open_domain ( conn - > cli , conn - > cli - > mem_ctx ,
& basic_conn - > pol , des_access ,
domain_sid , & conn - > pol ) ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
return NULL ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
/* Add to list */
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
DLIST_ADD ( cm_conns , conn ) ;
2001-10-08 04:34:14 +04:00
ok :
2001-11-28 02:48:44 +03:00
hnd . pol = conn - > pol ;
hnd . cli = conn - > cli ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
return & hnd ;
2001-10-05 04:20:06 +04:00
}
/* Return a SAM policy handle on a domain user */
2001-10-08 04:34:14 +04:00
CLI_POLICY_HND * cm_get_sam_user_handle ( char * domain , DOM_SID * domain_sid ,
2001-11-28 02:48:44 +03:00
uint32 user_rid )
2001-10-05 04:20:06 +04:00
{
2001-11-28 02:48:44 +03:00
struct winbindd_cm_conn * conn , * basic_conn = NULL ;
static CLI_POLICY_HND hnd ;
NTSTATUS result ;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED ;
/* Look for existing connections */
for ( conn = cm_conns ; conn ; conn = conn - > next ) {
if ( strequal ( conn - > domain , domain ) & &
strequal ( conn - > pipe_name , PIPE_SAMR ) & &
conn - > pipe_data . samr . pipe_type = = SAM_PIPE_USER & &
conn - > pipe_data . samr . rid = = user_rid ) {
if ( ! connection_ok ( conn ) ) {
2002-02-11 04:29:07 +03:00
/* Shutdown cli? Free conn? Allow retry of DC? */
2001-11-28 02:48:44 +03:00
DLIST_REMOVE ( cm_conns , conn ) ;
return NULL ;
}
goto ok ;
}
}
/* Create a domain handle to open a user handle from */
if ( ! cm_get_sam_dom_handle ( domain , domain_sid ) )
return NULL ;
for ( conn = cm_conns ; conn ; conn = conn - > next ) {
if ( strequal ( conn - > domain , domain ) & &
strequal ( conn - > pipe_name , PIPE_SAMR ) & &
conn - > pipe_data . samr . pipe_type = = SAM_PIPE_DOM )
basic_conn = conn ;
}
if ( ! basic_conn ) {
DEBUG ( 0 , ( " No domain sam handle was created! \n " ) ) ;
return NULL ;
}
if ( ! ( conn = ( struct winbindd_cm_conn * )
malloc ( sizeof ( struct winbindd_cm_conn ) ) ) )
return NULL ;
ZERO_STRUCTP ( conn ) ;
fstrcpy ( conn - > domain , basic_conn - > domain ) ;
fstrcpy ( conn - > controller , basic_conn - > controller ) ;
fstrcpy ( conn - > pipe_name , basic_conn - > pipe_name ) ;
conn - > pipe_data . samr . pipe_type = SAM_PIPE_USER ;
conn - > cli = basic_conn - > cli ;
conn - > pipe_data . samr . rid = user_rid ;
result = cli_samr_open_user ( conn - > cli , conn - > cli - > mem_ctx ,
& basic_conn - > pol , des_access , user_rid ,
& conn - > pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return NULL ;
/* Add to list */
DLIST_ADD ( cm_conns , conn ) ;
2001-10-08 04:34:14 +04:00
ok :
2001-11-28 02:48:44 +03:00
hnd . pol = conn - > pol ;
hnd . cli = conn - > cli ;
2001-10-08 04:34:14 +04:00
2001-11-28 02:48:44 +03:00
return & hnd ;
2001-10-05 04:20:06 +04:00
}
/* Return a SAM policy handle on a domain group */
2001-10-10 02:55:00 +04:00
CLI_POLICY_HND * cm_get_sam_group_handle ( char * domain , DOM_SID * domain_sid ,
2001-11-28 02:48:44 +03:00
uint32 group_rid )
2001-10-05 04:20:06 +04:00
{
2001-11-28 02:48:44 +03:00
struct winbindd_cm_conn * conn , * basic_conn = NULL ;
static CLI_POLICY_HND hnd ;
NTSTATUS result ;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED ;
/* Look for existing connections */
for ( conn = cm_conns ; conn ; conn = conn - > next ) {
if ( strequal ( conn - > domain , domain ) & &
strequal ( conn - > pipe_name , PIPE_SAMR ) & &
conn - > pipe_data . samr . pipe_type = = SAM_PIPE_GROUP & &
conn - > pipe_data . samr . rid = = group_rid ) {
if ( ! connection_ok ( conn ) ) {
2002-02-11 04:29:07 +03:00
/* Shutdown cli? Free conn? Allow retry of DC? */
2001-11-28 02:48:44 +03:00
DLIST_REMOVE ( cm_conns , conn ) ;
return NULL ;
}
goto ok ;
}
}
/* Create a domain handle to open a user handle from */
if ( ! cm_get_sam_dom_handle ( domain , domain_sid ) )
return NULL ;
for ( conn = cm_conns ; conn ; conn = conn - > next ) {
if ( strequal ( conn - > domain , domain ) & &
strequal ( conn - > pipe_name , PIPE_SAMR ) & &
conn - > pipe_data . samr . pipe_type = = SAM_PIPE_DOM )
basic_conn = conn ;
}
if ( ! basic_conn ) {
DEBUG ( 0 , ( " No domain sam handle was created! \n " ) ) ;
return NULL ;
}
if ( ! ( conn = ( struct winbindd_cm_conn * )
malloc ( sizeof ( struct winbindd_cm_conn ) ) ) )
return NULL ;
ZERO_STRUCTP ( conn ) ;
fstrcpy ( conn - > domain , basic_conn - > domain ) ;
fstrcpy ( conn - > controller , basic_conn - > controller ) ;
fstrcpy ( conn - > pipe_name , basic_conn - > pipe_name ) ;
conn - > pipe_data . samr . pipe_type = SAM_PIPE_GROUP ;
conn - > cli = basic_conn - > cli ;
conn - > pipe_data . samr . rid = group_rid ;
result = cli_samr_open_group ( conn - > cli , conn - > cli - > mem_ctx ,
& basic_conn - > pol , des_access , group_rid ,
& conn - > pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) )
return NULL ;
/* Add to list */
DLIST_ADD ( cm_conns , conn ) ;
2001-10-10 02:55:00 +04:00
ok :
2001-11-28 02:48:44 +03:00
hnd . pol = conn - > pol ;
hnd . cli = conn - > cli ;
2001-10-10 02:55:00 +04:00
2001-11-28 02:48:44 +03:00
return & hnd ;
2001-10-05 04:20:06 +04:00
}
2001-11-05 03:21:17 +03:00
2001-11-15 09:55:56 +03:00
# endif
/* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
netlogon pipe as no handle is returned . */
2001-11-05 03:21:17 +03:00
2002-11-13 02:20:50 +03:00
NTSTATUS cm_get_netlogon_cli ( const char * domain , const unsigned char * trust_passwd ,
2001-11-28 02:48:44 +03:00
struct cli_state * * cli )
2001-11-05 03:21:17 +03:00
{
2002-02-11 04:29:07 +03:00
NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND ;
2002-02-15 16:28:59 +03:00
struct winbindd_cm_conn * conn ;
2002-09-25 19:19:00 +04:00
uint32 neg_flags = 0x000001ff ;
2003-03-18 02:06:12 +03:00
fstring lock_name ;
BOOL got_mutex ;
2001-11-05 03:21:17 +03:00
2003-01-16 03:27:27 +03:00
if ( ! cli )
2002-02-15 16:28:59 +03:00
return NT_STATUS_INVALID_PARAMETER ;
2003-01-16 03:27:27 +03:00
2003-01-16 23:08:26 +03:00
/* Open an initial conection - keep the mutex. */
2003-01-16 03:27:27 +03:00
2003-03-18 02:06:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = get_connection_from_cache ( domain , PIPE_NETLOGON , & conn ) ) )
2002-02-15 16:28:59 +03:00
return result ;
2002-02-11 04:29:07 +03:00
2003-03-18 02:06:12 +03:00
snprintf ( lock_name , sizeof ( lock_name ) , " NETLOGON \\ %s " , conn - > controller ) ;
if ( ! ( got_mutex = secrets_named_mutex ( lock_name , WINBIND_SERVER_MUTEX_WAIT_TIME ) ) ) {
DEBUG ( 0 , ( " cm_get_netlogon_cli: mutex grab failed for %s \n " , conn - > controller ) ) ;
}
2002-09-25 19:19:00 +04:00
result = cli_nt_setup_creds ( conn - > cli , get_sec_chan ( ) , trust_passwd , & neg_flags , 2 ) ;
2001-11-05 03:21:17 +03:00
2003-03-18 02:06:12 +03:00
if ( got_mutex )
secrets_named_mutex_release ( lock_name ) ;
2003-01-16 03:27:27 +03:00
2001-11-15 22:40:00 +03:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 0 , ( " error connecting to domain password server: %s \n " ,
2002-03-17 07:36:35 +03:00
nt_errstr ( result ) ) ) ;
2002-02-15 16:28:59 +03:00
/* Hit the cache code again. This cleans out the old connection and gets a new one */
if ( conn - > cli - > fd = = - 1 ) {
2003-03-18 02:06:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = get_connection_from_cache ( domain , PIPE_NETLOGON , & conn ) ) )
2003-01-16 03:27:27 +03:00
return result ;
2002-02-15 16:28:59 +03:00
2003-03-18 02:06:12 +03:00
snprintf ( lock_name , sizeof ( lock_name ) , " NETLOGON \\ %s " , conn - > controller ) ;
if ( ! ( got_mutex = secrets_named_mutex ( lock_name , WINBIND_SERVER_MUTEX_WAIT_TIME ) ) ) {
DEBUG ( 0 , ( " cm_get_netlogon_cli: mutex grab failed for %s \n " , conn - > controller ) ) ;
}
2002-02-15 16:28:59 +03:00
/* Try again */
2002-09-25 19:19:00 +04:00
result = cli_nt_setup_creds ( conn - > cli , get_sec_chan ( ) , trust_passwd , & neg_flags , 2 ) ;
2003-01-16 03:27:27 +03:00
2003-03-18 02:06:12 +03:00
if ( got_mutex )
secrets_named_mutex_release ( lock_name ) ;
2002-02-15 16:28:59 +03:00
}
if ( ! NT_STATUS_IS_OK ( result ) ) {
2002-02-11 04:29:07 +03:00
cli_shutdown ( conn - > cli ) ;
DLIST_REMOVE ( cm_conns , conn ) ;
SAFE_FREE ( conn ) ;
2001-11-28 02:48:44 +03:00
return result ;
2002-02-15 16:28:59 +03:00
}
2001-11-15 22:40:00 +03:00
}
2001-11-05 03:21:17 +03:00
2002-02-15 16:28:59 +03:00
* cli = conn - > cli ;
2001-11-05 03:21:17 +03:00
2001-11-28 02:48:44 +03:00
return result ;
2001-11-05 03:21:17 +03:00
}
2001-11-14 09:18:13 +03:00
/* Dump the current connection status */
static void dump_conn_list ( void )
{
2001-11-15 22:40:00 +03:00
struct winbindd_cm_conn * con ;
2001-11-14 09:18:13 +03:00
2001-11-28 02:48:44 +03:00
DEBUG ( 0 , ( " \t Domain Controller Pipe \n " ) ) ;
2001-11-14 09:18:13 +03:00
2001-11-15 22:40:00 +03:00
for ( con = cm_conns ; con ; con = con - > next ) {
char * msg ;
2001-11-14 09:18:13 +03:00
2001-11-15 22:40:00 +03:00
/* Display pipe info */
2001-11-28 02:48:44 +03:00
2002-01-19 20:29:32 +03:00
if ( asprintf ( & msg , " \t %-15s %-15s %-16s " , con - > domain , con - > controller , con - > pipe_name ) < 0 ) {
DEBUG ( 0 , ( " Error: not enough memory! \n " ) ) ;
} else {
DEBUG ( 0 , ( " %s \n " , msg ) ) ;
SAFE_FREE ( msg ) ;
}
2001-11-15 22:40:00 +03:00
}
2001-11-14 09:18:13 +03:00
}
void winbindd_cm_status ( void )
{
2001-11-15 22:40:00 +03:00
/* List open connections */
2001-11-14 09:18:13 +03:00
2001-11-15 22:40:00 +03:00
DEBUG ( 0 , ( " winbindd connection manager status: \n " ) ) ;
2001-11-14 09:18:13 +03:00
2001-11-15 22:40:00 +03:00
if ( cm_conns )
dump_conn_list ( ) ;
else
DEBUG ( 0 , ( " \t No active connections \n " ) ) ;
2001-11-14 09:18:13 +03:00
}