Active Directory/Search for a user: Difference between revisions

From Rosetta Code
Content added Content deleted
(Add NetRexx implementation)
(Add Java implementation)
Line 25: Line 25:
ldap_msgfree(*result); /* free messages */
ldap_msgfree(*result); /* free messages */
ldap_unbind(ld); /* disconnect */</lang>
ldap_unbind(ld); /* disconnect */</lang>

=={{header|Java}}==
{{Trans|NetRexx}}
<lang java>
import java.io.IOException;
import java.util.Arrays;

import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.apache.directory.shared.ldap.model.cursor.EntryCursor;
import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.exception.LdapException;
import org.apache.directory.shared.ldap.model.message.SearchScope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class RDirectorySearchLDAP {

protected static final Logger log_;
private static LdapConnection connection;
private static final String ldapHostName;
private static final int ldapPort;
private static final String ldapDnStr;
private static final String ldapCreds;

static {

log_ = LoggerFactory.getLogger(RDirectorySearchLDAP.class);

ldapHostName = "localhost";
ldapPort = 11389;
ldapDnStr="uid=admin,ou=system";
ldapCreds="********";
}

public static void main(String[] args) {

boolean connected = false;

try {
connected = setUp();
if (connected) {
search("*mil*");
}
}
finally {
if (connected) {
tearDown();
}
}

return;
}

private static boolean search(String uid) {

boolean state;
EntryCursor cursor;
Entry ev;
String baseDn;
String filter;
SearchScope scope;
String attributes[];
int ksearch = 0;

state = true;

baseDn = "ou=users,o=mojo";
filter = "(&(objectClass=person)(&(uid=" + uid + ")))";
scope = SearchScope.SUBTREE;
attributes = new java.lang.String[] { "dn", "cn", "sn", "uid" };

try {
if (log_.isTraceEnabled()) { log_.trace("LDAP search"); }
if (log_.isInfoEnabled()) {
log_.info("Begin search");
log_.info(" search base distinguished name: " + baseDn);
log_.info(" search filter: " + filter);
log_.info(" search attributes: " + (Arrays.asList(attributes).toString()));
}
cursor = connection.search(baseDn, filter, scope, attributes);
while (cursor.next()) {
ksearch++;
ev = cursor.get();
if (log_.isInfoEnabled()) { log_.info("Search cursor entry count: " + ksearch); }
if (log_.isInfoEnabled()) { log_.info(ev.toString()); }
}
}
catch (LdapException lex) {
state = false;
log_.error("LDAP Error in cursor loop: Iteration " + ksearch, lex);
}
catch (Exception ex) {
state = false;
log_.error("I/O Error in cursor loop: Iteration " + ksearch, ex);
}

return state;
}

private static boolean search() {
return search("*");
}

private static boolean setUp() {

boolean state = false;

try {
if (log_.isInfoEnabled()) { log_.info("LDAP Connection to " + ldapHostName + " on port " + ldapPort); }
connection = new LdapNetworkConnection(ldapHostName, ldapPort);

if (log_.isTraceEnabled()) { log_.trace("LDAP bind"); }
connection.bind(ldapDnStr, ldapCreds);

state = true;
}
catch (LdapException lex) {
state = false;
log_.error("LDAP Error", lex);
}
catch (IOException iox) {
state = false;
log_.error("I/O Error", iox);
}

return state;
}

private static boolean tearDown() {

boolean state = false;

try {
if (log_.isTraceEnabled()) { log_.trace("LDAP unbind"); }
connection.unBind();
state = true;
}
catch (LdapException lex) {
state = false;
log_.error("LDAP Error", lex);
}
finally {
try {
connection.close();
}
catch (IOException iox) {
state = false;
log_.error("I/O Error on connection.close()", iox);
}
}

return state;
}
}
</lang>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Line 62: Line 220:
ldapPort = int 11389
ldapPort = int 11389
ldapDnStr = String 'uid=admin,ou=system'
ldapDnStr = String 'uid=admin,ou=system'
ldapCreds = String 'secret'
ldapCreds = String '********'


isTrue = boolean (1 == 1)
isTrue = boolean (1 == 1)

Revision as of 00:18, 3 October 2012

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

Make sure you Connect to Active Directory

C

<lang C>#include <ldap.h>

char *name, *password; ...

LDAP *ld = ldap_init("ldap.somewhere.com", 389); ldap_simple_bind_s(ld, name, password);

LDAPMessage **result; ldap_search_s(ld, "dc=somewhere,dc=com", LDAP_SCOPE_SUBTREE, /* search for all persons whose names start with joe or shmoe */ "(&(objectclass=person)(|(cn=joe*)(cn=shmoe*)))", NULL, /* return all attributes */ 0, /* want both types and values of attrs */ result); /* ldap will allocate room for return messages */

/* arduously do stuff here to result, with ldap_first_message(), ldap_parse_result(), etc. */

ldap_msgfree(*result); /* free messages */ ldap_unbind(ld); /* disconnect */</lang>

Java

Translation of: NetRexx

<lang java> import java.io.IOException; import java.util.Arrays;

import org.apache.directory.ldap.client.api.LdapConnection; import org.apache.directory.ldap.client.api.LdapNetworkConnection; import org.apache.directory.shared.ldap.model.cursor.EntryCursor; import org.apache.directory.shared.ldap.model.entry.Entry; import org.apache.directory.shared.ldap.model.exception.LdapException; import org.apache.directory.shared.ldap.model.message.SearchScope; import org.slf4j.Logger; import org.slf4j.LoggerFactory;


public class RDirectorySearchLDAP {

 protected static final Logger log_;
 private static LdapConnection connection;
 private static final String ldapHostName;
 private static final int ldapPort;
 private static final String ldapDnStr;
 private static final String ldapCreds;
 static {
   log_ = LoggerFactory.getLogger(RDirectorySearchLDAP.class);
   ldapHostName = "localhost";
   ldapPort = 11389;
   ldapDnStr="uid=admin,ou=system";
   ldapCreds="********";
 }
 public static void main(String[] args) {
   boolean connected = false;
   try {
     connected = setUp();
     if (connected) {
       search("*mil*");
     }
   }
   finally {
     if (connected) {
       tearDown();
     }
   }
   return;
 }
 private static boolean search(String uid) {
   boolean state;
   EntryCursor cursor;
   Entry ev;
   String baseDn;
   String filter;
   SearchScope scope;
   String attributes[];
   int ksearch = 0;
   state = true;
   baseDn = "ou=users,o=mojo";
   filter = "(&(objectClass=person)(&(uid=" + uid + ")))";
   scope = SearchScope.SUBTREE;
   attributes = new java.lang.String[] { "dn", "cn", "sn", "uid" };
   try {
     if (log_.isTraceEnabled()) { log_.trace("LDAP search"); }
     if (log_.isInfoEnabled()) {
       log_.info("Begin search");
       log_.info("  search base distinguished name: " + baseDn);
       log_.info("  search filter: " + filter);
       log_.info("  search attributes: " + (Arrays.asList(attributes).toString()));
     }
     cursor = connection.search(baseDn, filter, scope, attributes);
     while (cursor.next()) {
       ksearch++;
       ev = cursor.get();
       if (log_.isInfoEnabled()) { log_.info("Search cursor entry count: " + ksearch); }
       if (log_.isInfoEnabled()) { log_.info(ev.toString()); }
     }
   }
   catch (LdapException lex) {
     state = false;
     log_.error("LDAP Error in cursor loop: Iteration " + ksearch, lex);
   }
   catch (Exception ex) {
     state = false;
     log_.error("I/O Error in cursor loop: Iteration " + ksearch, ex);
   }
   return state;
 }
 private static boolean search() {
   
   return search("*");
 }
 private static boolean setUp() {
   boolean state = false;
   try {
     if (log_.isInfoEnabled()) { log_.info("LDAP Connection to " + ldapHostName + " on port " + ldapPort); }
     connection = new LdapNetworkConnection(ldapHostName, ldapPort);
     if (log_.isTraceEnabled()) { log_.trace("LDAP bind"); }
     connection.bind(ldapDnStr, ldapCreds);
     state = true;
   }
   catch (LdapException lex) {
     state = false;
     log_.error("LDAP Error", lex);
   }
   catch (IOException iox) {
     state = false;
     log_.error("I/O Error", iox);
   }
   return state;
 }
 private static boolean tearDown() {
   boolean state = false;
   try {
     if (log_.isTraceEnabled()) { log_.trace("LDAP unbind"); }
     connection.unBind();
     state = true;
   }
   catch (LdapException lex) {
     state = false;
     log_.error("LDAP Error", lex);
   }
   finally {
     try {
       connection.close();
     }
     catch (IOException iox) {
       state = false;
       log_.error("I/O Error on connection.close()", iox);
     }
   }
   return state;
 }

} </lang>

PicoLisp

<lang PicoLisp>(de ldapsearch (Sn)

  (in
     (list "ldapsearch" "-xH" "ldap://db.debian.org"
        "-b" "dc=debian,dc=org"
        (pack "sn=" Sn) )
     (list
        (cons 'cn (prog (from "cn: ") (line T)))
        (cons 'uid (prog (from "uid: ") (line T))) ) ) )</lang>

Test:

: (ldapsearch "Fischer")
-> ((cn . "Mika") (uid . "mf"))

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.cursor.EntryCursor import org.apache.directory.shared.ldap.model.entry.Entry import org.apache.directory.shared.ldap.model.exception.LdapException import org.apache.directory.shared.ldap.model.message.SearchScope import org.slf4j.Logger import org.slf4j.LoggerFactory

class RDirectorySearchLDAP public

 properties constant
   log_ = LoggerFactory.getLogger(RDirectorySearchLDAP.class)
 properties private constant
   ldapHostName = String 'localhost'
   ldapPort = int 11389
   ldapDnStr = String 'uid=admin,ou=system'
   ldapCreds = String '********'
   isTrue = boolean (1 == 1)
   isFalse = boolean (1 \== 1)
 properties private static
   connection = LdapConnection
 method main(args = String[]) public static
   connected = isFalse
   do
     connected = setUp()
     if connected then do
       search('*mil*')
       end
   finally
     if connected then do
       tearDown()
       end
   end
   return
 method search(uid = String '*') static returns boolean
   state      = isTrue
   cursor     = EntryCursor
   baseDn     = 'ou=users,o=mojo'
   filter     = '(&(objectClass=person)(&(uid=' || uid || ')))'
   scope      = SearchScope.SUBTREE
   attributes = String[] [String 'dn', 'cn', 'sn', 'uid']
   do
     if log_.isTraceEnabled() then log_.trace('LDAP search')
     if log_.isInfoEnabled() then do
       log_.info('Begin search')
       log_.info('  search base distinguished name:' baseDn)
       log_.info('  search filter:' filter)
       log_.info('  search attributes:' Arrays.asList(attributes))
       end
     cursor = connection.search(baseDn, filter, scope, attributes)
     loop ksearch = 1 while cursor.next()
       ev = cursor.get()
       if log_.isInfoEnabled() then log_.info('Search cursor entry count:' ksearch)
       if log_.isInfoEnabled() then log_.info(ev.toString())
       end ksearch
   catch lex = LdapException
     state = isFalse
     log_.error('LDAP Error in cursor loop: Iteration' ksearch, Throwable lex)
   catch ex = Exception
     state = isFalse
     log_.error('I/O Error in cursor loop: Iteration' ksearch, Throwable ex)
   end
   return state
 method setUp() static returns boolean
   state = isFalse
   do
     if log_.isInfoEnabled() then log_.info('LDAP Connection to' ldapHostName 'on port' ldapPort)
     connection = LdapNetworkConnection(ldapHostName, ldapPort)
     if log_.isTraceEnabled() then log_.trace('LDAP bind')
     connection.bind(ldapDnStr, ldapCreds)
     state = isTrue
   catch lex = LdapException
     state = isFalse
     log_.error('LDAP Error', Throwable lex)
   catch iox = IOException
     state = isFalse
     log_.error('I/O Error', Throwable iox)
   end
   return state
 method tearDown() static returns boolean
   state = isFalse
   do
     if log_.isTraceEnabled() then log_.trace('LDAP unbind')
     connection.unBind()
     state = isTrue
   catch lex = LdapException
     state = isFalse
     log_.error('LDAP Error', Throwable lex)
   finally
     do
       connection.close()
     catch iox = IOException
       state = isFalse
       log_.error('I/O Error on connection.close()', Throwable iox)
     end
   end
   return state

</lang> Output:

[16:51:37] INFO  [RDirectorySearchLDAP] - LDAP Connection to localhost on port 11389 
[16:51:39] INFO  [RDirectorySearchLDAP] - Begin search 
[16:51:39] INFO  [RDirectorySearchLDAP] -   search base distinguished name: ou=users,o=mojo 
[16:51:39] INFO  [RDirectorySearchLDAP] -   search filter: (&(objectClass=person)(&(uid=*mil*))) 
[16:51:39] INFO  [RDirectorySearchLDAP] -   search attributes: [dn, cn, sn, uid] 
[16:51:39] INFO  [RDirectorySearchLDAP] - Search cursor entry count: 1 
[16:51:39] INFO  [RDirectorySearchLDAP] - Entry 
    dn: cn=John Milton,ou=users,o=mojo 
    uid: jmilton 
    sn: Milton 
    cn: John Milton

PHP

Translation of: Python
Library: php-ldap

<lang php><?php

$l = ldap_connect('ldap.example.com'); ldap_set_option($l, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($l, LDAP_OPT_REFERRALS, false);

$bind = ldap_bind($l, 'me@example.com', 'password');

$base = 'dc=example, dc=com'; $criteria = '(&(objectClass=user)(sAMAccountName=username))'; $attributes = array('displayName', 'company');

$search = ldap_search($l, $base, $criteria, $attributes); $entries = ldap_get_entries($l, $search);

var_dump($entries);</lang>

Python

Works with: Python version 2.6
Library: python-ldap

python-ldap Documentation

<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")
   
   base = "dc=example, dc=com"
   criteria = "(&(objectClass=user)(sAMAccountName=username))"
   attributes = ['displayName', 'company']
   result = l.search_s(base, ldap.SCOPE_SUBTREE, criteria, attributes)
   results = [entry for dn, entry in result if isinstance(entry, dict)]
   print results

finally:

   l.unbind()

</lang>

Ruby

Assume AD server talks LDAP.

Library: RubyGems

<lang ruby>require 'rubygems' require 'net/ldap'

ldap = Net::LDAP.new(:host => 'hostname', :base => 'base') ldap.authenticate('bind_dn', 'bind_pass')

filter = Net::LDAP::Filter.pres('objectclass') filter &= Net::LDAP::Filter.eq('sn','Jackman')

  1. or

filter = Net::LDAP::Filter.construct('(&(objectclass=*)(sn=Jackman))')

results = ldap.search(:filter => filter) # returns an array of Net::LDAP::Entry objects

puts results[0][:sn] # ==> "Jackman"</lang>

Run BASIC

This allows the client on the web to see their directory.
The user can click on any file or directory and this will give them the following options:
 [upload] data from their computer to the server
 [delete] data from their directory 
 [rename] files
 [view]   image files

<lang runbasic>' --------------------------------------------- ' Directory maintenance ' --------------------------------------------- cr$ = chr$(13) dirOf$ = "c:\*.*" ' get directory of

' ------------------------------------------- ' Shell out directory ' -------------------------------------------

[dirShell] cls

html "

"

loc$ = strRep$(dirOf$,"*.*","") x$ = shell$("dir ";dirOf$)

i = 1 while word$(x$,i,cr$) <> "" a$ = word$(x$,i,cr$) if trim$(a$) = "" then goto [next] if left$(a$,1) = " " then goto [next] if left$(a$,1) = cr$ then goto [next] type$ = mid$(a$,26,3) size$ = mid$(a$,30,9) size$ = strRep$(size$,",","") size = val(size$) if type$ <> "DIR" and size = 0 then goto [next] name$ = mid$(a$,40) a$ = strRep$(a$,"<","[") a$ = strRep$(a$,">","]") html left$(a$,39) link #ddir,name$, [doDir] #ddir setkey(type$;"|";loc$;name$) html "
" goto [next1]

    [next]

print a$

    [next1]

i = i + 1 wend wait [doDir] type$ = word$(EventKey$,1,"|") name$ = word$(EventKey$,2,"|")

if type$ = "DIR" then dirOf$ = name$;"\*.*" goto [dirShell] end if

html "<script> document.getElementById('wk').innerHTML = '" nname$ = strRep$(name$,"\","\\") html "What do you want to do with ";nname$;"
" button #dofile, "Upload",[upload] button #dofile, "Delete",[delete] button #rename, "Rename",[rename] button #view, "View", [view] html "';</script>" wait

[delete]

kill name$
goto [dirShell]

[view] nname$ = strRep$(name$,"\","/") print "File:";nname$ nname$ = mid$(nname$,3) html "<EMBED SRC=""..";nname$;""">" print "<EMBED SRC=""..";nname$;""">"

wait

[upload] print "Upload File:";name$ files #f, name$ if #f HASANSWER() = 0 then print "File: ";name$;" not found" end if

' ------------------------------------- ' load data to directory ' ------------------------------------- OPEN name$ FOR binary AS #f filedata$ = input$(#f, LOF(#f)) CLOSE #f print filedata$ wait

f$ = photoDir$;uploadId$ OPEN f$ FOR binary AS #f PRINT #f, filedata$ CLOSE #f wait

' -------------------------------- ' string replace rep str with ' -------------------------------- FUNCTION strRep$(strRep$,rep$,with$) ln = len(rep$) k = instr(strRep$,rep$) while k strRep$ = left$(strRep$,k - 1) + with$ + mid$(strRep$,k + ln) k = instr(strRep$,rep$) WEND END FUNCTION end</lang>

Output as seen by the client on the web

Volume in drive C has no label.
Volume Serial Number is F42C-D87A

 Directory of c:\
06/10/2009  02:42 PM                24 autoexec.bat
06/10/2009  02:42 PM                10 config.sys
01/30/2012  02:26 PM               206 csb.log
03/09/2012  10:00 AM    [DIR]          data
02/07/2012  07:48 AM       748,990,464 precise-desktop-i386.iso
03/20/2012  04:07 PM    [DIR]          Program Files
02/05/2012  05:09 PM    [DIR]          Python
03/19/2012  04:55 PM    [DIR]          rbp101
01/30/2012  02:26 PM             3,081 RHDSetup.log
01/30/2012  10:14 PM    [DIR]          Users
01/30/2012  02:35 PM    [DIR]          wamp
03/06/2012  04:00 AM    [DIR]          Windows
               5 File(s)    748,993,785 bytes
               7 Dir(s) 952,183,820,288 bytes free

Tcl

One can do it with the low level Connect to Active Directory based handle with this code:

This is just the basic setup. <lang tcl>set Username "TestUser" set Filter "((&objectClass=*)(sAMAccountName=$Username))" set Base "dc=skycityauckland,dc=sceg,dc=com" set Attrs distinguishedName</lang>

Now do the actual search. <lang tcl>set result [ldap::search $conn $Base $Filter $Attrs -scope subtree]</lang>

If we have only a single result its easy: <lang tcl>if {[llength $result] == 1} {

   puts [dict get [lindex $result 0 1] distinguishedName]

}</lang>

Looping over the result set to output some values. <lang tcl>foreach pair $result {

   lassign $pair cn attributes
   puts [dict get $attributes distinguishedName]

}</lang>

If you're bored you can also use this instead: <lang tcl>package require ldapx set conn [ldapx::connect $BindDN $Password] $conn traverse $Base $Filter $Attrs e {

   puts [$e get distinguishedName]

}</lang>

VBScript

The search string and execution of the string <lang vbscript>strUsername = "TestUser" strQuery = "<LDAP://dc=skycityauckland,dc=sceg,dc=com>;"_

& "(&(objectclass=*)(samaccountname=" & strUsername & "));distinguishedname;subtree"

objCmd.ActiveConnection = objConn objCmd.Properties("Page Size")=100 objCmd.CommandText = strQuery Set objRS = objCmd.Execute</lang>

Doing something with a single result (this will output the returned users full DN) <lang vbscript>If objRS.RecordCount = 1 Then

 WScript.Echo objRS.Fields("DistinguishedName")

End If</lang>

Doing something with multiple results (this will output each returned users full DN) <lang vbscript>If objRS.RecordCount > 0 Then

 For Each objUser in ObjRS
   WScript.Echo objRS.Fields("DistinguishedName")
 Next

End If</lang>