/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*   モジュール名    ：JECCTGN00001TPMA
*   ソースファイル名：JECCTGN00001TPMA.java
*   作成者          ：富士通
*   日付            ：2012年02月20日
*＜機能概要＞
*   主処理(共通)<BR>
*   統合認証システム連携独自処理部品クラス.
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2012/02/20   富士通      新規作成
*   v5.00.00    2013/12/12   FJ          ログ出力追加
*   v11.00.00   2014/12/04   FJ)山下     ANK-2408-00-00
*   v11.00.01   2014/12/09   FJ)山下     ANK-2408-00-00(正式対応)
*	v74.00.00   2025/01/20   FJ) 古村   【ANK-4631-00-00】SIMSの組織コード変更対応
*
**********************************************************************/

package eo.ejb.cbs.mainproc;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateMainHandler;

import eo.common.util.JCCFrameworkException;
import eo.common.util.JCCcomEncryptionUtil;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg2List;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg3List;
import eo.ejb.cbs.cbsmsg.ECCTGN00001CBSMsg4List;
import eo.ejb.common.JCCModelCommon;
import eo.ejb.common.JZMGetOrgPosCode;

/**
 * <p>
 * 統合認証システム連携独自処理部品クラスです。
 * </p>
 * @author 富士通
 */
public class JECCTGN00001TPMA implements TemplateMainHandler {

	/**
	 * コンストラクタ.
	 */
	public JECCTGN00001TPMA()
	{
		super();
	}
	
	/** カンマ */
	private static final String COMMA = ",";
	/** コンテキスト初期化ファクトリー */
	private static final String INITIAL_CONTEXT_FACTORY =  "com.sun.jndi.ldap.LdapCtxFactory";
	/** 従業員管理区分CD */
	private static final String EMPLOYEE_TYPE = "employeeType";
	/** 漢字氏名（姓） */
	private static final String SN = "sn";
	/** 漢字氏名（名） */
	private static final String GIVEN_NAME = "givenName";
	/** 所属職位 */
// ANK-4631-00-00 MOD START
	//private static final String KOPT_POSITION = "koptPosition";
	private static final String KOPT_NPOSITION = "koptNPosition";
// ANK-4631-00-00 MOD END
	/** 初期パスワードフラグ */
	private static final String KOPT_PASSWORD_INIT_FLAG = "koptPasswordInitFlag";
	/** パスワード有効期限 */
	private static final String KOPT_PASSWORD_EXPIRATION = "koptPasswordExpiration";
	/** システム003利用不可 */
	private static final String KOPT_SYSTEM_003_DISABLE = "koptsystem003Disable";
	/** システム003役割 */
	private static final String KOPT_SYSTEM_003_ROLE = "koptsystem003Role";
	/** システム003付帯情報1 */
	private static final String KOPT_SYSTEM_003_SUB_1 = "koptsystem003Sub1";
	/** 認証OK */
	private static final String NINSHO_OK = "0";
	/** 認証NG */
	private static final String NINSHO_NG = "1";
	

	/**
	 * 統合認証システム連携処理
	 * 統合認証システムへ認証を行い、認証結果をCBSMsgへ設定する。<BR>
	 * @param inMsg 
	 * @param inContext 
	 */
	public static void invoke(CAANMsg inCBSMsg, AgentDispatchContext inContext) throws Exception
	{
		
		// 機能コードが1(ユーザーIDおよびパスワード認証)の場合、パスワード必須チェック
		if("1".equals(inCBSMsg.getString(ECCTGN00001CBSMsg.FUNC_CODE)))
		{
			if(inCBSMsg.isNull(ECCTGN00001CBSMsg.PASSWORD) || "".equals(inCBSMsg.getString(ECCTGN00001CBSMsg.PASSWORD)))
			{
				// inCBSMsgの指定項目に"E1"を設定
				inCBSMsg.set(ECCTGN00001CBSMsg.PASSWORD_ERR, "E1");
				// inCBSMsg（ステータス）に「単項目チェックでエラー」を設定
				inCBSMsg.set(ECCTGN00001CBSMsg.STATUS, StatusCodes.SINGLEDATA_ERR);
				
				return;
			}
		}
		
		// プロパティファイルより統合認証システム連携モードを取得する。
		String ldapRenkeiMode = JCCModelCommon.getApplicationConst("LDAP_CONNECT_MODE");
		// 統合認証システム連携モードが取得できない場合、システムエラーとして終了する。
		if (null == ldapRenkeiMode || ldapRenkeiMode.isEmpty())
		{
			String errMsg = "統合認証システム連携モード（キー：LDAP_CONNECT_MODE）が"+
				  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
				throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
		}
		
		// 連携モードが0「スタブ」の場合、認証結果をOKにして返却
		if(ldapRenkeiMode.equals("0"))
		{
			
// スタブの場合の組織・立場情報を共通機能の部品より設定する。 start
			JZMGetOrgPosCode.getOrgPosCode(inCBSMsg);
// スタブの場合の組織・立場情報を共通機能の部品より設定する。 end

//			// 認証結果
//			inCBSMsg.set(ECCTGN00001CBSMsg.NINSHO_STAT, NINSHO_OK);
//			
//			// 特別権限組織コード・立場コード明細のスタブ値を設定
//			ArrayList<CAANMsg> inMsgSpclList = new ArrayList<CAANMsg>();
//			CAANMsg inMsgSpcl1 = new CAANMsg(ECCTGN00001CBSMsg4List.class.getName());
//			inMsgSpcl1.set(ECCTGN00001CBSMsg4List.SPCL_ORG_CD, "0000000001");
//			inMsgSpcl1.set(ECCTGN00001CBSMsg4List.SPCL_POSITION_CD, "0000000002");
//			inMsgSpclList.add(inMsgSpcl1);
//			CAANMsg inMsgSpcl2 = new CAANMsg(ECCTGN00001CBSMsg4List.class.getName());
//			inMsgSpcl2.set(ECCTGN00001CBSMsg4List.SPCL_ORG_CD, "0000000011");
//			inMsgSpcl2.set(ECCTGN00001CBSMsg4List.SPCL_POSITION_CD, "0000000012");
//			inMsgSpclList.add(inMsgSpcl2);
//			CAANMsg[] inSpclModel = (CAANMsg[])inMsgSpclList.toArray(new CAANMsg[0]);
//			inCBSMsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG4LIST, inSpclModel);
			return;
		}
		
		// プロパティファイルよりLDAPサーバURLを取得する。
		String ldapURL = JCCModelCommon.getApplicationConst("LDAP_URL");
		// LDAPサーバURLが取得できない場合、システムエラーとして終了する。
		if (null == ldapURL || ldapURL.isEmpty())
		{
			String errMsg = "LDAPサーバURL（キー：LDAP_URL）が"+
				  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
				throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
		}
		// プロパティファイルよりLDAPドメインを取得する。
		String ldapDC = JCCModelCommon.getApplicationConst("LDAP_DOMAIN");
		// LDAPドメインが取得できない場合、システムエラーとして終了する。
		if (null == ldapDC || ldapDC.isEmpty())
		{
			String errMsg = "LDAPドメイン（キー：LDAP_DOMAIN）が"+
				  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
				throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
		}
		// プロパティファイルよりLDAP接続パスワードを取得する。
		String ldapConnectPw = JCCModelCommon.getApplicationConst("LDAP_CONNECT_PW");
		// LDAP接続パスワードが取得できない場合、システムエラーとして終了する。
		if (null == ldapConnectPw || ldapConnectPw.isEmpty())
		{
			String errMsg = "LDAP接続パスワード（キー：LDAP_CONNECT_PW）が"+
				  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
				throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
		}
		
		// プロパティファイルより複合化キーを取得
		String decryptKey = JCCModelCommon.getApplicationConst("ENCRYPT_KEY");
		// 複合化キーが取得できない場合、システムエラーとして終了する。
		if (null == decryptKey || decryptKey.isEmpty())
		{
			String errMsg = "複合化キー（キー：ENCRYPT_KEY）が"+
				  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
				throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
		}
		
		// 取得したパスワードの複合化を行う。
		String decryptLdapConnectPw = JCCcomEncryptionUtil.decrypt(decryptKey, ldapConnectPw);
		
		// 連携モードが1「連携」の場合は、統合認証システムへの連携処理を行う
		// 機能コードが1(ユーザーIDおよびパスワード認証)の場合、ユーザ認証を行う
		if("1".equals(inCBSMsg.getString(ECCTGN00001CBSMsg.FUNC_CODE)))
		{
			Hashtable<String, String> env = new Hashtable<String, String>();
			
			// コンテキスト初期化ファクトリー
			env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
			// プロバイダURL
			env.put(Context.PROVIDER_URL, "ldap://" + ldapURL);
			// rootdn(管理者DN)
			env.put(Context.SECURITY_PRINCIPAL, "cn=" + inCBSMsg.getString(ECCTGN00001CBSMsg.USER_ID) 
					+ ",ou=people,dc=" + ldapDC + ",dc=local");
			// rootpw(管理者パスワード)
			env.put(Context.SECURITY_CREDENTIALS, inCBSMsg.getString(ECCTGN00001CBSMsg.PASSWORD));
			
			// 2013/03/21 FST_mukuo) オブジェクトのクローズ漏れ対応 start
			DirContext ctx = null;
			try
			{
				ctx = new InitialDirContext(env);
			}
			catch(AuthenticationException ae)
			{
				// AuthenticationException発生時は認証失敗
				// 認証結果NG
				inCBSMsg.set(ECCTGN00001CBSMsg.NINSHO_STAT, NINSHO_NG);
				// 2013/12/12 v5.00.00 ログ出力追加
				JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION, JECCTGN00001TPMA.class, "JECCTGN00001TPMA [AuthenticationException] "
						+ ae.getMessage() + " ou=people,dc=" + ldapDC + ",dc=local,cn=" + inCBSMsg.getString(ECCTGN00001CBSMsg.USER_ID));
				return;
			}
			catch(Exception e)
			{
				// ANK-2408-00-00 ADD START
				int propertiesCount = 2;
				
				while (true)
				{
					// LDAPサーバURLX
					String strLdapUrlX = "LDAP_URL_" + String.valueOf(propertiesCount);
					// LDAPドメインX
					String strLdapDomainX = "LDAP_DOMAIN_" + String.valueOf(propertiesCount);
					// LDAP接続パスワードX
					String strLdapConnectPwX = "LDAP_CONNECT_PW_" + String.valueOf(propertiesCount);
					// 複合化キーX
					String strEncryptKeyX = "ENCRYPT_KEY_" + String.valueOf(propertiesCount);
					
					// プロパティファイルよりLDAPサーバURLを取得する。
					ldapURL = JCCModelCommon.getApplicationConst(strLdapUrlX);
					// プロパティファイルよりLDAPドメインを取得する。
					ldapDC = JCCModelCommon.getApplicationConst(strLdapDomainX);
					// プロパティファイルよりLDAP接続パスワードを取得する。
					ldapConnectPw = JCCModelCommon.getApplicationConst(strLdapConnectPwX);
					// プロパティファイルより複合化キーを取得
					decryptKey = JCCModelCommon.getApplicationConst(strEncryptKeyX);
					
					// 4項目全てが未定義の場合
					if (null == ldapURL && null == ldapDC && null == ldapConnectPw && null == decryptKey)
					{
						// 認証で発生した例外をスローする
						throw new CAANRuntimeException(e);
					}
					
					// LDAPサーバURLが取得できない場合、システムエラーとして終了する。
					if (null == ldapURL || ldapURL.isEmpty())
					{
						String errMsg = "LDAPサーバURL（キー：" + strLdapUrlX + "）が"+
							  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
							throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
					}
					
					// LDAPドメインが取得できない場合、システムエラーとして終了する。
					if (null == ldapDC || ldapDC.isEmpty())
					{
						String errMsg = "LDAPドメイン（キー：" + strLdapDomainX + "）が"+
							  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
							throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
					}
					
					// LDAP接続パスワードが取得できない場合、システムエラーとして終了する。
					if (null == ldapConnectPw || ldapConnectPw.isEmpty())
					{
						String errMsg = "LDAP接続パスワード（キー：" + strLdapConnectPwX + "）が"+
							  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
							throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
					}
					
					// 複合化キーが取得できない場合、システムエラーとして終了する。
					if (null == decryptKey || decryptKey.isEmpty())
					{
						String errMsg = "複合化キー（キー：" + strEncryptKeyX + "）が"+
							  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
							throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
					}
					
					// 取得したパスワードの複合化を行う。
					decryptLdapConnectPw = JCCcomEncryptionUtil.decrypt(decryptKey, ldapConnectPw);
					
					env = new Hashtable<String, String>();
					
					// コンテキスト初期化ファクトリー
					env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
					// プロバイダURL
					env.put(Context.PROVIDER_URL, "ldap://" + ldapURL);
					// rootdn(管理者DN)
					env.put(Context.SECURITY_PRINCIPAL, "cn=" + inCBSMsg.getString(ECCTGN00001CBSMsg.USER_ID) 
							+ ",ou=people,dc=" + ldapDC + ",dc=local");
					// rootpw(管理者パスワード)
					env.put(Context.SECURITY_CREDENTIALS, inCBSMsg.getString(ECCTGN00001CBSMsg.PASSWORD));
					
					try
					{
						ctx = new InitialDirContext(env);
						
						// 認証成功でループを抜ける
						break;
					}
					catch(AuthenticationException ae)
					{
						// AuthenticationException発生時は認証失敗
						// 認証結果NG
						inCBSMsg.set(ECCTGN00001CBSMsg.NINSHO_STAT, NINSHO_NG);
						// ログ出力
						JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION, JECCTGN00001TPMA.class, "JECCTGN00001TPMA [AuthenticationException] "
								+ ae.getMessage() + " ou=people,dc=" + ldapDC + ",dc=local,cn=" + inCBSMsg.getString(ECCTGN00001CBSMsg.USER_ID));
						return;
					}
					catch(Exception e2)
					{
						// プロパティカウントをインクリメント
						propertiesCount++;
					}
				}
				// ANK-2408-00-00 ADD END
				
				// ANK-2408-00-00 DEL START
				// Exception発生
				//throw new CAANRuntimeException(e);
				// ANK-2408-00-00 DEL END
			}
			finally
			{
				if(null != ctx)
				{
					ctx.close();
				}
			}
			// 2013/03/21 FST_mukuo) オブジェクトのクローズ漏れ対応 end
		}
		
		// システムIDにて認証を行いデータを取得する
		Hashtable<String, String> env = new Hashtable<String, String>();
		// コンテキスト初期化ファクトリー
		env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
		// プロバイダURL
		env.put(Context.PROVIDER_URL, "ldap://" + ldapURL);
		// rootdn(管理者DN)
		env.put(Context.SECURITY_PRINCIPAL, "cn=koptsystem003,ou=system,dc=" + ldapDC + ",dc=local");
		// rootpw(管理者パスワード)
		env.put(Context.SECURITY_CREDENTIALS, decryptLdapConnectPw);
		
		// 2013/03/21 FST_mukuo) オブジェクトのクローズ漏れ対応 start
		DirContext ctx = null;
		NamingEnumeration entries = null;
		try
		{
			// ANK-2408-00-00 MOD START
			//ctx = new InitialDirContext(env);
			
			// 機能コードが1の場合
			if("1".equals(inCBSMsg.getString(ECCTGN00001CBSMsg.FUNC_CODE)))
			{
				ctx = new InitialDirContext(env);
			}
			else
			{
				try
				{
					ctx = new InitialDirContext(env);
				}
				catch (Exception e)
				{
					int propertiesCount = 2;
					
					while (true)
					{
						// LDAPサーバURLX
						String strLdapUrlX = "LDAP_URL_" + String.valueOf(propertiesCount);
						// LDAPドメインX
						String strLdapDomainX = "LDAP_DOMAIN_" + String.valueOf(propertiesCount);
						// LDAP接続パスワードX
						String strLdapConnectPwX = "LDAP_CONNECT_PW_" + String.valueOf(propertiesCount);
						// 複合化キーX
						String strEncryptKeyX = "ENCRYPT_KEY_" + String.valueOf(propertiesCount);
						
						// プロパティファイルよりLDAPサーバURLを取得する。
						ldapURL = JCCModelCommon.getApplicationConst(strLdapUrlX);
						// プロパティファイルよりLDAPドメインを取得する。
						ldapDC = JCCModelCommon.getApplicationConst(strLdapDomainX);
						// プロパティファイルよりLDAP接続パスワードを取得する。
						ldapConnectPw = JCCModelCommon.getApplicationConst(strLdapConnectPwX);
						// プロパティファイルより複合化キーを取得
						decryptKey = JCCModelCommon.getApplicationConst(strEncryptKeyX);
						
						// 4項目全てが未定義の場合
						if (null == ldapURL && null == ldapDC && null == ldapConnectPw && null == decryptKey)
						{
							// 認証で発生した例外をスローする
							throw new CAANRuntimeException(e);
						}
						
						// LDAPサーバURLが取得できない場合、システムエラーとして終了する。
						if (null == ldapURL || ldapURL.isEmpty())
						{
							String errMsg = "LDAPサーバURL（キー：" + strLdapUrlX + "）が"+
								  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
								throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
						}
						
						// LDAPドメインが取得できない場合、システムエラーとして終了する。
						if (null == ldapDC || ldapDC.isEmpty())
						{
							String errMsg = "LDAPドメイン（キー：" + strLdapDomainX + "）が"+
								  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
								throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
						}
						
						// LDAP接続パスワードが取得できない場合、システムエラーとして終了する。
						if (null == ldapConnectPw || ldapConnectPw.isEmpty())
						{
							String errMsg = "LDAP接続パスワード（キー：" + strLdapConnectPwX + "）が"+
								  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
								throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
						}
						
						// 複合化キーが取得できない場合、システムエラーとして終了する。
						if (null == decryptKey || decryptKey.isEmpty())
						{
							String errMsg = "複合化キー（キー：" + strEncryptKeyX + "）が"+
								  "アプリケーションプロパティファイル（AplConst）にて設定されていません。";
								throw new CAANRuntimeException(new JCCFrameworkException(errMsg));
						}
						
						// 取得したパスワードの複合化を行う。
						decryptLdapConnectPw = JCCcomEncryptionUtil.decrypt(decryptKey, ldapConnectPw);
						
						// システムIDにて認証を行いデータを取得する
						env = new Hashtable<String, String>();
						// コンテキスト初期化ファクトリー
						env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
						// プロバイダURL
						env.put(Context.PROVIDER_URL, "ldap://" + ldapURL);
						// rootdn(管理者DN)
						env.put(Context.SECURITY_PRINCIPAL, "cn=koptsystem003,ou=system,dc=" + ldapDC + ",dc=local");
						// rootpw(管理者パスワード)
						env.put(Context.SECURITY_CREDENTIALS, decryptLdapConnectPw);
						
						try
						{
							// システムIDにて認証を行いデータを取得する
							ctx = new InitialDirContext(env);
							
							// 認証成功でループを抜ける
							break;
						}
						catch (Exception e2)
						{
							// プロパティカウントをインクリメント
							propertiesCount++;
						}
					}
				}
			}
			// ANK-2408-00-00 MOD END
			
			SearchControls searchControls = new SearchControls();
			searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
			// 検索をツリー上のどこから開始、検索条件、ツリー上のどこまでを検索スコープとするか
			entries = ctx.search("ou=people,dc=" + ldapDC + ",dc=local", "cn=" 
					+ inCBSMsg.getString(ECCTGN00001CBSMsg.USER_ID), searchControls);
			
			HashMap<String, ArrayList<Object>> entryMap = getLdapData(entries);
			
			// 何も取得できない場合は認証NGで返却
			if(entryMap.size() == 0)
			{
				// 認証結果NG
				inCBSMsg.set(ECCTGN00001CBSMsg.NINSHO_STAT, NINSHO_NG);
				// 2013/12/12 v5.00.00 ログ出力追加
				JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION, JECCTGN00001TPMA.class, "JECCTGN00001TPMA getLdapData() is Empty. "
						+ "Search Param: 'ou=people,dc=" + ldapDC + ",dc=local', cn=" + inCBSMsg.getString(ECCTGN00001CBSMsg.USER_ID));
				return;
			}
			
			// システム003利用不可
			if(entryMap.containsKey(KOPT_SYSTEM_003_DISABLE))
			{
				// 利用不可フラグが「1:利用不可」の場合は、認証NGで返却する。
				if("1".equals(entryMap.get(KOPT_SYSTEM_003_DISABLE).get(0)))
				{
					inCBSMsg.set(ECCTGN00001CBSMsg.NINSHO_STAT, NINSHO_NG);
					// 2013/12/12 v5.00.00 ログ出力追加
					JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION, JECCTGN00001TPMA.class, "JECCTGN00001TPMA KOPT_SYSTEM_003_DISABLE = 1."
							+ "Search Param: 'ou=people,dc=" + ldapDC + ",dc=local', cn=" + inCBSMsg.getString(ECCTGN00001CBSMsg.USER_ID));
					return;
				}
			}
			
			// 認証結果OKを設定
			inCBSMsg.set(ECCTGN00001CBSMsg.NINSHO_STAT, NINSHO_OK);
			
			// 初期パスワードフラグ
			if(entryMap.containsKey(KOPT_PASSWORD_INIT_FLAG))
			{
				inCBSMsg.set(ECCTGN00001CBSMsg.SHK_PASSWORD_FLG, entryMap.get(KOPT_PASSWORD_INIT_FLAG).get(0));
			}
			// パスワード有効期限
			if(entryMap.containsKey(KOPT_PASSWORD_EXPIRATION))
			{	
				inCBSMsg.set(ECCTGN00001CBSMsg.PASSWORD_YK_KIGEN, entryMap.get(KOPT_PASSWORD_EXPIRATION).get(0));
			}
			// 従業員管理区分CD
			if(entryMap.containsKey(EMPLOYEE_TYPE))
			{
				inCBSMsg.set(ECCTGN00001CBSMsg.WORKER_KANRI_DIV_CD, entryMap.get(EMPLOYEE_TYPE).get(0));
			}
			// 漢字氏名（姓）
			if(entryMap.containsKey(SN))
			{
				inCBSMsg.set(ECCTGN00001CBSMsg.KANJI_NM_FMLNM, entryMap.get(SN).get(0));
			}
			// 漢字氏名（名）
			if(entryMap.containsKey(GIVEN_NAME))
			{
				inCBSMsg.set(ECCTGN00001CBSMsg.KANJI_NM_FSTNM, entryMap.get(GIVEN_NAME).get(0));
			}
			// 所属職位の場合は、主所属と兼務で振り分ける
			// 所属コード
// ANK-4631-00-00 MOD START
//			if(entryMap.containsKey(KOPT_POSITION))
			if(entryMap.containsKey(KOPT_NPOSITION))
// ANK-4631-00-00 MOD END
			{
				// 兼務情報明細
				ArrayList<CAANMsg> inMsgWorkList = new ArrayList<CAANMsg>();
				
// ANK-4631-00-00 MOD START
//				String[] koptPositionSplit = String.valueOf(entryMap.get(KOPT_POSITION).get(0)).split(COMMA);
				String[] koptPositionSplit = String.valueOf(entryMap.get(KOPT_NPOSITION).get(0)).split(COMMA);
// ANK-4631-00-00 MOD END
				for(int i = 0 ; i < koptPositionSplit.length ; i++)
				{
					// 1順目は、所属コードおよび職位コードへ設定する
					if(i == 0)
					{
						// 主所属コード
						inCBSMsg.set(ECCTGN00001CBSMsg.SYOZK_CD, koptPositionSplit[i]);
						i++;
						// 連番より分割文字の数が小さい場合はbreakする
						if(i >= koptPositionSplit.length)
						{
							break;
						}
						// 主職位コード
						inCBSMsg.set(ECCTGN00001CBSMsg.SYOKUI_CD, koptPositionSplit[i]);
					}
					else
					{
					
						CAANMsg inMsgWork = new CAANMsg(ECCTGN00001CBSMsg1List.class.getName());
						// 兼務所属コード
						inMsgWork.set(ECCTGN00001CBSMsg1List.KENMU_SYOZK_CD, koptPositionSplit[i]);
						i++;
						// 連番より分割文字の数が小さい場合はbreakする
						if(i >= koptPositionSplit.length)
						{
							inMsgWorkList.add(inMsgWork);
							break;
						}
						else
						{
							// 兼務職位コード
							inMsgWork.set(ECCTGN00001CBSMsg1List.KENMU_SYOKUI_CD, koptPositionSplit[i]);
						}
						inMsgWorkList.add(inMsgWork);
					}
				}
				// 兼務情報明細をセット
				CAANMsg[] inWorkModel = (CAANMsg[])inMsgWorkList.toArray(new CAANMsg[0]);
				inCBSMsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG1LIST, inWorkModel);
			}
			
			// システム003役割の場合は、明細（ワークグループ、中間）に振り分ける
			if(entryMap.containsKey(KOPT_SYSTEM_003_ROLE))
			{
				// ワークグループ組織コード・立場コード明細
				ArrayList<CAANMsg> inMsgWorkList1 = new ArrayList<CAANMsg>();
				// 中間組織コード・立場コード明細
				ArrayList<CAANMsg> inMsgWorkList2 = new ArrayList<CAANMsg>();
				
				String[] koptsystemRoleSplit = String.valueOf(entryMap.get(KOPT_SYSTEM_003_ROLE).get(0)).split(COMMA);
				for(int i = 0 ; i < koptsystemRoleSplit.length ; i++)
				{	
					// ワークグループの情報は15×3セット
					if(i < 45)
					{
						CAANMsg inMsgWork = new CAANMsg(ECCTGN00001CBSMsg2List.class.getName());
						// ワークグループ上位組織コード
						inMsgWork.set(ECCTGN00001CBSMsg2List.WKGRP_JOI_ORG_CD, koptsystemRoleSplit[i]);
						i++;
						// 連番より分割文字の数が小さい場合はbreakする
						if(i >= koptsystemRoleSplit.length)
						{
							inMsgWorkList1.add(inMsgWork);
							break;
						}
						// ワークグループ組織コード
						inMsgWork.set(ECCTGN00001CBSMsg2List.WKGRP_ORG_CD, koptsystemRoleSplit[i]);
						i++;
						// 連番より分割文字の数が小さい場合はbreakする
						if(i >= koptsystemRoleSplit.length)
						{
							inMsgWorkList1.add(inMsgWork);
							break;
						}
						// ワークグループ立場コード
						inMsgWork.set(ECCTGN00001CBSMsg2List.WKGRP_POSITION_CD, koptsystemRoleSplit[i]);
						// すべてブランクだった場合は、設定はリストへの追加は行わない。
						if(!"".equals(inMsgWork.getString(ECCTGN00001CBSMsg2List.WKGRP_JOI_ORG_CD))
								|| !"".equals(inMsgWork.getString(ECCTGN00001CBSMsg2List.WKGRP_ORG_CD))
								|| !"".equals(inMsgWork.getString(ECCTGN00001CBSMsg2List.WKGRP_POSITION_CD)))
						{
							inMsgWorkList1.add(inMsgWork);
						}
					}
					else
					{
						CAANMsg inMsgWork = new CAANMsg(ECCTGN00001CBSMsg3List.class.getName());
						// 中間上位組織コード
						inMsgWork.set(ECCTGN00001CBSMsg3List.CHUKAN_JOI_ORG_CD, koptsystemRoleSplit[i]);
						i++;
						// 連番より分割文字の数が小さい場合はbreakする
						if(i >= koptsystemRoleSplit.length)
						{
							inMsgWorkList2.add(inMsgWork);
							break;
						}
						// 中間組織コード
						inMsgWork.set(ECCTGN00001CBSMsg3List.CHUKAN_ORG_CD, koptsystemRoleSplit[i]);
						i++;
						// 連番より分割文字の数が小さい場合はbreakする
						if(i >= koptsystemRoleSplit.length)
						{
							inMsgWorkList2.add(inMsgWork);
							break;
						}
						// 中間立場コード
						inMsgWork.set(ECCTGN00001CBSMsg3List.CHUKAN_POSITION_CD, koptsystemRoleSplit[i]);
						inMsgWorkList2.add(inMsgWork);
					}
					
				}
				// ワークグループ組織コード・立場コード明細をセット
				CAANMsg[] inWorkModel1 = (CAANMsg[])inMsgWorkList1.toArray(new CAANMsg[0]);
				inCBSMsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG2LIST, inWorkModel1);
				// 中間組織コード・立場コード明細をセット
				CAANMsg[] inWorkModel2 = (CAANMsg[])inMsgWorkList2.toArray(new CAANMsg[0]);
				inCBSMsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG3LIST, inWorkModel2);
			}

			// システム003付帯情報1の場合は、明細（特別）に振り分ける
			if(entryMap.containsKey(KOPT_SYSTEM_003_SUB_1))
			{
				// 特別権限組織コード・立場コード明細
				ArrayList<CAANMsg> inMsgWorkList = new ArrayList<CAANMsg>();
				
				String[] koptsystem003Split = String.valueOf(entryMap.get(KOPT_SYSTEM_003_SUB_1).get(0)).split(COMMA);
				for(int i = 0 ; i < koptsystem003Split.length ; i++)
				{	
					CAANMsg inMsgWork = new CAANMsg(ECCTGN00001CBSMsg4List.class.getName());
					// 一つ目はカテゴリーが入るため加算する
					i++;
					// 連番より分割文字の数が小さい場合はbreakする
					if(i >= koptsystem003Split.length)
					{
						break;
					}
					// 特別組織コード
					inMsgWork.set(ECCTGN00001CBSMsg4List.SPCL_ORG_CD, koptsystem003Split[i]);
					i++;
					// 連番より分割文字の数が小さい場合はbreakする
					if(i >= koptsystem003Split.length)
					{
						inMsgWorkList.add(inMsgWork);
						break;
					}
					// 特別立場コード
					inMsgWork.set(ECCTGN00001CBSMsg4List.SPCL_POSITION_CD, koptsystem003Split[i]);
					inMsgWorkList.add(inMsgWork);
				}
				// 特別権限組織コード・立場コード明細をセット
				CAANMsg[] inWorkModel = (CAANMsg[])inMsgWorkList.toArray(new CAANMsg[0]);
				inCBSMsg.set(ECCTGN00001CBSMsg.ECCTGN00001CBSMSG4LIST, inWorkModel);
			}
		}
		catch(Exception e)
		{
			throw new CAANRuntimeException(e);
		}
		// 2013/03/21 FST_mukuo) オブジェクトのクローズ漏れ対応 start
		finally
		{
			if(null != entries)
			{
				entries.close();
			}
			if(null != ctx)
			{
				ctx.close();
			}
		}
		// 2013/03/21 FST_mukuo) オブジェクトのクローズ漏れ対応 end
	}
	
	/**
	 * LDAPデータ取得処理です。
	 * NamingEnumerationから取得したLDAPデータをHashMapに変換し、キーと値で返却します。
	 * @param entries LDAPデータ
	 * @return HashMap形式のLDAPデータ
	 * @exception Exceptionがスローされます。
	 */
	private static HashMap<String, ArrayList<Object>> getLdapData(NamingEnumeration entries) throws Exception
	{
		
		HashMap<String, ArrayList<Object>> entry = new HashMap<String, ArrayList<Object>>();
		
		while(entries.hasMore())
		{
			SearchResult searchResult = (SearchResult)entries.next();
			NamingEnumeration attrs = searchResult.getAttributes().getAll();
			Attribute attr = null;
			
			try
			{
				while(attrs.hasMore())
				{
					attr = (Attribute)attrs.nextElement();
					Enumeration attrValEnum = attr.getAll();
					ArrayList<Object> attrValueList = new ArrayList<Object>();
					while(attrValEnum.hasMoreElements())
					{
						Object elem = attrValEnum.nextElement();
						attrValueList.add(elem);
					}
					entry.put(attr.getID(), attrValueList);
				}
			}
			// 2013/03/21 FST_mukuo) オブジェクトのクローズ漏れ対応 start
			finally
			{
				if(null != attr)
				{
					attrs.close();
				}
			}
			// 2013/03/21 FST_mukuo) オブジェクトのクローズ漏れ対応 end
		}
		return entry;
	}
}
