Active Directory/Connect: Difference between revisions
Thundergnat (talk | contribs) m (→{{header|smart BASIC}}: marked incorrect) |
(Add Rust implementation) |
||
Line 387:
{{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>
=={{header|Rust}}==
This solution uses the popular [https://crates.io/crates/ldap3 ldap3] crate.
<lang rust>
let conn = ldap3::LdapConn::new("ldap://ldap.example.com")?;
conn.simple_bind("bind_dn", "bind_pass")?.success()?;
</lang>
=={{header|Scala}}==
|
Revision as of 17:39, 19 August 2019
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.
AutoIt
<lang AutoIt> #include <AD.au3> _AD_Open()</lang>
AutoHotkey
<lang AutoHotkey>objConn := CreateObject("ADODB.Connection") objCmd := CreateObject("ADODB.Command") objConn.Provider := "ADsDSOObject" objConn.Open()</lang>
C
With OpenLDAP: <lang C>#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);</lang>
C#
<lang csharp> // Requires adding a reference to System.DirectoryServices var objDE = new System.DirectoryServices.DirectoryEntry("LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com"); </lang>
ColdFusion
<lang cfm> <cfldap server = "#someip#" action="query" start="somestart#" username = "#someusername#" password = "#somepassowrd#" name = "results" scope="subtree" attributes = "#attributeslist#" > </lang>
D
Based on dopenldap. <lang d> 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 ...
} </lang>
Erlang
This needs a test case. Is there a LDAP server available? <lang Erlang> -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 ).
</lang>
F#
For Active Directory we use the library System.DirectoryServices
<lang fsharp>let adObject = new System.DirectoryServices.DirectoryEntry("LDAP://DC=onecity,DC=corp,DC=fabrikam,DC=com")</lang>
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 <lang fsharp>let ldapServer = new System.DirectoryServices.Protocols.LdapDirectoryIdentifier("127.0.0.1") let connect = new System.DirectoryServices.Protocols.LdapConnection(ldapServer) connect.Bind()</lang>
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.
<lang go>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
}</lang>
Haskell
Example uses the ldap-client package:
<lang haskell>{-# 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</lang>
Java
This code uses the Apache Directory third-party library.
<lang java>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(); } }
}</lang>
Kotlin
<lang scala> 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() </lang>
NetRexx
Uses the Apache LDAP API, connecting to a local ApacheDS LDAP directory server. <lang NetRexx>/* 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
</lang>
Sample log4j.xml configuration file: <lang xml><?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>
<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> </lang>
Output:
[08:40:05] INFO [RDirectoryLDAP] - LDAP Connection to localhost on port 10389
Perl
LDAP Modules <lang perl> use Net::LDAP;
my $ldap = Net::LDAP->new('ldap://ldap.example.com') or die $@; my $mesg = $ldap->bind( $bind_dn, password => $bind_pass ); </lang>
Perl 6
Using module LMDB - bindings to the openLDAP library. Requires an LDAP instance.
<lang perl6>use LMDB;
my %DB := LMDB::DB.open(:path<some-dir>, %connection-parameters); </lang>
%DB may be accessed, read from and written to like a native hash.
PHP
PHP LDAP Reference <lang php><?php $ldap = ldap_connect($hostname, $port); $success = ldap_bind($ldap, $username, $password);</lang>
PicoLisp
<lang 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")</lang>
Python
<lang python>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()
</lang>
Racket
This version uses the ldap package, and was tested against OpenLDAP (with real values): <lang racket>#lang racket (require net/ldap) (ldap-authenticate "ldap.somewhere.com" 389 "uid=username,ou=people,dc=somewhere,dc=com" password)</lang>
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
(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)</lang>
Ring
<lang ring> see system("dir") + nl </lang>
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")
<lang ruby>require 'rubygems' require 'net/ldap' ldap = Net::LDAP.new(:host => 'ldap.example.com', :base => 'o=companyname') ldap.authenticate('bind_dn', 'bind_pass')</lang>
Run BASIC
<lang runbasic>print shell$("dir") ' shell out to the os and print it</lang>
Rust
This solution uses the popular ldap3 crate. <lang rust> let conn = ldap3::LdapConn::new("ldap://ldap.example.com")?; conn.simple_bind("bind_dn", "bind_pass")?.success()?; </lang>
Scala
<lang 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() } }
}</lang>
smart BASIC
smart BASIC uses three separate commands to list the current directory, folder and files respectively. <lang qbasic>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</lang>
Tcl
This does not use SSPI/Kerberos yet, so your AD would need to allow simple ldap access. <lang tcl>package require ldap set conn [ldap::connect $host $port] ldap::bind $conn $user $password</lang>
VBScript
Creating the normal connection to AD <lang vbscript>Set objConn = CreateObject("ADODB.Connection") Set objCmd = CreateObject("ADODB.Command") objConn.Provider = "ADsDSOObject" objConn.Open</lang>
- Programming Tasks
- Programming environment operations
- AutoIt
- AutoHotkey
- C
- C sharp
- ColdFusion
- D
- Erlang
- F Sharp
- Go
- Go-ldap-client
- Haskell
- Java
- Kotlin
- NetRexx
- Perl
- Perl 6
- PHP
- PicoLisp
- Python
- Python-ldap
- Racket
- Ring
- Ring examples needing attention
- Examples needing attention
- Ruby
- RubyGems
- Run BASIC
- Run BASIC examples needing attention
- Rust
- Scala
- Smart BASIC
- Smart BASIC examples needing attention
- Tcl
- VBScript
- Active Directory/Omit
- AWK/Omit
- Clojure/Omit
- GUISS/Omit
- Inform 7/Omit
- Lilypond/Omit
- Lingo/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- Mathematica/Omit
- MIPS Assembly/Omit
- ML/I/Omit
- PARI/GP/Omit
- PostScript/Omit
- Retro/Omit
- SNOBOL4/Omit
- Yorick/Omit
- ZX Spectrum Basic/Omit
- Maxima/Omit
- Active Directory