From 2260970634ce7738c7aa99d619d85be9b8d992c8 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Wed, 12 Jul 2023 21:00:45 -0700 Subject: [PATCH 1/4] Register a callback to AssemblyLoadContext.Default.ResolvingUnmanagedDll event that tries to load other libraries --- .../Interop/Linux/OpenLdap/Interop.Ldap.cs | 23 ++++++++++++++++++- .../src/Resources/Strings.resx | 3 +++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs index cfde1935a1f65e..8bd0f6ef5fa709 100644 --- a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Runtime.InteropServices; using System.DirectoryServices.Protocols; +using System.Runtime.InteropServices; +using System.Runtime.Loader; namespace System.DirectoryServices.Protocols { @@ -67,6 +68,26 @@ internal static partial class Ldap { static Ldap() { + // Register callback that tries to load other libraries when the default library "libldap-2.4.so.2" not found + AssemblyLoadContext.Default.ResolvingUnmanagedDll += (assembly, ldapName) => + { + IntPtr handle = IntPtr.Zero; + + if (ldapName != Libraries.OpenLdap) + { + return handle; + } + + if (NativeLibrary.TryLoad("libldap-2.5.so.0", out handle) || + NativeLibrary.TryLoad("libldap-2.6.so.0", out handle) || + NativeLibrary.TryLoad(Libraries.OpenLdap, out handle)) + { + return handle; + } + + throw new DllNotFoundException(SR.Format(SR.LDAP_LIBRARY_NOT_FOUND, ldapName)); + }; + // 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. diff --git a/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx b/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx index b63f103619fbdb..dfac5a12996192 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx +++ b/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx @@ -426,4 +426,7 @@ Only ReferralChasingOptions.None and ReferralChasingOptions.All are supported on Linux. + + The OpenLDAP library {0} not found. + \ No newline at end of file From 298469cddb757b7e7a7e3813a5ff4976a1c84ba2 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 14 Jul 2023 12:51:51 -0700 Subject: [PATCH 2/4] Apply feedbacks --- .../Common/src/Interop/Linux/Interop.Libraries.cs | 2 +- .../src/Interop/Linux/OpenLdap/Interop.Ldap.cs | 15 +++++++++------ .../src/Resources/Strings.resx | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs b/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs index 836bd00f9f7306..a8b0bd05a40794 100644 --- a/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs @@ -9,7 +9,7 @@ internal static partial class Libraries 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"; } } diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs index 8bd0f6ef5fa709..9b0095aacc8ddc 100644 --- a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs @@ -3,6 +3,7 @@ using System; using System.DirectoryServices.Protocols; +using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.Loader; @@ -68,19 +69,21 @@ internal static partial class Ldap { static Ldap() { - // Register callback that tries to load other libraries when the default library "libldap-2.4.so.2" not found - AssemblyLoadContext.Default.ResolvingUnmanagedDll += (assembly, ldapName) => + 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) => { IntPtr handle = IntPtr.Zero; - if (ldapName != Libraries.OpenLdap) + if (assembly != currentAssembly || ldapName != Libraries.OpenLdap) { return handle; } - if (NativeLibrary.TryLoad("libldap-2.5.so.0", out handle) || - NativeLibrary.TryLoad("libldap-2.6.so.0", out handle) || - NativeLibrary.TryLoad(Libraries.OpenLdap, out handle)) + // Try loading previous (libldap-2.4.so.2) and next (libldap-2.6.so.0) versions + if (NativeLibrary.TryLoad("libldap-2.4.so.2", out handle) || + NativeLibrary.TryLoad("libldap-2.6.so.0", out handle)) { return handle; } diff --git a/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx b/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx index dfac5a12996192..7b1c63e529b6ca 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx +++ b/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx @@ -427,6 +427,6 @@ Only ReferralChasingOptions.None and ReferralChasingOptions.All are supported on Linux. - The OpenLDAP library {0} not found. + The OpenLDAP library with version {0} was not found. \ No newline at end of file From 4d776fdabb37ae0e15e3d14cdc93a835c8d979e4 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 14 Jul 2023 14:22:18 -0700 Subject: [PATCH 3/4] Do not throw when library not found --- .../Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs | 8 +++----- .../src/Resources/Strings.resx | 3 --- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs index 9b0095aacc8ddc..eedeefc3ffa99d 100644 --- a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs @@ -74,21 +74,19 @@ static Ldap() // 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) => { - IntPtr handle = IntPtr.Zero; - if (assembly != currentAssembly || ldapName != Libraries.OpenLdap) { - return handle; + return IntPtr.Zero; } // Try loading previous (libldap-2.4.so.2) and next (libldap-2.6.so.0) versions - if (NativeLibrary.TryLoad("libldap-2.4.so.2", out handle) || + if (NativeLibrary.TryLoad("libldap-2.4.so.2", out IntPtr handle) || NativeLibrary.TryLoad("libldap-2.6.so.0", out handle)) { return handle; } - throw new DllNotFoundException(SR.Format(SR.LDAP_LIBRARY_NOT_FOUND, ldapName)); + return IntPtr.Zero; }; // OpenLdap must be initialized on a single thread, once this is done it allows concurrent calls diff --git a/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx b/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx index 7b1c63e529b6ca..b63f103619fbdb 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx +++ b/src/libraries/System.DirectoryServices.Protocols/src/Resources/Strings.resx @@ -426,7 +426,4 @@ Only ReferralChasingOptions.None and ReferralChasingOptions.All are supported on Linux. - - The OpenLDAP library with version {0} was not found. - \ No newline at end of file From a34961c1bf0982e083e4a5089995062bdb82b49d Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 17 Jul 2023 09:47:46 -0700 Subject: [PATCH 4/4] Check version 2.6 first --- .../Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs index eedeefc3ffa99d..0c34222f682059 100644 --- a/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs +++ b/src/libraries/Common/src/Interop/Linux/OpenLdap/Interop.Ldap.cs @@ -79,9 +79,9 @@ static Ldap() return IntPtr.Zero; } - // Try loading previous (libldap-2.4.so.2) and next (libldap-2.6.so.0) versions - if (NativeLibrary.TryLoad("libldap-2.4.so.2", out IntPtr handle) || - NativeLibrary.TryLoad("libldap-2.6.so.0", out handle)) + // 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; }