Browse Source

Merge branch 'candidate-6.2.2' into candidate-6.4.0

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 8 years ago
parent
commit
dc208458bb

+ 183 - 0
docs/ECLWatch/TheECLWatchMan.xml

@@ -1138,6 +1138,189 @@
         </figure></para>
     </sect1>
 
+    <sect1 id="ECLWatch-DynamicESDL">
+      <title>Dynamic ESDL</title>
+
+      <para>The Dynamic ESDL tab in ECL Watch displays the available ESP
+      Services. You can explore the DESDL services and ESDL bindings, also
+      known as service configurations.</para>
+
+      <para>To access Dynamic ESDL through ECL Watch, click on the <emphasis
+      role="bold">Operations</emphasis> link, then click on <emphasis
+      role="bold">Dynamic ESDL</emphasis> from the navigation sub-menu
+      bar.</para>
+
+      <para>The DESDL-based ESP services available are listed in the navigator
+      pane on the left as children of their parent ESP process.</para>
+
+      <figure>
+        <title>Dynamic ESDL sub-menu</title>
+
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="images/DESDL03.jpg" />
+          </imageobject>
+        </mediaobject>
+      </figure>
+
+      <para>This tab contains a list of all DESDL based ESP Services and their
+      ESDL Binding information.. For more information about Dynamic ESDL refer
+      to the documentation; <emphasis>Dynamic ESDL</emphasis> available from
+      the HPCC Systems portal: <ulink
+      url="https://hpccsystems.com/download/documentation/learning-ecl/dynamic-esdl">https://hpccsystems.com/download/documentation/learning-ecl/dynamic-esdl</ulink></para>
+
+      <sect2 id="USING_Dynamic_ESDL">
+        <title>Using Dynamic ESDL</title>
+
+        <para>Click on the triangle icon next to the ESP process to expand and
+        display the DESDL services. Select the desired DESDL service from the
+        navigator pane.</para>
+
+        <para>The selected service's information displays on the <emphasis
+        role="bold">Summary</emphasis> tab to the right.</para>
+
+        <para>Select the <emphasis role="bold">Binding</emphasis> tab to
+        display the ESDL definition in XML format and the configuration
+        information. Press the Definition button to view the XML.</para>
+
+        <para><figure>
+            <title>Dynamic ESDL Binding Definition</title>
+
+            <mediaobject>
+              <imageobject>
+                <imagedata fileref="images/DESDL02.jpg" />
+              </imageobject>
+            </mediaobject>
+          </figure></para>
+
+        <para>You can select ESP Services and assign them an interface (an
+        ESDL Definition) and configure each available method.</para>
+
+        <sect3 id="Configure_ESDL_Bindings">
+          <title>Configuring ESDL Bindings</title>
+
+          <para>You can select a service and if there is a binding for it you
+          can review, delete, or modify the configuration of that
+          binding.</para>
+
+          <para>Press the <emphasis role="bold">Configuration</emphasis>
+          button to view or edit the method configurations. The methods are
+          configured by adding or editing these attributes. <figure>
+              <title>Dynamic EDSL Binding Configuration</title>
+
+              <mediaobject>
+                <imageobject>
+                  <imagedata fileref="images/DESDL04.jpg" />
+                </imageobject>
+              </mediaobject>
+            </figure></para>
+
+          <para><emphasis role="bold">To Add an attribute:</emphasis></para>
+
+          <para><orderedlist>
+              <listitem>
+                <para>Expand the target method configuration attributes (if
+                there are more than one methods) and display the attributes
+                and values.</para>
+              </listitem>
+
+              <listitem>
+                <para>Check the box next to the method to modify.</para>
+              </listitem>
+
+              <listitem>
+                <para>Press the Add Attribute(s) button. This opens an
+                <emphasis role="bold">Add attributes/values</emphasis>
+                dialog.</para>
+              </listitem>
+
+              <listitem>
+                <para>Enter the Attribute and Value to the method,</para>
+              </listitem>
+
+              <listitem>
+                <para>Press the Save button.</para>
+              </listitem>
+            </orderedlist><emphasis role="bold">To Remove attributes and
+          values</emphasis>:.</para>
+
+          <para><orderedlist>
+              <listitem>
+                <para>Check the box next to the method to modify.</para>
+              </listitem>
+
+              <listitem>
+                <para>Select the box for the desired attribute (and value) to
+                remove.</para>
+              </listitem>
+
+              <listitem>
+                <para>Press the <emphasis role="bold">Remove
+                Attribute(s)</emphasis> button. This removes the
+                attribute.</para>
+              </listitem>
+            </orderedlist></para>
+
+          <para>If a configuration does not have a binding, you can add a
+          binding.</para>
+        </sect3>
+
+        <sect3>
+          <title>Add a Binding</title>
+
+          <para>To add a service binding to an
+          <emphasis>unconfigured</emphasis> ESP Service. Select the
+          unconfigured ESP service, then press the enabled <emphasis
+          role="bold">Add Binding</emphasis> button.</para>
+
+          <para><figure>
+              <title>Adding a service binding</title>
+
+              <mediaobject>
+                <imageobject>
+                  <imagedata fileref="images/DESDL05.jpg" />
+                </imageobject>
+              </mediaobject>
+            </figure>This will open a dialog listing the available interfaces
+          that have definitions. Select the interface to bind to the ESP
+          service.</para>
+
+          <para><figure>
+              <title>Adding the definition</title>
+
+              <mediaobject>
+                <imageobject>
+                  <imagedata fileref="images/DESDL06.jpg" />
+                </imageobject>
+              </mediaobject>
+            </figure>Press the <emphasis role="bold">Apply</emphasis> button
+          to apply the definition.</para>
+        </sect3>
+
+        <sect3>
+          <title>Delete a Binding</title>
+
+          <para>To delete a service binding for a
+          <emphasis>configured</emphasis> ESP Service. Select the ESP service
+          that contains the binding to delete.</para>
+
+          <para><figure>
+              <title>Deleting service binding</title>
+
+              <mediaobject>
+                <imageobject>
+                  <imagedata fileref="images/DESDL07.jpg" />
+                </imageobject>
+              </mediaobject>
+            </figure>Press the <emphasis role="bold">Delete Binding</emphasis>
+          button. Confirm that you want to delete the binding by pressing OK
+          on the confirmation dialog.</para>
+
+          <para>The binding is deleted.</para>
+        </sect3>
+      </sect2>
+    </sect1>
+
     <xi:include href="HPCCCertify/Cert-Mods/CertPreflight.xml"
                 xpointer="Preflight_system_servers"
                 xmlns:xi="http://www.w3.org/2001/XInclude" />

BIN
docs/images/DESDL01.jpg


BIN
docs/images/DESDL02.jpg


BIN
docs/images/DESDL03.jpg


BIN
docs/images/DESDL04.jpg


BIN
docs/images/DESDL05.jpg


BIN
docs/images/DESDL06.jpg


BIN
docs/images/DESDL07.jpg


+ 6 - 6
esp/scm/ws_esdlconfig.ecm

@@ -23,9 +23,9 @@ ESPstruct BaseESDLStatus
 
 ESPStruct MethodConfig
 {
-    String Name;
+    string Name;
     ESParray<ESPstruct NamedValue, Attribute> Attributes;
-    String Elements;
+    string Elements;
 };
 
 ESPStruct ESDLConfiguration
@@ -41,10 +41,10 @@ ESPstruct ESDLBinding
 
 ESPstruct ESDLDefinition
 {
-    String Name;
+    string Name;
     int Seq;
-    String Id;
-    [min_ver("1.1")] String Interface;
+    string Id;
+    [min_ver("1.1")] string Interface;
     [min_ver("1.2")] ESParray<string, Name> ESDLServices;
 };
 
@@ -196,7 +196,7 @@ ESPresponse [exceptions_inline] GetESDLBindingResponse
     string EspProcName;   //Name of ESP Process
     string BindingName;
     string EspPort;
-    String ConfigXML;
+    string ConfigXML;
     [min_ver("1.1")] ESPStruct ESDLBindingContents ESDLBinding;
     ESPstruct BaseESDLStatus status;
 };

+ 1 - 1
initfiles/componentfiles/configxml/dali.xsl

@@ -297,7 +297,7 @@
             </xsl:attribute>
 
             <xsl:for-each select="$ldapServerNode">
-              <xsl:copy-of select="@ldapPort | @ldapSecurePort | @cacheTimeout | @workunitsBasedn | @modulesBasedn | @systemBasedn | @systemCommonName | @systemUser | @systemPassword | @usersBasedn | @groupsBasedn| @viewsBasedn | @serverType"/>
+              <xsl:copy-of select="@ldapPort | @ldapSecurePort | @ldapTimeoutSecs | @cacheTimeout | @workunitsBasedn | @modulesBasedn | @systemBasedn | @systemCommonName | @systemUser | @systemPassword | @usersBasedn | @groupsBasedn| @viewsBasedn | @serverType"/>
             </xsl:for-each>
           </xsl:element>
         </xsl:if>

+ 8 - 0
initfiles/componentfiles/configxml/ldapserver.xsd

@@ -162,6 +162,14 @@
                     </xs:appinfo>
                 </xs:annotation>
             </xs:attribute>
+            <xs:attribute name="ldapTimeoutSecs" type="xs:nonNegativeInteger" use="optional" default="60">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <required>true</required>
+                        <tooltip>The maximum number of seconds to wait for most LDAP calls.</tooltip>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:attribute>
             <xs:attribute name="cacheTimeout" type="xs:nonNegativeInteger" use="optional" default="5">
                 <xs:annotation>
                     <xs:appinfo>

+ 57 - 45
system/security/LdapSecurity/ldapconnection.cpp

@@ -268,6 +268,8 @@ private:
     int                  m_maxConnections;
     
     StringBuffer         m_sdfieldname;
+
+    int                  m_timeout;
 public:
     IMPLEMENT_IINTERFACE
 
@@ -329,6 +331,8 @@ public:
         else
             m_ldap_secure_port = atoi(portbuf.str());
 
+        m_timeout = cfg->getPropInt(".//@ldapTimeoutSecs", LDAPTIMEOUT);
+
         int rc = LDAP_OTHER;
         StringBuffer hostbuf, dcbuf;
         const char * ldapDomain = cfg->queryProp(".//@ldapDomain");
@@ -337,7 +341,7 @@ public:
             getLdapHost(hostbuf);
             for(int retries = 0; retries <= LDAPSEC_MAX_RETRIES; retries++)
             {
-                rc = LdapUtils::getServerInfo(hostbuf.str(), m_ldapport, dcbuf, m_serverType, ldapDomain);
+                rc = LdapUtils::getServerInfo(hostbuf.str(), m_ldapport, dcbuf, m_serverType, ldapDomain, m_timeout);
                 if(!LdapServerDown(rc) || retries >= LDAPSEC_MAX_RETRIES)
                     break;
                 sleep(LDAPSEC_RETRY_WAIT);
@@ -670,6 +674,11 @@ public:
         else if(m_serverType == IPLANET)
             sysuser_basedn.append("ou=administrators,ou=topologymanagement,o=netscaperoot");
     }
+
+    virtual int getLdapTimeout()
+    {
+        return m_timeout;
+    }
 };
 
 
@@ -712,9 +721,9 @@ private:
         m_ld = LdapUtils::LdapInit(protocol, ldapserver, m_ldapconfig->getLdapPort(), m_ldapconfig->getLdapSecurePort());
         int rc = LDAP_SUCCESS;
         if(m_ldapconfig->sysuserSpecified())
-            rc =  LdapUtils::LdapBind(m_ld, m_ldapconfig->getDomain(), m_ldapconfig->getSysUser(), m_ldapconfig->getSysUserPassword(), m_ldapconfig->getSysUserDn(), m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
+            rc =  LdapUtils::LdapBind(m_ld, m_ldapconfig->getLdapTimeout(), m_ldapconfig->getDomain(), m_ldapconfig->getSysUser(), m_ldapconfig->getSysUserPassword(), m_ldapconfig->getSysUserDn(), m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
         else
-            rc =  LdapUtils::LdapBind(m_ld, m_ldapconfig->getDomain(), NULL, NULL, NULL, m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
+            rc =  LdapUtils::LdapBind(m_ld, m_ldapconfig->getLdapTimeout(), m_ldapconfig->getDomain(), NULL, NULL, NULL, m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
 
         if(rc == LDAP_SUCCESS)
         {
@@ -823,7 +832,7 @@ public:
         {
             LDAPMessage* msg = NULL;
             
-            TIMEVAL timeOut = {LDAPTIMEOUT,0};
+            TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
             int err = ldap_search_ext_s(m_ld, NULL, LDAP_SCOPE_BASE, "objectClass=*", NULL, 0, NULL, NULL, &timeOut, 1, &msg);
 
             if(msg != NULL)
@@ -1116,6 +1125,7 @@ private:
     struct berval * m_pCookie;
     LDAPMessage *   m_pPageEntry;
     LDAPMessage *   m_pPageBlock;
+    int             m_timeout;
 
     //local helper class, ensures ldap Page Control memory freed
     class CPageControlMemWrapper
@@ -1144,7 +1154,7 @@ private:
             return false;
 
         CPageControlMemWrapper pageCtrlMem;
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};
+        TIMEVAL timeOut = {m_timeout,0};
         try
         {
 #ifdef LDAP_API_FEATURE_PAGED_RESULTS
@@ -1250,10 +1260,12 @@ private:
 
 public:
 
-    CPagedLDAPSearch(LDAP* _pLdapConn, char * _pszDN, unsigned long _scope, char * _pszFilter, char * _pszAttrs[])
+    CPagedLDAPSearch(LDAP* _pLdapConn, int _timeout, char * _pszDN, unsigned long _scope, char * _pszFilter, char * _pszAttrs[])
     {
         m_pLdapConn =_pLdapConn;
+
         m_pszDN = _pszDN;
+        m_timeout = _timeout;
         m_scope = _scope;
         m_pszFilter = _pszFilter;
         m_pszAttrs = _pszAttrs;
@@ -1315,7 +1327,7 @@ public:
 };
 
 static CriticalSection  mpaCrit;
-static __int64 getMaxPwdAge(Owned<ILdapConnectionPool> _conns, const char * _baseDN)
+static __int64 getMaxPwdAge(Owned<ILdapConnectionPool> _conns, const char * _baseDN, int _timeout)
 {
     static time_t   lastPwdAgeCheck = 0;
     static __int64  maxPwdAge = PWD_NEVER_EXPIRES;
@@ -1328,7 +1340,7 @@ static __int64 getMaxPwdAge(Owned<ILdapConnectionPool> _conns, const char * _bas
     DBGLOG("Retrieving LDAP 'maxPwdAge'");
     char* attrs[] = {"maxPwdAge", NULL};
     CLDAPMessage searchResult;
-    TIMEVAL timeOut = {LDAPTIMEOUT,0};
+    TIMEVAL timeOut = {_timeout,0};
     Owned<ILdapConnection> lconn = _conns->getConnection();
     LDAP* sys_ld = ((CLdapConnection*)lconn.get())->getLd();
     int result = ldap_search_ext_s(sys_ld, (char*)_baseDN, LDAP_SCOPE_BASE, NULL,
@@ -1447,7 +1459,7 @@ public:
         __int64 time = 0;
         for (unsigned x=0; x < len; x++)
             time = time * 10 + ( (int)val[x] - '0');
-        time += getMaxPwdAge(m_connections,(char*)m_ldapconfig->getBasedn() );
+        time += getMaxPwdAge(m_connections,(char*)m_ldapconfig->getBasedn(), m_ldapconfig->getLdapTimeout());
         dt.setFromFILETIME(time);
         dt.adjustTime(dt.queryUtcToLocalDelta());
     }
@@ -1463,7 +1475,7 @@ public:
             if(!username || !*username || !password || !*password)
                 return false;
 
-            if (getMaxPwdAge(m_connections,(char*)m_ldapconfig->getBasedn()) != PWD_NEVER_EXPIRES)
+            if (getMaxPwdAge(m_connections,(char*)m_ldapconfig->getBasedn(), m_ldapconfig->getLdapTimeout()) != PWD_NEVER_EXPIRES)
                 m_domainPwdsNeverExpire = false;
             else
                 m_domainPwdsNeverExpire = true;
@@ -1500,7 +1512,7 @@ public:
             Owned<ILdapConnection> lconn = m_connections->getConnection();
             LDAP* sys_ld = ((CLdapConnection*)lconn.get())->getLd();
             CLDAPMessage searchResult;
-            TIMEVAL timeOut = {LDAPTIMEOUT,0};
+            TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
             int result = ldap_search_ext_s(sys_ld,
                             (char*)m_ldapconfig->getUserBasedn(), //distinguished name of the entry at which to start the search
                             LDAP_SCOPE_SUBTREE,
@@ -1523,7 +1535,7 @@ public:
             if(entries == 0)
             {
                 searchResult.ldapMsgFree();
-                TIMEVAL timeOut = {LDAPTIMEOUT,0};
+                TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
                 result = ldap_search_ext_s(sys_ld, (char*)m_ldapconfig->getSysUserBasedn(), LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs, 0, NULL, NULL, &timeOut, LDAP_NO_LIMIT, &searchResult.msg);
                 if(result != LDAP_SUCCESS)
                 {
@@ -1637,7 +1649,7 @@ public:
                 DBGLOG("LdapBind for user %s (retries=%d).", username, retries);
                 {
                     LDAP* user_ld = LdapUtils::LdapInit(m_ldapconfig->getProtocol(), hostbuf.str(), m_ldapconfig->getLdapPort(), m_ldapconfig->getLdapSecurePort());
-                    rc = LdapUtils::LdapBind(user_ld, m_ldapconfig->getDomain(), username, password, userdnbuf.str(), m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
+                    rc = LdapUtils::LdapBind(user_ld, m_ldapconfig->getLdapTimeout(), m_ldapconfig->getDomain(), username, password, userdnbuf.str(), m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
                     if(rc != LDAP_SUCCESS)
                         ldap_get_option(user_ld, LDAP_OPT_ERROR_STRING, &ldap_errstring);
                     LDAP_UNBIND(user_ld);
@@ -1660,7 +1672,7 @@ public:
                 {
                     WARNLOG("Using automatically obtained LDAP Server %s", dc.str());
                     LDAP* user_ld = LdapUtils::LdapInit(m_ldapconfig->getProtocol(), dc.str(), m_ldapconfig->getLdapPort(), m_ldapconfig->getLdapSecurePort());
-                    rc = LdapUtils::LdapBind(user_ld, m_ldapconfig->getDomain(), username, password, userdnbuf.str(), m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
+                    rc = LdapUtils::LdapBind(user_ld, m_ldapconfig->getLdapTimeout(), m_ldapconfig->getDomain(), username, password, userdnbuf.str(), m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
                     if(rc != LDAP_SUCCESS)
                         ldap_get_option(user_ld, LDAP_OPT_ERROR_STRING, &ldap_errstring);
                     LDAP_UNBIND(user_ld);
@@ -1924,7 +1936,7 @@ public:
         {
             CLdapSecUser* ldapuser = dynamic_cast<CLdapSecUser*>(&user);
 
-            TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+            TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
             Owned<ILdapConnection> lconn = m_connections->getConnection();
             LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
 
@@ -1995,7 +2007,7 @@ public:
 
             filter.append(user.getName());
 
-            TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+            TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
             
             Owned<ILdapConnection> lconn = m_connections->getConnection();
             LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -2115,7 +2127,7 @@ public:
             filter.appendf("entryid=%d", uid);
         }
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0}; 
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -2204,7 +2216,7 @@ public:
             act_fieldname = "uid";
         }
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0}; 
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -2279,7 +2291,7 @@ public:
         char        *attribute;       
         LDAPMessage *message;
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -2394,7 +2406,7 @@ public:
         else
             filter.append("objectClass=inetorgperson");
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -2420,7 +2432,7 @@ public:
 
         char *attrs[] = {act_fieldname, sid_fieldname, "cn", "userAccountControl", "pwdLastSet", "employeeNumber", NULL};
 
-        CPagedLDAPSearch pagedSrch(ld, (char*)m_ldapconfig->getUserBasedn(), LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
+        CPagedLDAPSearch pagedSrch(ld, m_ldapconfig->getLdapTimeout(), (char*)m_ldapconfig->getUserBasedn(), LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
         for (message = pagedSrch.getFirstEntry(); message; message = pagedSrch.getNextEntry())
         {
             bool accountPwdNeverExpires = false;
@@ -3054,7 +3066,7 @@ public:
         char        *attribute, **values = NULL;
         LDAPMessage *message;
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         StringBuffer filter;
         filter.append("sAMAccountName=").append(username);
@@ -3145,7 +3157,7 @@ public:
         m_ldapconfig->getLdapHost(hostbuf);
 
         LDAP* user_ld = LdapUtils::LdapInit(m_ldapconfig->getProtocol(), hostbuf.str(), m_ldapconfig->getLdapPort(), m_ldapconfig->getLdapSecurePort());
-        int rc = LdapUtils::LdapBind(user_ld, m_ldapconfig->getDomain(), username, password, userdn, m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
+        int rc = LdapUtils::LdapBind(user_ld, m_ldapconfig->getLdapTimeout(),m_ldapconfig->getDomain(), username, password, userdn, m_ldapconfig->getServerType(), m_ldapconfig->getAuthMethod());
         if(rc != LDAP_SUCCESS)
             ldap_get_option(user_ld, LDAP_OPT_ERROR_STRING, &ldap_errstring);
         LDAP_UNBIND(user_ld);
@@ -3275,7 +3287,7 @@ public:
             char        **values = NULL;
             LDAPMessage *message;
 
-            TIMEVAL timeOut = {LDAPTIMEOUT,0};
+            TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
             Owned<ILdapConnection> lconn = m_connections->getConnection();
             LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -3334,7 +3346,7 @@ public:
         LdapUtils::normalizeDn(basedn, m_ldapconfig->getBasedn(), basednbuf);
         StringBuffer filter("objectClass=*");
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -3347,7 +3359,7 @@ public:
             fldname = "ou";
         char        *attrs[] = {(char*)fldname, "description", NULL};
 
-        CPagedLDAPSearch pagedSrch(ld, (char*)basednbuf.str(), LDAP_SCOPE_ONELEVEL, (char*)filter.str(), attrs);
+        CPagedLDAPSearch pagedSrch(ld, m_ldapconfig->getLdapTimeout(), (char*)basednbuf.str(), LDAP_SCOPE_ONELEVEL, (char*)filter.str(), attrs);
         for (message = pagedSrch.getFirstEntry(); message; message = pagedSrch.getNextEntry())
         {
             // Go through the search results by checking message types
@@ -3415,7 +3427,7 @@ public:
             filter.appendf(")(|(%s=*%s*)))", "uNCName", searchstr);
         }
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -3428,7 +3440,7 @@ public:
             fldname = "ou";
         char        *attrs[] = {(char*)fldname, "description", NULL};
 
-        CPagedLDAPSearch pagedSrch(ld, (char*)basednbuf.str(), LDAP_SCOPE_ONELEVEL, (char*)filter.str(), attrs);
+        CPagedLDAPSearch pagedSrch(ld, m_ldapconfig->getLdapTimeout(), (char*)basednbuf.str(), LDAP_SCOPE_ONELEVEL, (char*)filter.str(), attrs);
         for (message = pagedSrch.getFirstEntry(); message; message = pagedSrch.getNextEntry())
         {
             // Go through the search results by checking message types
@@ -3614,13 +3626,13 @@ public:
         else
             filter.append("objectClass=groupofuniquenames");
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
         char *attrs[] = {"cn", "managedBy", "description", NULL};
 
-        CPagedLDAPSearch pagedSrch(ld, baseDN==nullptr ? (char*)m_ldapconfig->getGroupBasedn() : (char*)baseDN, LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
+        CPagedLDAPSearch pagedSrch(ld, m_ldapconfig->getLdapTimeout(), baseDN==nullptr ? (char*)m_ldapconfig->getGroupBasedn() : (char*)baseDN, LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
         for (message = pagedSrch.getFirstEntry(); message; message = pagedSrch.getNextEntry())
         {
             // Go through the search results by checking message types
@@ -3837,7 +3849,7 @@ public:
             StringBuffer filter("sAMAccountName=");
             filter.append(user);
 
-            TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+            TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
             Owned<ILdapConnection> lconn = m_connections->getConnection();
             LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -4124,7 +4136,7 @@ public:
             filter.append("cn=").append(groupname);
         }
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -4144,7 +4156,7 @@ public:
         StringBuffer groupbasedn;
         getGroupBaseDN(groupname, groupbasedn, groupsDN);
 
-        CPagedLDAPSearch pagedSrch(ld, (char*)groupbasedn.str(), LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
+        CPagedLDAPSearch pagedSrch(ld, m_ldapconfig->getLdapTimeout(), (char*)groupbasedn.str(), LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
         for (message = pagedSrch.getFirstEntry(); message; message = pagedSrch.getNextEntry())
         {
             // Go through the search results by checking message types
@@ -4399,13 +4411,13 @@ public:
 
     virtual int countEntries(const char* basedn, const char* filter, int limit)
     {
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
 
         char *attrs[] = { LDAP_NO_ATTRS, NULL };
-        CPagedLDAPSearch pagedSrch(ld, (char*)basedn, LDAP_SCOPE_SUBTREE, (char*)filter, attrs);
+        CPagedLDAPSearch pagedSrch(ld, m_ldapconfig->getLdapTimeout(), (char*)basedn, LDAP_SCOPE_SUBTREE, (char*)filter, attrs);
         int entries = pagedSrch.countEntries();
         return entries;
     }
@@ -4421,7 +4433,7 @@ public:
                 
                 char* pw_attrs[] = {"nsslapd-rootpwstoragescheme", NULL};
                 CLDAPMessage msg;
-                TIMEVAL timeOut = {LDAPTIMEOUT,0};
+                TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
                 int err = ldap_search_ext_s(ld, "cn=config", LDAP_SCOPE_BASE, "objectClass=*", pw_attrs, false, NULL, NULL, &timeOut, LDAP_NO_LIMIT, &msg.msg);
                 if(err != LDAP_SUCCESS)
                 {
@@ -4513,7 +4525,7 @@ private:
             char        *attribute;
             LDAPMessage *message;
 
-            TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+            TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
             char *dn_fieldname;
             dn_fieldname = "distinguishedName";
@@ -4594,7 +4606,7 @@ private:
         char        *attribute;
         LDAPMessage *message;
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         char *uid_fieldname = "sAMAccountName";
 
@@ -4920,7 +4932,7 @@ private:
         }
         filter.append(")");
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
         
         char* attrs[] = {(char*)id_fieldname, (char*)des_fieldname, NULL};
         Owned<ILdapConnection> lconn = m_connections->getConnection();
@@ -5087,7 +5099,7 @@ private:
         }
         filter.append(")");
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
         
         char* attrs[] = {sd_fieldname, NULL};
         Owned<ILdapConnection> lconn = m_connections->getConnection();
@@ -5170,7 +5182,7 @@ private:
         LDAP* sys_ld = ((CLdapConnection*)lconn.get())->getLd();
         char* attrs[] = {"ou", NULL};
         CLDAPMessage searchResult;
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
         int rc = ldap_search_ext_s(sys_ld,const_cast <char*>(ou),LDAP_SCOPE_ONELEVEL,NULL,attrs,0,NULL,NULL,&timeOut,LDAP_NO_LIMIT,&searchResult.msg);
         return rc == LDAP_SUCCESS;
     }
@@ -5588,7 +5600,7 @@ private:
         char        *attribute;
         LDAPMessage *message;
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};   
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         char        *attrs[] = {"userAccountControl", NULL};
         CLDAPMessage searchResult;
@@ -6005,7 +6017,7 @@ private:
         attrs[0] = &desc_attr;
         attrs[1] = nullptr;
 
-        TIMEVAL timeOut = { LDAPTIMEOUT, 0 };
+        TIMEVAL timeOut = { m_ldapconfig->getLdapTimeout(), 0 };
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*) lconn.get())->getLd();
 
@@ -6125,7 +6137,7 @@ private:
         else
             filter.append("objectClass=groupofuniquenames");
 
-        TIMEVAL timeOut = {LDAPTIMEOUT,0};
+        TIMEVAL timeOut = {m_ldapconfig->getLdapTimeout(),0};
 
         Owned<ILdapConnection> lconn = m_connections->getConnection();
         LDAP* ld = ((CLdapConnection*)lconn.get())->getLd();
@@ -6133,7 +6145,7 @@ private:
 
         StringBuffer dn;
         dn.appendf("CN=%s,%s", viewName, (char*)m_ldapconfig->getViewBasedn() );
-        CPagedLDAPSearch pagedSrch(ld, (char*)dn.str(), LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
+        CPagedLDAPSearch pagedSrch(ld, m_ldapconfig->getLdapTimeout(), (char*)dn.str(), LDAP_SCOPE_SUBTREE, (char*)filter.str(), attrs);
         int idx = 0;
         LDAPMessage *message = pagedSrch.getFirstEntry();
         if (message)

+ 2 - 1
system/security/LdapSecurity/ldapconnection.hpp

@@ -84,7 +84,7 @@ ldap_compare_ext_s LDAP_P((
 #ifdef _DEBUG
 	#define LDAPTIMEOUT 5
 #else
-	#define LDAPTIMEOUT 20
+	#define LDAPTIMEOUT 60
 #endif
 #define DEFAULT_LDAP_POOL_SIZE 10
 
@@ -186,6 +186,7 @@ interface ILdapConfig : extends IInterface
     virtual bool sysuserSpecified() = 0;
     virtual int getMaxConnections() = 0;
     virtual void setResourceBasedn(const char* rbasedn, SecResourceType rtype = RT_DEFAULT) = 0;
+    virtual int getLdapTimeout() = 0;
 };
 
 

+ 8 - 8
system/security/LdapSecurity/ldaputils.cpp

@@ -103,10 +103,10 @@ LDAP* LdapUtils::LdapInit(const char* protocol, const char* host, int port, int
     return ld;
 }
 
-int LdapUtils::LdapSimpleBind(LDAP* ld, char* userdn, char* password)
+int LdapUtils::LdapSimpleBind(LDAP* ld, int ldapTimeout, char* userdn, char* password)
 {
 #ifndef _WIN32
-    TIMEVAL timeout = {LDAPTIMEOUT, 0};
+    TIMEVAL timeout = {ldapTimeout, 0};
     ldap_set_option(ld, LDAP_OPT_TIMEOUT, &timeout);
     ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
 #endif
@@ -119,7 +119,7 @@ int LdapUtils::LdapSimpleBind(LDAP* ld, char* userdn, char* password)
 }
 
 // userdn is required for ldap_simple_bind_s, not really necessary for ldap_bind_s.
-int LdapUtils::LdapBind(LDAP* ld, const char* domain, const char* username, const char* password, const char* userdn, LdapServerType server_type, const char* method)
+int LdapUtils::LdapBind(LDAP* ld, int ldapTimeout, const char* domain, const char* username, const char* password, const char* userdn, LdapServerType server_type, const char* method)
 {
     bool binddone = false;
     int rc = LDAP_SUCCESS;
@@ -168,13 +168,13 @@ int LdapUtils::LdapBind(LDAP* ld, const char* domain, const char* username, cons
             DBGLOG("userdn can't be NULL in order to bind to ldap server.");
             return LDAP_INVALID_CREDENTIALS;
         }
-        int rc = LdapSimpleBind(ld, (char*)userdn, (char*)password);
+        int rc = LdapSimpleBind(ld, ldapTimeout, (char*)userdn, (char*)password);
         if (rc != LDAP_SUCCESS && server_type == OPEN_LDAP && strchr(userdn,','))
         {   //Fedora389 is happier without the domain component specified
             StringBuffer cn(userdn);
             cn.replace(',',(char)NULL);
             if (cn.length())//disallow call if no cn
-                rc = LdapSimpleBind(ld, (char*)cn.str(), (char*)password);
+                rc = LdapSimpleBind(ld, ldapTimeout, (char*)cn.str(), (char*)password);
         }
         if (rc != LDAP_SUCCESS )
         {
@@ -183,7 +183,7 @@ int LdapUtils::LdapBind(LDAP* ld, const char* domain, const char* username, cons
             {
                 StringBuffer logonname;
                 logonname.append(domain).append("\\").append(username);
-                rc = LdapSimpleBind(ld, (char*)logonname.str(), (char*)password);
+                rc = LdapSimpleBind(ld, ldapTimeout, (char*)logonname.str(), (char*)password);
                 if(rc != LDAP_SUCCESS)
                 {
 #ifdef LDAP_OPT_DIAGNOSTIC_MESSAGE
@@ -208,7 +208,7 @@ int LdapUtils::LdapBind(LDAP* ld, const char* domain, const char* username, cons
     return rc;
 }
 
-int LdapUtils::getServerInfo(const char* ldapserver, int ldapport, StringBuffer& domainDN, LdapServerType& stype, const char* domainname)
+int LdapUtils::getServerInfo(const char* ldapserver, int ldapport, StringBuffer& domainDN, LdapServerType& stype, const char* domainname, int timeout)
 {
     LdapServerType deducedSType = LDAPSERVER_UNKNOWN;
     LDAP* ld = LdapInit("ldap", ldapserver, ldapport, 636);
@@ -218,7 +218,7 @@ int LdapUtils::getServerInfo(const char* ldapserver, int ldapport, StringBuffer&
         return false;
     }
 
-    int err = LdapSimpleBind(ld, NULL, NULL);
+    int err = LdapSimpleBind(ld, timeout,NULL, NULL);
     if(err != LDAP_SUCCESS)
     {
         DBGLOG("ldap anonymous bind error (%d) - %s", err, ldap_err2string(err));

+ 3 - 3
system/security/LdapSecurity/ldaputils.hpp

@@ -38,11 +38,11 @@ class LdapUtils
 {
 public:
     static LDAP* LdapInit(const char* protocol, const char* host, int port, int secure_port);
-    static int LdapSimpleBind(LDAP* ld, char* userdn, char* password);
+    static int LdapSimpleBind(LDAP* ld, int ldapTimeout, char* userdn, char* password);
     // userdn is required for ldap_simple_bind_s, not really necessary for ldap_bind_s.
-    static int LdapBind(LDAP* ld, const char* domain, const char* username, const char* password, const char* userdn, LdapServerType server_type, const char* method="kerberos");
+    static int LdapBind(LDAP* ld, int ldapTimeout, const char* domain, const char* username, const char* password, const char* userdn, LdapServerType server_type, const char* method="kerberos");
     static void bin2str(MemoryBuffer& from, StringBuffer& to);
-    static int getServerInfo(const char* ldapserver, int ldapport, StringBuffer& domainDN, LdapServerType& stype, const char* domainname);
+    static int getServerInfo(const char* ldapserver, int ldapport, StringBuffer& domainDN, LdapServerType& stype, const char* domainname, int timeout);
     static void normalizeDn(const char* dn, const char* basedn, StringBuffer& dnbuf);
     static bool containsBasedn(const char* str);
     static void cleanupDn(const char* dn, StringBuffer& dnbuf);