Register a callback that tries to load other versions Open LDAP library if the defaul...
authorBuyaa Namnan <bunamnan@microsoft.com>
Mon, 17 Jul 2023 21:03:43 +0000 (14:03 -0700)
committerGitHub <noreply@github.com>
Mon, 17 Jul 2023 21:03:43 +0000 (14:03 -0700)
* Register a callback to AssemblyLoadContext.Default.ResolvingUnmanagedDll event that tries to load other libraries

* Do not throw when library not found

* Check version 2.6 first

src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs
src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs

index 836bd00..a8b0bd0 100644 (file)
@@ -9,7 +9,7 @@ internal static partial class Interop
         internal const string Liblog = "liblog";
 
         internal const string Odbc32 = "libodbc.so.2";
-        internal const string OpenLdap = "libldap-2.4.so.2";
+        internal const string OpenLdap = "libldap-2.5.so.0";
         internal const string MsQuic = "libmsquic.so";
     }
 }
index cfde193..0c34222 100644 (file)
@@ -2,8 +2,10 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
-using System.Runtime.InteropServices;
 using System.DirectoryServices.Protocols;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.Loader;
 
 namespace System.DirectoryServices.Protocols
 {
@@ -67,6 +69,26 @@ internal static partial class Interop
     {
         static Ldap()
         {
+            Assembly currentAssembly = typeof(Ldap).Assembly;
+
+            // Register callback that tries to load other libraries when the default library "libldap-2.5.so.0" not found
+            AssemblyLoadContext.GetLoadContext(currentAssembly).ResolvingUnmanagedDll += (assembly, ldapName) =>
+            {
+                if (assembly != currentAssembly || ldapName != Libraries.OpenLdap)
+                {
+                    return IntPtr.Zero;
+                }
+
+                // Try load next (libldap-2.6.so.0) or previous (libldap-2.4.so.2) versions
+                if (NativeLibrary.TryLoad("libldap-2.6.so.0", out IntPtr handle) ||
+                    NativeLibrary.TryLoad("libldap-2.4.so.2", out handle))
+                {
+                    return handle;
+                }
+
+                return IntPtr.Zero;
+            };
+
             // OpenLdap must be initialized on a single thread, once this is done it allows concurrent calls
             // By doing so in the static constructor we guarantee this is run before any other methods are called.