diff --git a/src/main/java/org/olat/ldap/LDAPLoginManager.java b/src/main/java/org/olat/ldap/LDAPLoginManager.java
index 7ffac3daf83c1a548b4e78faa09957553eefbd60..e3e58f7fb55d22717b3911d9f8a807942c1e6e35 100644
--- a/src/main/java/org/olat/ldap/LDAPLoginManager.java
+++ b/src/main/java/org/olat/ldap/LDAPLoginManager.java
@@ -53,6 +53,8 @@ public interface LDAPLoginManager {
 	
 	public void syncUser(Map<String,String> olatPropertyMap, Identity identity);
 	
+	public void syncUserGroups(Identity identity);
+	
 	public void deletIdentities(List<Identity> identityList);
 
 	public boolean doBatchSync(LDAPError errors, boolean full);
diff --git a/src/main/java/org/olat/ldap/manager/LDAPDAO.java b/src/main/java/org/olat/ldap/manager/LDAPDAO.java
index 07429db9d2512fd2233b1f7db55ee1485ae76c0b..9c1e9390a073ebd22039bc0ef63e6e9ab88c75e2 100644
--- a/src/main/java/org/olat/ldap/manager/LDAPDAO.java
+++ b/src/main/java/org/olat/ldap/manager/LDAPDAO.java
@@ -30,6 +30,7 @@ import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.SizeLimitExceededException;
 import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
@@ -38,8 +39,6 @@ import javax.naming.ldap.LdapContext;
 import javax.naming.ldap.PagedResultsControl;
 import javax.naming.ldap.PagedResultsResponseControl;
 
-import net.fortuna.ical4j.util.TimeZones;
-
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
@@ -51,6 +50,8 @@ import org.olat.ldap.model.LDAPUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import net.fortuna.ical4j.util.TimeZones;
+
 /**
  * 
  * Initial date: 24.11.2014<br>
@@ -90,6 +91,30 @@ public class LDAPDAO {
 		return ldapGroups;
 	}
 	
+	public List<LDAPGroup> searchGroups(LdapContext ctx, List<String> groupDNs, String filter) {
+		final List<LDAPGroup> ldapGroups = new ArrayList<>();
+		String[] groupAttributes = new String[]{ "cn" };
+		for(String groupDN:groupDNs) {
+			LDAPVisitor visitor = new LDAPVisitor() {
+				@Override
+				public void visit(SearchResult searchResult) throws NamingException {
+					Attributes resAttributes = searchResult.getAttributes();
+					Attribute cnAttr = resAttributes.get("cn");
+
+					Object cn = cnAttr.get();
+					if(cn instanceof String) {
+						LDAPGroup group = new LDAPGroup();
+						group.setCommonName((String)cn);
+						ldapGroups.add(group);
+					}
+				}
+				
+			};
+			search(visitor, groupDN, filter, groupAttributes, ctx);
+		}
+		return ldapGroups;
+	}
+	
 	public void search(LDAPVisitor visitor, String ldapBase, String filter, String[] returningAttrs, LdapContext ctx) {
 		SearchControls ctls = new SearchControls();
 		ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
@@ -217,7 +242,7 @@ public class LDAPDAO {
 		return userDN;
 	}
 	
-	private String buildSearchUserFilter(String attribute, String uid) {
+	protected String buildSearchUserFilter(String attribute, String uid) {
 		String ldapUserFilter = syncConfiguration.getLdapUserFilter();
 		StringBuilder filter = new StringBuilder();
 		if (ldapUserFilter != null) {
diff --git a/src/main/java/org/olat/ldap/manager/LDAPLoginManagerImpl.java b/src/main/java/org/olat/ldap/manager/LDAPLoginManagerImpl.java
index d4d4c7cfbad6e1bf476e143a9321ba433637a2c9..b0995f1e2d1f59e843d40bdc459f3a3fbea17d8e 100644
--- a/src/main/java/org/olat/ldap/manager/LDAPLoginManagerImpl.java
+++ b/src/main/java/org/olat/ldap/manager/LDAPLoginManagerImpl.java
@@ -40,6 +40,7 @@ import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.Control;
 import javax.naming.ldap.InitialLdapContext;
@@ -640,6 +641,89 @@ public class LDAPLoginManagerImpl implements LDAPLoginManager, GenericEventListe
 		}
 	}
 
+	/**
+	 * The method search in LDAP the user, search the groups
+	 * of which it is member of, and sync the groups.
+	 * 
+	 * @param identity The identity to sync
+	 */
+	@Override
+	public void syncUserGroups(Identity identity) {	
+		LdapContext ctx = bindSystem();
+		if (ctx == null) {
+			log.error("could not bind to ldap", null);
+		}
+			
+		String ldapUserIDAttribute = syncConfiguration.getOlatPropertyToLdapAttribute(LDAPConstants.LDAP_USER_IDENTIFYER);
+		String filter = ldapDao.buildSearchUserFilter(ldapUserIDAttribute, identity.getName());
+
+		boolean withCoacheOfGroups = StringHelper.containsNonWhitespace(syncConfiguration.getCoachedGroupAttribute());
+		List<String> ldapBases = syncConfiguration.getLdapBases();
+		String[] searchAttr;
+		if(withCoacheOfGroups) {
+			searchAttr = new String[]{ "dn", syncConfiguration.getCoachedGroupAttribute() };
+		} else {
+			searchAttr = new String[]{ "dn" };
+		}
+
+		SearchControls ctls = new SearchControls();
+		ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+		ctls.setReturningAttributes(searchAttr);
+
+		String userDN = null;
+		List<String> groupList = null;
+		for (String ldapBase : ldapBases) {
+			try {
+				NamingEnumeration<SearchResult> enm = ctx.search(ldapBase, filter, ctls);
+				while (enm.hasMore()) {
+					SearchResult result = enm.next();
+					userDN = result.getNameInNamespace();
+					
+					if(withCoacheOfGroups) {
+						Attributes resAttributes = result.getAttributes();
+						Attribute coachOfGroupsAttr = resAttributes.get(syncConfiguration.getCoachedGroupAttribute());
+						if(coachOfGroupsAttr != null && coachOfGroupsAttr.get() instanceof String) {
+							String groupString = (String)coachOfGroupsAttr.get();
+							if(!"-".equals(groupString)) {
+								String[] groupArr = groupString.split(syncConfiguration.getCoachedGroupAttributeSeparator());
+								groupList = new ArrayList<>(groupArr.length);
+								for(String group:groupArr) {
+									groupList.add(group);
+								}
+							}
+						}
+					}
+				}
+				if (userDN != null) {
+					break;
+				}
+			} catch (NamingException e) {
+				log.error("NamingException when trying to bind user with username::" + identity.getName() + " on ldapBase::" + ldapBase, e);
+			}
+		}
+
+		// get the potential groups
+		if(userDN != null) {
+			List<String> groupDNs = syncConfiguration.getLdapGroupBases();
+			String groupFilter = "(&(objectClass=groupOfNames)(member=" + userDN + "))";
+			List<LDAPGroup> groups = ldapDao.searchGroups(ctx, groupDNs, groupFilter);
+			for(LDAPGroup group:groups) {
+				BusinessGroup managedGroup = getManagerBusinessGroup(group.getCommonName());
+				if(managedGroup != null) {
+					List<String> roles = businessGroupRelationDao.getRoles(identity, managedGroup);
+					if(roles.isEmpty()) {
+						boolean coach = groupList != null && groupList.contains(group.getCommonName());
+						if(coach) {
+							businessGroupRelationDao.addRole(identity, managedGroup, GroupRoles.coach.name());
+						} else {
+							businessGroupRelationDao.addRole(identity, managedGroup, GroupRoles.participant.name());
+						}
+					}
+				}
+			}
+		}
+	}
+
 	/**
 	 * Searches for Identity in OLAT.
 	 * 
diff --git a/src/main/java/org/olat/ldap/ui/LDAPGroupsLoginInterceptor.java b/src/main/java/org/olat/ldap/ui/LDAPGroupsLoginInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4c5aebba62739e0aecec7949b5e9f01758a9045
--- /dev/null
+++ b/src/main/java/org/olat/ldap/ui/LDAPGroupsLoginInterceptor.java
@@ -0,0 +1,77 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.ldap.ui;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.ldap.LDAPLoginManager;
+import org.olat.ldap.LDAPLoginModule;
+import org.olat.login.SupportsAfterLoginInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 18 juil. 2017<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class LDAPGroupsLoginInterceptor extends FormBasicController implements SupportsAfterLoginInterceptor {
+	
+	@Autowired
+	private LDAPLoginModule ldapModule;
+	@Autowired
+	private LDAPLoginManager ldapManager;
+	
+	public LDAPGroupsLoginInterceptor(UserRequest ureq, WindowControl wControl) {
+		super(ureq, wControl);
+		
+		initForm(ureq);
+	}
+
+	@Override
+	public boolean isUserInteractionRequired(UserRequest ureq) {
+		if(ldapModule.isLDAPEnabled()) {
+			try {
+				ldapManager.syncUserGroups(getIdentity());
+			} catch (Exception e) {
+				logError("Cannot sync LDAP groups", e);
+			}
+		}
+		return false;
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		//
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		//
+	}
+
+	@Override
+	protected void doDispose() {
+		//
+	}
+}