Winbind hangs in ads_try_connect (SYN_SENT hang)

Phil Mayers p.mayers at imperial.ac.uk
Mon Jun 9 19:23:52 GMT 2003


All,

Not strictly a Samba bug, but definitely something it might want to
handle more gracefully.

For various reasons, a trusted domain of our main Win2K Active Directory
is running NT4, and one of the DCs has an IP registered in WINS which
isn't reachable (at least from where I am). This results in the
following in winbindd.log after doing a "wbinfo -m":

[2003/06/09 19:55:41, 10] libsmb/namequery.c:internal_resolve_name(926)
  internal_resolve_name: returning 6 addresses: 192.168.52.11
192.168.52.25 192.168.52.10 192.168.62.246 192.168.62.241 192.168.62.245 
[2003/06/09 19:55:41, 6] libads/ldap.c:ads_try_netbios(209)
  ads_try_netbios: trying server '192.168.52.11'
[2003/06/09 19:55:41, 5] libads/ldap.c:ads_try_connect(53)
  ads_try_connect: trying ldap server '192.168.52.11' port 389

The thing actually hangs inside "ldap_open" with the TCP socket in a
SYN_SENT state - strace shows:

write(4, "  ads_try_connect: trying ldap s"..., 63) = 63
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 18
fcntl64(18, F_GETFL)                    = 0x2 (flags O_RDWR)
fcntl64(18, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(18, {sin_family=AF_INET, sin_port=htons(389),
  sin_addr=inet_addr("192.168.52.11")}}, 16) = -1 EINPROGRESS (Operation
  now in progress)
select(1024, NULL, [18], NULL, NULL

The following patch seems to correct it for me:

diff -uNr samba-3.0.0beta1/source/libads/ldap.c
samba-3.0.0beta1-patched/source/libads/ldap.c
--- samba-3.0.0beta1/source/libads/ldap.c       2003-06-07 18:57:33.000000000 +0100
+++ samba-3.0.0beta1-patched/source/libads/ldap.c       2003-06-09 20:12:22.000000000 +0100
@@ -45,6 +45,7 @@
 static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server,
unsigned port)
 {
        char *srv;
+       struct timeval tv;
 
        if (!server || !*server) {
                return False;
@@ -55,11 +56,17 @@
        /* this copes with inet_ntoa brokenness */
        srv = strdup(server);
 
-       ads->ld = ldap_open(srv, port);
+       ads->ld = ldap_init(srv, port);
        if (!ads->ld) {
                free(srv);
                return False;
        }
+       /* Set the network layer timeout
+        * for unreachable or buggy servers
+        */
+       tv.tv_sec = 15; /* should be configureable */
+       tv.tv_usec = 0;
+       ldap_set_option(ads->ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
        ads->ldap_port = port;
        ads->ldap_ip = *interpret_addr2(srv);
        free(srv);

However, I'm not sure the error handling logic elsewhere in libads may
be setup to handle errors that would otherwise have resulted from
ldap_open actually failing to make the connection.

I note that ldap_open is listed as "deprecated" in the "ldap_open"
manpage on my RedHat 8 machine (OpenLDAP 2.0.27) in favour of
"ldap_init".

-- 

Regards,
Phil

+------------------------------------------+
| Phil Mayers                              |
| Network & Infrastructure Group           |
| Information & Communication Technologies |
| Imperial College                         |
+------------------------------------------+



More information about the samba-technical mailing list