Active Directory/Connect: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Phix}}: added syntax colouring the hard way)
(Added FreeBASIC)
 
(10 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[Category:Active Directory]]
{{task|Programming environment operations}}
{{task|Programming environment operations}}



The task is to establish a connection to an Active Directory or Lightweight Directory Access Protocol server.
The task is to establish a connection to an Active Directory or Lightweight Directory Access Protocol server.
Line 6: Line 8:
{{works with|AutoHotkey_L}}
{{works with|AutoHotkey_L}}
{{trans|VBScript}}
{{trans|VBScript}}
<lang AutoHotkey>objConn := CreateObject("ADODB.Connection")
<syntaxhighlight lang="autohotkey">objConn := CreateObject("ADODB.Connection")
objCmd := CreateObject("ADODB.Command")
objCmd := CreateObject("ADODB.Command")
objConn.Provider := "ADsDSOObject"
objConn.Provider := "ADsDSOObject"
objConn.Open()</lang>
objConn.Open()</syntaxhighlight>


=={{header|AutoIt}}==
=={{header|AutoIt}}==
{{works with|AutoIt}}
{{works with|AutoIt}}
<lang AutoIt> #include <AD.au3>
<syntaxhighlight lang="autoit"> #include <AD.au3>
_AD_Open()</lang>
_AD_Open()</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
With OpenLDAP:
With OpenLDAP:
<lang C>#include <ldap.h>
<syntaxhighlight lang="c">#include <ldap.h>
...
...
char *name, *password;
char *name, *password;
Line 25: Line 27:
ldap_simple_bind_s(ld, name, password);
ldap_simple_bind_s(ld, name, password);
... after done with it...
... after done with it...
ldap_unbind(ld);</lang>
ldap_unbind(ld);</syntaxhighlight>


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang csharp>
<syntaxhighlight lang="csharp">
// Requires adding a reference to System.DirectoryServices
// Requires adding a reference to System.DirectoryServices
var objDE = new System.DirectoryServices.DirectoryEntry("LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com");
var objDE = new System.DirectoryServices.DirectoryEntry("LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com");
</syntaxhighlight>
</lang>


=={{header|ColdFusion}}==
=={{header|ColdFusion}}==
<lang cfm>
<syntaxhighlight lang="cfm">
<cfldap
<cfldap
server = "#someip#"
server = "#someip#"
Line 45: Line 47:
attributes = "#attributeslist#"
attributes = "#attributeslist#"
>
>
</syntaxhighlight>
</lang>


=={{header|D}}==
=={{header|D}}==
Based on dopenldap.
Based on dopenldap.
<syntaxhighlight lang="d">
<lang d>
import openldap;
import openldap;
import std.stdio;
import std.stdio;
Line 68: Line 70:
}
}
</syntaxhighlight>
</lang>


=={{header|Erlang}}==
=={{header|Erlang}}==
This needs a test case. Is there a LDAP server available?
This needs a test case. Is there a LDAP server available?
<syntaxhighlight lang="erlang">
<lang Erlang>
-module(ldap_example).
-module(ldap_example).
-export( [main/1] ).
-export( [main/1] ).
Line 80: Line 82:
ok = eldap:simple_bind( Handle, DN, Password ),
ok = eldap:simple_bind( Handle, DN, Password ),
eldap:close( Handle ).
eldap:close( Handle ).
</syntaxhighlight>
</lang>


=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
{{trans|C_sharp}}
{{trans|C_sharp}}
<p>For Active Directory we use the library System.DirectoryServices</p>
<p>For Active Directory we use the library System.DirectoryServices</p>
<lang fsharp>let adObject = new System.DirectoryServices.DirectoryEntry("LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com")</lang>
<syntaxhighlight lang="fsharp">let adObject = new System.DirectoryServices.DirectoryEntry("LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com")</syntaxhighlight>
<p>For your average LDAP server we use System.DirectoryServices.Protocol</p>
<p>For your average LDAP server we use System.DirectoryServices.Protocol</p>
<p>For a minimal example we make an anonymous connect to the local machine on the well-known LDAP port 389
<p>For a minimal example we make an anonymous connect to the local machine on the well-known LDAP port 389
<lang fsharp>let ldapServer = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier("127.0.0.1")
<syntaxhighlight lang="fsharp">let ldapServer = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier("127.0.0.1")
let connect = new System.DirectoryServices.Protocols.LdapConnection(ldapServer)
let connect = new System.DirectoryServices.Protocols.LdapConnection(ldapServer)
connect.Bind()</lang>
connect.Bind()</syntaxhighlight>

=={{header|FreeBASIC}}==
{{libheader|winldap}}
<syntaxhighlight lang="vbnet">#Include "win\winldap.bi"

Dim ldap As LDAP Ptr
Dim hostname As String
Dim port As Integer
Dim username As String
Dim password As String
Dim result As Integer

hostname = "ldap.example.com"
port = 389 ' Standard port for LDAP. Use 636 for LDAPS.
username = "cn=username,dc=example,dc=com"
password = "password"

' Initialize the LDAP connection
ldap = ldap_init(hostname, port)
If ldap = NULL Then
Print "Error initializing LDAP connection"
Sleep
End 1
End If

' Authenticate with the LDAP server
result = ldap_simple_bind_s(ldap, username, password)
If result <> LDAP_SUCCESS Then
Print "Error authenticating with LDAP server: "; ldap_err2string(result)
Sleep
End 1
End If

' Here you can perform LDAP operations
'...

' We close the connection when finished
ldap_unbind(ldap)</syntaxhighlight>


=={{header|Go}}==
=={{header|Go}}==
Line 96: Line 136:
<br>
<br>
There are a large number of third-party LDAP libraries for Go. This uses one of the simpler ones and the code below is largely taken from the example on its main page.
There are a large number of third-party LDAP libraries for Go. This uses one of the simpler ones and the code below is largely taken from the example on its main page.
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 121: Line 161:
}
}
// Do something
// Do something
}</lang>
}</syntaxhighlight>


=={{header|Haskell}}==
=={{header|Haskell}}==
Line 127: Line 167:
Example uses the [https://hackage.haskell.org/package/ldap-client <tt>ldap-client</tt>] package:
Example uses the [https://hackage.haskell.org/package/ldap-client <tt>ldap-client</tt>] package:


<lang haskell>{-# LANGUAGE OverloadedStrings #-}
<syntaxhighlight lang="haskell">{-# LANGUAGE OverloadedStrings #-}


module Main (main) where
module Main (main) where
Line 141: Line 181:
Ldap.search ldap (Ldap.Dn "o=example.com") (Ldap.typesOnly True) (Attr "uid" := Text.encodeUtf8 "user") []
Ldap.search ldap (Ldap.Dn "o=example.com") (Ldap.typesOnly True) (Attr "uid" := Text.encodeUtf8 "user") []
for_ entries $ \entry ->
for_ entries $ \entry ->
print entry</lang>
print entry</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
Line 147: Line 187:
This code uses the Apache Directory third-party library.
This code uses the Apache Directory third-party library.


<lang java>import java.io.IOException;
<syntaxhighlight lang="java">import java.io.IOException;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapConnection;
Line 160: Line 200:
}
}
}
}
}</lang>
}</syntaxhighlight>


=={{header|Julia}}==
<syntaxhighlight lang="julia">using LDAPClient

conn = LDAPClient.LDAPConnection("ldap://localhost:10389")
LDAPClient.simple_bind(conn, "user", "password")
LDAPClient.unbind(conn)
</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>
<syntaxhighlight lang="scala">
import org.apache.directory.api.ldap.model.exception.LdapException
import org.apache.directory.api.ldap.model.exception.LdapException
import org.apache.directory.ldap.client.api.LdapNetworkConnection
import org.apache.directory.ldap.client.api.LdapNetworkConnection
Line 207: Line 256:


fun main(args: Array<String>) = LDAP(mapOf("hostname" to "localhost", "port" to "10389")).run()
fun main(args: Array<String>) = LDAP(mapOf("hostname" to "localhost", "port" to "10389")).run()
</syntaxhighlight>
</lang>


=={{header|NetRexx}}==
=={{header|NetRexx}}==
Uses the [http://directory.apache.org/api/ Apache LDAP API], connecting to a local [http://directory.apache.org/apacheds/1.5/ ApacheDS] LDAP directory server.
Uses the [http://directory.apache.org/api/ Apache LDAP API], connecting to a local [http://directory.apache.org/apacheds/1.5/ ApacheDS] LDAP directory server.
<lang NetRexx>/* NetRexx */
<syntaxhighlight lang="netrexx">/* NetRexx */
options replace format comments java crossref symbols binary
options replace format comments java crossref symbols binary


Line 254: Line 303:


return
return
</syntaxhighlight>
</lang>


'''Sample <tt>log4j.xml</tt> configuration file:'''
'''Sample <tt>log4j.xml</tt> configuration file:'''
<lang xml><?xml version="1.0" encoding="UTF-8" ?>
<syntaxhighlight lang="xml"><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
Line 283: Line 332:
</root>
</root>
</log4j:configuration>
</log4j:configuration>
</syntaxhighlight>
</lang>


'''Output:'''
'''Output:'''
Line 292: Line 341:
=={{header|Perl}}==
=={{header|Perl}}==
[http://search.cpan.org/dist/perl-ldap/|Perl LDAP Modules]
[http://search.cpan.org/dist/perl-ldap/|Perl LDAP Modules]
<lang perl>
<syntaxhighlight lang="perl">
use Net::LDAP;
use Net::LDAP;


my $ldap = Net::LDAP->new('ldap://ldap.example.com') or die $@;
my $ldap = Net::LDAP->new('ldap://ldap.example.com') or die $@;
my $mesg = $ldap->bind( $bind_dn, password => $bind_pass );
my $mesg = $ldap->bind( $bind_dn, password => $bind_pass );
</syntaxhighlight>
</lang>


=={{header|Phix}}==
=={{header|Phix}}==
Line 304: Line 353:
This has been tested against a random 7-year-old list of public ldap servers, getting mixed errors of
This has been tested against a random 7-year-old list of public ldap servers, getting mixed errors of
LDAP_SERVER_DOWN/LDAP_INVALID_CREDENTIALS/LDAP_INVALID_DN_SYNTAX/LDAP_CONFIDENTIALITY_REQUIRED.
LDAP_SERVER_DOWN/LDAP_INVALID_CREDENTIALS/LDAP_INVALID_DN_SYNTAX/LDAP_CONFIDENTIALITY_REQUIRED.
<!--<lang Phix>-->
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #000000;">ldap</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #000000;">ldap</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 320: Line 369:
<span style="color: #000000;">ldap_unbind</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ld</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">ldap_unbind</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ld</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 328: Line 377:
=={{header|PHP}}==
=={{header|PHP}}==
[http://php.net/ldap PHP LDAP Reference]
[http://php.net/ldap PHP LDAP Reference]
<lang php><?php
<syntaxhighlight lang="php"><?php
$ldap = ldap_connect($hostname, $port);
$ldap = ldap_connect($hostname, $port);
$success = ldap_bind($ldap, $username, $password);</lang>
$success = ldap_bind($ldap, $username, $password);</syntaxhighlight>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(unless (=0 (setq Ldap (native "libldap.so" "ldap_open" 'N "example.com" 389)))
<syntaxhighlight lang="picolisp">(unless (=0 (setq Ldap (native "libldap.so" "ldap_open" 'N "example.com" 389)))
(quit "Can't open LDAP") )
(quit "Can't open LDAP") )


(native "libldap.so" "ldap_simple_bind_s" 'I Ldap "user" "password")</lang>
(native "libldap.so" "ldap_simple_bind_s" 'I Ldap "user" "password")</syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
Line 344: Line 393:
[http://www.python-ldap.org/doc/html/index.html python-ldap Documentation]
[http://www.python-ldap.org/doc/html/index.html python-ldap Documentation]


<lang python>import ldap
<syntaxhighlight lang="python">import ldap


l = ldap.initialize("ldap://ldap.example.com")
l = ldap.initialize("ldap://ldap.example.com")
Line 354: Line 403:
finally:
finally:
l.unbind()
l.unbind()
</syntaxhighlight>
</lang>


=={{header|Racket}}==
=={{header|Racket}}==
This version uses the ldap package, and was tested against OpenLDAP (with real values):
This version uses the ldap package, and was tested against OpenLDAP (with real values):
<lang racket>#lang racket
<syntaxhighlight lang="racket">#lang racket
(require net/ldap)
(require net/ldap)
(ldap-authenticate "ldap.somewhere.com" 389 "uid=username,ou=people,dc=somewhere,dc=com" password)</lang>
(ldap-authenticate "ldap.somewhere.com" 389 "uid=username,ou=people,dc=somewhere,dc=com" password)</syntaxhighlight>


{{trans|C}}
{{trans|C}}
Line 366: Line 415:
This is a direct translation of the C code -- I have no idea how to try it out since I don't have a working ldap server... So take it as a stub that waits for someone who can try it to do so. (And it's a low level thing anyway, there's an ldap package for Racket which I can't try for a similar reason.)
This is a direct translation of the C code -- I have no idea how to try it out since I don't have a working ldap server... So take it as a stub that waits for someone who can try it to do so. (And it's a low level thing anyway, there's an ldap package for Racket which I can't try for a similar reason.)


<lang racket>#lang racket
<syntaxhighlight lang="racket">#lang racket


(require ffi/unsafe ffi/unsafe/define)
(require ffi/unsafe ffi/unsafe/define)
Line 381: Line 430:
(ldap_simple_bind_s ld name password)
(ldap_simple_bind_s ld name password)


(ldap_unbind ld)</lang>
(ldap_unbind ld)</syntaxhighlight>


=={{header|Raku}}==
=={{header|Raku}}==
Line 388: Line 437:
Using module LMDB - bindings to the openLDAP library. Requires an LDAP instance.
Using module LMDB - bindings to the openLDAP library. Requires an LDAP instance.


<lang perl6>use LMDB;
<syntaxhighlight lang="raku" line>use LMDB;


my %DB := LMDB::DB.open(:path<some-dir>, %connection-parameters);
my %DB := LMDB::DB.open(:path<some-dir>, %connection-parameters);
</syntaxhighlight>
</lang>


%DB may be accessed, read from and written to like a native hash.
%DB may be accessed, read from and written to like a native hash.
Line 401: Line 450:


{{libheader|RubyGems}}
{{libheader|RubyGems}}
<lang ruby>require 'rubygems'
<syntaxhighlight lang="ruby">require 'rubygems'
require 'net/ldap'
require 'net/ldap'
ldap = Net::LDAP.new(:host => 'ldap.example.com', :base => 'o=companyname')
ldap = Net::LDAP.new(:host => 'ldap.example.com', :base => 'o=companyname')
ldap.authenticate('bind_dn', 'bind_pass')</lang>
ldap.authenticate('bind_dn', 'bind_pass')</syntaxhighlight>


=={{header|Run BASIC}}==
=={{header|Run BASIC}}==
{{incorrect|Run BASIC|Active Directory has nothing to do with the local file system}}
{{incorrect|Run BASIC|Active Directory has nothing to do with the local file system}}
<lang runbasic>print shell$("dir") ' shell out to the os and print it</lang>
<syntaxhighlight lang="runbasic">print shell$("dir") ' shell out to the os and print it</syntaxhighlight>


=={{header|Rust}}==
=={{header|Rust}}==
This solution uses the popular [https://crates.io/crates/ldap3 ldap3] crate.
This solution uses the popular [https://crates.io/crates/ldap3 ldap3] crate.
<lang rust>
<syntaxhighlight lang="rust">
let conn = ldap3::LdapConn::new("ldap://ldap.example.com")?;
let conn = ldap3::LdapConn::new("ldap://ldap.example.com")?;
conn.simple_bind("bind_dn", "bind_pass")?.success()?;
conn.simple_bind("bind_dn", "bind_pass")?.success()?;
</syntaxhighlight>
</lang>


=={{header|Scala}}==
=={{header|Scala}}==
<lang scala>import java.io.IOException
<syntaxhighlight lang="scala">import java.io.IOException


import org.apache.directory.api.ldap.model.exception.LdapException
import org.apache.directory.api.ldap.model.exception.LdapException
Line 435: Line 484:
}
}
}
}
}</lang>
}</syntaxhighlight>


=={{header|smart BASIC}}==
=={{header|smart BASIC}}==
Line 441: Line 490:


smart BASIC uses three separate commands to list the current directory, folder and files respectively.
smart BASIC uses three separate commands to list the current directory, folder and files respectively.
<lang qbasic>PRINT "Current directory: ";CURRENT_DIR$()
<syntaxhighlight lang="qbasic">PRINT "Current directory: ";CURRENT_DIR$()
PRINT
PRINT
PRINT "Folders:"
PRINT "Folders:"
Line 455: Line 504:
FOR n = 0 TO c-1
FOR n = 0 TO c-1
PRINT ,a$(n)
PRINT ,a$(n)
NEXT n</lang>
NEXT n</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
This does not use SSPI/Kerberos yet, so your AD would need to allow simple ldap access.
This does not use SSPI/Kerberos yet, so your AD would need to allow simple ldap access.
<lang tcl>package require ldap
<syntaxhighlight lang="tcl">package require ldap
set conn [ldap::connect $host $port]
set conn [ldap::connect $host $port]
ldap::bind $conn $user $password</lang>
ldap::bind $conn $user $password</syntaxhighlight>


=={{header|VBScript}}==
=={{header|VBScript}}==
Creating the normal connection to AD
Creating the normal connection to AD
<lang vbscript>Set objConn = CreateObject("ADODB.Connection")
<syntaxhighlight lang="vbscript">Set objConn = CreateObject("ADODB.Connection")
Set objCmd = CreateObject("ADODB.Command")
Set objCmd = CreateObject("ADODB.Command")
objConn.Provider = "ADsDSOObject"
objConn.Provider = "ADsDSOObject"
objConn.Open</lang>
objConn.Open</syntaxhighlight>

=={{header|Wren}}==
{{trans|C}}
{{libheader|OpenLDAP}}
As it's not currently possible for Wren-cli to access OpenLDAP directly, we embed a Wren script in a C application to complete this task.
<syntaxhighlight lang="wren">/* Active_Directory_Connect.wren */

foreign class LDAP {
construct init(host, port) {}

foreign simpleBindS(name, password)

foreign unbind()
}

class C {
foreign static getInput(maxSize)
}

var name = ""
while (name == "") {
System.write("Enter name : ")
name = C.getInput(40)
}

var password = ""
while (password == "") {
System.write("Enter password : ")
password = C.getInput(40)
}

var ld = LDAP.init("ldap.somewhere.com", 389)
ld.simpleBindS(name, password)

// do something here

ld.unbind()</syntaxhighlight>
<br>
We now embed this in the following C program, compile and run it.
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <ldap.h>
#include "wren.h"

/* C <=> Wren interface functions */

void C_ldapAllocate(WrenVM* vm) {
LDAP** pldap = (LDAP**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(LDAP*));
char *host = (char *)wrenGetSlotString(vm, 1);
int port = (int)wrenGetSlotDouble(vm, 2);
*pldap = ldap_init(host, port);
}

void C_simpleBindS(WrenVM* vm) {
LDAP* ldap = *(LDAP**)wrenGetSlotForeign(vm, 0);
const char *name = wrenGetSlotString(vm, 1);
const char *password = wrenGetSlotString(vm, 2);
ldap_simple_bind_s(ldap, name, password);
}

void C_unbind(WrenVM* vm) {
LDAP* ldap = *(LDAP**)wrenGetSlotForeign(vm, 0);
ldap_unbind(ldap);
}

void C_getInput(WrenVM* vm) {
int maxSize = (int)wrenGetSlotDouble(vm, 1) + 2;
char input[maxSize];
fgets(input, maxSize, stdin);
__fpurge(stdin);
input[strcspn(input, "\n")] = 0;
wrenSetSlotString(vm, 0, (const char*)input);
}

WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
WrenForeignClassMethods methods;
methods.finalize = NULL;
if (strcmp(className, "LDAP") == 0) {
methods.allocate = C_ldapAllocate;
}
return methods;
}

WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "LDAP") == 0) {
if (!isStatic && strcmp(signature, "simpleBindS(_,_)") == 0) return C_simpleBindS;
if (!isStatic && strcmp(signature, "unbind()") == 0) return C_unbind;
} else if (strcmp(className, "C") == 0) {
if (isStatic && strcmp(signature, "getInput(_)") == 0) return C_getInput;
}
}
return NULL;
}

static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}

char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}

int main(int argc, char **argv) {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignClassFn = &bindForeignClass;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "Active_Directory_Connect.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>


{{omit from|Active Directory}}
{{omit from|Active Directory}}
Line 477: Line 684:
{{omit from|Lilypond}}
{{omit from|Lilypond}}
{{omit from|Lingo}}
{{omit from|Lingo}}
{{omit from|TI-83 BASIC}}
{{omit from|TI-89 BASIC}} <!-- Does not have network access. -->
{{omit from|Mathematica}}
{{omit from|Mathematica}}
{{omit from|Maxima}}
{{omit from|MIPS Assembly|None of the commonly used implementations can access AD functions}}
{{omit from|MIPS Assembly|None of the commonly used implementations can access AD functions}}
{{omit from|ML/I}}
{{omit from|ML/I}}
Line 486: Line 692:
{{omit from|Retro}}
{{omit from|Retro}}
{{omit from|SNOBOL4|Does not have network access.}}
{{omit from|SNOBOL4|Does not have network access.}}
{{omit from|TI-83 BASIC}}
{{omit from|TI-89 BASIC}} <!-- Does not have network access. -->
{{omit from|Yorick|Does not have network access.}}
{{omit from|Yorick|Does not have network access.}}
{{omit from|ZX Spectrum Basic|Does not have network access.}}
{{omit from|ZX Spectrum Basic|Does not have network access.}}
{{omit from|Maxima}}

[[Category:Active Directory]]

Latest revision as of 21:13, 14 March 2024

Task
Active Directory/Connect
You are encouraged to solve this task according to the task description, using any language you may know.


The task is to establish a connection to an Active Directory or Lightweight Directory Access Protocol server.

AutoHotkey

Works with: AutoHotkey_L
Translation of: VBScript
objConn := CreateObject("ADODB.Connection")
objCmd := CreateObject("ADODB.Command")
objConn.Provider := "ADsDSOObject"
objConn.Open()

AutoIt

Works with: AutoIt
 #include <AD.au3>
_AD_Open()

C

With OpenLDAP:

#include <ldap.h>
...
char *name, *password;
...
LDAP *ld = ldap_init("ldap.somewhere.com", 389);
ldap_simple_bind_s(ld, name, password);
... after done with it...
ldap_unbind(ld);

C#

// Requires adding a reference to System.DirectoryServices 
var objDE = new System.DirectoryServices.DirectoryEntry("LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com");

ColdFusion

<cfldap 
server = "#someip#"
action="query" 
start="somestart#" 
username = "#someusername#" 
password = "#somepassowrd#" 
name = "results" 
scope="subtree" 
attributes = "#attributeslist#"
>

D

Based on dopenldap.

import openldap;
import std.stdio;

void main() {
  auto ldap = LDAP("ldap://localhost");
  auto r = ldap.search_s("dc=example,dc=com", LDAP_SCOPE_SUBTREE, "(uid=%s)".format("test"));
  int b = ldap.bind_s(r[0].dn, "password");
  scope(exit) ldap.unbind;
  if (b)
  {
    writeln("error on binding");
    return;
  }

  // do something
  ...
    
}

Erlang

This needs a test case. Is there a LDAP server available?

-module(ldap_example).
-export( [main/1] ).

main( [Host, DN, Password] ) ->
 {ok, Handle} = eldap:open( [Host] ),
 ok = eldap:simple_bind( Handle, DN, Password ),
 eldap:close( Handle ).

F#

Translation of: C_sharp

For Active Directory we use the library System.DirectoryServices

let adObject = new System.DirectoryServices.DirectoryEntry("LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com")

For your average LDAP server we use System.DirectoryServices.Protocol

For a minimal example we make an anonymous connect to the local machine on the well-known LDAP port 389

let ldapServer = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier("127.0.0.1")
let connect = new System.DirectoryServices.Protocols.LdapConnection(ldapServer)
connect.Bind()

FreeBASIC

Library: winldap
#Include "win\winldap.bi"

Dim ldap As LDAP Ptr
Dim hostname As String
Dim port As Integer
Dim username As String
Dim password As String
Dim result As Integer

hostname = "ldap.example.com"
port = 389    ' Standard port for LDAP. Use 636 for LDAPS.
username = "cn=username,dc=example,dc=com"
password = "password"

' Initialize the LDAP connection
ldap = ldap_init(hostname, port)
If ldap = NULL Then
     Print "Error initializing LDAP connection"
     Sleep
     End 1
End If

' Authenticate with the LDAP server
result = ldap_simple_bind_s(ldap, username, password)
If result <> LDAP_SUCCESS Then
     Print "Error authenticating with LDAP server: "; ldap_err2string(result)
     Sleep
     End 1
End If

' Here you can perform LDAP operations
'...

' We close the connection when finished
ldap_unbind(ldap)

Go


There are a large number of third-party LDAP libraries for Go. This uses one of the simpler ones and the code below is largely taken from the example on its main page.

package main

import (
    "log"
    "github.com/jtblin/go-ldap-client"
)

func main() {
    client := &ldap.LDAPClient{
        Base:         "dc=example,dc=com",
        Host:         "ldap.example.com",
        Port:         389,
        UseSSL:       false,
        BindDN:       "uid=readonlyuser,ou=People,dc=example,dc=com",
        BindPassword: "readonlypassword",
        UserFilter:   "(uid=%s)",
        GroupFilter:  "(memberUid=%s)",
        Attributes:   []string{"givenName", "sn", "mail", "uid"},
    }
    defer client.Close()
    err := client.Connect()
    if err != nil { 
        log.Fatalf("Failed to connect : %+v", err)
    }
    // Do something
}

Haskell

Example uses the ldap-client package:

{-# LANGUAGE OverloadedStrings #-}

module Main (main) where

import           Data.Foldable (for_)
import qualified Data.Text.Encoding as Text (encodeUtf8)
import           Ldap.Client (Attr(..), Filter(..))
import qualified Ldap.Client as Ldap (Dn(..), Host(..), search, with, typesOnly)

main :: IO ()
main = do
    entries <- Ldap.with (Ldap.Plain "localhost") 389 $ \ldap ->
        Ldap.search ldap (Ldap.Dn "o=example.com") (Ldap.typesOnly True) (Attr "uid" := Text.encodeUtf8 "user") []
    for_ entries $ \entry ->
        print entry

Java

This code uses the Apache Directory third-party library.

import java.io.IOException;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;

public class LdapConnectionDemo {

    public static void main(String[] args) throws LdapException, IOException {
        try (LdapConnection connection = new LdapNetworkConnection("localhost", 10389)) {
            connection.bind();
            connection.unBind();
        }
    }
}


Julia

using LDAPClient

conn = LDAPClient.LDAPConnection("ldap://localhost:10389")
LDAPClient.simple_bind(conn, "user", "password")
LDAPClient.unbind(conn)

Kotlin

import org.apache.directory.api.ldap.model.exception.LdapException
import org.apache.directory.ldap.client.api.LdapNetworkConnection
import java.io.IOException
import java.util.logging.Level
import java.util.logging.Logger

class LDAP(map: Map<String, String>) {
    fun run() {
        var connection: LdapNetworkConnection? = null
        try {
            if (info) log.info("LDAP Connection to $hostname on port $port")
            connection = LdapNetworkConnection(hostname, port.toInt())

            try {
                if (info) log.info("LDAP bind")
                connection.bind()
            } catch (e: LdapException) {
                log.severe(e.toString())
            }

            try {
                if (info) log.info("LDAP unbind")
                connection.unBind()
            } catch (e: LdapException) {
                log.severe(e.toString())
            }
        } finally {
            try {
                if (info) log.info("LDAP close connection")
                connection!!.close()
            } catch (e: IOException) {
                log.severe(e.toString())
            }
        }
    }

    private val log = Logger.getLogger(LDAP::class.java.name)
    private val info = log.isLoggable(Level.INFO)
    private val hostname: String by map
    private val port: String by map
}

fun main(args: Array<String>) = LDAP(mapOf("hostname" to "localhost", "port"  to "10389")).run()

NetRexx

Uses the Apache LDAP API, connecting to a local ApacheDS LDAP directory server.

/* NetRexx */
options replace format comments java crossref symbols binary

import org.apache.directory.ldap.client.api.LdapConnection
import org.apache.directory.ldap.client.api.LdapNetworkConnection
import org.apache.directory.shared.ldap.model.exception.LdapException
import org.slf4j.Logger
import org.slf4j.LoggerFactory

class RDirectoryLDAP public

  properties constant
    log_ = LoggerFactory.getLogger(RDirectoryLDAP.class)

  properties private static
    connection = LdapConnection null

  method main(args = String[]) public static
    ldapHostName = String "localhost"
    ldapPort = int 10389

    if log_.isInfoEnabled() then log_.info("LDAP Connection to" ldapHostName "on port" ldapPort)
    connection = LdapNetworkConnection(ldapHostName, ldapPort)

    do
      if log_.isTraceEnabled() then log_.trace("LDAP bind")
      connection.bind()

      if log_.isTraceEnabled() then log_.trace("LDAP unbind")
      connection.unBind()
    catch lex = LdapException
      log_.error("LDAP Error", Throwable lex)
    catch iox = IOException
      log_.error("I/O Error", Throwable iox)
    finally
      do
      if connection \= null then connection.close()
      catch iox = IOException
        log_.error("I/O Error on connection.close()", Throwable iox)
      end
    end

    return

Sample log4j.xml configuration file:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
  <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="[%d{HH:mm:ss}] %-5p [%c] - %m%n" />
    </layout>
  </appender>

  <!-- with these we'll not get innundated when switching to DEBUG -->
  <logger name="org.apache.directory.shared.ldap.name">
    <level value="warn" />
  </logger>
  <logger name="org.apache.directory.shared.codec">
    <level value="warn" />
  </logger>
  <logger name="org.apache.directory.shared.asn1">
    <level value="warn" />
  </logger>

  <root>
    <level value="info" />
    <appender-ref ref="stdout" />
  </root>
</log4j:configuration>

Output:

[08:40:05] INFO  [RDirectoryLDAP] - LDAP Connection to localhost on port 10389

Perl

LDAP Modules

use Net::LDAP;

my $ldap = Net::LDAP->new('ldap://ldap.example.com') or die $@;
my $mesg = $ldap->bind( $bind_dn, password => $bind_pass );

Phix

Translation of: C

Note that builtins\ldap.e is incomplete, windows-only (depends on wldap32.dll), and largely untested. This has been tested against a random 7-year-old list of public ldap servers, getting mixed errors of LDAP_SERVER_DOWN/LDAP_INVALID_CREDENTIALS/LDAP_INVALID_DN_SYNTAX/LDAP_CONFIDENTIALITY_REQUIRED.

include builtins/ldap.e
 
constant servers = {
"ldap.somewhere.com",
}
--...
string name="name", password="passwd"
--...
for i=1 to length(servers) do
    atom ld = ldap_init(servers[i])
    integer res = ldap_simple_bind_s(ld, name, password)
    printf(1,"%s: %d [%s]\n",{servers[i],res,ldap_err_desc(res)})
    --... after done with it...
    ldap_unbind(ld)
end for
Output:
ldap.somewhere.com: 81 [LDAP_SERVER_DOWN]

PHP

PHP LDAP Reference

<?php
$ldap = ldap_connect($hostname, $port);
$success = ldap_bind($ldap, $username, $password);

PicoLisp

(unless (=0 (setq Ldap (native "libldap.so" "ldap_open" 'N "example.com" 389)))
   (quit "Can't open LDAP") )

(native "libldap.so" "ldap_simple_bind_s" 'I Ldap "user" "password")

Python

Works with: Python version 2.6
Library: python-ldap

python-ldap Documentation

import ldap

l = ldap.initialize("ldap://ldap.example.com")
try:
    l.protocol_version = ldap.VERSION3
    l.set_option(ldap.OPT_REFERRALS, 0)

    bind = l.simple_bind_s("me@example.com", "password")
finally:
    l.unbind()

Racket

This version uses the ldap package, and was tested against OpenLDAP (with real values):

#lang racket
(require net/ldap)
(ldap-authenticate "ldap.somewhere.com" 389 "uid=username,ou=people,dc=somewhere,dc=com" password)
Translation of: C

This is a direct translation of the C code -- I have no idea how to try it out since I don't have a working ldap server... So take it as a stub that waits for someone who can try it to do so. (And it's a low level thing anyway, there's an ldap package for Racket which I can't try for a similar reason.)

#lang racket

(require ffi/unsafe ffi/unsafe/define)

(define-ffi-definer defldap (ffi-lib "libldap"))
(defldap ldap_init (_fun _string _int -> _pointer))
(defldap ldap_unbind (_fun _pointer -> _void))
(defldap ldap_simple_bind_s (_fun _pointer _string _string -> _int))
(defldap ldap_err2string (_fun _int -> _string))

(define name ...)
(define password ...)
(define ld (ldap_init "ldap.somewhere.com" 389))
(ldap_simple_bind_s ld name password)

(ldap_unbind ld)

Raku

(formerly Perl 6)

Using module LMDB - bindings to the openLDAP library. Requires an LDAP instance.

use LMDB;

my %DB := LMDB::DB.open(:path<some-dir>, %connection-parameters);

%DB may be accessed, read from and written to like a native hash.

Ruby

Similar to Tcl, assume the AD server talks LDAP.

There are many Ruby LDAP packages ([1]) -- this solution uses Net::LDAP ("Pure Ruby LDAP Tools" on RubyForge, gem name "ruby-net-ldap")

Library: RubyGems
require 'rubygems'
require 'net/ldap'
ldap = Net::LDAP.new(:host => 'ldap.example.com', :base => 'o=companyname')
ldap.authenticate('bind_dn', 'bind_pass')

Run BASIC

This example is incorrect. Please fix the code and remove this message.

Details: Active Directory has nothing to do with the local file system

print shell$("dir") ' shell out to the os and print it

Rust

This solution uses the popular ldap3 crate.

let conn = ldap3::LdapConn::new("ldap://ldap.example.com")?;
conn.simple_bind("bind_dn", "bind_pass")?.success()?;

Scala

import java.io.IOException

import org.apache.directory.api.ldap.model.exception.LdapException
import org.apache.directory.ldap.client.api.{LdapConnection, LdapNetworkConnection}

object LdapConnectionDemo {
  @throws[LdapException]
  @throws[IOException]
  def main(args: Array[String]): Unit = {
    try {
      val connection: LdapConnection = new LdapNetworkConnection("localhost", 10389)
      try {
        connection.bind()
        connection.unBind()
      } finally if (connection != null) connection.close()
    }
  }
}

smart BASIC

This example is incorrect. Please fix the code and remove this message.

Details: Active Directory has nothing to do with the local file system

smart BASIC uses three separate commands to list the current directory, folder and files respectively.

PRINT "Current directory: ";CURRENT_DIR$()
PRINT
PRINT "Folders:"
PRINT
DIR "/" LIST DIRS a$,c
FOR n = 0 TO c-1
PRINT ,a$(n)
NEXT n
PRINT
PRINT "Files:"
PRINT
DIR "/" LIST FILES a$,c
FOR n = 0 TO c-1
PRINT ,a$(n)
NEXT n

Tcl

This does not use SSPI/Kerberos yet, so your AD would need to allow simple ldap access.

package require ldap
set conn [ldap::connect $host $port]
ldap::bind $conn $user $password

VBScript

Creating the normal connection to AD

Set objConn = CreateObject("ADODB.Connection")
Set objCmd = CreateObject("ADODB.Command")
objConn.Provider = "ADsDSOObject"
objConn.Open

Wren

Translation of: C
Library: OpenLDAP

As it's not currently possible for Wren-cli to access OpenLDAP directly, we embed a Wren script in a C application to complete this task.

/* Active_Directory_Connect.wren */

foreign class LDAP {
    construct init(host, port) {}

    foreign simpleBindS(name, password)

    foreign unbind()
}

class C {
    foreign static getInput(maxSize)
}

var name = ""
while (name == "") {
    System.write("Enter name : ")
    name = C.getInput(40)
}

var password = ""
while (password == "") {
    System.write("Enter password : ")
    password = C.getInput(40)
}

var ld = LDAP.init("ldap.somewhere.com", 389)
ld.simpleBindS(name, password)

// do something here

ld.unbind()


We now embed this in the following C program, compile and run it.

#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <ldap.h>
#include "wren.h"

/* C <=> Wren interface functions */

void C_ldapAllocate(WrenVM* vm) {
    LDAP** pldap = (LDAP**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(LDAP*));
    char *host = (char *)wrenGetSlotString(vm, 1);
    int port = (int)wrenGetSlotDouble(vm, 2);
    *pldap = ldap_init(host, port);
}

void C_simpleBindS(WrenVM* vm) {
    LDAP* ldap = *(LDAP**)wrenGetSlotForeign(vm, 0);
    const char *name = wrenGetSlotString(vm, 1);
    const char *password = wrenGetSlotString(vm, 2);
    ldap_simple_bind_s(ldap, name, password);
}

void C_unbind(WrenVM* vm) {
    LDAP* ldap = *(LDAP**)wrenGetSlotForeign(vm, 0);
    ldap_unbind(ldap);
}

void C_getInput(WrenVM* vm) {
    int maxSize = (int)wrenGetSlotDouble(vm, 1) + 2;
    char input[maxSize];
    fgets(input, maxSize, stdin);
    __fpurge(stdin);
    input[strcspn(input, "\n")] = 0;
    wrenSetSlotString(vm, 0, (const char*)input);
}

WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
    WrenForeignClassMethods methods;
    methods.finalize = NULL;
    if (strcmp(className, "LDAP") == 0) {
        methods.allocate = C_ldapAllocate;
    } 
    return methods;
}

WrenForeignMethodFn bindForeignMethod(
    WrenVM* vm,
    const char* module,
    const char* className,
    bool isStatic,
    const char* signature) {
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "LDAP") == 0) {
            if (!isStatic && strcmp(signature, "simpleBindS(_,_)") == 0) return C_simpleBindS;
            if (!isStatic && strcmp(signature, "unbind()") == 0) return C_unbind;
        } else if (strcmp(className, "C") == 0) {
            if (isStatic && strcmp(signature, "getInput(_)") == 0) return C_getInput;
        }
    }
    return NULL;
}

static void writeFn(WrenVM* vm, const char* text) {
    printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
    switch (errorType) {
        case WREN_ERROR_COMPILE:
            printf("[%s line %d] [Error] %s\n", module, line, msg);
            break;
        case WREN_ERROR_STACK_TRACE:
            printf("[%s line %d] in %s\n", module, line, msg);
            break;
        case WREN_ERROR_RUNTIME:
            printf("[Runtime Error] %s\n", msg);
            break;
    }
}

char *readFile(const char *fileName) {
    FILE *f = fopen(fileName, "r");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    rewind(f);
    char *script = malloc(fsize + 1);
    fread(script, 1, fsize, f);
    fclose(f);
    script[fsize] = 0;
    return script;
}

int main(int argc, char **argv) {
    WrenConfiguration config;
    wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
    config.errorFn = &errorFn;
    config.bindForeignClassFn = &bindForeignClass;
    config.bindForeignMethodFn = &bindForeignMethod;
    WrenVM* vm = wrenNewVM(&config);
    const char* module = "main";
    const char* fileName = "Active_Directory_Connect.wren";
    char *script = readFile(fileName);
    WrenInterpretResult result = wrenInterpret(vm, module, script);
    switch (result) {
        case WREN_RESULT_COMPILE_ERROR:
            printf("Compile Error!\n");
            break;
        case WREN_RESULT_RUNTIME_ERROR:
            printf("Runtime Error!\n");
            break;
        case WREN_RESULT_SUCCESS:
            break;
    }
    wrenFreeVM(vm);
    free(script);
    return 0;
}