/******************************************************************************* * Copyright (C) 1999, 2000, 2001, 2002 Novell, Inc. All Rights Reserved. * * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND * TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE * AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS * THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO * DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE * CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS * TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF * DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR * DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE. * * $name: ExtensibleMatch.java * * $description: The ExtensibleMatch.java sample constructs the extensible * match filter with the given inputs, searches the directory * and prints the results. Extensible match requires * eDirectory version 8.7 or higher. * * The LDAP v3 Core protocol specification requires LDAP servers to recognize a * search element called an extensible match. Extensible match provides * additional features which can be expressed in the search filter. * * Feature 1. Allow matching to components of the object's Distinguished Name * as well as attributes of the object. * * Feature 2. Allow a specific matching rule to be used for an attribute-value * comparison, such as a sounds-alike match. * * Feature 3. Allow a match to any attribute of an object supporting a * particular matching rule. For example, one could search for * objects with any string attribute containing "Dino". * * These features may be used independently or in combination. * * All the supported matching rules are advertised through LDAP subschema * subentry object using the standard matchingRules and matchingRuleUse * schema attributes. * * It is mandatory that either dnAttribute or matching rule be present * as part of extensible match filter. * * NOTE: In eDirectory 8.7, only the DN feature of extensible match * is supported (feature 1). * * The following examples illustrate the use of extensible match filters * and correspond to the features listed above. * * Example #1: (ou:dn:=Sales) * Same as filter "(ou=Sales)" except that DN components should be * considered part of the entry when doing the match. Any object * with "ou=Sales" as part of its DN will match. * * Example #2: (cn:2.4.6.8:=Barney Rubble) * Specifies matching rule "2.4.6.8" to be used when making comparisons * for (cn="Barney Rubble"). * * Example #2a: (cn:dn:2.4.6.8:=Barney Rubble) * Combines examples #1 and #2. Specifies the matching rule to use and * indicates that components of entry's DN should be considered attributes of * the entry when evaluating the match. * * Example #3: (:2.4.6.8:=Dino) * Indicates this filter should be applied to all attributes supporting * this matching rule. * * Example #3a: (:dn:2.4.6.8:=Dino) * Same as example #3, but also includes components of the DN in the match. * * For further details, refer to IETF RFC 2251 and RFC 2254. * ******************************************************************************/ import com.novell.ldap.*; import java.io.UnsupportedEncodingException; public class ExtensibleMatch { public static void main( String[] args ) { boolean useDN = false, useAttribute = false, useRule = false; int argc=0, counter=0; argc = args.length; // Determine which options are set. "-d" option to come before the parameters if ( argc == 9 ) { // -d option inserts ":dn" in the filter if (args[0].equals("-d")) { useDN = true; counter++; argc--; } } else // -d option is not set if ( argc != 8 ) { usage(); System.exit(1); } int searchScope = LDAPConnection.SCOPE_SUB; int ldapVersion = LDAPConnection.LDAP_V3; String[] attrs = {LDAPConnection.NO_ATTRS}; String ldapHost = args[counter++]; int ldapPort = Integer.parseInt(args[counter++]); String loginDN = args[counter++]; String password = args[counter++]; String searchBase = args[counter++]; String matchAttribute = args[counter++]; String matchingRule = args[counter++]; String matchValue = args[counter]; if (!matchAttribute.equals("")) useAttribute = true; if (!matchingRule.equals("")) useRule = true; /* Must have dn option or matching rule. */ if ((useDN == false) && (useRule == false)) { System.out.println("Error: Either <attribute name> or" + " <matching rule> must be present as part of an" + " extensible matching fileter."); usage(); System.exit(1); } // Construct extensible matching filter. Example:"(attr:dn:rule:=value)" String extMatchFilter = "("; if (useAttribute) extMatchFilter += matchAttribute; if (useDN) extMatchFilter += ":dn"; if (useRule) { extMatchFilter += ":"; extMatchFilter += matchingRule; } extMatchFilter += ":="; extMatchFilter += matchValue; extMatchFilter += ")"; System.out.println("Extensible match filter: " + extMatchFilter); // Setting search time out to 10 seconds LDAPSearchConstraints cons = new LDAPSearchConstraints(); cons.setTimeLimit( 10000 ); LDAPConnection lc = new LDAPConnection(); try { // connect to the server lc.connect( ldapHost, ldapPort ); // bind to the server lc.bind( ldapVersion, loginDN, password.getBytes("UTF8") ); LDAPSearchResults searchResults = lc.search( searchBase, searchScope, extMatchFilter, attrs, false, cons ); // time out value // To print matched entry names int cnt = 0; while ( searchResults.hasMore()) { LDAPEntry nextEntry = null; try { nextEntry = searchResults.next(); cnt += 1; } catch(LDAPException e) { System.out.println("Error: " + e.toString()); System.exit(1); } System.out.println("\n" + nextEntry.getDN()); } if( cnt == 0) { System.out.println("No entries returned from search."); } } catch( LDAPException e ) { System.out.println( "Error: " + e.toString() ); System.exit(1); } catch( UnsupportedEncodingException e ) { System.out.println( "Error: " + e.toString() ); } System.out.println("\nExtensible match search completed successfully."); return; } public static void usage() { System.err.println("Usage:\njava ExtensibleMatch [-d] <host name>" + " <port number> <login dn> <password>\n" + "\t <search base> <attribute name> <matching rule>" + " <match value>\n" + "where: \n" + " -d means consider DN components as attributes of" + " the object \n" + " <search base> is the starting container for a" + " subtree search \n" + " <attribute name> is the attribute to match" + " against, or \"\" for all attrs \n" + " <matching rule> is an OID specifying the" + " matching rule to use, or \"\"\n" + " <match value> is the value to compare against in" + " the search filter\n"); System.err.println("Examples:\n" + "#1. java ExtensibleMatch -d Acme.com 389" + " cn=admin,o=Acme secret o=Acme\n\t\tou \"\" Sales \n" + "#2. java ExtensibleMatch Acme.com 389" + " cn=admin,o=Acme secret \n\t\tou=Sales,o=Acme" + " cn 2.4.6.8 \"Barney Rubble\" \n" + "#3. java ExtensibleMatch Acme.com 389 " + "cn=admin,o=Acme secret o=Acme\n\t\t\"\" 2.4.6.8 Dino \n\n" + "NOTE: Only example 1 is supported by eDirectory" + " 8.7"); return; } }