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
select distinct user_source from dm_user; -------------- user_source -------------- LDAP inline password ''
- OS Users
select user_login_name, user_login_domain from dm_user where user_source = ' '; ------------------------------------------ user_login_name | user_login_domain ------------------------------------------ DOCUMENTUM | dmadmin | MYDCTMSERVER dm_superusers | dm_superusers_dynamic | dm_browse_all | dm_browse_all_dynamic | dm_retention_managers | dm_retention_users | ...
- LDAP Users
select user_login_name, user_login_domain from dm_user where user_source = 'LDAP'; ------------------------------------------ user_login_name | user_login_domain ------------------------------------------ myuser1 | my-ad myuser2 | my-ad myuser3 | my-ad myuser4 | my-ad myuser5 | my-ad myuser6 | my-ad ...
- Inline Password Users
select user_login_name, user_login_domain from dm_user where user_source = 'inline password'; ------------------------------------------ user_login_name | user_login_domain ------------------------------------------ mytestuser1 | mytestuser2 | dmadmin_TEST | testread | ...
Class for correction the user based on the log of dm_LDAPSynchronization job:
package com.java.lu.business.service.ecm.utils.repair;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import com.documentum.com.DfClientX;
import com.documentum.com.IDfClientX;
import com.documentum.fc.client.DfAuthenticationException;
import com.documentum.fc.client.DfIdentityException;
import com.documentum.fc.client.DfPrincipalException;
import com.documentum.fc.client.DfQuery;
import com.documentum.fc.client.DfServiceException;
import com.documentum.fc.client.IDfClient;
import com.documentum.fc.client.IDfDocbaseMap;
import com.documentum.fc.client.IDfDocument;
import com.documentum.fc.client.IDfQuery;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSessionManager;
import com.documentum.fc.client.IDfUser;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.DfLoginInfo;
public class CorrectLDAP {
private static class User {
final private String cn;
private String username;
private String uniqueId;
private boolean readUserName;
private boolean readUniqueId;
public User(String cn) {
this.cn = cn;
}
public void setUsername(String username) {
this.username = username;
}
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
@Override
public String toString() {
return MessageFormat.format("userName:{0} - uniqueId:{1} - cn:{2}", username, uniqueId, cn);
}
}
private final static Pattern CN_NAME_PATTERN = Pattern.compile("User DN: (.*)$");
private final static Pattern UNIQUE_ID_PATTERN = Pattern.compile("--Unique Id--:$");
private final static Pattern UNIQUE_ID_SPLITER = Pattern.compile("([^:]*):([a-f0-9]{32})");
private final static Pattern USER_NAME_PATTERN = Pattern.compile("sAMAccountName:$");
private final static Pattern VALUE_PATTERN = Pattern.compile("\\t\\t(.*)$");
private final static Pattern END_PATTERN = Pattern.compile(" [-*]{81}$");
private User currentUser;
Map<String, User> map = new TreeMap<>();
public void processLine(String line) {
Matcher matcher;
if ((matcher = CN_NAME_PATTERN.matcher(line)).find()) {
String cn = matcher.group(1);
if (!map.containsKey(cn)) {
currentUser = new User(cn);
}
} else if (currentUser != null) {
if ((matcher = END_PATTERN.matcher(line)).find()) {
if (!map.containsKey(currentUser.cn)) {
map.put(currentUser.cn, currentUser);
currentUser = null;
}
} else {
if ((matcher = USER_NAME_PATTERN.matcher(line)).find()) {
currentUser.readUserName = true;
} else if ((matcher = UNIQUE_ID_PATTERN.matcher(line)).find()) {
currentUser.readUniqueId = true;
} else if (currentUser.readUserName) {
currentUser.readUserName = false;
if ((matcher = VALUE_PATTERN.matcher(line)).find()) {
currentUser.setUsername(matcher.group(1));
} else {
printWriter.println(MessageFormat.format("#Unable to retrieve UserName for {0} : ''{1}''", currentUser.cn, line));
}
} else if (currentUser.readUniqueId) {
currentUser.readUniqueId = false;
if ((matcher = VALUE_PATTERN.matcher(line)).find()) {
currentUser.setUniqueId(matcher.group(1));
} else {
printWriter.println(MessageFormat.format("#Unable to retrieve UniqueId for {0} : ''{1}''", currentUser.cn, line));
}
}
}
}
}
public void printTable() {
int i = 0;
for (Entry<String, User> entry : map.entrySet()) {
printWriter.println(MessageFormat.format("{0,number,00000} - {1}", ++i, entry.getValue()));
}
}
private final IDfClientX clientx;
private final IDfClient client;
private IDfSessionManager sMgr;
private PrintWriter printWriter;
private CorrectLDAP() throws DfException {
this.clientx = new DfClientX();
this.client = clientx.getLocalClient();
}
public CorrectLDAP(String username, String password) throws DfException {
this();
IDfSessionManager sMgr = client.newSessionManager();
sMgr.setIdentity(IDfSessionManager.ALL_DOCBASES, new DfLoginInfo(username, password));
this.sMgr = sMgr;
this.printWriter = new PrintWriter(System.out);
}
public CorrectLDAP(IDfSessionManager sMgr, PrintWriter printWriter) throws DfException {
this();
this.sMgr = sMgr;
this.printWriter = printWriter;
}
public static void main(String[] args) throws IOException, DfException {
CorrectLDAP correctLDAP = new CorrectLDAP(args[0], args[1]);
correctLDAP.setUpdateLdapDN(true);
correctLDAP.setUpdateGlobalUniqueId(true);
correctLDAP.setUpdateDomain(false);
correctLDAP.setLaunchUpdate(false);
correctLDAP.correctLdap();
}
public void setUpdateDomain(boolean updateDomain) {
this.updateDomain = updateDomain;
}
public void setUpdateGlobalUniqueId(boolean updateGlobalUniqueId) {
this.updateGlobalUniqueId = updateGlobalUniqueId;
}
public void setUpdateLdapDN(boolean updateLdapDN) {
this.updateLdapDN = updateLdapDN;
}
public void setLaunchUpdate(boolean launchUpdate) {
this.launchUpdate = launchUpdate;
}
private boolean updateLdapDN = true;
private boolean updateGlobalUniqueId = true;
private boolean updateDomain = true;
private boolean launchUpdate = false;
public void correctLdap() throws DfException, IOException {
IDfDocbaseMap dfDocbaseMap = client.getDocbaseMap();
for (int i = 0; i < dfDocbaseMap.getDocbaseCount(); i++) {
String repository = dfDocbaseMap.getDocbaseName(i);
correctLdap(repository);
}
}
public void correctLdap(String repository) throws DfIdentityException, DfAuthenticationException, DfPrincipalException, DfServiceException, DfException, IOException {
IDfSession dfSession = sMgr.newSession(repository);
try {
boolean transaction = false;
boolean noError = false;
try {
if (launchUpdate && !dfSession.isTransactionActive()) {
dfSession.beginTrans();
transaction = true;
}
currentUser = null;
map.clear();
IDfDocument dfDocument = (IDfDocument) dfSession.getObjectByQualification("dm_document WHERE FOLDER('/Temp/Jobs/dm_LDAPSynchronization') ORDER BY r_creation_date DESC ENABLE(RETURN_TOP 1)");
if (dfDocument != null) {
printWriter.println("# *******************************");
printWriter.println("# * " + repository);
printWriter.println("# *******************************");
try (InputStream inputStream = dfDocument.getContent(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
for (String line; (line = bufferedReader.readLine()) != null;) {
processLine(line);
}
}
boolean foundError = false;
for (User user : map.values()) {
IDfUser dfUser = dfSession.getUser(user.username);
if (dfUser != null) {
String dql = null;
if (updateLdapDN && StringUtils.isNotBlank(user.cn) && !user.cn.contains("?") && !dfUser.getString("user_ldap_dn").equals(user.cn)) {
dql = MessageFormat.format("UPDATE dm_user OBJECTS SET user_ldap_dn = ''{0}'' WHERE user_name = ''{1}'';", StringUtils.replace(user.cn, "'", "''"), StringUtils.replace(user.username, "'", "''"));
}
if (updateGlobalUniqueId && StringUtils.isNotBlank(user.uniqueId) && !dfUser.getString("user_global_unique_id").equals(user.uniqueId)) {
Matcher matcher = UNIQUE_ID_SPLITER.matcher(user.uniqueId);
if (matcher.matches()) {
if (updateDomain) {
if (!dfUser.getString("user_global_unique_id").equals(user.uniqueId) || !dfUser.getString("user_login_domain").equals(matcher.group(2))) {
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, "'", "''"));
}
} else {
if (!dfUser.getString("user_global_unique_id").endsWith(matcher.group(2))) {
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, "'", "''"));
}
}
}
}
if (dql != null) {
foundError = true;
printWriter.print(dql);
if (launchUpdate) {
new DfQuery(dql).execute(dfSession, IDfQuery.DF_EXEC_QUERY).close();
printWriter.print(" => OK");
}
printWriter.println();
}
}
}
// relancer le LDAP à une date inférieure
if (foundError) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.MONTH, -1);
String dql = MessageFormat.format("UPDATE dm_ldap_config OBJECTS SET a_last_run = ''{0,date,yyyyMMddHHmmss.S}Z'' WHERE a_last_run != '' '';", calendar.getTime());
printWriter.print(dql);
if (launchUpdate) {
new DfQuery(dql).execute(dfSession, IDfQuery.DF_EXEC_QUERY).close();
printWriter.print(" => OK");
}
printWriter.println();
}
printWriter.println("#=======================================================");
noError = true;
}
} finally {
if (transaction) {
if (noError) {
dfSession.commitTrans();
} else {
dfSession.abortTrans();
}
}
}
} finally {
sMgr.release(dfSession);
}
}
}
Best regards,
Huseyin OZVEREN