This merges in my 'always use ADS' patch. Tested on a mix of NT and ADS
[Samba/gebeck_regimport.git] / source3 / nsswitch / winbindd_cm.c
blob53c91c01c7bdcbb01ebc3e4d67442a04a8ba04f4
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind daemon connection manager
6 Copyright (C) Tim Potter 2001
7 Copyright (C) Andrew Bartlett 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 We need to manage connections to domain controllers without having to
26 mess up the main winbindd code with other issues. The aim of the
27 connection manager is to:
29 - make connections to domain controllers and cache them
30 - re-establish connections when networks or servers go down
31 - centralise the policy on connection timeouts, domain controller
32 selection etc
33 - manage re-entrancy for when winbindd becomes able to handle
34 multiple outstanding rpc requests
36 Why not have connection management as part of the rpc layer like tng?
37 Good question. This code may morph into libsmb/rpc_cache.c or something
38 like that but at the moment it's simply staying as part of winbind. I
39 think the TNG architecture of forcing every user of the rpc layer to use
40 the connection caching system is a bad idea. It should be an optional
41 method of using the routines.
43 The TNG design is quite good but I disagree with some aspects of the
44 implementation. -tpot
49 TODO:
51 - I'm pretty annoyed by all the make_nmb_name() stuff. It should be
52 moved down into another function.
54 - Take care when destroying cli_structs as they can be shared between
55 various sam handles.
59 #include "includes.h"
60 #include "winbindd.h"
62 #undef DBGC_CLASS
63 #define DBGC_CLASS DBGC_WINBIND
65 /* Global list of connections. Initially a DLIST but can become a hash
66 table or whatever later. */
68 struct winbindd_cm_conn {
69 struct winbindd_cm_conn *prev, *next;
70 fstring domain;
71 fstring controller;
72 fstring pipe_name;
73 size_t mutex_ref_count;
74 struct cli_state *cli;
75 POLICY_HND pol;
78 static struct winbindd_cm_conn *cm_conns = NULL;
81 /* Choose between anonymous or authenticated connections. We need to use
82 an authenticated connection if DCs have the RestrictAnonymous registry
83 entry set > 0, or the "Additional restrictions for anonymous
84 connections" set in the win2k Local Security Policy.
86 Caller to free() result in domain, username, password
89 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
91 *username = secrets_fetch(SECRETS_AUTH_USER, NULL);
92 *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
93 *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
95 if (*username && **username) {
97 if (!*domain || !**domain)
98 *domain = smb_xstrdup(lp_workgroup());
100 if (!*password || !**password)
101 *password = smb_xstrdup("");
103 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
104 *domain, *username));
106 } else {
107 DEBUG(3, ("IPC$ connections done anonymously\n"));
108 *username = smb_xstrdup("");
109 *domain = smb_xstrdup("");
110 *password = smb_xstrdup("");
114 /* Open a connction to the remote server, cache failures for 30 seconds */
116 static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index,
117 struct winbindd_cm_conn *new_conn)
119 NTSTATUS result;
120 char *machine_password;
121 char *machine_krb5_principal, *ipc_username, *ipc_domain, *ipc_password;
122 struct in_addr dc_ip;
123 int i;
124 BOOL retry = True;
126 ZERO_STRUCT(dc_ip);
128 fstrcpy(new_conn->domain, domain->name);
130 /* connection failure cache has been moved inside of get_dc_name
131 so we can deal with half dead DC's --jerry */
133 if (!get_dc_name(domain->name, domain->alt_name[0] ? domain->alt_name : NULL,
134 new_conn->controller, &dc_ip)) {
135 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
136 add_failed_connection_entry(domain->name, "", result);
137 return result;
140 /* Initialise SMB connection */
141 fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
143 /* grab stored passwords */
144 machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
146 if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(), lp_realm()) == -1) {
147 SAFE_FREE(machine_password);
148 return NT_STATUS_NO_MEMORY;
151 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
153 for (i = 0; retry && (i < 3); i++) {
154 BOOL got_mutex;
155 if (!(got_mutex = secrets_named_mutex(new_conn->controller, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
156 DEBUG(0,("cm_open_connection: mutex grab failed for %s\n", new_conn->controller));
157 result = NT_STATUS_POSSIBLE_DEADLOCK;
158 continue;
161 new_conn->cli = NULL;
162 result = cli_start_connection(&new_conn->cli, global_myname(),
163 new_conn->controller,
164 &dc_ip, 0, Undefined,
165 CLI_FULL_CONNECTION_USE_KERBEROS,
166 &retry);
168 if (NT_STATUS_IS_OK(result)) {
170 /* reset the error code */
171 result = NT_STATUS_UNSUCCESSFUL;
173 /* Krb5 session */
175 if ((lp_security() == SEC_ADS)
176 && (new_conn->cli->protocol >= PROTOCOL_NT1 && new_conn->cli->capabilities & CAP_EXTENDED_SECURITY)) {
177 ADS_STATUS ads_status;
178 new_conn->cli->use_kerberos = True;
179 DEBUG(5, ("connecting to %s from %s with kerberos principal [%s]\n",
180 new_conn->controller, global_myname(), machine_krb5_principal));
182 ads_status = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal,
183 machine_password,
184 lp_workgroup());
185 if (!ADS_ERR_OK(ads_status)) {
186 DEBUG(4,("failed kerberos session setup with %s\n", ads_errstr(ads_status)));
187 result = ads_ntstatus(ads_status);
188 } else {
189 result = NT_STATUS_OK;
192 new_conn->cli->use_kerberos = False;
194 /* only do this is we have a username/password for thr IPC$ connection */
196 if ( !NT_STATUS_IS_OK(result)
197 && new_conn->cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
198 && strlen(ipc_username) )
200 DEBUG(5, ("connecting to %s from %s with username [%s]\\[%s]\n",
201 new_conn->controller, global_myname(), ipc_domain, ipc_username));
203 result = NT_STATUS_OK;
205 if (!cli_session_setup(new_conn->cli, ipc_username,
206 ipc_password, strlen(ipc_password)+1,
207 ipc_password, strlen(ipc_password)+1,
208 ipc_domain)) {
209 result = cli_nt_error(new_conn->cli);
210 DEBUG(4,("failed authenticated session setup with %s\n", nt_errstr(result)));
211 if (NT_STATUS_IS_OK(result))
212 result = NT_STATUS_UNSUCCESSFUL;
216 /* anonymous is all that is left if we get to here */
218 if (!NT_STATUS_IS_OK(result)) {
220 DEBUG(5, ("anonymous connection attempt to %s from %s\n",
221 new_conn->controller, global_myname()));
223 result = NT_STATUS_OK;
225 if (!cli_session_setup(new_conn->cli, "", NULL, 0, NULL, 0, ""))
227 result = cli_nt_error(new_conn->cli);
228 DEBUG(4,("failed anonymous session setup with %s\n", nt_errstr(result)));
229 if (NT_STATUS_IS_OK(result))
230 result = NT_STATUS_UNSUCCESSFUL;
235 if (NT_STATUS_IS_OK(result) && !cli_send_tconX(new_conn->cli, "IPC$", "IPC",
236 "", 0)) {
237 result = cli_nt_error(new_conn->cli);
238 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
239 cli_shutdown(new_conn->cli);
240 if (NT_STATUS_IS_OK(result)) {
241 result = NT_STATUS_UNSUCCESSFUL;
246 if (NT_STATUS_IS_OK(result)) {
247 struct ntuser_creds creds;
248 init_creds(&creds, ipc_username, ipc_domain, ipc_password);
249 cli_init_creds(new_conn->cli, &creds);
252 if (got_mutex)
253 secrets_named_mutex_release(new_conn->controller);
255 if (NT_STATUS_IS_OK(result))
256 break;
259 SAFE_FREE(ipc_username);
260 SAFE_FREE(ipc_domain);
261 SAFE_FREE(ipc_password);
262 SAFE_FREE(machine_password);
264 if (!NT_STATUS_IS_OK(result)) {
265 add_failed_connection_entry(domain->name, new_conn->controller, result);
266 return result;
269 /* set the domain if empty; needed for schannel connections */
270 if ( !*new_conn->cli->domain )
271 fstrcpy( new_conn->cli->domain, domain->name );
274 if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
275 result = NT_STATUS_PIPE_NOT_AVAILABLE;
277 * only cache a failure if we are not trying to open the
278 * **win2k** specific lsarpc UUID. This could be an NT PDC
279 * and therefore a failure is normal. This should probably
280 * be abstracted to a check for 2k specific pipes and wondering
281 * if the PDC is an NT4 box. but since there is only one 2k
282 * specific UUID right now, i'm not going to bother. --jerry
284 if ( !is_win2k_pipe(pipe_index) )
285 add_failed_connection_entry(domain->name, new_conn->controller, result);
286 cli_shutdown(new_conn->cli);
287 return result;
290 return NT_STATUS_OK;
293 /************************************************************************
294 Wrapper around statuc cm_open_connection to retreive a freshly
295 setup cli_state struct
296 ************************************************************************/
298 NTSTATUS cm_fresh_connection(struct winbindd_domain *domain, const int pipe_index,
299 struct cli_state **cli)
301 NTSTATUS result;
302 struct winbindd_cm_conn conn;
304 result = cm_open_connection( domain, pipe_index, &conn );
306 if ( NT_STATUS_IS_OK(result) )
307 *cli = conn.cli;
309 return result;
312 /* Return true if a connection is still alive */
314 static BOOL connection_ok(struct winbindd_cm_conn *conn)
316 if (!conn) {
317 smb_panic("Invalid parameter passed to connection_ok(): conn was NULL!\n");
318 return False;
321 if (!conn->cli) {
322 DEBUG(3, ("Connection to %s for domain %s (pipe %s) has NULL conn->cli!\n",
323 conn->controller, conn->domain, conn->pipe_name));
324 return False;
327 if (!conn->cli->initialised) {
328 DEBUG(3, ("Connection to %s for domain %s (pipe %s) was never initialised!\n",
329 conn->controller, conn->domain, conn->pipe_name));
330 return False;
333 if (conn->cli->fd == -1) {
334 DEBUG(3, ("Connection to %s for domain %s (pipe %s) has died or was never started (fd == -1)\n",
335 conn->controller, conn->domain, conn->pipe_name));
336 return False;
339 return True;
342 /* Search the cache for a connection. If there is a broken one,
343 shut it down properly and return NULL. */
345 static void find_cm_connection(struct winbindd_domain *domain, const char *pipe_name,
346 struct winbindd_cm_conn **conn_out)
348 struct winbindd_cm_conn *conn;
350 for (conn = cm_conns; conn; ) {
351 if (strequal(conn->domain, domain->name) &&
352 strequal(conn->pipe_name, pipe_name)) {
353 if (!connection_ok(conn)) {
354 /* Dead connection - remove it. */
355 struct winbindd_cm_conn *conn_temp = conn->next;
356 if (conn->cli)
357 cli_shutdown(conn->cli);
358 DLIST_REMOVE(cm_conns, conn);
359 SAFE_FREE(conn);
360 conn = conn_temp; /* Keep the loop moving */
361 continue;
362 } else {
363 break;
366 conn = conn->next;
369 *conn_out = conn;
372 /* Initialize a new connection up to the RPC BIND. */
374 static NTSTATUS new_cm_connection(struct winbindd_domain *domain, const char *pipe_name,
375 struct winbindd_cm_conn **conn_out)
377 struct winbindd_cm_conn *conn;
378 NTSTATUS result;
380 if (!(conn = malloc(sizeof(*conn))))
381 return NT_STATUS_NO_MEMORY;
383 ZERO_STRUCTP(conn);
385 if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) {
386 DEBUG(3, ("Could not open a connection to %s for %s (%s)\n",
387 domain->name, pipe_name, nt_errstr(result)));
388 SAFE_FREE(conn);
389 return result;
391 DLIST_ADD(cm_conns, conn);
393 *conn_out = conn;
394 return NT_STATUS_OK;
397 /* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */
399 static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain, const char *pipe_name,
400 struct winbindd_cm_conn **conn_out)
402 find_cm_connection(domain, pipe_name, conn_out);
404 if (*conn_out != NULL)
405 return NT_STATUS_OK;
407 return new_cm_connection(domain, pipe_name, conn_out);
410 /**********************************************************************************
411 We can 'sense' certain things about the DC by it's replies to certain questions.
413 This tells us if this particular remote server is Active Directory, and if it is
414 native mode.
415 **********************************************************************************/
417 void set_dc_type_and_flags( struct winbindd_domain *domain )
419 NTSTATUS result;
420 struct winbindd_cm_conn conn;
421 DS_DOMINFO_CTR ctr;
422 TALLOC_CTX *mem_ctx;
424 ZERO_STRUCT( conn );
425 ZERO_STRUCT( ctr );
427 domain->native_mode = False;
428 domain->active_directory = False;
430 if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) {
431 DEBUG(5, ("set_dc_type_and_flags: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
432 domain->name, nt_errstr(result)));
433 return;
436 if ( conn.cli ) {
437 if ( !NT_STATUS_IS_OK(cli_ds_getprimarydominfo( conn.cli,
438 conn.cli->mem_ctx, DsRolePrimaryDomainInfoBasic, &ctr)) ) {
439 goto done;
443 if ( (ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING)
444 && !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
445 domain->native_mode = True;
447 /* Cheat - shut down the DS pipe, and open LSA */
449 cli_nt_session_close(conn.cli);
451 if ( cli_nt_session_open (conn.cli, PI_LSARPC) ) {
452 char *domain_name = NULL;
453 char *dns_name = NULL;
454 DOM_SID *dom_sid = NULL;
456 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n", domain->name);
457 if (!mem_ctx) {
458 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
459 return;
462 result = cli_lsa_open_policy2(conn.cli, mem_ctx, True,
463 SEC_RIGHTS_MAXIMUM_ALLOWED,
464 &conn.pol);
466 if (NT_STATUS_IS_OK(result)) {
467 /* This particular query is exactly what Win2k clients use
468 to determine that the DC is active directory */
469 result = cli_lsa_query_info_policy2(conn.cli, mem_ctx,
470 &conn.pol,
471 12, &domain_name,
472 &dns_name, NULL,
473 NULL, &dom_sid);
476 if (NT_STATUS_IS_OK(result)) {
477 if (domain_name)
478 fstrcpy(domain->name, domain_name);
480 if (dns_name)
481 fstrcpy(domain->alt_name, dns_name);
483 if (dom_sid)
484 sid_copy(&domain->sid, dom_sid);
486 domain->active_directory = True;
487 } else {
489 result = cli_lsa_open_policy(conn.cli, mem_ctx, True,
490 SEC_RIGHTS_MAXIMUM_ALLOWED,
491 &conn.pol);
493 if (!NT_STATUS_IS_OK(result))
494 goto done;
496 result = cli_lsa_query_info_policy(conn.cli, mem_ctx,
497 &conn.pol, 5, &domain_name,
498 &dom_sid);
500 if (NT_STATUS_IS_OK(result)) {
501 if (domain_name)
502 fstrcpy(domain->name, domain_name);
504 if (dom_sid)
505 sid_copy(&domain->sid, dom_sid);
510 done:
512 /* close the connection; no other cals use this pipe and it is called only
513 on reestablishing the domain list --jerry */
515 if ( conn.cli )
516 cli_shutdown( conn.cli );
518 talloc_destroy(mem_ctx);
520 return;
525 /* Return a LSA policy handle on a domain */
527 NTSTATUS cm_get_lsa_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd)
529 struct winbindd_cm_conn *conn;
530 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
531 NTSTATUS result;
532 static CLI_POLICY_HND hnd;
534 /* Look for existing connections */
536 if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_LSARPC, &conn)))
537 return result;
539 /* This *shitty* code needs scrapping ! JRA */
541 if (policy_handle_is_valid(&conn->pol)) {
542 hnd.pol = conn->pol;
543 hnd.cli = conn->cli;
544 *return_hnd = &hnd;
546 return NT_STATUS_OK;
549 result = cli_lsa_open_policy(conn->cli, conn->cli->mem_ctx, False,
550 des_access, &conn->pol);
552 if (!NT_STATUS_IS_OK(result)) {
553 /* Hit the cache code again. This cleans out the old connection and gets a new one */
554 if (conn->cli->fd == -1) { /* Try again, if the remote host disapeared */
555 if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_LSARPC, &conn)))
556 return result;
558 result = cli_lsa_open_policy(conn->cli, conn->cli->mem_ctx, False,
559 des_access, &conn->pol);
562 if (!NT_STATUS_IS_OK(result)) {
563 cli_shutdown(conn->cli);
564 DLIST_REMOVE(cm_conns, conn);
565 SAFE_FREE(conn);
566 return result;
570 hnd.pol = conn->pol;
571 hnd.cli = conn->cli;
573 *return_hnd = &hnd;
575 return NT_STATUS_OK;
578 /* Return a SAM policy handle on a domain */
580 NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd)
582 struct winbindd_cm_conn *conn;
583 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
584 NTSTATUS result;
585 static CLI_POLICY_HND hnd;
587 /* Look for existing connections */
589 if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_SAMR, &conn)))
590 return result;
592 /* This *shitty* code needs scrapping ! JRA */
594 if (policy_handle_is_valid(&conn->pol)) {
595 hnd.pol = conn->pol;
596 hnd.cli = conn->cli;
598 *return_hnd = &hnd;
600 return NT_STATUS_OK;
603 result = cli_samr_connect(conn->cli, conn->cli->mem_ctx,
604 des_access, &conn->pol);
606 if (!NT_STATUS_IS_OK(result)) {
607 /* Hit the cache code again. This cleans out the old connection and gets a new one */
608 if (conn->cli->fd == -1) { /* Try again, if the remote host disapeared */
610 if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_SAMR, &conn)))
611 return result;
613 result = cli_samr_connect(conn->cli, conn->cli->mem_ctx,
614 des_access, &conn->pol);
617 if (!NT_STATUS_IS_OK(result)) {
619 cli_shutdown(conn->cli);
620 DLIST_REMOVE(cm_conns, conn);
621 SAFE_FREE(conn);
623 return result;
627 hnd.pol = conn->pol;
628 hnd.cli = conn->cli;
630 *return_hnd = &hnd;
632 return NT_STATUS_OK;
635 /* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
636 netlogon pipe as no handle is returned. */
638 NTSTATUS cm_get_netlogon_cli(struct winbindd_domain *domain,
639 const unsigned char *trust_passwd,
640 uint32 sec_channel_type,
641 BOOL fresh,
642 struct cli_state **cli)
644 NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
645 struct winbindd_cm_conn *conn;
646 fstring lock_name;
647 BOOL got_mutex;
649 if (!cli)
650 return NT_STATUS_INVALID_PARAMETER;
652 /* Open an initial conection - keep the mutex. */
654 find_cm_connection(domain, PIPE_NETLOGON, &conn);
656 if ( fresh && (conn != NULL) ) {
657 cli_shutdown(conn->cli);
658 conn->cli = NULL;
660 conn = NULL;
662 /* purge connection from cache */
663 find_cm_connection(domain, PIPE_NETLOGON, &conn);
664 if (conn != NULL) {
665 DEBUG(0,("Could not purge connection\n"));
666 return NT_STATUS_UNSUCCESSFUL;
670 if (conn != NULL) {
671 *cli = conn->cli;
672 return NT_STATUS_OK;
675 result = new_cm_connection(domain, PIPE_NETLOGON, &conn);
677 if (!NT_STATUS_IS_OK(result))
678 return result;
680 fstr_sprintf(lock_name, "NETLOGON\\%s", conn->controller);
682 if (!(got_mutex = secrets_named_mutex(lock_name, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
683 DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
686 if ( sec_channel_type == SEC_CHAN_DOMAIN )
687 fstr_sprintf(conn->cli->mach_acct, "%s$", lp_workgroup());
690 fstrcpy( conn->cli->domain, domain->name);
693 result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd);
695 if (got_mutex)
696 secrets_named_mutex_release(lock_name);
698 if (!NT_STATUS_IS_OK(result)) {
699 cli_shutdown(conn->cli);
700 DLIST_REMOVE(cm_conns, conn);
701 SAFE_FREE(conn);
702 return result;
705 *cli = conn->cli;
707 return result;
710 /* Dump the current connection status */
712 static void dump_conn_list(void)
714 struct winbindd_cm_conn *con;
716 DEBUG(0, ("\tDomain Controller Pipe\n"));
718 for(con = cm_conns; con; con = con->next) {
719 char *msg;
721 /* Display pipe info */
723 if (asprintf(&msg, "\t%-15s %-15s %-16s", con->domain, con->controller, con->pipe_name) < 0) {
724 DEBUG(0, ("Error: not enough memory!\n"));
725 } else {
726 DEBUG(0, ("%s\n", msg));
727 SAFE_FREE(msg);
732 void winbindd_cm_status(void)
734 /* List open connections */
736 DEBUG(0, ("winbindd connection manager status:\n"));
738 if (cm_conns)
739 dump_conn_list();
740 else
741 DEBUG(0, ("\tNo active connections\n"));
744 /* Close all cached connections */
746 void winbindd_cm_flush(void)
748 struct winbindd_cm_conn *conn, tmp;
750 /* Flush connection cache */
752 for (conn = cm_conns; conn; conn = conn->next) {
754 if (!connection_ok(conn))
755 continue;
757 DEBUG(10, ("Closing connection to %s on %s\n",
758 conn->pipe_name, conn->controller));
760 if (conn->cli)
761 cli_shutdown(conn->cli);
763 tmp.next = conn->next;
765 DLIST_REMOVE(cm_conns, conn);
766 SAFE_FREE(conn);
767 conn = &tmp;
770 /* Flush failed connection cache */
772 flush_negative_conn_cache();