Hello,
I would like to present in this post, the LDAP servers configuration in Documentum Administrator (DA) and the dm_LDAPSynchronization job.
Creation of LDAP server configuration:
- Go to the LDAP Servers node in DA:

- Click on the FILE > LDAP Server Configuration menu:


- Fill in the informations concerning the LDAP server:
Warning: the name of LDAP Server Configuration must be identical to domain name.

In update mode, the password is necessary in order to modify others informations:

- Go on to the Sync & Authentication tab:


- Go on to the Mapping tab:

- Go on to the Failover tab:

LDAP Synchronisation job : dm_LDAPSynchronization:
- Go to the Jobs node in DA:

- Go on to the Job Properties:

- Go on to the Schedule tab:

- Go on to the Method tab:

- Go on to the SysObject Info tab:

The job dm_LDAPSynchronization creates item of « dm_job_request » type for the jobs :
+ dm_UserRename : « object_name=’UserRename’, job_name=’dm_UserRename’ » to rename users
+ dm_GroupRename : « object_name=’GroupRename’, job_name=’dm_GroupRename’ » to rename groups
DQL: List LDAP being used to authenticate users
- Source of Users
1 | select distinct user_source from dm_user; |
- OS Users
01 | select user_login_name, user_login_domain from dm_user where user_source = ' ' ; |
03 | user_login_name | user_login_domain |
08 | dm_superusers_dynamic | |
10 | dm_browse_all_dynamic | |
11 | dm_retention_managers | |
- LDAP Users
01 | select user_login_name, user_login_domain from dm_user where user_source = 'LDAP' ; |
03 | user_login_name | user_login_domain |
- Inline Password Users
1 | select user_login_name, user_login_domain from dm_user where user_source = 'inline password' ; |
3 | user_login_name | user_login_domain |
Class for correction the user based on the log of dm_LDAPSynchronization job:
001 | package com.java.lu.business.service.ecm.utils.repair; |
003 | import java.io.BufferedReader; |
004 | import java.io.IOException; |
005 | import java.io.InputStream; |
006 | import java.io.InputStreamReader; |
007 | import java.io.PrintWriter; |
008 | import java.text.MessageFormat; |
009 | import java.util.Calendar; |
011 | import java.util.Map.Entry; |
012 | import java.util.TreeMap; |
013 | import java.util.regex.Matcher; |
014 | import java.util.regex.Pattern; |
016 | import org.apache.commons.lang.StringUtils; |
018 | import com.documentum.com.DfClientX; |
019 | import com.documentum.com.IDfClientX; |
020 | import com.documentum.fc.client.DfAuthenticationException; |
021 | import com.documentum.fc.client.DfIdentityException; |
022 | import com.documentum.fc.client.DfPrincipalException; |
023 | import com.documentum.fc.client.DfQuery; |
024 | import com.documentum.fc.client.DfServiceException; |
025 | import com.documentum.fc.client.IDfClient; |
026 | import com.documentum.fc.client.IDfDocbaseMap; |
027 | import com.documentum.fc.client.IDfDocument; |
028 | import com.documentum.fc.client.IDfQuery; |
029 | import com.documentum.fc.client.IDfSession; |
030 | import com.documentum.fc.client.IDfSessionManager; |
031 | import com.documentum.fc.client.IDfUser; |
032 | import com.documentum.fc.common.DfException; |
033 | import com.documentum.fc.common.DfLoginInfo; |
035 | public class CorrectLDAP { |
037 | private static class User { |
038 | final private String cn; |
039 | private String username; |
040 | private String uniqueId; |
041 | private boolean readUserName; |
042 | private boolean readUniqueId; |
044 | public User(String cn) { |
048 | public void setUsername(String username) { |
049 | this .username = username; |
052 | public void setUniqueId(String uniqueId) { |
053 | this .uniqueId = uniqueId; |
057 | public String toString() { |
058 | return MessageFormat.format( "userName:{0} - uniqueId:{1} - cn:{2}" , username, uniqueId, cn); |
062 | private final static Pattern CN_NAME_PATTERN = Pattern.compile( "User DN: (.*)$" ); |
063 | private final static Pattern UNIQUE_ID_PATTERN = Pattern.compile( "--Unique Id--:$" ); |
064 | private final static Pattern UNIQUE_ID_SPLITER = Pattern.compile( "([^:]*):([a-f0-9]{32})" ); |
065 | private final static Pattern USER_NAME_PATTERN = Pattern.compile( "sAMAccountName:$" ); |
066 | private final static Pattern VALUE_PATTERN = Pattern.compile( "\\t\\t(.*)$" ); |
067 | private final static Pattern END_PATTERN = Pattern.compile( " [-*]{81}$" ); |
069 | private User currentUser; |
071 | Map<String, User> map = new TreeMap<>(); |
073 | public void processLine(String line) { |
075 | if ((matcher = CN_NAME_PATTERN.matcher(line)).find()) { |
076 | String cn = matcher.group( 1 ); |
077 | if (!map.containsKey(cn)) { |
078 | currentUser = new User(cn); |
080 | } else if (currentUser != null ) { |
081 | if ((matcher = END_PATTERN.matcher(line)).find()) { |
082 | if (!map.containsKey(currentUser.cn)) { |
083 | map.put(currentUser.cn, currentUser); |
087 | if ((matcher = USER_NAME_PATTERN.matcher(line)).find()) { |
088 | currentUser.readUserName = true ; |
089 | } else if ((matcher = UNIQUE_ID_PATTERN.matcher(line)).find()) { |
090 | currentUser.readUniqueId = true ; |
091 | } else if (currentUser.readUserName) { |
092 | currentUser.readUserName = false ; |
093 | if ((matcher = VALUE_PATTERN.matcher(line)).find()) { |
094 | currentUser.setUsername(matcher.group( 1 )); |
096 | printWriter.println(MessageFormat.format( "#Unable to retrieve UserName for {0} : ''{1}''" , currentUser.cn, line)); |
098 | } else if (currentUser.readUniqueId) { |
099 | currentUser.readUniqueId = false ; |
100 | if ((matcher = VALUE_PATTERN.matcher(line)).find()) { |
101 | currentUser.setUniqueId(matcher.group( 1 )); |
103 | printWriter.println(MessageFormat.format( "#Unable to retrieve UniqueId for {0} : ''{1}''" , currentUser.cn, line)); |
110 | public void printTable() { |
112 | for (Entry<String, User> entry : map.entrySet()) { |
113 | printWriter.println(MessageFormat.format( "{0,number,00000} - {1}" , ++i, entry.getValue())); |
117 | private final IDfClientX clientx; |
118 | private final IDfClient client; |
119 | private IDfSessionManager sMgr; |
120 | private PrintWriter printWriter; |
122 | private CorrectLDAP() throws DfException { |
123 | this .clientx = new DfClientX(); |
124 | this .client = clientx.getLocalClient(); |
127 | public CorrectLDAP(String username, String password) throws DfException { |
129 | IDfSessionManager sMgr = client.newSessionManager(); |
130 | sMgr.setIdentity(IDfSessionManager.ALL_DOCBASES, new DfLoginInfo(username, password)); |
132 | this .printWriter = new PrintWriter(System.out); |
135 | public CorrectLDAP(IDfSessionManager sMgr, PrintWriter printWriter) throws DfException { |
138 | this .printWriter = printWriter; |
141 | public static void main(String[] args) throws IOException, DfException { |
142 | CorrectLDAP correctLDAP = new CorrectLDAP(args[ 0 ], args[ 1 ]); |
143 | correctLDAP.setUpdateLdapDN( true ); |
144 | correctLDAP.setUpdateGlobalUniqueId( true ); |
145 | correctLDAP.setUpdateDomain( false ); |
146 | correctLDAP.setLaunchUpdate( false ); |
147 | correctLDAP.correctLdap(); |
150 | public void setUpdateDomain( boolean updateDomain) { |
151 | this .updateDomain = updateDomain; |
154 | public void setUpdateGlobalUniqueId( boolean updateGlobalUniqueId) { |
155 | this .updateGlobalUniqueId = updateGlobalUniqueId; |
158 | public void setUpdateLdapDN( boolean updateLdapDN) { |
159 | this .updateLdapDN = updateLdapDN; |
162 | public void setLaunchUpdate( boolean launchUpdate) { |
163 | this .launchUpdate = launchUpdate; |
166 | private boolean updateLdapDN = true ; |
167 | private boolean updateGlobalUniqueId = true ; |
168 | private boolean updateDomain = true ; |
169 | private boolean launchUpdate = false ; |
171 | public void correctLdap() throws DfException, IOException { |
172 | IDfDocbaseMap dfDocbaseMap = client.getDocbaseMap(); |
173 | for ( int i = 0 ; i < dfDocbaseMap.getDocbaseCount(); i++) { |
174 | String repository = dfDocbaseMap.getDocbaseName(i); |
175 | correctLdap(repository); |
179 | public void correctLdap(String repository) throws DfIdentityException, DfAuthenticationException, DfPrincipalException, DfServiceException, DfException, IOException { |
180 | IDfSession dfSession = sMgr.newSession(repository); |
182 | boolean transaction = false ; |
183 | boolean noError = false ; |
185 | if (launchUpdate && !dfSession.isTransactionActive()) { |
186 | dfSession.beginTrans(); |
192 | IDfDocument dfDocument = (IDfDocument) dfSession.getObjectByQualification( "dm_document WHERE FOLDER('/Temp/Jobs/dm_LDAPSynchronization') ORDER BY r_creation_date DESC ENABLE(RETURN_TOP 1)" ); |
193 | if (dfDocument != null ) { |
194 | printWriter.println( "# *******************************" ); |
195 | printWriter.println( "# * " + repository); |
196 | printWriter.println( "# *******************************" ); |
198 | try (InputStream inputStream = dfDocument.getContent(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { |
199 | for (String line; (line = bufferedReader.readLine()) != null ;) { |
203 | boolean foundError = false ; |
204 | for (User user : map.values()) { |
205 | IDfUser dfUser = dfSession.getUser(user.username); |
206 | if (dfUser != null ) { |
208 | if (updateLdapDN && StringUtils.isNotBlank(user.cn) && !user.cn.contains( "?" ) && !dfUser.getString( "user_ldap_dn" ).equals(user.cn)) { |
209 | dql = MessageFormat.format( "UPDATE dm_user OBJECTS SET user_ldap_dn = ''{0}'' WHERE user_name = ''{1}'';" , StringUtils.replace(user.cn, "'" , "''" ), StringUtils.replace(user.username, "'" , "''" )); |
211 | if (updateGlobalUniqueId && StringUtils.isNotBlank(user.uniqueId) && !dfUser.getString( "user_global_unique_id" ).equals(user.uniqueId)) { |
212 | Matcher matcher = UNIQUE_ID_SPLITER.matcher(user.uniqueId); |
213 | if (matcher.matches()) { |
215 | if (!dfUser.getString( "user_global_unique_id" ).equals(user.uniqueId) || !dfUser.getString( "user_login_domain" ).equals(matcher.group( 2 ))) { |
216 | dql = MessageFormat.format( "UPDATE dm_user OBJECTS SET user_global_unique_id = ''{0}'', SET user_login_domain = ''{1}'' WHERE user_name = ''{2}'';" , StringUtils.replace(user.uniqueId, "'" , "''" ), StringUtils.replace(matcher.group( 1 ), "'" , "''" ), StringUtils.replace(user.username, "'" , "''" )); |
219 | if (!dfUser.getString( "user_global_unique_id" ).endsWith(matcher.group( 2 ))) { |
220 | dql = MessageFormat.format( "UPDATE dm_user OBJECTS SET user_global_unique_id = ''{0}:{1}'' WHERE user_name = ''{2}'';" , StringUtils.replace(dfUser.getString( "user_login_domain" ), "'" , "''" ), StringUtils.replace(matcher.group( 2 ), "'" , "''" ), StringUtils.replace(user.username, "'" , "''" )); |
227 | printWriter.print(dql); |
229 | new DfQuery(dql).execute(dfSession, IDfQuery.DF_EXEC_QUERY).close(); |
230 | printWriter.print( " => OK" ); |
232 | printWriter.println(); |
239 | Calendar calendar = Calendar.getInstance(); |
240 | calendar.set(Calendar.MILLISECOND, 0 ); |
241 | calendar.set(Calendar.SECOND, 0 ); |
242 | calendar.set(Calendar.MINUTE, 0 ); |
243 | calendar.set(Calendar.HOUR_OF_DAY, 0 ); |
244 | calendar.set(Calendar.DAY_OF_MONTH, 1 ); |
245 | calendar.add(Calendar.MONTH, - 1 ); |
246 | String dql = MessageFormat.format( "UPDATE dm_ldap_config OBJECTS SET a_last_run = ''{0,date,yyyyMMddHHmmss.S}Z'' WHERE a_last_run != '' '';" , calendar.getTime()); |
247 | printWriter.print(dql); |
249 | new DfQuery(dql).execute(dfSession, IDfQuery.DF_EXEC_QUERY).close(); |
250 | printWriter.print( " => OK" ); |
252 | printWriter.println(); |
255 | printWriter.println( "#=======================================================" ); |
261 | dfSession.commitTrans(); |
263 | dfSession.abortTrans(); |
268 | sMgr.release(dfSession); |
Best regards,
Huseyin OZVEREN
Related