LECTURE 5 ディレクトリエントリの属性変更

○ はじめに

ディレクトリエントリの登録/削除、エントリの検索と来たところで、今度はエントリの属性に対する操作を行う方法について説明していきたいと思います。可能な操作には、追加、修正、削除の 3 種類があります。

○ サンプルプログラム

LDAP サーバに接続し、指定されたエントリの属性に対して指定された操作 ( 追加 / 修正 / 削除 ) を行うサンプルプログラム LDAPModify.java です。

コンパイルが終了したら

java LDAPModify [LDAPサーバ名/IPアドレス] \
                [bindユーザのDN] \
                [bindユーザのパスワード] \
                [add(追加) / mod(修正) / del(削除)] \
                [属性を操作するエントリのDN] \
                [操作する属性名] \
                [新たに設定する属性値]

で実行です。正常に処理が終了した場合はその旨が表示されます。何らかの例外が発生したら、その内容が表示されます。

なお、はじめに のページから全てのサンプルプログラムを固めた tar ボールをダウンロードすることもできます。

--- LDAPModify.java ---

    1	import org.ietf.ldap.LDAPAttribute;
    2	import org.ietf.ldap.LDAPConnection;
    3	import org.ietf.ldap.LDAPException;
    4	import org.ietf.ldap.LDAPModification;
    5	import org.ietf.ldap.LDAPModificationSet;
    6	
    7	
    8	/**
    9	 * LDAP サーバに接続し、指定されたエントリの属性値に対して操作を行う。
   10	 *
   11	 * @version 19 May 2002
   12	 * @author  Ryo Ichinose
   13	 */
   14	public class LDAPModify
   15	{
   16		/**
   17		 * LDAP Protocol Version 3
   18		 */
   19		public static final int LDAP_V3 = 3; // LDAPv3
   20	
   21	
   22		/**
   23		 * 指定された LDAP サーバに接続し、指定された DN で識別されるエントリ
   24		 * の属性に対して変更処理を行う。変更処理には、追加 / 修正 / 削除の 
   25		 * 3 種類の処理が含まれる。
   26		 *
   27		 * @param host    ホスト名もしくは IPアドレス
   28		 * @param binddn  bind ユーザの DN
   29		 * @param bindpw  bind ユーザのパスワード
   30		 * @param cmd     追加( add )/修正( mod )/削除( del )
   31		 * @param moddn   属性を操作するエントリの DN
   32		 * @param name    操作する属性名
   33		 * @param value   新たに設定する属性値
   34		 */
   35		public void modify( String host, String binddn, String bindpw,
   36				    String cmd,  String moddn,  
   37				    String name, String value )
   38		{
   39			LDAPModificationSet ms = new LDAPModificationSet();
   40			LDAPAttribute attr = new LDAPAttribute( name, value );
   41	
   42			// cmd に応じて LDAPModificationSet に設定する操作種別を
   43			// 変更する。
   44			if ( cmd.equals( "add" ) ) {
   45				ms.add( LDAPModification.ADD, attr );
   46			}
   47			else if ( cmd.equals( "mod" ) ) {
   48				ms.add( LDAPModification.REPLACE, attr );
   49			}
   50			else if ( cmd.equals( "del" ) ) {
   51				ms.add( LDAPModification.DELETE, attr );
   52			}
   53	
   54			LDAPConnection lc = new LDAPConnection();
   55			
   56			try {
   57				// LDAP サーバに接続する。ポートはデフォルト(389番)を使う。
   58				lc.connect( host, LDAPConnection.DEFAULT_PORT );
   59				System.out.println( "Connected to " + host );
   60				System.out.println();
   61	
   62	
   63				// 指定された DN およびパスワードでバインド(認証)する。
   64				// これを実行しない場合、anonymous 状態で操作することになる。
   65				lc.bind( LDAPModify.LDAP_V3, binddn, bindpw );
   66	
   67	
   68				// 指定エントリの属性操作を実行する。
   69				lc.modify( moddn, ms );
   70				System.out.println( "Successfully modified" );
   71	
   72				// 接続を切断する。
   73				lc.disconnect();
   74				System.out.println();		
   75				System.out.println( "Disconnected" );
   76			}
   77			catch( LDAPException e ) {
   78				System.out.println( "LDAPException occured : " + 
   79						    e.toString() );
   80			}
   81		}
   82	
   83	
   84		/**
   85		 * エントリポイント
   86		 *
   87		 * @param args 
   88		 *    <ul>
   89		 *      <li>args[0] --- ホスト名もしくは IP アドレス
   90		 *      <li>args[1] --- bind ユーザの DN
   91		 *      <li>args[2] --- bind ユーザのパスワード
   92		 *      <li>args[3] --- 追加( add )/修正( mod )/削除( del )
   93		 *      <li>args[4] --- 属性を操作するエントリの DN
   94		 *      <li>args[5] --- 操作する属性名
   95		 *      <li>args[6] --- 新たに設定する属性値
   96		 *    </ul>
   97		 */
   98		public static void main( String[] args )
   99		{
  100			LDAPModify obj = new LDAPModify();
  101			obj.modify( args[0], args[1], args[2], args[3], 
  102				    args[4], args[5], args[6] );
  103		}
  104	}


○ サンプルプログラムの説明

では、サンプルプログラムについて説明していきます。

  • 1 〜 5 行目

    使用するクラスライブラリのパッケージ指定を行っています。LDAPModify.java では、新たに LDAPModification、LDAPModificationSet の 2 つのクラスを使用します。

  • 22 〜 81 行目 ( LDAPModify#modify() )

    LDAPModify#modify() メソッドで、指定されたエントリの属性に対して操作を行います。各ヶ所 について以降で説明します。

    • 39 行目

      LDAPModificationSet クラスのインスタンスを作成しています。何のためにかと言うと、操作する 属性の名称と値は LDAPAttribute クラスのインスタンスに設定しますが、LDAP サーバに対して要 求を出すには LDAPAttribute を更に LDAPModification もしくは LDAPModificationSet クラスの インスタンスに設定する必要があります。LDAPModification および LDAPModificationSet クラス が、属性の操作を行う場合の要求単位になるわけです。

      LDAPModification と LDAPModificationSet の違いは、LDAPModification が単一の属性情報を保持 するのに対して、LDAPModificationSet は複数の属性情報を保持できることです。 つまり、単一属性の操作を行う場合は LDAPModification を、複数属性の操作を行う場合は LDAPModificationSet を使用すれば良いということです。

      実は LDAPModify.java では単一属性の操作しか行わないため LDAPModification を使用すれば良い のですが、何故か LDAPModificationSet を使っています。 何故かというと、サンプルプログラムを作成した時点ではそれを知らなかったからです。。。

    • 40 行目

      属性名と属性値の組から、LDAPAttribute クラスのインスタンスを作成しています。 これを上で作成した LDAPModificationSet に設定することになります。

    • 42 〜 52 行目

      既に作成した LDAPAttribute クラスのインスタンスを LDAPModificationSet に設定します。 LDAPModificationSet に属性情報を設定する際には、その属性に対する操作種別も同時に 設定しなければいけません( LDAPModification の場合も同様 )。操作種別には以下のいずれかを 設定できます。

      • LDAPModification.ADD ( 追加 )
      • LDAPModification.DELETE ( 削除 )
      • LDAPModification.REPLACE ( 置換、要は修正 )

      実際に設定するには、LDAPModificationSet#add() を使います。

        public void LDAPModificationSet#add( int op, LDAPAttribute attr )
      
        op   : 操作種別
        attr : 属性情報
      
      

      なお LDAPModification を使う場合は、コンストラクタの引数に操作種別と属性情報を与えて インスタンスを作成します。

        (例)
        LDAPModification md = 
                   new LDAPModification( 
                           LDAPModification.ADD, 
                           new LDAPAttribute( name, value ));
      
      

    • 68 〜 70 行目

      LDAPConnection#modify() を使って、属性に対する操作を実行しています。

        public void LDAPConnection#modify( 
                                String              dn,
                                LDAPModificationSet mods )
           throws LDAPException
      
        dn   : 属性を操作するエントリの DN
        mods : 属性情報とそれに対する操作種別の組が複数含まれる
      
      

      何らかの理由で操作に失敗した場合、LDAPException が throw されます。その内容については後述 します。

      modify() メソッドは上の形式以外の形でいくつかオーバーロードされています。それぞれの詳細に ついては JLDAP の API ドキュメントを参照して下さい。なお、LDAPModification を使う際には オーバーロードされているメソッドを使用することになります。

    • 77 〜 80 行目

      ここまでの処理で発生した LDAPException を catch して、内容を表示しています。今回の 新たな処理によって発生する可能性のある例外内容について、自分が確認できた範囲で 以下にまとめておきます。例によってこれで全てという意味ではありません。

      番号 エラーコードの定数名(LDAPException.XXX の形で参照可) 内容
      2 PROTOCOL_ERROR LDAP サーバがクライアントから不正な要求を受け取った。LDAPModify.java の場合、 操作種別に不正な値を指定すると発生する。
      16 NO_SUCH_ATTRIBUTE 指定された属性がエントリ内に存在しない。削除するために属性名と属性値を指定する際に、 属性名に対して LDAP サーバ側で既に設定されている属性値ではなく適当な値を設定すると、 この例外が発生する。属性名が間違っている場合は下の UNDEFINED_ATTRIBUTE_TYPE が発生する。
      17 UNDEFINED_ATTRIBUTE_TYPE 指定された属性が LDAP サーバ側のスキーマに存在しない。つまり、LDAPAttributeSet クラスのインスタンスに設定した属性名が正しくないことを表している。
      32 NO_SUCH_OBJECT modify() に指定した DN で識別されるオブジェクトを参照することができない (存在しない)。
      34 INVALID_DN_SYNTAX 指定した DN の構文が正しくない。
      65 OBJECT_CLASS_VIOLATION オブジェクトクラスに適用される規則に反した処理を行おうとしている。 必須属性を削除しようとした場合に発生する。

以上で LDAPModify.java についての説明は終わりです。実は、今の所ここまで紹介してきた処理以外の LDAP クライアントの利用方法を自分が思い付きません。ので、思い付くまで今後の予定は未定。。。