|
○ はじめに
今回は、LDAP サーバに接続してディレクトリエントリを登録する、あるいはディレクトリエントリを削除する方法について説明します。登録されたエントリの確認、あるいは削除されたことの確認に使用する検索処理については次回説明します。ここでは LDAP サーバ側、あるいは LDAP サーバに付いているツールなどで確認してもらえればと思います。
○ サンプルプログラム
LDAP サーバに接続し、指定された DN を使ってディレクトリエントリを登録、あるいは削除するサンプルプログラム LDAPAddDel.java です。登録するディレクトリエントリの属性内容は固定です。
コンパイルが終了したら
java LDAPAddDel [LDAPサーバ名/IPアドレス] \ [bindユーザのDN] \ [bindユーザのパスワード] \ [add(追加) / del(削除)] \ [エントリの DN]
で実行です。正常に処理が終了した場合はその旨が表示されます。何らかの例外が発生したら、その内容が表示されます。
なお、はじめに のページから全てのサンプルプログラムを固めた tar ボールをダウンロードすることもできます。
--- LDAPAddDel.java ---
1 import org.ietf.ldap.LDAPAttribute; 2 import org.ietf.ldap.LDAPAttributeSet; 3 import org.ietf.ldap.LDAPConnection; 4 import org.ietf.ldap.LDAPEntry; 5 import org.ietf.ldap.LDAPException; 6 7 8 /** 9 * LDAP サーバに接続し、指定された DN でエントリを登録する。 10 * あるいは指定 DN のエントリを削除する。エントリ登録時の属性値に 11 * ついては、本クラス内部で固定の内容。 12 * 13 * @version 19 May 2002 14 * @author Ryo Ichinose 15 */ 16 public class LDAPAddDel 17 { 18 /** 19 * LDAP Protocol Version 3 20 */ 21 public static final int LDAP_V3 = 3; // LDAPv3 22 23 24 /** 25 * LDAP サーバに接続し、指定された DN でエントリを登録する。 26 * エントリ登録時の属性値については固定の内容。 27 * 28 * @param host ホスト名もしくは IPアドレス 29 * @param binddn bind ユーザの DN 30 * @param bindpw bind ユーザのパスワード 31 * @param dn 登録エントリの DN 32 */ 33 public void add( String host, String binddn, String bindpw, String dn ) 34 { 35 // 登録するエントリの各属性値を設定する。 36 LDAPAttributeSet attrset = new LDAPAttributeSet(); 37 38 39 // posixAccount の必須属性 40 String objcls[] = { "posixAccount" }; 41 String cn[] = { "name1" }; 42 String uid[] = { "123456" }; 43 String uidnum[] = { "501" }; 44 String gidnum[] = { "502" }; 45 String home[] = { "/home/123456" }; 46 47 attrset.add( new LDAPAttribute( "objectclass", objcls ) ); 48 attrset.add( new LDAPAttribute( "cn", cn ) ); 49 attrset.add( new LDAPAttribute( "uid", uid ) ); 50 attrset.add( new LDAPAttribute( "uidNumber", uidnum ) ); 51 attrset.add( new LDAPAttribute( "gidNumber", gidnum ) ); 52 attrset.add( new LDAPAttribute( "homeDirectory", home ) ); 53 54 55 // DN と属性値で登録するエントリを LDAPEntry のインスタンス 56 // として作成。 57 LDAPEntry entry = new LDAPEntry( dn, attrset ); 58 LDAPConnection lc = new LDAPConnection(); 59 60 try { 61 // LDAP サーバに接続する。ポートはデフォルト(389番)を使う。 62 lc.connect( host, LDAPConnection.DEFAULT_PORT ); 63 System.out.println( "Connected to " + host ); 64 System.out.println(); 65 66 67 // 指定された DN およびパスワードでバインド(認証)する。 68 // これを実行しない場合、anonymous 状態で操作することになる。 69 lc.bind( LDAPAddDel.LDAP_V3, binddn, bindpw ); 70 71 72 // 指定エントリの登録を実行する。 73 lc.add( entry ); 74 System.out.println( "Successfully added" ); 75 76 // 接続を切断する。 77 lc.disconnect(); 78 System.out.println(); 79 System.out.println( "Disconnected" ); 80 } 81 catch( LDAPException e ) { 82 System.out.println( "LDAPException occured : " + 83 e.toString() ); 84 } 85 } 86 87 88 /** 89 * LDAP サーバに接続し、指定された DN のエントリを削除する。 90 * 91 * @param host ホスト名もしくは IPアドレス 92 * @param binddn bind ユーザの DN 93 * @param bindpw bind ユーザのパスワード 94 * @param dn 削除エントリの DN 95 */ 96 public void del( String host, String binddn, String bindpw, String dn ) 97 { 98 LDAPConnection lc = new LDAPConnection(); 99 100 try { 101 // LDAP サーバに接続する。ポートはデフォルト(389番)を使う。 102 lc.connect( host, LDAPConnection.DEFAULT_PORT ); 103 System.out.println( "Connected to " + host ); 104 System.out.println(); 105 106 107 // 指定された DN およびパスワードでバインド(認証)する。 108 // これを実行しない場合、anonymous 状態で操作することになる。 109 lc.bind( LDAPAddDel.LDAP_V3, binddn, bindpw ); 110 111 // 指定エントリの登録を実行する。 112 lc.delete( dn ); 113 System.out.println( "Successfully deleted" ); 114 115 // 接続を切断する。 116 lc.disconnect(); 117 118 System.out.println(); 119 System.out.println( "Disconnected" ); 120 } 121 catch( LDAPException e ) { 122 System.out.println( "LDAPException occured : " + 123 e.toString() ); 124 } 125 } 126 127 128 /** 129 * エントリポイント 130 * 131 * @param args 132 * <ul> 133 * <li>args[0] --- ホスト名もしくは IP アドレス 134 * <li>args[1] --- bind ユーザの DN 135 * <li>args[2] --- bind ユーザのパスワード 136 * <li>args[3] --- 登録( add )/削除( del ) 137 * <li>args[4] --- 登録/削除エントリの DN 138 * </ul> 139 */ 140 public static void main( String[] args ) 141 { 142 LDAPAddDel obj = new LDAPAddDel(); 143 144 if ( args[3].equals( "add" ) ) { 145 obj.add( args[0], args[1], args[2], args[4] ); 146 } 147 else if ( args[3].equals( "del" ) ) { 148 obj.del( args[0], args[1], args[2], args[4] ); 149 } 150 } 151 }
○ サンプルプログラムの説明
では、サンプルプログラムについて説明していきます。
- 1 〜 5 行目
使用するクラスライブラリのパッケージ指定を行っています。LDAPAddDel.java では、前回の LDAPConnect.java で使用したクラスの他に、LDAPAttribute、LDAPAttributeSet、LDAPEntry の 3 つのクラスを新たに使用します。
- 24 〜 85 行目 ( LDAPAddDel#add() )
LDAPAddDel#add() メソッドで、ディレクトリエントリの登録処理を行います。各ヶ所について 以降で説明します。
- 35 〜 36 行目
登録するディレクトリエントリに設定する属性および属性値の組を格納するために、 LDAPAttributeSet クラスのインスタンスを作成しています。LDAPAttributeSet クラスには、 複数の LDAPAttribute クラスのインスタンスを格納することが出来ます。LDAPAttribute クラスのインスタンスが各々の属性名および属性値の情報を保持します。
- 39 〜 52 行目
登録するディレクトリエントリに設定する属性および属性値の組を LDAPAttributeSet クラス のインスタンスに格納するまでの処理を行っています。ここでは posixAccount というオブジェクトクラスでディレクトリエントリを登録します。
posixAccount というオプジェクトクラスは RFC 2307 で定義されています。 これによると、cn、uid、uidNumber、gidNumber、homeDirectory という属性は必須であると されています。よってこれらの属性に対する値を 40 〜 45 行目でそれぞれ String の配列 として作成しています( objectclass という属性は全てのエントリで必須 )。
何故配列かというと、属性名と値の情報を実際に保持する LDAPAttribute クラスの コンストラクタがそれを要求しているからです。 これは、各々の属性が複数の属性値を持つことができるためです。よって、属性値が 1 つの場合でも配列として扱う必要があります。
47 〜 52 行目で、属性名と属性値を引数として LDAPAttribute クラスのインスタンスを 作成した上で、それを LDAPAttributeSet クラスのインスタンス が保持する要素に 追加しています。
- 55 〜 57 行目
必要な属性名と属性値の情報を格納した LDAPAttributeSet クラスのインスタンスと登録 するエントリの DN を指定して、 LDAPEntry クラスのインスタンスを作成しています。JLDAP (以外の Directory SDK でも多分同様)でディレクトリエントリを登録する場合は、この LDAPEntry クラスのインスタンスが登録する単位となります。
- 72 〜 74 行目
LDAPEntry クラスのインスタンスを使って、LDAP サーバにディレクトリエントリを登録 しています。エントリを登録するには、LDAPConnection#add() メソッドを使用します。
public void LDAPConnection#add( LDAPEntry entry ) throws LDAPException entry : 登録するエントリ情報
何らかの理由で登録に失敗した場合、LDAPException が throw されます。LDAPException の 内容については後述します。
add() メソッドは上の形式以外の形でいくつかオーバーロードされています。それぞれの 詳細については JLDAP の API ドキュメントを参照して下さい。
- 81 〜 84 行目
ここまでの処理で発生した LDAPException を catch して、内容を表示しています。ここまで の新たな処理によって発生する可能性のある例外内容について、自分が確認できた範囲 で以下にまとめておきます。これで全てという意味ではありません。
番号 エラーコードの定数名(LDAPException.XXX の形で参照可) 内容 17 UNDEFINED_ATTRIBUTE_TYPE 指定された属性が LDAP サーバ側のスキーマに存在しない。つまり、LDAPAttributeSet クラスのインスタンスに設定した属性名が正しくないことを表している。使用したオブ ジェクトクラス(ここでは posixAccount )が、対象の LDAP サーバで定義されていない 可能性もある。 32 NO_SUCH_OBJECT add() に指定した DN で識別されるオブジェクトを参照することができない。登録する DN が存在しないのはある意味当然で、ここで発生するのは DN を登録するためのディ レクトリが存在しないことを意味している。仮に "uid=foo,ou=people,dc=sample,dc=jp" という DN でエントリを登録しようとしていたなら、"ou=people,dc=sample,dc=jp" という DN で識別されるディレクトリが存在しないことを表している。 34 INVALID_DN_SYNTAX 指定した DN の構文が正しくない。 65 OBJECT_CLASS_VIOLATION オブジェクトクラスに適用される規則に反した処理を行おうとしている。必須属性の値 を指定せずにエントリを追加した、定義されていない属性と値を設定してエントリを追 加/修正した、必須属性を削除しようとした、などの場合に発生する。
- 88 〜 125 行目 ( LDAPAddDel#del() )
LDAPAddDel#del() メソッドで指定エントリの削除を行います。新しい部分は 113 行目の lc.delete( dn ); という所のみです。エントリの削除には、LDAPConnection#delete() を使います。
public void LDAPConnection#delete( String dn ) throws LDAPException dn : 削除するエントリを示す DN
何らかの理由で削除に失敗した場合、LDAPException が throw されます。自分で確認した範囲 では、以下の例外内容が発生します。なお、これが全てという意味ではありません。
番号 エラーコードの定数名(LDAPException.XXX の形で参照可) 内容 32 NO_SUCH_OBJECT delete() に指定した DN で識別されるオブジェクトを参照することができない。 つまり、指定したエントリが存在しないということである。 34 INVALID_DN_SYNTAX delete() に指定した DN の構文が正しくない。
以上で LDAPAddDel.java についての説明は終わりです。次は最も使用されると思われるディレクトリエントリの検索処理について説明していきます。