diff --git a/src/main/java/org/gcube/portal/ldapexport/LDAPSync.java b/src/main/java/org/gcube/portal/ldapexport/LDAPSync.java index 55d9d47..047e480 100644 --- a/src/main/java/org/gcube/portal/ldapexport/LDAPSync.java +++ b/src/main/java/org/gcube/portal/ldapexport/LDAPSync.java @@ -35,6 +35,8 @@ public class LDAPSync implements Runnable { private static final String LDAP_ORG_FILTER = "(objectClass=organizationalUnit)"; private static final String LDAP_GROUP_FILTER = "(objectClass=posixGroup)"; + private static final String USER_CONTEXT = ",ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org"; + private static final String DEFAULT_GID_NUMBER = "1000"; private String ldapUrl; private String filter; @@ -102,12 +104,13 @@ public class LDAPSync implements Runnable { try { DirContext ctx = new InitialDirContext(env); _log.debug("Initiating LDAP Sync ..."); - //update the whole list of users (uid="+username+",ou=People,o=Liferay,ou=Organizations,dc=d4science,dc=org") - exportSingleUsers(ctx, env, users); + createUsersOrganizationalUnit(ctx); //crate or update the whole list of organizations (objectClass=organizationalUnit, ou="+orgName+",dc=d4science,dc=org) and groups ( objectClass=top and POSIXGroup) + updateGroups(ctx, rootVO); - + //and update the users list + exportSingleUsers(ctx, env, users); } catch (NamingException e) { _log.error("Something went Wrong during LDAP Sync in Exporting to LDAP"); e.printStackTrace(); @@ -116,7 +119,50 @@ public class LDAPSync implements Runnable { es.printStackTrace(); } } + + /** + * create the following: ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org + * @param ctx + * @throws NamingException + */ + private void createUsersOrganizationalUnit(DirContext ctx) throws NamingException { + if (!checkIfLDAPOrganizationalUnitExists(ctx, "ou=Organizations,dc=d4science,dc=org")) { + Attributes attributes = new BasicAttributes(); + Attribute objectClass = new BasicAttribute("objectClass"); + objectClass.add("organizationalUnit"); + attributes.put(objectClass); + Attribute description = new BasicAttribute("description"); + description.add("Where to find users"); + attributes.put(description); + // private static final String USER_CONTEXT = ","; + ctx.createSubcontext("ou=Organizations,dc=d4science,dc=org", attributes); + + attributes = new BasicAttributes(); + objectClass = new BasicAttribute("objectClass"); + objectClass.add("Organization"); + attributes.put(objectClass); + description.add("Default Organization"); + ctx.createSubcontext("o=D4Science,ou=Organizations,dc=d4science,dc=org", attributes); + + attributes = new BasicAttributes(); + objectClass = new BasicAttribute("objectClass"); + objectClass.add("organizationalUnit"); + attributes.put(objectClass); + description.add("People Org Unit"); + ctx.createSubcontext("ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org", attributes); + } + else + _log.info("ou=Organizations,dc=d4science,dc=org already present, skip"); + } + + /** + * + * @param ctx + * @param root + * @throws NamingException + * @throws SystemException + */ private void updateGroups(DirContext ctx, Organization root) throws NamingException, SystemException { String subCtx = getOrgSubContext(root.getName()); if (!checkIfLDAPOrganizationalUnitExists(ctx, subCtx)) @@ -134,7 +180,14 @@ public class LDAPSync implements Runnable { } } } - + /** + * + * @param ctx + * @param vreSubCtx + * @param vre + * @throws NamingException + * @throws SystemException + */ private void updateUsersInGroup(DirContext ctx, String vreSubCtx, Organization vre) throws NamingException, SystemException { List users = UserLocalServiceUtil.getOrganizationUsers(vre.getOrganizationId()); for (User userObj : users) { @@ -206,7 +259,7 @@ public class LDAPSync implements Runnable { attributes.put(cn); Attribute gidNumber = new BasicAttribute("gidNumber"); - gidNumber.add(getRandomPOSIXidentifier(ctx)); + gidNumber.add(String.valueOf(getRandomPOSIXidentifier())); attributes.put(gidNumber); ctx.createSubcontext(subContext, attributes); @@ -262,7 +315,7 @@ public class LDAPSync implements Runnable { * @return the single user subContext */ private String getSubContext(String username) { - return "uid="+username+",ou=People,o=Liferay,ou=Organizations,dc=d4science,dc=org"; + return "uid="+username+USER_CONTEXT; } /** * @@ -297,6 +350,7 @@ public class LDAPSync implements Runnable { Attributes attributes=new BasicAttributes(); Attribute objectClass=new BasicAttribute("objectClass"); objectClass.add("inetOrgPerson"); + objectClass.add("posixAccount"); attributes.put(objectClass); //the main ldap server uses 'givenName' for the First name, 'cn' for "first name last name', 'sn' for the last name @@ -305,24 +359,43 @@ public class LDAPSync implements Runnable { Attribute sn = new BasicAttribute("sn"); Attribute mail = new BasicAttribute("mail"); Attribute userPassword = new BasicAttribute("userPassword"); + Attribute gidNumber = new BasicAttribute("gidNumber"); + Attribute homeDirectory = new BasicAttribute("homeDirectory"); + givenName.add(name); cn.add(fullName); sn.add(lastName); mail.add(email); userPassword.add(passwd); - + gidNumber.add(DEFAULT_GID_NUMBER); + homeDirectory.add("/home/"+username); + attributes.put(givenName); attributes.put(cn); attributes.put(sn); attributes.put(mail); attributes.put(userPassword); + attributes.put(gidNumber); + attributes.put(homeDirectory); + + if (checkIfLDAPUserExists(username, ctx, filter)) { //_log.debug("User " + username + " already exists, replacing attributes"); ctx.modifyAttributes(getSubContext(username), DirContext.REPLACE_ATTRIBUTE, attributes); + _log.debug("Updated attributes for already existing user with uid=" + username); } else { + int n = getRandomPOSIXidentifier(); + while (checkIfPosixUidNumberExists(ctx, n)) { + _log.info("Found collision on UidNumber="+n); + n = getRandomPOSIXidentifier(); + _log.info("Trying newone="+n); + } + Attribute uidNumber = new BasicAttribute("uidNumber"); + attributes.put(uidNumber); + uidNumber.add(String.valueOf(n)); ctx.createSubcontext(getSubContext(username),attributes); _log.debug("New User Found with uid=" + username + " created"); } @@ -350,11 +423,28 @@ public class LDAPSync implements Runnable { * * @return an integer between 1000 and 2147483647 */ - private String getRandomPOSIXidentifier(DirContext ctx) { + private int getRandomPOSIXidentifier() { final int Low = 1000; final int High = 2147483647; Random r = new Random(); int toReturn = r.nextInt(High-Low) + Low; - return toReturn+""; + return toReturn; + } + + + private boolean checkIfPosixUidNumberExists(DirContext ctx, int numberToCheck) { + SearchControls ctls = new SearchControls(); + ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); + NamingEnumeration answer; + try { + answer = ctx.search("ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org", "(uidNumber="+numberToCheck+")", ctls); + } catch (NamingException e) { + _log.info("exception"); + return false; + } + + boolean toReturn = answer.hasMoreElements(); + _log.info("return " + toReturn); + return toReturn; } }