flamencist / ldap4net Goto Github PK
View Code? Open in Web Editor NEWOpenLdap port for DotNet Core (Linux\OSX\Windows)
License: MIT License
OpenLdap port for DotNet Core (Linux\OSX\Windows)
License: MIT License
Describe the bug
ToLdapEntry method messes up with binary values in such a way that they are not reversible.
To Reproduce
Expected behavior
I would expect the two methods to retain the same data among conversions.
Environment:
Additional context
This is quite an issue if you're using Search methods and you need to get binary attributes (e.g. objectSid or objectGuid). Also the SID conversion routines are internal so, if you're using SendRequest, you cannot make use of them for searching by objectSid.
I prepared a small NUnit test case for this: https://gist.github.com/axelgenus/622eca57b4e6218f0789136671a5cf72
Also, I ported from LDAP-wiki a very handy routine to get the objectSid SDDL string representation: https://gist.github.com/axelgenus/a9872a8bb57e3d3fa614dab3b9fa0b86
It would be nice if you could include both in LdapForNet.
I am using dependency injection to allow the mocking of ILdapConnection interface.
How can I mock the SearchAsync
method? I need to return "fake" values with fake attributes (fake name, fake sAMAccountName, etc).
_ldapConnectionMock.Setup(_ => _.SearchAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string[]>(),
It.IsAny<Native.LdapSearchScope>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new List<LdapEntry>()
{
new LdapEntry
{
DirectoryAttributes = new SearchResultAttributeCollection() // Internal, not visible
{
new DirectoryAttribute() // ???
}
}
});
Thank you in advance.
Is your feature request related to a problem? Please describe.
Hi!
I'm still working on an LDAP connection and trying to replace the DirectoryServices package by your LdapForNet package.
I need to find a replacement for LdapDirectoryIdentifier objects, but I can't find any, could you help me ?
Thank you a lot for your work, it is really great :)
Describe the bug
Search for objects dose not work on linux(ubuntu 18.04).
To Reproduce
add-type -AssemblyName /mnt/c/Users/kiranna/Source/LdapForNet.dll
$cn = [LdapForNet.LdapConnection]::new()
$cn.Connect("ldap://server.example.com:389",[LdapForNet.Native.Native+LdapVersion]::LDAP_VERSION3)
$base = "dc=example,dc=com"
$filter = "(&(objectcategory=person)(name=kiran*))"
$ldapcred = [LdapForNet.LdapCredential]::new()
$ldapcred.UserName = "admin"
$ldapcred.Password = "password"
$ldapcred.Realm = "example.com"
$cn.Bind([LdapForNet.Native.Native+LdapAuthType]::Digest,$ldapcred)
$cn.Search($base,$filter,"Name",[LdapForNet.Native.Native+LdapSearchScope]::LDAP_SCOPE_SUBTREE)
Expected behavior
The search function completes showing the returned objects.
Actual behavior
The search function seems to get stuck and never returns or times out.
Desktop (please complete the following information):
Additional context
The search works perfectly fine on windows with the same ldap server its only on linux that its failing.
Also the search works with ad lds on linux so something seems to be going wrong specifically with AD.I have also tried changing the ad server but same result. Perhaps I am missing some parameter or setting something incorrectly on linux.
Would appreciate an example where it works with AD on linux.
Is your feature request related to a problem? Please describe.
Now you couldn't handle invalid password with LdapException. Only parse message string and extract result code.
Describe the solution you'd like
Add result property to LdapException.
I am presently writing what amounts to a linux-based Active Directory proxy for authentication (I authenticate against AD then use AD group membership for API authorization).
With my current configuration, I use kinit <username>
to get and store a (static) Kerberos ticket for an Active Directory user. BindKerebos
uses this ticket to send LDAP requests to Active Directory, ignoring any supplied username and password.
Is there a way I can securely bind using a provided username and password combination?
(Edit: I guess I'm asking if you've implemented SASL yet.)
Is your feature request related to a problem? Please describe.
Opening new ldap connections is very expensive. It is better to reuse them, but this requires passing connections around your codebase. This is not an ideal solution.
Describe the solution you'd like
Many data access libraries contain a connection pooling mechanism, like Microsoft.Data.SqlClient for C#, and ldaptive for Java. I'd like a connection pooling mechanism for ldap4net.
Describe alternatives you've considered
Passing connections around.
Is it possible to use ldap4net library to achieve SASL proxy authorization scenario described here 15.3: http://www.openldap.org/doc/admin24/sasl.html#SASL%20Proxy%20Authorization ?
Describe the bug
Hi !
I would like to connect to my localhost:5389
server. The connection is okay but the binding will fail with a ServerDown
error.
To Reproduce
var server = "localhost:5389"
using var connection = new LdapConnection();
connection.Connect(server);
connection.Bind(LdapAuthType.Negotiate, credential);
When I use server = "http://localhost:5389"
the binding is successful.
Why can't I bind on the localhost without http or https ?
Desktop (please complete the following information):
Describe the bug
ObjectDisposedException occurs when cancelling the cancellation token used in async ldap request, after the request has already been completed.
Stack trace: https://pastebin.com/eWkb8dpB
To Reproduce
Desktop (please complete the following information):
Additional context
I believe the problem is in LdapConnection.ProcessResponse.
token.Register(() => Abandon(new AbandonRequest(messageId)));
The CancellationToken.Register method returns CancellationTokenRegistration, which should be disposed after the ldap request is completed.
In my case, i have a background HostedService, which gets a cancellation token from the framework.
I create a new linked cancellation token for each ldap operation, but the abandon registration isn't cleaned up, and is called long after original request - when the application stops, and the root cancellation token is cancelled.
Describe the bug
Hi ! I need to use a DirectoryAttribute
and convert it into strings but when I do it I have wrong values.
For example, if I convert a DirectoryAttribute
into a string and back into a DirectoryAttribute
, it won't have the same values. I am using a GUID like beneath :
To Reproduce
attribute = entry.Attributes["name"];
attribute.GetValues<string>().ToList();
var bytes = Encoding.ASCII.GetBytes(Values[0]);
var guid = new Guid(bytes).ToString("N", CultureInfo.InvariantCulture);
where attribute
is a DirectoryAttribute.
The bytes
object is only 15 bytes long whereas I need 16 bytes to create a GUID. My attribute
object is 16 bytes long so there is no reason for the bytes
not to be 16 bytes long.
In order to do a modify password in Active Directory (not admin reset) you need to create a single request with a Delete and then an Add of unicodePwd (https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/6e803168-f140-4d23-b2d3-c3a8ab5917d2).
But, since ModifyAttributeCollection
inherits from KeyedCollection<string, DirectoryAttribute>
it does not allow adding 2 attributes with the same name.
What is the purpose for this instead of having it inherit from something like List<DirectoryModificationAttribute>
?
I would be willing to do a pull request, but this is a potential breaking change...
var oldPasswordAttribute = new DirectoryModificationAttribute
{
Name = "unicodePwd",
LdapModOperation = Native.LdapModOperation.LDAP_MOD_DELETE
};
oldPasswordAttribute.Add(Encoding.Unicode.GetBytes($"\"{oldPassword}\""));
var newPasswordAttribute = new DirectoryModificationAttribute
{
Name = "unicodePwd",
LdapModOperation = Native.LdapModOperation.LDAP_MOD_ADD
};
newPasswordAttribute.Add(Encoding.Unicode.GetBytes($"\"{newPassword}\""));
var response = await _ldapConnection.Value.SendRequestAsync(new ModifyRequest(userDistinguishedName, oldPasswordAttribute, newPasswordAttribute));
First of all. Thank you for your effort. Very easy to use library which works very well.
I have just a small problem when for example the username has an ä
in his name. In this case i will get back "B�ck" when the expected value is "Bäck".
My Code:
private async Task<IEnumerable<LdapEntry>> QueryAsync(string filter)
{
using var ldapConnection = new LdapConnection();
ldapConnection.Connect(adOptions.LdapHost, ldapsPort, LdapForNet.Native.Native.LdapVersion.LDAP_VERSION3);
await ldapConnection.BindAsync(mechanism: LdapForNet.Native.Native.LdapAuthMechanism.SIMPLE, userDn: adOptions.LdapQueryUserDn, password: adOptions.LdapQueryUserPassword);
var entries = await ldapConnection.SearchAsync(adOptions.LdapBase, filter);
return entries;
}
I put a breakpoint on the return line and got the value "B�ck" with the following query in the watcher window.
entries.First().Attributes.Where(x => x.Key == "sn").First().Value.First()
Expected Value is "Bäck"
I have use Version 2.2.0 of your library which should according to your release notes contains support for unicode.
I can provide further details if needed.
Is your feature request related to a problem? Please describe.
There seems to be missing an option to specify the Autobind value. This might be a result of my ignorance on the subject of LDAP. I am specifically referring to this property (also mentioned here).
Describe the solution you'd like
Support for Autobind or a workaround.
Hi does this library support paged directory queries?
I see SizeLimit on the SearchRequest object but only see values 0<x<1000 for SizeLimit = x actually having a result.
Any x greater than 1000, only 1000 objects are returned from the directory.
Is your feature request related to a problem? Please describe.
When using a VLV control you need to specify a Sort control, Sort controls can have maximum entry counts to be "UnwillingToPerform". The Response message will return with a error code 12 (unavailable extention error) but the controls themselves will contain a sub error to determine what went wrong (VLV missing Sort, Sort Unwilling to perform etc)
Describe the solution you'd like
When this occurs we would like to be able to read the response controls when an exception is thrown via the LdapConnection ThrowIfResponseError method to handle this gracefully
Describe alternatives you've considered
N/A
Additional context
N/A
Describe the bug
Hi ! I am having trouble using a SendRequest
, I have the following exception:
Error running send request: 00000057: LdapErr: DSID-0C0910B5, comment: Error in attribute conversion operation, data 0, v47ba
To Reproduce
The error message is contained in my response
:
var response = connection.SendRequest(request);
if (response.ResultCode != LdapForNet.Native.Native.ResultCode.Success)
{
throw new Exception("Error running send request: " + response.ErrorMessage);
}
The request
is an AddRequest
and the connection
is inherited from an LdapConnection
. More specifically, it is a pooled Ldap connection (you can find few documentation on google about it).
I am using a Bind()
method for my connection, and an Anonymous authType.
I really don't understand where a conversion is done and why it fails.
Desktop (please complete the following information):
Is your feature request related to a problem? Please describe.
I would like to replace the options from DirectoryServices with LdapForNet options.
Here is my code :
connection.SessionOptions.Sealing = true;
connection.SessionOptions.Signing = true;
connection.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback((con, cer) => true);
connection.SessionOptions.QueryClientCertificate = new QueryClientCertificateCallback((con, trustedCAs) => null);
Describe the solution you'd like
How can I use LdapForNet to set those options ? And with which options ?
I already use connection.SetOption(LdapForNet.Native.Native.LdapOption.LDAP_OPT_SSL, 1);
for example
Is your feature request related to a problem? Please describe.
For some attributes you need byte[]: objectGUID, ObjectSid, nTSecurityDescriptor, systemFlags, uSNChanged etc + exchange attributes.
Describe the solution you'd like
Change ToLdapEntry method to:
public LdapEntry ToLdapEntry()
{
return new LdapEntry
{
Dn = Dn,
Attributes = Attributes.ToDictionary(_ => _.Name, _ => _.GetValues<byte[]>().ToList())
};
}
And add to LdapEntry methods:
=> this.Attributes.Contains(attribute) ? this.Attributes[attribute] : null;
public string GetString(string attributeName) => this.GetAttribute(attributeName)?.GetValue<string>();
public IEnumerable<byte[]> GetBytes(string attributeName) => this.GetAttribute(attributeName)?.GetValues<byte[]>();
And some helper methods:
public static class DirectoryAttributeExtension
{
public static T GetValue<T>(this DirectoryAttribute attribute)
where T : class, IEnumerable
{
var items = attribute.GetValues<T>();
var item = items.FirstOrDefault();
return item == default(T) ? default(T) : item;
}
}
public static class DictionaryExtensions
{
public static T Get<T>(this IDictionary<string, object> storage, string key)
{
if (storage == null)
{
throw new ArgumentNullException(nameof(storage));
}
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (!storage.TryGetValue(key, out object value))
{
throw new KeyNotFoundException(
$"Method Get<{typeof(T).FullName}>(\"{key}\") can't resolve key in dictionary of type \"{storage}\".");
}
try
{
return (T)value;
}
catch (Exception ex)
{
throw new InvalidCastException(
$"Method Get<{typeof(T).FullName}>(\"{key}\") can't cast value \"{value?.ToString() ?? "<NULL>"}\"" +
$" of type \"{value?.GetType().FullName}\" to a resulting type \"{typeof(T).FullName}\".",
ex);
}
}
}
Describe the bug
I am trying to use the LdapConnection and PageResultRequestControl that you use in your example which is supposed to support ldap v3 search controls, but the class PageResultRequestControl doesn't exist. Neither does the Controls attribute.
To Reproduce
var searchRequest = new SearchRequest(baseDN, filter, scope, attributes)
{
AttributesOnly = false,
TimeLimit = TimeSpan.Zero,
Controls =
{
new PageResultRequestControl(sizeLimit)
{
IsCritical = true,
},
},
}
Expected behavior
Controls and PageResultRequestControl are supposed to exist without the DirectoryServices package.
Desktop :
Is your feature request related to a problem? Please describe.
When creating a new SendRequest
, no ThrowIfResponseError
is used so some errors may not be seen.
Describe the solution you'd like
The ThrowIfResponseError
could be used directly within the SendRequest
and not in the methods using the SendRequest
(e.g. public void Add(LdapEntry entry) => ThrowIfResponseError(SendRequest(new AddRequest(entry)));
)
Describe alternatives you've considered
The SendRequest could become like this :
public DirectoryResponse SendRequest(DirectoryRequest directoryRequest)
{
ThrowIfNotBound();
var requestHandler = SendRequest(directoryRequest, out var messageId);
var directoryResponse = ProcessResponse(directoryRequest, requestHandler, messageId, CancellationToken.None);
ThrowIfResponseError(directoryResponse);
return directoryResponse;
}
And then the other methods would be like this :
public void Add(LdapEntry entry) => SendRequest(new AddRequest(entry));
Hi sir. I'm using Vs2019 on windows.
When i try to connect open ldap server i'm getting this error.
What am i doing wrong ?
{"Unable to load DLL 'ldap-2.4.so.2' or one of its dependencies: The specified module could not be found. (Exception from HRESULT: 0x8007007E)"}
Here is my code.
using (var connection = new LdapConnection())
{
connection.Connect(Config.LdapHost, Config.LdapPort);
connection.Bind(LdapAuthMechanism.SIMPLE, Config.LdapUserDn, Config.LdapPassword);
var entries = connection.Search(Config.RootDn, "(&(objectclass=top)(cn=admin))");
return true;
}
In the README, you say
For Linux\OSX you must ensure you have the latest OpenLDAP client libraries installed from http://www.openldap.org
Would you mind specifying some (Debian-based) package names? My program works fine on windows, but BindKerebos fails every time from Ubuntu.
Describe the bug
In TrustAllCertificates()
, the operation is delegated to the native classes.
In linux and mac, a new LdapHandle
is created and passed to ldap_set_option
, meaning that this must be called before Connect()
, or else the option won't apply to the current connection, only subsequent ones.
However, on Windows, this doesn't work, as the call to ldap_get_option
is called with the passed-in handle, meaning it must be called after Connect()
, as the handle is null until Connect
is called.
I would create a PR for this, but I'm not sure which is the intended/correct behavior, but I suspect the Windows behavior is intended.
To Reproduce
using var connection = new LdapConnection();
connection.TrustAllCertificates(); // breaks on windows
connection.Connect();
connection.TrustAllCertificates(); // calling this here does not apply it to the current connection on mac/linux, only later ones
Expected behavior
Consistent behavior across platforms
Desktop (please complete the following information):
Additional context
Exception thrown on Windows:
System.ArgumentNullException: SafeHandle cannot be null. (Parameter 'pHandle')
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at LdapForNet.Native.NativeMethodsWindows.ldap_get_option(SafeHandle ld, Int32 option, Int32& value)
at LdapForNet.Native.LdapNativeWindows.ldap_get_option(SafeHandle ld, Int32 option, Int32& value)
at LdapForNet.Native.LdapNativeWindows.TrustAllCertificates(SafeHandle ld)
at LdapForNet.LdapConnection.TrustAllCertificates()
Is your feature request related to a problem? Please describe.
The powershell module portion should be published to the Powershell Gallery. I can assist with getting this set up with a PR to the Azure Pipelines file if required.
After creating the object of LdapForNet.LdapConnection, I am getting the System.DllNotFoundException error when I try to use connect method in Xamarin.Forms (iOS).
Below is the code sample
var connection = new LdapForNet.LdapConnection();
connection.Connect(Host, int.Parse(Port));
connection.Bind(LdapAuthMechanism.SIMPLE, Email, password);
Error log:
{System.DllNotFoundException: libldap assembly: type: member:(null)
at (wrapper managed-to-native) LdapForNet.Native.NativeMethodsOsx.ldap_initialize(intptr&,string)
at LdapForNet.Native.LdapNativeOsx.Init (System.IntPtr& ld, System.String hostname, System.Int32 port) [0x00012] in <54341b85b3ad47748ae5f4d0c2393a96>:0
at LdapForNet.LdapConnection.Connect (System.String hostname, System.Int32 port, LdapForNet.Native.Native+LdapVersion version) [0x00046] in <54341b85b3ad47748ae5f4d0c2393a96>:0
at LDAPDemo.Models.LoginViewModel.OnSubmit () [0x0001b] in }
Describe the bug
Hi !
I am working on an LdapConnection
and a SearchRequest
.
The problem is that even if I have the attribute "parentdn" in my list of attributes, the entries will never have an attribute called "parentdn".
To Reproduce
Here is a sample of my code :
var searchRequest = new SearchRequest(baseDN, filter, scope, attributes)
{
AttributesOnly = false,
TimeLimit = TimeSpan.Zero,
Controls =
{
new PageResultRequestControl()
{
IsCritical = true,
},
},
};
var searchResponse = await connection.SendRequestAsync(searchRequest);
The attributes given in the SearchRequest
are 13 and contain a "parentdn" attribute.
The results in my searchResponse
only have 7 or 8 attributes and no "parentdn".
Expected behavior
I expected to have at least the "parentdn" attribute since I have the "Dn" and other attributes.
Desktop:
Additional context
I am using the SUBTREE scope
Is your feature request related to a problem? Please describe.
Sometimes you need to parse nTSecurityDescriptor attribute. So it would be very usefull to handle it via library. This is not common ldap functional.
Describe the solution you'd like
https://stackoverflow.com/questions/16521790/how-can-i-access-the-ntsecuritydescriptor-with-a-normal-ldap-client
https://github.com/ldaptools/ldaptools/blob/master/src/LdapTools/Security/SecurityDescriptor.php
Here examples of parsing this context.
Describe the bug
Although LdapConnection
contains async versions of add, delete, and modify, the ILdapConnection
interface does not.
To Reproduce
ILdapConnection conn = new LdapConnection();
// connect and bind
await conn.AddAsync(params)
Does not compile.
Expected behavior
These methods to exist on the interface
Desktop (please complete the following information):
Describe the bug
Binding doesn't work on Linux
To Reproduce
using (var cn = new LdapConnection()) { cn.Connect("xxx.zzz.ccc.com", 389); cn.Bind(LdapAuthType.Digest, new LdapCredential { UserName = "xxxxxxxxx", AuthorizationId = "dc=xx,dc=xxx,dc=xxxx", Password = "xxxx2009" }); var user = cn.WhoAmI().Result; }
Expected behavior
It should return user id after running WhoAmI
Desktop (please complete the following information):
Additional context
Code runs fine when ran in IISExpress, but not in Docker linux container
Describe the bug
We plan to use this library on FreeBSD, but the platform detection mechanism is not implemented for FreeBSD.
Since .NET 5.0 Preview 8 and .NET Core 3.1 3.0 the OSPlatform enum contains this new value:
public static System.Runtime.InteropServices.OSPlatform FreeBSD { get; }
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.osplatform.freebsd?view=netcore-3.1
Current behavior
A PlatformNotSupportedException is thrown.
Expected behavior
The platform should be identified correctly.
Potential problem
The current target framework of this library is netstandard2.0;netstandard2.1
. Since the FreeBSD enum value is not supported by any .Net Standard version, netcoreapp3.0
should probably be added as a target.
Code snippets
if (RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD))
{
return new UnixEncoder();
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD))
{
return new LdapNativeLinux();
}
Hello, is there way to reset other user password using your library. I need implement changing user password in Windows Active Directory with .net core application hosted on Linux server. If this is possible please write some example for it. Thank you in advance.
Is there a sample on how i have to convert an image (thumbnailPhoto Attribute) back to an image?
Would be nice if you could provide a sample or push me into the right direction.
After get an LdapEntry I can not retrieve the correct value for objectSid attribute coming from AD.
It is a binary value and is being copied as if it is a string here.
Hello, I'm looking to see if you have sample C# code to operate your async operations available somewhere?
Is your feature request related to a problem? Please describe.
I am currently working on a program using DirectoryServices.Protocols, and I am trying to replace everything related to this package with the LdapForNet solution.
How can I replace DirectoryOperationExceptions ? Is it implemented yet ?
Describe the solution you'd like
For example
try{ _something_ } catch(DirectoryOperationException);
I don't think that using LdapExceptions will be correct here.
Is your feature request related to a problem? Please describe.
Now timeout for connection is 10 minutes and you couldn't change it.
Describe the solution you'd like
Add param to Bind method.
Describe the bug
SID.ToByteArray() always returns a byte array where byte[1] is zero, when it should be the number of subauthorities in the SID
To Reproduce
Expected behavior
The second byte should be the number of subauthorities in the SID
Desktop (please complete the following information):
Additional context
The issue is that the line of code in the method that is trying to set this value is taking the 4th byte of the bytes returned from GetBytes:
buff.Write(NumberFacility.GetBytes(this.subAuthorities.Count)[3]);
It should be taking the first byte - it should look like this:
buff.Write(NumberFacility.GetBytes(this.subAuthorities.Count)[0]);
With the default LDAP classes, you could go
ldapConnection.AuthType = AuthType.Anonymous;
Your current version equivalent is
LdapCredential anonymousCredential = new LdapCredential();
ldapConnection.Bind(Native.LdapAuthType.Simple, anonymousCredential);
I suggest a
ldapConnection.Bind(Native.LdapAuthType.Anonymous);
version to simplify migration.
Is your feature request related to a problem? Please describe.
Use of LdapException
for every problem is not the best way to expose an error (we need to compare the ResultCode
).
Describe the solution you'd like
An exception for every result code (ex. LdapInvalidCredentialsException, LdapUnavailableException, etc).
try
{
// Connection
}
catch (LdapUnavailableException exception)
{
// Do something
}
Describe alternatives you've considered
Currently the code is like this.
try
{
// Connection
}
catch (LdapException exception) when (exception.ResultCode == Native.ResultCode.Unavailable)
{
// Do something
}
Description of the Problem
I am creating unit tests that need to mock (using the Moq library) various parts of LdapForNet. I have an interface (ILapService) and implementation (LdapService) between my application and LdapForNet. In order to unit LdapService, I need to be able to mock what LdapForNet returns. To be specific, I want to set up my unit test such that a call to SearchAsync returns a list of LdapEntry objects that I have created in advance of the call.
I can easily create multiple LdapEntry instances and put them in a list, but I'm having trouble setting up their DirectoryAttribute values, because I cannot create a new SearchResultAttributeCollection instance to assign to the DirectoryAttributes property of the LdapEntry instance, because the constructor for SearchResultAttributeCollection uses the internal access modifier. Also, the LdapEntry class has no constructors defined, so the default generated by the compiler will leave the DirectoryAttributes property set to null.
Because of this, my unit test code throws a NullReferenceException when I'm trying to add DirectoryAttribute objects to the DirectoryAttributes property using it's Add method,
To Reproduce
Here is the relevant code
private void SetupUserSearchOneUser(string dn)
{
// Next line creates a new LdapEntry instance, no constructor is defined, so
// compiler generated default leaves the DirectoryAttributes property as null
var entry = new LdapEntry();
// Can't do this next line because the constructor has internal access modifier
//entry.DirectoryAttributes = new SearchResultAttributeCollection();
entry.Dn = dn;
AddNewDirectoryAttribute(entry, "distinguishedName", dn);
AddNewDirectoryAttribute(entry, "accountExpires", "0x7FFFFFFFFFFFFFFF");
AddNewDirectoryAttribute(entry, "pwdLastSet", "0x0");
AddNewDirectoryAttribute(entry, "userAccountControl", "512");
// purposely leaving off logonHours
var list = new List<LdapEntry> { entry };
this.mockLdapConnection.Setup(m => m.SearchAsync(It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string[]>(),
Native.LdapSearchScope.LDAP_SCOPE_SUB,
new CancellationToken())).ReturnsAsync(list);
}
private void AddNewDirectoryAttribute(LdapEntry e, string name, string value)
{
var dirAttr = new DirectoryAttribute();
dirAttr.Name = name;
dirAttr.Add(value);
// This next line throws the NullReferenceException because e.DirectoryAttributes is null.
e.DirectoryAttributes.Add(dirAttr);
}
Expected behavior
I expect to be able to manually construct LdapEntry objects with DirectoryAttribute instances in the DirectoryAttributes property for use in unit testing. I see two possible ways to address this:
OR
I'd be more than happy to clone the repo, make either of these changes (I lean towards #2 being the better option), and then create a pull request.
Desktop (please complete the following information):
Additional context
This code is part of an IdentityServer4 based service that provides authentication & authorization services within our enterprise, and is part of a project to host this service in a Linux Kubernetes cluster. Development occurs under Windows, but some testing and production use will be hosted in the Linux Kubernetes cluster.
Describe the bug
Attributes with empty or null values cause an exception
To Reproduce
filter = "(&(cn=JohnDoe)(objectCategory=Person)(objectClass=user))"
var entries = cn.Search(Base, Filter,string[]{"cn","manager"} scope: ToSearchScope(Scope));
foreach (var entry in entries)
{
var res = new PSObject();
foreach (string attrName in string[]{"cn","manager"})
{
res.Properties.Add(new PSNoteProperty(attrName, entry.Attributes[attrName][0]));
}
WriteObject(res);
}
Expected behavior
The user JohnDoe has a null value for the manager attribute so the entry should list something like this:
cn manager
-- --
JohnDoe
Actual Behavior
cn
--
JohnDoe
Desktop (please complete the following information):
Additional context
It seems that when the search returns an attribute with an empty or null that attribute is not added to the dictionary or is removed.
The reason this is a problem is because when we use a filter like so:
filter = "(&(cn=John*)(objectCategory=Person)(objectClass=user))"
It process lets say 5 users and as soon as it comes across the user with empty manager attribute it throws an error:
The given key was not present in the dictionary.
i could additionally check and catch this exception within the foreach loop but when processing a large number of results this will add a lot of overhead and time.
Describe the bug
I am unable to reference the LdapForNet package in an application that is strongly signed.
CSC : error CS8002: Referenced assembly 'LdapForNet, Version=2.7.10.0, Culture=neutral, PublicKeyToken=null' does not have a strong name.
To Reproduce
Reference this package in a project that uses strong name signing. You cannot reference unsigned assembly from a signed assembly.
Expected behavior
The package should be strongly signed.
Desktop (please complete the following information):
Additional information
I am currently using the following package as a workaround:
<PackageReference Include="Brutal.Dev.StrongNameSigner" Version="2.7.1" />
Is your feature request related to a problem? Please describe.
At enterprise level infrastructure contains multiple domains. You connect to domain via kerberos and couldn't search at another trusted domain. This is fixed at Windows default library with ReferralChasingOptions option. Class LdapSessionOptions.
Settings:
LdapOption.LDAP_OPT_REFERRALS
LdapOption.LDAP_OPT_REFERRAL_HOP_LIMIT
Also usefull fuction:
LdapOption.LDAP_OPT_AUTO_RECONNECT
Describe the solution you'd like
Add referral chasing function to code.
Example:
https://www.php.net/manual/en/function.ldap-set-rebind-proc.php
https://linux.die.net/man/5/slapd-meta
https://klikr.org/4bbb0c55d527603667041ed0ce0a.png
This is current net framework referral connection example.
Is your feature request related to a problem? Please describe.
Now I couldn't get some options of connection directly via ldap_get_option.
Describe the solution you'd like
Make method ldap_get_option in connection class. Or maybe make LdapNative field in connection class protected, so anybody could inherit base class and use additional api of LdapNative functions.
Hi !
I recently used the TryGetValue and I found out that it is case sensitive.
I believe that it would be great to implement a TryGetValue case insensitive or to be able to chose between sensitive or insensitive
For example :
entry.Attributes.TryGetValue("whencreated", out var whencreatedResult)
won't return me anything if my attribute is named "whenCreated".
I believe that you can do it for all KeyedCollection this way for example :
internal ModifyAttributeCollection()
:base(comparer)
{
}
Hello, i have some problem with connecting to Active Directory using ldaps (port 636) under linux environment(ubuntu).
I call Connect, after that i call Bind (via kerberos), and nothing happens, no errors, no cpu usage, no any other answers from Bind method.
All works fine using ldap port (389) without encription.
AD server configured for using ldaps.
Certificates verification ignored on client (LDAPTLS_REQCERT=never )
Same problem when i use ldapsearch, but if i set option maxssf (-O maxssf=200) all works fine.
I suggest if i set maxssf in LdapForNet before bind i would bind successfully, but SetOption not works without Bind (There is call method ThrowIfNotBound() before settting options as i see), i got error "LdapForNet.LdapException: Not bound. Please invoke Bind method before"
I try to setup SASL_SECPROPS maxssf= in /etc/ldap/ldap.conf and it had not affected LDapForNet behavior.
My question is how can i specify option LDAP_OPT_X_SASL_SSF_MAX via this LdapForNet library?
I'm trying to use this lib in .NET Standard 2.0 dll. It seems to work with a dotnetcore projects, but brakes if i use it in .NetFramework
PInvokeStackImbalance' : 'A call to PInvoke function 'LdapForNet!LdapForNet.Native.NativeMethodsWindows::ldap_init' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.