SlideShare una empresa de Scribd logo
1 de 36
Descargar para leer sin conexión
Lotus Software - Messaging & Collaboration
Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation
From Now To Next
Ken Lin
Senior Software Engineer
klin@us.ibm.com
Collaborative Cuisine's
1 Hour JNDI Cookbook
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Goals
Review common directory-related
collaboration scenarios
Examine solutions through algorithms
and JNDI code
Refine and improve solutions
Lotus Software - Messaging & Collaboration
Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation
From Now To Next
Starters
Main Courses
Desserts
Tidy Up
Today's Menu
Lotus Software - Messaging & Collaboration
Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation
From Now To Next
Locate a Directory Server
Resolve and Authenticate a User
Starters
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Locate a Directory Server
Properties File
Configured by each application administrator
Application-dependent solution
Easy to code via java.util.Properties
Manageable when few applications
RFC 2782 - A DNS RR for specifying the location of services
(DNS SRV)
Configured centrally by DNS administrator
Application-independent solution
Easy to code via JNDI
Manageable even when many applications
Recognized by com.sun.jndi.ldap.LdapCtxFactory in
JDK 1.4.1
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DNS SRV (RFC 2782)
w32 [C:] winntsystem32nslookup
Default Server: ns1.iris.com
Address: 9.95.aaa.bbb
> set q=srv
> _ldap._tcp.iris.com you type this
0=highest
65535=lowest
Server: ns1.iris.com
Address: 9.95.aaa.bbb
_ldap._tcp.iris.com SRV service location:
priority = 0
weight = 0
port = 389
svr hostname = clapton.iris.com
_ldap._tcp.iris.com SRV service location:
priority = 100
weight = 0
port = 389
svr hostname = little-village.iris.com
clapton.iris.com internet address = 9.95.ccc.ddd
little-village.iris.com internet address = 9.95.eee.fff
>^Z
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirServer.getServers returns host:port strings
public static Vector getServers(String domain) throws NamingException {
Vector servers = new Vector();
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
DirContext ctx = new InitialDirContext(env);
Attributes attrs = ctx.getAttributes("_ldap._tcp." + domain, new String[] {"SRV"});
Attribute srv = attrs.get("SRV");
if (srv != null) {
NamingEnumeration results = srv.getAll();
if (results.hasMore()) {
while (results.hasMore()) {
String result = (String)results.next();
StringTokenizer tokens = new StringTokenizer(result, " ");
String priority = tokens.nextToken();
String weight = tokens.nextToken();
String port = tokens.nextToken();
String target = tokens.nextToken();
servers.add(target + ":" + port);
}
}
}
return servers;
}
J2SE 1.4.1 or higher
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Resolve and Authenticate Users
How do we code
applications to
authenticate using
"friendly" names?
cn=ken lin,ou=westford,o=ibm
is not very friendly!
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Resolve and Authenticate Users Algorithm
Does the supplied name look like an LDAP DN?
Yes: ask the LDAP server if DN exists?
Yes: go to Authenticated Bind
No: go to Resolve DN
No: go to Resolve LDAP DN
Resolve supplied name to LDAP DN
Unauthenticated search the name to obtain its DN
(&(objectclass=person)(|(uid={0})(mail={0})(cn={0})))
Allow the filter to be customized to fit customer
(&(objectclass=person)(telephonenumber={0}))
If number of search hits is ...
0: name not found
1: go to Authenticated Bind
otherwise: ambiguous DN
Authenticated Bind
Use LDAP DN and supplied password
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirUser.authenticate to Authenticate and Resolve a Name
boolean authenticate(String hostport, String anyname, String password) throws
NamingException
{
boolean authenticated = false;
DirContext ctx = null;
try {
String dn = resolve(anyname);
if (dn != null) {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, m_ServiceProvider);
env.put(Context.PROVIDER_URL, "ldap://" + hostport);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, dn);
env.put(Context.SECURITY_CREDENTIALS, password);
ctx = new InitialDirContext(env);
authenticated = true;
}
} catch (AuthenticationException e) {
authenticated = false;
} finally {
try {
if (ctx != null) ctx.close();
} catch (Exception e) {
}
}
return authenticated;
}
"com.sun.jndi.ldap.LdapCtxFactory"
local DirContext for dn/password
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirUser.resolve to Get a DN from anyname
String resolve(String anyname) throws NamingException
{
// If anyname looks like it might be a DN, try a base search
if (anyname.indexOf("=") != -1) {
try {
Attributes attrs = m_Ctx.getAttributes(anyname);
return anyname;
} catch (NameNotFoundException e) {
// not a valid or known DN, try filtered search
}
}
// anyname must not look like a DN, search for m_FilterPattern with anyname
Object args[] = {anyname};
String filter = java.text.MessageFormat.format(m_FilterPattern, args);
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(null);
ctls.setCountLimit(1);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration results = m_Ctx.search(m_Base, filter, ctls);
if (results.hasMore()) {
SearchResult result = (SearchResult)results.next();
return result.getName();
} else {
throw new NameNotFoundException("Neither DN nor filter hits");
}
}
"(&(objectclass=person)
(|(uid={0})(mail={0})(cn={0})))"
DirContext for this application
some vendors require base
so more than 1 result causes
SizeLimitExceededException
Lotus Software - Messaging & Collaboration
Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation
From Now To Next
Find a Member's Group
Find a Group's Members
Main Courses
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Directory Groups
IETF, Defacto, and Vendor Group Definitions
Definitions for Static Groups in IETF RFC 2782
groupOfNames / member
groupOfUniqueNames / uniqueMember
Group operations are coded by the application, not the
LDAP server!
Applications must understand schema
Applications must code findMembers
Applications must code findGroups
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
dgservlet Demo
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Two Common Uses for findMembers and findGroups
findMembers can be used
to expand and flatten out a
buddy list
findGroups can be used to
create Notes-like NamesLists
for authorization
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirGroups Class
public class DirGroups
{
protected DirContext m_Ctx = null;
protected NameParser m_Parser = null;
protected String m_GroupObjectClasses[] = {"groupOfNames"};
protected String m_MemberNames[] = {"member"};
protected String m_Base = "";
protected String m_MemberFilter = "(&(objectclass=groupOfNames)(member={0}))";
protected int m_FindMembersDepth = 10;
protected String m_MemberAttrIds[] = {"objectclass", "member", "cn"};
public DirGroups(DirContext ctx) {
m_Ctx = ctx;
}
public void findGroups(String memberDN, Hashtable groups) throws NamingException
{ described later... }
public void findMembers(Name groupDN, Hashtable groups,
Hashtable users, Hashtable unknown) throws NamingException
{ described later... }
etc...
}
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
findMembers Algorithm
get entry g from groupDN and verify it is a group
foreach memberDN in g {
if memberDN isn't in groups, users, or unknown {
get entry m from memberDN
if m is a group --> add m to groups and recurse...
findMembers(memberDN, groups, users, unknown)
if m is a non-group --> add m to users
if m's objectclass is unknown --> add m to unknown
}
}
findMembers(in String groupDN,
inout Hashtable groups,
inout Hashtable users,
inout Hashtable unknown)
Optimize!
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirGroups.findMembers
public void findMembers(Name groupDN,
Hashtable groups,
Hashtable users,
Hashtable unknown)
throws NamingException
{
// Verify arguments
if (groupDN == null ||
groups == null || users == null || unknown == null)
{
return;
}
// Verify the groupDN is really a group
Attributes attrs = m_Ctx.getAttributes(groupDN, m_MemberAttrIds);
if (!isGroup(attrs)) {
throw new NamingException("'objectclass' is not a group");
}
findMembers(attrs, m_FindMembersDepth, groups, users, unknown);
}
DirContext for this DirGroups object
10
{"objectclass", "member", "cn"}
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirGroups.findMembers
private void findMembers(Attributes attrs, int depth, Hashtable groups,
Hashtable users,Hashtable unknown) throws NamingException {
if (depth <= 0) { return; }
for (int i = 0; i < m_MemberNames.length; i++) {
Attribute attr = attrs.get(m_MemberNames[i]);
if (attr != null) {
NamingEnumeration members = attr.getAll();
while (members.hasMore()) {
Name memberDN = toName((String)members.nextElement());
// Process memberDN only if it hasn't yet been encounterred
if (!users.containsKey(memberDN) && !groups.containsKey(memberDN) &&
!unknown.containsKey(memberDN)) {
try {
if (isGroup(memberDN)) { // memberDN is a group
attrs = m_Ctx.getAttributes(memberDN, m_MemberAttrIds);
if (groups.put(memberDN, attrs) == null) {
findMembers(attrs, depth-1, groups, users, unknown);
}
} else { // memberDN is a non-group
users.put(memberDN, memberDN/*null*/);
}
} catch (NamingException e) { // memberDN is unknown
unknown.put(memberDN, memberDN/*null*/);
}
}
} // while
}
} // for
}
{"objectclass",
"member", "cn"}
{"member"}
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirGroups.isGroup
private boolean isGroup(Name name)
throws NamingException
{
if (m_GroupObjectClasses.length == 1) {
return compare(name, "objectclass", m_GroupObjectClasses[0]);
} else {
Attributes attrs = m_Ctx.getAttributes(name, m_MemberAttrIds);
return isGroup(attrs);
}
}
private boolean isGroup(Attributes attrs)
throws NamingException
{
Attribute attr = attrs.get("objectclass");
if (attr != null) {
for (int i = 0; i < m_GroupObjectClasses.length; i++) {
if (attr.contains(m_GroupObjectClasses[i])) {
return true;
}
}
return false;
} else {
throw new NamingException("'objectclass' attribute not found");
}
}
LDAP compare is faster than search
{"groupOfNames"}
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirGroups.compare
private boolean compare(Name name, String attr, String value)
throws NamingException
{
SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
ctls.setReturningAttributes(new String[0]); // no attributes
// LDAP compare operation
NamingEnumeration results = m_Ctx.search(name, "(" + attr + "=" + value + ")",
ctls);
return results.hasMore(); // if successful, results will contain a single item
}
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
findGroups Algorithm
findGroups(in String memberDN,
inout Hashtable groups)
g = DNs of groups that memberDN
is a direct member
tovisit = g
while tovisit is not empty {
pop any groupDN from tovisit
if groupDN is not in groups {
groups += groupDN
g = DNs of groups that groupDN
is a direct member of
tovisit += elements of g not in
tovisit or groups
}
}
1. cn=bugs bunny,o=toons
empty
2. cn=looney toons
3. cn=looney toons
4. cn=looney toons
empty
5. cn=looney toons
6. cn=all toons
7. cn=all toons
8. cn=all toons
9. cn=all toons
empty
10. cn=looney toons
cn=all toons
11. empty
12. empty
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirGroups.findGroups
public void findGroups(Name memberDN,
Hashtable groups)
throws NamingException
{
Hashtable tovisit = new Hashtable(); // DNs of groups to visit
// Initialize tovisit to groups that memberDN is a direct member of.
putDirectGroups(memberDN, tovisit, groups);
// groups = union(groups, tovisit)
while (!tovisit.isEmpty()) {
// Pop groupDN from tovisit
Name groupDN = (Name)tovisit.keys().nextElement();
tovisit.remove(groupDN);
// Add groupDN to groups
if (groups.put(groupDN, groupDN) == null) {
// Wasn't previously processed, search what groups it is a
// member of.
try {
putDirectGroups(groupDN, tovisit, groups);
} catch (NamingException e) {
e.printStackTrace();
}
} else {
// Was processed previously, don't do anything
}
}
}
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirGroups.putDirectGroups
private void putDirectGroups(Name memberDN,
Hashtable tovisit,
Hashtable groups)
throws NamingException
{
// Find in results the groups that memberDN is a direct member of.
NamingEnumeration results = findDirectGroups(memberDN);
// Put each group in tovisit if it doesn't already exist in tovisit or
// groups.
while (results.hasMore()) {
SearchResult result = (SearchResult)results.next();
Name groupDN = toName(result.getName());
if (!groups.containsKey(groupDN) && !tovisit.contains(groupDN)) {
tovisit.put(groupDN, groupDN);
}
}
}
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirGroups.findDirectGroups
private NamingEnumeration findDirectGroups(Name memberDN)
throws NamingException
{
Object args[] = {memberDN};
String filter = java.text.MessageFormat.format(m_MemberFilter, args);
SearchControls ctls = new SearchControls();
String[] attrIDs = {};
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration results = m_Ctx.search(m_Base, filter, ctls);
return results;
}
"(&(objectclass=groupOfNames)
(member={0}))"
some vendors require base
DirContext for this DirGroups object
Lotus Software - Messaging & Collaboration
Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation
From Now To Next
Domino LDAP Server Tips
Client-side LDAP Improvements
Two and Three-Tier Architectures
Desserts
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
DirUser.m_FilterPattern =
"(&(objectclass=person)(|(uid={0})(mail={0})(cn={0})))"
More "|" terms increases search time
FT Index Domino Directory if term cannot be serviced by view
search
DirGroups.m_GroupObjectClasses = {"groupOfNames"}
Uses slightly more efficient LDAP compare instead LDAP
search
Use {"groupOfUniqueNames"} when running against Netscape
only
Use {"groupOfNames", "groupOfUniqueNames"} when running
against LDAP servers from various vendors
Domino 6 LDAP Query-Results Cache
Domino 6.02 LDAP improves DirGroups.findMembers response
for attributes with hundreds of values
Use LDAPDEBUG=1 in Notes.ini to trace LDAP server
Domino LDAP Server Tips
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Client-side LDAP Improvements
Eliminate trips to LDAP server for duplicated group queries
findMembers("cn=Iris Directory Team", ...)
findGroups("cn=ken lin,ou=westford,o=ibm", ...)
Reduce trips to LDAP server for "similar" group queries
findMembers("cn=Iris Directory Team", ...) vs.
findMembers("cn=LDAP Server Dev', ...)
findGroups("cn=ken lin,ou=westford,o=ibm") -> 104 groups vs.
findGroups("cn=scott m davidson,ou=westford,o=ibm") -> 135
groups
Eliminate trips to LDAP server for duplicated name resolution
queries
TBD - improve DirGroups.isGroup by consulting cached
"objectclass=groupOfNames" results (FT Index)
TBD - cache LDAP bind requests
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
InitialDirContextCache
Extends javax.naming.InitialDirContext
Overrides and caches DirContext's getAttributes and search
DirGroups
or other
JNDI calls
Initial-
DirContext-
Cache
Initial
DirContext
LDAP
ServerApp
Internally, query-results caches are implemented via Hashtables
Name.compareTo() is important for Hashtable entry comparison
Not a single line of DirGroups or your JNDI calls was changed to
take advantage of caching!
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
InitialDirContextCache.getAttributes
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException
{
String key = toKey(name, attrIds);
Object cached = m_AttributesCache.get(key);
Attributes attrs = null;
if (cached == null) {
try {
attrs = super.getAttributes(name, attrIds);
if (attrs != null) {
Attributes value = (Attributes)attrs.clone();
m_AttributesCache.put(key, value);
}
} catch (NamingException e) {
m_AttributesCache.put(key, e.toString());
throw e;
}
} else {
if (cached instanceof String) {
throw new NamingException(cached.toString());
} else {
attrs = (Attributes)cached;
}
}
return attrs;
}
cache implemented via Hashtable
performs the real LDAP call
makes a 2-tuple from name/attrIDs
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Two and Three-Tier Architectures
Two-Tier Architecture
LDAP
Server
JNDI or
DirGroups
App
JNDI or
DirGroups
App
JNDI or
DirGroups
App
JNDI or
DirGroups
App
Back
App
Front
App
Front
App
Front
LDAP
Server
Three-Tier Architecture
e.g., Domino DA, Sametime, J2EE, dgservlet
e.g., Mail clients
Lotus Software - Messaging & Collaboration
Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation
From Now To Next
Review
Tomorrow
Questions
Tidy Up
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Review
Algorithms and Code
Locate a Directory Server DirServer.getServers()
Resolve and Authenticate a userDirUser.authenticate()
Find a Group's Members DirGroups.findMembers()
Find a Member's Groups DirGroups.findGroups()
Cache Query Results InitialDirContextCache
Improvements
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
Tomorrow
Run nslookup, look for SRVs
Download seminar samples
Run DirServer.main()
Run DirUser.main()
Install and run dgservlet
Try "real" directories
Experiment!
Lotus Software - Messaging and Collaboration
© 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003
References
Collaborative Cuisine's 1 Hour JNDI Cookbook - LSM 2003
https://www-914.ibm.com/events/lsm/03lsm.nsf
Building Directory Friendly Applications - LSM 2002
https://www-914.ibm.com/events/lsm/02lsm.nsf/lookupwebpage/AbsPresAppDev
JNDI Tutorial - Tips for LDAP Users
http://java.sun.com/products/jndi/tutorial/ldap/index.html
Java Servlet Technology
http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Servlets.html
Eclipse - an open extensible IDE
http://eclipse.org
Directory Services Markup Language
http://www.oasis-open.org/cover/dsml.html
The String Representation of LDAP Search Filters
http://www.ietf.org/rfc/rfc2254.txt
A DNS RR for specifying the location of services (DNS SRV)
http://www.ietf.org/rfc/rfc2782.txt
http://www.ietf.org/internet-drafts/draft-ietf-ldapext-locate-08.txt
A Summary of the X.500(96) User Schema for use with LDAPv3
http://www.ietf.org/rfc/rfc2256.txt
Misc.
LDAP
JNDI
Lotus Software - Messaging & Collaboration
Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation
From Now To Next
Questions?

Más contenido relacionado

La actualidad más candente

HA Hadoop -ApacheCon talk
HA Hadoop -ApacheCon talkHA Hadoop -ApacheCon talk
HA Hadoop -ApacheCon talk
Steve Loughran
 
2012 07-jvm-summit-batches
2012 07-jvm-summit-batches2012 07-jvm-summit-batches
2012 07-jvm-summit-batches
Will Cook
 
Summer Training In Dotnet
Summer Training In DotnetSummer Training In Dotnet
Summer Training In Dotnet
DUCC Systems
 

La actualidad más candente (9)

HA Hadoop -ApacheCon talk
HA Hadoop -ApacheCon talkHA Hadoop -ApacheCon talk
HA Hadoop -ApacheCon talk
 
Name a naming mechanism for delay disruption tolerant network
Name a naming mechanism for delay disruption tolerant networkName a naming mechanism for delay disruption tolerant network
Name a naming mechanism for delay disruption tolerant network
 
Getting Started with OpenSplice DDS Community Ed.
Getting Started with OpenSplice DDS Community Ed.Getting Started with OpenSplice DDS Community Ed.
Getting Started with OpenSplice DDS Community Ed.
 
MongoDB.local Austin 2018: Tutorial - User Administration Without You - Integ...
MongoDB.local Austin 2018: Tutorial - User Administration Without You - Integ...MongoDB.local Austin 2018: Tutorial - User Administration Without You - Integ...
MongoDB.local Austin 2018: Tutorial - User Administration Without You - Integ...
 
2012 07-jvm-summit-batches
2012 07-jvm-summit-batches2012 07-jvm-summit-batches
2012 07-jvm-summit-batches
 
Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)
 
Summer Training In Dotnet
Summer Training In DotnetSummer Training In Dotnet
Summer Training In Dotnet
 
python and database
python and databasepython and database
python and database
 
Lec1
Lec1Lec1
Lec1
 

Similar a Collaborative Cuisine's 1 Hour JNDI Cookbook

Yuriy Gerasimov. Drupal Services. Integration with third party applications. ...
Yuriy Gerasimov. Drupal Services. Integration with third party applications. ...Yuriy Gerasimov. Drupal Services. Integration with third party applications. ...
Yuriy Gerasimov. Drupal Services. Integration with third party applications. ...
Vlad Savitsky
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
lennartkats
 
Building DSLs On CLR and DLR (Microsoft.NET)
Building DSLs On CLR and DLR (Microsoft.NET)Building DSLs On CLR and DLR (Microsoft.NET)
Building DSLs On CLR and DLR (Microsoft.NET)
Vitaly Baum
 
Do The Right Thing! How LDAP servers should help LDAP clients
Do The Right Thing! How LDAP servers should help LDAP clientsDo The Right Thing! How LDAP servers should help LDAP clients
Do The Right Thing! How LDAP servers should help LDAP clients
LDAPCon
 
DotNet Introduction
DotNet IntroductionDotNet Introduction
DotNet Introduction
Wei Sun
 
Edu.mit.jwi 2.2.3 manual
Edu.mit.jwi 2.2.3 manualEdu.mit.jwi 2.2.3 manual
Edu.mit.jwi 2.2.3 manual
zxcvbbb
 

Similar a Collaborative Cuisine's 1 Hour JNDI Cookbook (20)

Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
 
Docker interview Questions-3.pdf
Docker interview Questions-3.pdfDocker interview Questions-3.pdf
Docker interview Questions-3.pdf
 
Yuriy Gerasimov. Drupal Services. Integration with third party applications. ...
Yuriy Gerasimov. Drupal Services. Integration with third party applications. ...Yuriy Gerasimov. Drupal Services. Integration with third party applications. ...
Yuriy Gerasimov. Drupal Services. Integration with third party applications. ...
 
WAFFLE: Windows Authentication in Java
WAFFLE: Windows Authentication in JavaWAFFLE: Windows Authentication in Java
WAFFLE: Windows Authentication in Java
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
 
Building DSLs On CLR and DLR (Microsoft.NET)
Building DSLs On CLR and DLR (Microsoft.NET)Building DSLs On CLR and DLR (Microsoft.NET)
Building DSLs On CLR and DLR (Microsoft.NET)
 
Name services
Name servicesName services
Name services
 
Do The Right Thing! How LDAP servers should help LDAP clients
Do The Right Thing! How LDAP servers should help LDAP clientsDo The Right Thing! How LDAP servers should help LDAP clients
Do The Right Thing! How LDAP servers should help LDAP clients
 
JNDI, JMS, JPA, XML
JNDI, JMS, JPA, XMLJNDI, JMS, JPA, XML
JNDI, JMS, JPA, XML
 
Distributed Applications with Apache Zookeeper
Distributed Applications with Apache ZookeeperDistributed Applications with Apache Zookeeper
Distributed Applications with Apache Zookeeper
 
Centralizing users’ authentication at Active Directory level 
Centralizing users’ authentication at Active Directory level Centralizing users’ authentication at Active Directory level 
Centralizing users’ authentication at Active Directory level 
 
Name Services
Name Services Name Services
Name Services
 
Windows server Interview question and answers
Windows server Interview question and answersWindows server Interview question and answers
Windows server Interview question and answers
 
DotNet Introduction
DotNet IntroductionDotNet Introduction
DotNet Introduction
 
Java Naming & Directory Services
Java Naming & Directory ServicesJava Naming & Directory Services
Java Naming & Directory Services
 
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
 
ivanova-samba_backend.pdf
ivanova-samba_backend.pdfivanova-samba_backend.pdf
ivanova-samba_backend.pdf
 
Edu.mit.jwi 2.2.3 manual
Edu.mit.jwi 2.2.3 manualEdu.mit.jwi 2.2.3 manual
Edu.mit.jwi 2.2.3 manual
 
Reproducibility with R
Reproducibility with RReproducibility with R
Reproducibility with R
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Último (20)

Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

Collaborative Cuisine's 1 Hour JNDI Cookbook

  • 1. Lotus Software - Messaging & Collaboration Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation From Now To Next Ken Lin Senior Software Engineer klin@us.ibm.com Collaborative Cuisine's 1 Hour JNDI Cookbook
  • 2. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Goals Review common directory-related collaboration scenarios Examine solutions through algorithms and JNDI code Refine and improve solutions
  • 3. Lotus Software - Messaging & Collaboration Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation From Now To Next Starters Main Courses Desserts Tidy Up Today's Menu
  • 4. Lotus Software - Messaging & Collaboration Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation From Now To Next Locate a Directory Server Resolve and Authenticate a User Starters
  • 5. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Locate a Directory Server Properties File Configured by each application administrator Application-dependent solution Easy to code via java.util.Properties Manageable when few applications RFC 2782 - A DNS RR for specifying the location of services (DNS SRV) Configured centrally by DNS administrator Application-independent solution Easy to code via JNDI Manageable even when many applications Recognized by com.sun.jndi.ldap.LdapCtxFactory in JDK 1.4.1
  • 6. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DNS SRV (RFC 2782) w32 [C:] winntsystem32nslookup Default Server: ns1.iris.com Address: 9.95.aaa.bbb > set q=srv > _ldap._tcp.iris.com you type this 0=highest 65535=lowest Server: ns1.iris.com Address: 9.95.aaa.bbb _ldap._tcp.iris.com SRV service location: priority = 0 weight = 0 port = 389 svr hostname = clapton.iris.com _ldap._tcp.iris.com SRV service location: priority = 100 weight = 0 port = 389 svr hostname = little-village.iris.com clapton.iris.com internet address = 9.95.ccc.ddd little-village.iris.com internet address = 9.95.eee.fff >^Z
  • 7. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirServer.getServers returns host:port strings public static Vector getServers(String domain) throws NamingException { Vector servers = new Vector(); Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); DirContext ctx = new InitialDirContext(env); Attributes attrs = ctx.getAttributes("_ldap._tcp." + domain, new String[] {"SRV"}); Attribute srv = attrs.get("SRV"); if (srv != null) { NamingEnumeration results = srv.getAll(); if (results.hasMore()) { while (results.hasMore()) { String result = (String)results.next(); StringTokenizer tokens = new StringTokenizer(result, " "); String priority = tokens.nextToken(); String weight = tokens.nextToken(); String port = tokens.nextToken(); String target = tokens.nextToken(); servers.add(target + ":" + port); } } } return servers; } J2SE 1.4.1 or higher
  • 8. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Resolve and Authenticate Users How do we code applications to authenticate using "friendly" names? cn=ken lin,ou=westford,o=ibm is not very friendly!
  • 9. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Resolve and Authenticate Users Algorithm Does the supplied name look like an LDAP DN? Yes: ask the LDAP server if DN exists? Yes: go to Authenticated Bind No: go to Resolve DN No: go to Resolve LDAP DN Resolve supplied name to LDAP DN Unauthenticated search the name to obtain its DN (&(objectclass=person)(|(uid={0})(mail={0})(cn={0}))) Allow the filter to be customized to fit customer (&(objectclass=person)(telephonenumber={0})) If number of search hits is ... 0: name not found 1: go to Authenticated Bind otherwise: ambiguous DN Authenticated Bind Use LDAP DN and supplied password
  • 10. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirUser.authenticate to Authenticate and Resolve a Name boolean authenticate(String hostport, String anyname, String password) throws NamingException { boolean authenticated = false; DirContext ctx = null; try { String dn = resolve(anyname); if (dn != null) { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, m_ServiceProvider); env.put(Context.PROVIDER_URL, "ldap://" + hostport); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, dn); env.put(Context.SECURITY_CREDENTIALS, password); ctx = new InitialDirContext(env); authenticated = true; } } catch (AuthenticationException e) { authenticated = false; } finally { try { if (ctx != null) ctx.close(); } catch (Exception e) { } } return authenticated; } "com.sun.jndi.ldap.LdapCtxFactory" local DirContext for dn/password
  • 11. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirUser.resolve to Get a DN from anyname String resolve(String anyname) throws NamingException { // If anyname looks like it might be a DN, try a base search if (anyname.indexOf("=") != -1) { try { Attributes attrs = m_Ctx.getAttributes(anyname); return anyname; } catch (NameNotFoundException e) { // not a valid or known DN, try filtered search } } // anyname must not look like a DN, search for m_FilterPattern with anyname Object args[] = {anyname}; String filter = java.text.MessageFormat.format(m_FilterPattern, args); SearchControls ctls = new SearchControls(); ctls.setReturningAttributes(null); ctls.setCountLimit(1); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration results = m_Ctx.search(m_Base, filter, ctls); if (results.hasMore()) { SearchResult result = (SearchResult)results.next(); return result.getName(); } else { throw new NameNotFoundException("Neither DN nor filter hits"); } } "(&(objectclass=person) (|(uid={0})(mail={0})(cn={0})))" DirContext for this application some vendors require base so more than 1 result causes SizeLimitExceededException
  • 12. Lotus Software - Messaging & Collaboration Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation From Now To Next Find a Member's Group Find a Group's Members Main Courses
  • 13. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Directory Groups IETF, Defacto, and Vendor Group Definitions Definitions for Static Groups in IETF RFC 2782 groupOfNames / member groupOfUniqueNames / uniqueMember Group operations are coded by the application, not the LDAP server! Applications must understand schema Applications must code findMembers Applications must code findGroups
  • 14. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 dgservlet Demo
  • 15. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Two Common Uses for findMembers and findGroups findMembers can be used to expand and flatten out a buddy list findGroups can be used to create Notes-like NamesLists for authorization
  • 16. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirGroups Class public class DirGroups { protected DirContext m_Ctx = null; protected NameParser m_Parser = null; protected String m_GroupObjectClasses[] = {"groupOfNames"}; protected String m_MemberNames[] = {"member"}; protected String m_Base = ""; protected String m_MemberFilter = "(&(objectclass=groupOfNames)(member={0}))"; protected int m_FindMembersDepth = 10; protected String m_MemberAttrIds[] = {"objectclass", "member", "cn"}; public DirGroups(DirContext ctx) { m_Ctx = ctx; } public void findGroups(String memberDN, Hashtable groups) throws NamingException { described later... } public void findMembers(Name groupDN, Hashtable groups, Hashtable users, Hashtable unknown) throws NamingException { described later... } etc... }
  • 17. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 findMembers Algorithm get entry g from groupDN and verify it is a group foreach memberDN in g { if memberDN isn't in groups, users, or unknown { get entry m from memberDN if m is a group --> add m to groups and recurse... findMembers(memberDN, groups, users, unknown) if m is a non-group --> add m to users if m's objectclass is unknown --> add m to unknown } } findMembers(in String groupDN, inout Hashtable groups, inout Hashtable users, inout Hashtable unknown) Optimize!
  • 18. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirGroups.findMembers public void findMembers(Name groupDN, Hashtable groups, Hashtable users, Hashtable unknown) throws NamingException { // Verify arguments if (groupDN == null || groups == null || users == null || unknown == null) { return; } // Verify the groupDN is really a group Attributes attrs = m_Ctx.getAttributes(groupDN, m_MemberAttrIds); if (!isGroup(attrs)) { throw new NamingException("'objectclass' is not a group"); } findMembers(attrs, m_FindMembersDepth, groups, users, unknown); } DirContext for this DirGroups object 10 {"objectclass", "member", "cn"}
  • 19. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirGroups.findMembers private void findMembers(Attributes attrs, int depth, Hashtable groups, Hashtable users,Hashtable unknown) throws NamingException { if (depth <= 0) { return; } for (int i = 0; i < m_MemberNames.length; i++) { Attribute attr = attrs.get(m_MemberNames[i]); if (attr != null) { NamingEnumeration members = attr.getAll(); while (members.hasMore()) { Name memberDN = toName((String)members.nextElement()); // Process memberDN only if it hasn't yet been encounterred if (!users.containsKey(memberDN) && !groups.containsKey(memberDN) && !unknown.containsKey(memberDN)) { try { if (isGroup(memberDN)) { // memberDN is a group attrs = m_Ctx.getAttributes(memberDN, m_MemberAttrIds); if (groups.put(memberDN, attrs) == null) { findMembers(attrs, depth-1, groups, users, unknown); } } else { // memberDN is a non-group users.put(memberDN, memberDN/*null*/); } } catch (NamingException e) { // memberDN is unknown unknown.put(memberDN, memberDN/*null*/); } } } // while } } // for } {"objectclass", "member", "cn"} {"member"}
  • 20. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirGroups.isGroup private boolean isGroup(Name name) throws NamingException { if (m_GroupObjectClasses.length == 1) { return compare(name, "objectclass", m_GroupObjectClasses[0]); } else { Attributes attrs = m_Ctx.getAttributes(name, m_MemberAttrIds); return isGroup(attrs); } } private boolean isGroup(Attributes attrs) throws NamingException { Attribute attr = attrs.get("objectclass"); if (attr != null) { for (int i = 0; i < m_GroupObjectClasses.length; i++) { if (attr.contains(m_GroupObjectClasses[i])) { return true; } } return false; } else { throw new NamingException("'objectclass' attribute not found"); } } LDAP compare is faster than search {"groupOfNames"}
  • 21. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirGroups.compare private boolean compare(Name name, String attr, String value) throws NamingException { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.OBJECT_SCOPE); ctls.setReturningAttributes(new String[0]); // no attributes // LDAP compare operation NamingEnumeration results = m_Ctx.search(name, "(" + attr + "=" + value + ")", ctls); return results.hasMore(); // if successful, results will contain a single item }
  • 22. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 findGroups Algorithm findGroups(in String memberDN, inout Hashtable groups) g = DNs of groups that memberDN is a direct member tovisit = g while tovisit is not empty { pop any groupDN from tovisit if groupDN is not in groups { groups += groupDN g = DNs of groups that groupDN is a direct member of tovisit += elements of g not in tovisit or groups } } 1. cn=bugs bunny,o=toons empty 2. cn=looney toons 3. cn=looney toons 4. cn=looney toons empty 5. cn=looney toons 6. cn=all toons 7. cn=all toons 8. cn=all toons 9. cn=all toons empty 10. cn=looney toons cn=all toons 11. empty 12. empty
  • 23. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirGroups.findGroups public void findGroups(Name memberDN, Hashtable groups) throws NamingException { Hashtable tovisit = new Hashtable(); // DNs of groups to visit // Initialize tovisit to groups that memberDN is a direct member of. putDirectGroups(memberDN, tovisit, groups); // groups = union(groups, tovisit) while (!tovisit.isEmpty()) { // Pop groupDN from tovisit Name groupDN = (Name)tovisit.keys().nextElement(); tovisit.remove(groupDN); // Add groupDN to groups if (groups.put(groupDN, groupDN) == null) { // Wasn't previously processed, search what groups it is a // member of. try { putDirectGroups(groupDN, tovisit, groups); } catch (NamingException e) { e.printStackTrace(); } } else { // Was processed previously, don't do anything } } }
  • 24. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirGroups.putDirectGroups private void putDirectGroups(Name memberDN, Hashtable tovisit, Hashtable groups) throws NamingException { // Find in results the groups that memberDN is a direct member of. NamingEnumeration results = findDirectGroups(memberDN); // Put each group in tovisit if it doesn't already exist in tovisit or // groups. while (results.hasMore()) { SearchResult result = (SearchResult)results.next(); Name groupDN = toName(result.getName()); if (!groups.containsKey(groupDN) && !tovisit.contains(groupDN)) { tovisit.put(groupDN, groupDN); } } }
  • 25. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirGroups.findDirectGroups private NamingEnumeration findDirectGroups(Name memberDN) throws NamingException { Object args[] = {memberDN}; String filter = java.text.MessageFormat.format(m_MemberFilter, args); SearchControls ctls = new SearchControls(); String[] attrIDs = {}; ctls.setReturningAttributes(attrIDs); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration results = m_Ctx.search(m_Base, filter, ctls); return results; } "(&(objectclass=groupOfNames) (member={0}))" some vendors require base DirContext for this DirGroups object
  • 26. Lotus Software - Messaging & Collaboration Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation From Now To Next Domino LDAP Server Tips Client-side LDAP Improvements Two and Three-Tier Architectures Desserts
  • 27. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 DirUser.m_FilterPattern = "(&(objectclass=person)(|(uid={0})(mail={0})(cn={0})))" More "|" terms increases search time FT Index Domino Directory if term cannot be serviced by view search DirGroups.m_GroupObjectClasses = {"groupOfNames"} Uses slightly more efficient LDAP compare instead LDAP search Use {"groupOfUniqueNames"} when running against Netscape only Use {"groupOfNames", "groupOfUniqueNames"} when running against LDAP servers from various vendors Domino 6 LDAP Query-Results Cache Domino 6.02 LDAP improves DirGroups.findMembers response for attributes with hundreds of values Use LDAPDEBUG=1 in Notes.ini to trace LDAP server Domino LDAP Server Tips
  • 28. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Client-side LDAP Improvements Eliminate trips to LDAP server for duplicated group queries findMembers("cn=Iris Directory Team", ...) findGroups("cn=ken lin,ou=westford,o=ibm", ...) Reduce trips to LDAP server for "similar" group queries findMembers("cn=Iris Directory Team", ...) vs. findMembers("cn=LDAP Server Dev', ...) findGroups("cn=ken lin,ou=westford,o=ibm") -> 104 groups vs. findGroups("cn=scott m davidson,ou=westford,o=ibm") -> 135 groups Eliminate trips to LDAP server for duplicated name resolution queries TBD - improve DirGroups.isGroup by consulting cached "objectclass=groupOfNames" results (FT Index) TBD - cache LDAP bind requests
  • 29. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 InitialDirContextCache Extends javax.naming.InitialDirContext Overrides and caches DirContext's getAttributes and search DirGroups or other JNDI calls Initial- DirContext- Cache Initial DirContext LDAP ServerApp Internally, query-results caches are implemented via Hashtables Name.compareTo() is important for Hashtable entry comparison Not a single line of DirGroups or your JNDI calls was changed to take advantage of caching!
  • 30. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 InitialDirContextCache.getAttributes public Attributes getAttributes(Name name, String[] attrIds) throws NamingException { String key = toKey(name, attrIds); Object cached = m_AttributesCache.get(key); Attributes attrs = null; if (cached == null) { try { attrs = super.getAttributes(name, attrIds); if (attrs != null) { Attributes value = (Attributes)attrs.clone(); m_AttributesCache.put(key, value); } } catch (NamingException e) { m_AttributesCache.put(key, e.toString()); throw e; } } else { if (cached instanceof String) { throw new NamingException(cached.toString()); } else { attrs = (Attributes)cached; } } return attrs; } cache implemented via Hashtable performs the real LDAP call makes a 2-tuple from name/attrIDs
  • 31. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Two and Three-Tier Architectures Two-Tier Architecture LDAP Server JNDI or DirGroups App JNDI or DirGroups App JNDI or DirGroups App JNDI or DirGroups App Back App Front App Front App Front LDAP Server Three-Tier Architecture e.g., Domino DA, Sametime, J2EE, dgservlet e.g., Mail clients
  • 32. Lotus Software - Messaging & Collaboration Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation From Now To Next Review Tomorrow Questions Tidy Up
  • 33. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Review Algorithms and Code Locate a Directory Server DirServer.getServers() Resolve and Authenticate a userDirUser.authenticate() Find a Group's Members DirGroups.findMembers() Find a Member's Groups DirGroups.findGroups() Cache Query Results InitialDirContextCache Improvements
  • 34. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 Tomorrow Run nslookup, look for SRVs Download seminar samples Run DirServer.main() Run DirUser.main() Install and run dgservlet Try "real" directories Experiment!
  • 35. Lotus Software - Messaging and Collaboration © 2002 IBM CorporationCollaborative Cuisine's 1 Hour JNDI Cookbook | LSM Seminar 2003 References Collaborative Cuisine's 1 Hour JNDI Cookbook - LSM 2003 https://www-914.ibm.com/events/lsm/03lsm.nsf Building Directory Friendly Applications - LSM 2002 https://www-914.ibm.com/events/lsm/02lsm.nsf/lookupwebpage/AbsPresAppDev JNDI Tutorial - Tips for LDAP Users http://java.sun.com/products/jndi/tutorial/ldap/index.html Java Servlet Technology http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Servlets.html Eclipse - an open extensible IDE http://eclipse.org Directory Services Markup Language http://www.oasis-open.org/cover/dsml.html The String Representation of LDAP Search Filters http://www.ietf.org/rfc/rfc2254.txt A DNS RR for specifying the location of services (DNS SRV) http://www.ietf.org/rfc/rfc2782.txt http://www.ietf.org/internet-drafts/draft-ietf-ldapext-locate-08.txt A Summary of the X.500(96) User Schema for use with LDAPv3 http://www.ietf.org/rfc/rfc2256.txt Misc. LDAP JNDI
  • 36. Lotus Software - Messaging & Collaboration Confidential | June 2, 2003 | LSM Seminar 2003 © 2002 IBM Corporation From Now To Next Questions?