LdapForNet 0.1.0-beta

Porting of OpenLdap native lib for .NET Core. Implemented SASL GSSAPI (Kerberos)! Supported Ubuntu only (14.04, 16.04, 18.04).

This is a prerelease version of LdapForNet.
There is a newer version of this package available.
See the version list below for details.
Install-Package LdapForNet -Version 0.1.0-beta
dotnet add package LdapForNet --version 0.1.0-beta
<PackageReference Include="LdapForNet" Version="0.1.0-beta" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add LdapForNet --version 0.1.0-beta
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: LdapForNet, 0.1.0-beta"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install LdapForNet as a Cake Addin
#addin nuget:?package=LdapForNet&version=0.1.0-beta&prerelease

// Install LdapForNet as a Cake Tool
#tool nuget:?package=LdapForNet&version=0.1.0-beta&prerelease
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

ldap4net

Build Status
NuGet

Port of OpenLdap Client library (https://www.openldap.org/software/man.cgi?query=ldap) to DotNet Core (supported Ubuntu only)

It works with any LDAP protocol compatible directory server (including Microsoft Active Directory).

Supported SASL GSSAPI (Kerberos) authentication!

Sample usage (GSSAPI authentication)

using (var cn = new LdapConnection())
{
	// connect
	cn.Connect();
	// bind using kerberos credential cache file
	cn.Bind();
	// call ldap op
	var entries = cn.Search("<<basedn>>", "(objectClass=*)");
}

Overview

Supported platforms

  • Ubuntu 14.04, 16.04, 18.04
  • Supported on the .NET Standard - minimum required is 2.0 - compatible .NET runtimes: .NET Core, Mono.

Installation

Install-Package LdapForNet -Version 0.1.0-beta

dotnet add package LdapForNet --version 0.1.0-beta

Api

Connect

using (var cn = new LdapConnection())
{
	// connect use Domain Controller host from computer hostname and default port 389
	// Computer hostname - mycomp.example.com => DC host - example.com
	cn.Connect();
	....
}

using (var cn = new LdapConnection())
{
	// connect use hostname and port
	cn.Connect("dc.example.com",636);
	....
}

Bind

using (var cn = new LdapConnection())
{
	cn.Connect();
	// bind using kerberos credential cache file
	cn.Bind();
	...
}

using (var cn = new LdapConnection())
{
	cn.Connect("ldap.forumsys.com");
	// bind using userdn and password
	cn.Bind(LdapAuthMechanism.SIMPLE,"cn=read-only-admin,dc=example,dc=com","password");
	...
}

Search

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search all objects in catalog (default search scope = LdapSearchScope.LDAP_SCOPE_SUBTREE)
	var entries = cn.Search("dc=example,dc=com","(objectClass=*)");
}
using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  objects in catalog at first level scope
	var entries = cn.Search("dc=example,dc=com","(objectClass=*)", LdapSearchScope.LDAP_SCOPE_ONELEVEL);
}

SearchByCn

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  by CN, get @base from machine hostname (my.example.com => dn=example,dn=com )
	var entries = cn.SearchByCn("read-only-admin");
}
using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  by CN
	var entries = cn.SearchByCn("ou=admins,dn=example,dn=com", "read-only-admin", LdapSearchScope.LDAP_SCOPE_ONELEVEL);
}

SearchBySid

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  by CN, get @base from machine hostname (my.example.com => dn=example,dn=com )
	var entries = cn.SearchBySid("S-1-5-21-2127521184-1604012920-1887927527-72713");
}
using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  by CN
	var entries = cn.SearchBySid("ou=admins,dn=example,dn=com", "S-1-5-21-2127521184-1604012920-1887927527-72713", LdapSearchScope.LDAP_SCOPE_ONELEVEL);
}

SetOption

using (var cn = new LdapConnection())
{
	cn.Connect();
	var ldapVersion = (int)LdapVersion.LDAP_VERSION3;
	cn.SetOption(LdapOption.LDAP_OPT_PROTOCOL_VERSION, ref ldapVersion);
	cn.Bind();
}

Add

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	cn.Add(new LdapEntry
	{
	Dn = "cn=test,dc=example,dc=com",
	Attributes = new Dictionary<string, List<string>>
	{
	    {"sn", new List<string> {"Winston"}},
	    {"objectclass", new List<string> {"inetOrgPerson"}},
	    {"givenName", new List<string> {"your_name"}},
	    {"description", new List<string> {"your_description"}}
	}
	});
}

Modify

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	cn.Modify(new LdapModifyEntry
	{
	Dn = "cn=test,dc=example,dc=com",
	Attributes = new List<LdapModifyAttribute>
	{
	    new LdapModifyAttribute
	    {
		LdapModOperation = LdapModOperation.LDAP_MOD_REPLACE,
		Type = "givenName",
		Values = new List<string> {"test_value_2"}
	    },
	    new LdapModifyAttribute
	    {
		LdapModOperation = LdapModOperation.LDAP_MOD_ADD,
		Type = "displayName",
		Values = new List<string> {"test_display_name"}
	    },
	    new LdapModifyAttribute
	    {
		LdapModOperation = LdapModOperation.LDAP_MOD_ADD,
		Type = "sn",
		Values = new List<string> {"test"}
	    },
	    new LdapModifyAttribute
	    {
		LdapModOperation = LdapModOperation.LDAP_MOD_DELETE,
		Type = "description",
		Values = new List<string> {"test_value"}
	    }
	}
	});
}

Delete

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	cn.Delete("cn=test,dc=example,dc=com");
}

Rename

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	cn.Rename("cn=test,dc=example,dc=com", "cn=test2", null, true);
}

GetNativeLdapPtr

For own implementations or not implemented OpenLdap functions use GetNativeLdapPtr. It's provided pointer to native structure LDAP. So we can use this pointer in own implementations.
For example, implement "DIGEST-MD5" authentication

using static LdapForNet.Native.Native;

using (var cn = new LdapConnection())
{
	cn.Connect();
	var ld = cn.GetNativeLdapPtr();
	var defaults = new LdapSaslDefaults { 
		mech = "DIGEST-MD5",
		passwd="password",
        	authcid="user",
        	realm="realm.com",
        	authzid="user"
	};
	var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(defaults));
            Marshal.StructureToPtr(defaults, ptr, false);
	int rc = ldap_sasl_interactive_bind_s( ld, null,defaults.mech, IntPtr.Zero, IntPtr.Zero,
                (uint)LdapInteractionFlags.LDAP_SASL_QUIET, (l, flags, d, interact) => (int)LdapResultCode.LDAP_SUCCESS, ptr);
...
}

Native

OpenLdap native methods can be used directly. Native methods implemented in static class LdapForNet.Native.Native:

using static LdapForNet.Native.Native;

using (var cn = new LdapConnection())
{
	cn.Connect();
	var ld = cn.GetNativeLdapPtr();
	var res = ldap_sasl_interactive_bind_s(ld,...);
	if (res != (int)LdapResultCode.LDAP_SUCCESS)
	{
		Trace.TraceError($"Error {method}: {LdapError2String(res)} ({res}).");
	}
}

License

This software is distributed under the terms of the MIT License (MIT).

Authors

Alexander Chermyanin / LinkedIn

Contributions and bugs reports are welcome.

ldap4net

Build Status
NuGet

Port of OpenLdap Client library (https://www.openldap.org/software/man.cgi?query=ldap) to DotNet Core (supported Ubuntu only)

It works with any LDAP protocol compatible directory server (including Microsoft Active Directory).

Supported SASL GSSAPI (Kerberos) authentication!

Sample usage (GSSAPI authentication)

using (var cn = new LdapConnection())
{
	// connect
	cn.Connect();
	// bind using kerberos credential cache file
	cn.Bind();
	// call ldap op
	var entries = cn.Search("<<basedn>>", "(objectClass=*)");
}

Overview

Supported platforms

  • Ubuntu 14.04, 16.04, 18.04
  • Supported on the .NET Standard - minimum required is 2.0 - compatible .NET runtimes: .NET Core, Mono.

Installation

Install-Package LdapForNet -Version 0.1.0-beta

dotnet add package LdapForNet --version 0.1.0-beta

Api

Connect

using (var cn = new LdapConnection())
{
	// connect use Domain Controller host from computer hostname and default port 389
	// Computer hostname - mycomp.example.com => DC host - example.com
	cn.Connect();
	....
}

using (var cn = new LdapConnection())
{
	// connect use hostname and port
	cn.Connect("dc.example.com",636);
	....
}

Bind

using (var cn = new LdapConnection())
{
	cn.Connect();
	// bind using kerberos credential cache file
	cn.Bind();
	...
}

using (var cn = new LdapConnection())
{
	cn.Connect("ldap.forumsys.com");
	// bind using userdn and password
	cn.Bind(LdapAuthMechanism.SIMPLE,"cn=read-only-admin,dc=example,dc=com","password");
	...
}

Search

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search all objects in catalog (default search scope = LdapSearchScope.LDAP_SCOPE_SUBTREE)
	var entries = cn.Search("dc=example,dc=com","(objectClass=*)");
}
using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  objects in catalog at first level scope
	var entries = cn.Search("dc=example,dc=com","(objectClass=*)", LdapSearchScope.LDAP_SCOPE_ONELEVEL);
}

SearchByCn

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  by CN, get @base from machine hostname (my.example.com => dn=example,dn=com )
	var entries = cn.SearchByCn("read-only-admin");
}
using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  by CN
	var entries = cn.SearchByCn("ou=admins,dn=example,dn=com", "read-only-admin", LdapSearchScope.LDAP_SCOPE_ONELEVEL);
}

SearchBySid

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  by CN, get @base from machine hostname (my.example.com => dn=example,dn=com )
	var entries = cn.SearchBySid("S-1-5-21-2127521184-1604012920-1887927527-72713");
}
using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	//search  by CN
	var entries = cn.SearchBySid("ou=admins,dn=example,dn=com", "S-1-5-21-2127521184-1604012920-1887927527-72713", LdapSearchScope.LDAP_SCOPE_ONELEVEL);
}

SetOption

using (var cn = new LdapConnection())
{
	cn.Connect();
	var ldapVersion = (int)LdapVersion.LDAP_VERSION3;
	cn.SetOption(LdapOption.LDAP_OPT_PROTOCOL_VERSION, ref ldapVersion);
	cn.Bind();
}

Add

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	cn.Add(new LdapEntry
	{
	Dn = "cn=test,dc=example,dc=com",
	Attributes = new Dictionary<string, List<string>>
	{
	    {"sn", new List<string> {"Winston"}},
	    {"objectclass", new List<string> {"inetOrgPerson"}},
	    {"givenName", new List<string> {"your_name"}},
	    {"description", new List<string> {"your_description"}}
	}
	});
}

Modify

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	cn.Modify(new LdapModifyEntry
	{
	Dn = "cn=test,dc=example,dc=com",
	Attributes = new List<LdapModifyAttribute>
	{
	    new LdapModifyAttribute
	    {
		LdapModOperation = LdapModOperation.LDAP_MOD_REPLACE,
		Type = "givenName",
		Values = new List<string> {"test_value_2"}
	    },
	    new LdapModifyAttribute
	    {
		LdapModOperation = LdapModOperation.LDAP_MOD_ADD,
		Type = "displayName",
		Values = new List<string> {"test_display_name"}
	    },
	    new LdapModifyAttribute
	    {
		LdapModOperation = LdapModOperation.LDAP_MOD_ADD,
		Type = "sn",
		Values = new List<string> {"test"}
	    },
	    new LdapModifyAttribute
	    {
		LdapModOperation = LdapModOperation.LDAP_MOD_DELETE,
		Type = "description",
		Values = new List<string> {"test_value"}
	    }
	}
	});
}

Delete

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	cn.Delete("cn=test,dc=example,dc=com");
}

Rename

using (var cn = new LdapConnection())
{
	cn.Connect();
	cn.Bind();
	cn.Rename("cn=test,dc=example,dc=com", "cn=test2", null, true);
}

GetNativeLdapPtr

For own implementations or not implemented OpenLdap functions use GetNativeLdapPtr. It's provided pointer to native structure LDAP. So we can use this pointer in own implementations.
For example, implement "DIGEST-MD5" authentication

using static LdapForNet.Native.Native;

using (var cn = new LdapConnection())
{
	cn.Connect();
	var ld = cn.GetNativeLdapPtr();
	var defaults = new LdapSaslDefaults { 
		mech = "DIGEST-MD5",
		passwd="password",
        	authcid="user",
        	realm="realm.com",
        	authzid="user"
	};
	var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(defaults));
            Marshal.StructureToPtr(defaults, ptr, false);
	int rc = ldap_sasl_interactive_bind_s( ld, null,defaults.mech, IntPtr.Zero, IntPtr.Zero,
                (uint)LdapInteractionFlags.LDAP_SASL_QUIET, (l, flags, d, interact) => (int)LdapResultCode.LDAP_SUCCESS, ptr);
...
}

Native

OpenLdap native methods can be used directly. Native methods implemented in static class LdapForNet.Native.Native:

using static LdapForNet.Native.Native;

using (var cn = new LdapConnection())
{
	cn.Connect();
	var ld = cn.GetNativeLdapPtr();
	var res = ldap_sasl_interactive_bind_s(ld,...);
	if (res != (int)LdapResultCode.LDAP_SUCCESS)
	{
		Trace.TraceError($"Error {method}: {LdapError2String(res)} ({res}).");
	}
}

License

This software is distributed under the terms of the MIT License (MIT).

Authors

Alexander Chermyanin / LinkedIn

Contributions and bugs reports are welcome.

Release Notes

implemented CRUD (add,modify,delete,rename) methods

  • .NETStandard 2.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on LdapForNet:

Package Downloads
Volo.Abp.Ldap
Package Description
CAdESLib
This is rework of https://github.com/nonorganic/dssnet

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on LdapForNet:

Repository Stars
abpframework/abp
Open Source Web Application Framework for ASP.NET Core

Version History

Version Downloads Last updated
2.7.11 48,877 10/12/2020
2.7.10 1,627 9/18/2020
2.7.9 1,182 9/9/2020
2.7.8 190 9/8/2020
2.7.7 208 9/7/2020
2.7.6 318 9/2/2020
2.7.5 193 9/1/2020
2.7.4 617 8/27/2020
2.7.3 117 8/27/2020
2.7.2 974 7/17/2020
2.7.1 5,203 6/15/2020
2.7.0 210 6/13/2020
2.6.0 401 5/31/2020
2.5.0 1,414 5/25/2020
2.4.1 237 5/17/2020
2.4.0 3,519 5/7/2020
2.3.0 2,640 3/22/2020
2.2.1 267 3/5/2020
2.2.0 1,243 1/13/2020
2.1.0 278 1/4/2020
2.0.0 880 7/30/2019
1.1.0 290 7/2/2019
1.0.1 658 1/5/2019
0.2.0-beta 385 1/4/2019
0.1.0-beta 503 7/3/2018
0.0.6-alpha 732 3/27/2018
0.0.5-alpha 553 3/1/2018
0.0.4-alpha 517 2/28/2018
0.0.3-alpha 604 2/27/2018
0.0.2-alpha 520 2/25/2018
0.0.1-alpha 527 2/22/2018
Show less