From 0dc9ccd189682f82abd9ce1ab816213094b037db Mon Sep 17 00:00:00 2001 From: Rajani Karuturi Date: Tue, 11 Aug 2015 12:07:44 +0530 Subject: [PATCH] CLOUDSTACK-8647 added account_type to the linkDomainToLdap API --- .../api/command/LinkDomainToLdapCmd.java | 7 +++-- .../response/LinkDomainToLdapResponse.java | 30 +++++++++++++++++-- .../ldap/ADLdapUserManagerImpl.java | 8 +++-- .../cloudstack/ldap/LdapAuthenticator.java | 24 +++++++-------- .../apache/cloudstack/ldap/LdapManager.java | 2 +- .../cloudstack/ldap/LdapManagerImpl.java | 8 ++--- .../cloudstack/ldap/LdapTrustMapVO.java | 13 ++++++-- .../ldap/OpenLdapUserManagerImpl.java | 7 ++++- .../com/cloud/user/AccountManagerImpl.java | 8 +++++ setup/db/db/schema-452to460.sql | 1 + 10 files changed, 79 insertions(+), 29 deletions(-) diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java index 8601c2d2298..5a76e8ec20a 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LinkDomainToLdapCmd.java @@ -52,14 +52,17 @@ public class LinkDomainToLdapCmd extends BaseCmd { @Parameter(name = ApiConstants.ADMIN, type = CommandType.STRING, required = false, description = "domain admin username in LDAP ") private String admin; + @Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, required = true, description = "Type of the account to auto import. Specify 0 for user, 1 for root " + + "admin, and 2 for domain admin") + private short accountType; + @Inject private LdapManager _ldapManager; @Override public void execute() throws ServerApiException { - // TODO Auto-generated method stub try { - LinkDomainToLdapResponse response = _ldapManager.linkDomainToLdap(domainId, type, name); + LinkDomainToLdapResponse response = _ldapManager.linkDomainToLdap(domainId, type, name, accountType); response.setObjectName("LinkDomainToLdap"); response.setResponseName(getCommandName()); setResponseObject(response); diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LinkDomainToLdapResponse.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LinkDomainToLdapResponse.java index e548fcea1ac..103fb25e540 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LinkDomainToLdapResponse.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/response/LinkDomainToLdapResponse.java @@ -22,14 +22,12 @@ import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; -import org.apache.log4j.Logger; public class LinkDomainToLdapResponse extends BaseResponse { - public static final Logger s_logger = Logger.getLogger(LinkDomainToLdapResponse.class.getName()); @SerializedName(ApiConstants.DOMAIN_ID) @Param(description = "id of the Domain which is linked to LDAP") - private String domainId; + private long domainId; @SerializedName(ApiConstants.NAME) @Param(description = "name of the group or OU in LDAP which is linked to the domain") @@ -39,4 +37,30 @@ public class LinkDomainToLdapResponse extends BaseResponse { @Param(description = "type of the name in LDAP which is linke to the domain") private String type; + @SerializedName(ApiConstants.ACCOUNT_TYPE) + @Param(description = "Type of the account to auto import") + private short accountType; + + public LinkDomainToLdapResponse(long domainId, String type, String name, short accountType) { + this.domainId = domainId; + this.name = name; + this.type = type; + this.accountType = accountType; + } + + public long getDomainId() { + return domainId; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public short getAccountType() { + return accountType; + } } diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java index fc36267c0cf..89a278191a4 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/ADLdapUserManagerImpl.java @@ -32,7 +32,7 @@ import org.apache.log4j.Logger; public class ADLdapUserManagerImpl extends OpenLdapUserManagerImpl implements LdapUserManager { public static final Logger s_logger = Logger.getLogger(ADLdapUserManagerImpl.class.getName()); - private static final String MICROSOFT_AD_NESTED_MEMBERS_FILTER = "memberOf:1.2.840.113556.1.4.1941"; + private static final String MICROSOFT_AD_NESTED_MEMBERS_FILTER = "memberOf:1.2.840.113556.1.4.1941:"; @Override public List getUsersInGroup(String groupName, LdapContext context) throws NamingException { @@ -66,7 +66,7 @@ public class ADLdapUserManagerImpl extends OpenLdapUserManagerImpl implements Ld final StringBuilder memberOfFilter = new StringBuilder(); String groupCnName = _ldapConfiguration.getCommonNameAttribute() + "=" +groupName + "," + _ldapConfiguration.getBaseDn(); - memberOfFilter.append("(" + MICROSOFT_AD_NESTED_MEMBERS_FILTER + ":="); + memberOfFilter.append("(" + MICROSOFT_AD_NESTED_MEMBERS_FILTER + "="); memberOfFilter.append(groupCnName); memberOfFilter.append(")"); @@ -92,4 +92,8 @@ public class ADLdapUserManagerImpl extends OpenLdapUserManagerImpl implements Ld } return isDisabledUser; } + + protected String getMemberOfAttribute() { + return MICROSOFT_AD_NESTED_MEMBERS_FILTER; + } } diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java index fb1b01e2aee..a04868eca01 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java @@ -17,7 +17,6 @@ package org.apache.cloudstack.ldap; import com.cloud.server.auth.DefaultUserAuthenticator; -import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.user.User; import com.cloud.user.UserAccount; @@ -62,18 +61,16 @@ public class LdapAuthenticator extends DefaultUserAuthenticator { ActionOnFailedAuthentication action = null; if (_ldapManager.isLdapEnabled()) { + final UserAccount user = _userAccountDao.getUserAccount(username, domainId); LdapTrustMapVO ldapTrustMapVO = _ldapManager.getDomainLinkedToLdap(domainId); if(ldapTrustMapVO != null) { try { LdapUser ldapUser = _ldapManager.getUser(username, ldapTrustMapVO.getType(), ldapTrustMapVO.getName()); if(!ldapUser.isDisabled()) { result = _ldapManager.canAuthenticate(ldapUser.getPrincipal(), password); - if(result) { - final UserAccount user = _userAccountDao.getUserAccount(username, domainId); - if (user == null) { - // import user to cloudstack - createCloudStackUserAccount(ldapUser, domainId); - } + if(result && (user == null)) { + // import user to cloudstack + createCloudStackUserAccount(ldapUser, domainId, ldapTrustMapVO.getAccountType()); } } else { //disable user in cloudstack @@ -85,7 +82,6 @@ public class LdapAuthenticator extends DefaultUserAuthenticator { } else { //domain is not linked to ldap follow normal authentication - final UserAccount user = _userAccountDao.getUserAccount(username, domainId); if(user != null ) { try { LdapUser ldapUser = _ldapManager.getUser(username); @@ -99,18 +95,18 @@ public class LdapAuthenticator extends DefaultUserAuthenticator { } } } + if (!result && user != null) { + action = ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT; + } } - if (!result) { - action = ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT; - } return new Pair(result, action); } - private void createCloudStackUserAccount(LdapUser user, long domainId) { + private void createCloudStackUserAccount(LdapUser user, long domainId, short accountType) { String username = user.getUsername(); - _accountService.createUserAccount(username, "", user.getFirstname(), user.getLastname(), user.getEmail(), "GMT", username, Account.ACCOUNT_TYPE_DOMAIN_ADMIN, domainId, - username, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), User.Source.LDAP); + _accountService.createUserAccount(username, "", user.getFirstname(), user.getLastname(), user.getEmail(), null, username, accountType, domainId, username, null, + UUID.randomUUID().toString(), UUID.randomUUID().toString(), User.Source.LDAP); } private void disableUserInCloudStack(LdapUser ldapUser, long domainId) { diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java index 76d8ce05a48..97cee3d8cd6 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManager.java @@ -53,7 +53,7 @@ public interface LdapManager extends PluggableService { List searchUsers(String query) throws NoLdapUserMatchingQueryException; - LinkDomainToLdapResponse linkDomainToLdap(Long domainId, String type, String name); + LinkDomainToLdapResponse linkDomainToLdap(Long domainId, String type, String name, short accountType); public LdapTrustMapVO getDomainLinkedToLdap(long domainId); } \ No newline at end of file diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java index 9d48956e592..301fcc33653 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java @@ -264,10 +264,10 @@ public class LdapManagerImpl implements LdapManager, LdapValidator { } @Override - public LinkDomainToLdapResponse linkDomainToLdap(Long domainId, String type, String name) { - // TODO Auto-generated method stub - LdapTrustMapVO ldapTrustMapVO = _ldapTrustMapDao.persist(new LdapTrustMapVO(domainId, type, name)); - return null; + public LinkDomainToLdapResponse linkDomainToLdap(Long domainId, String type, String name, short accountType) { + LdapTrustMapVO vo = _ldapTrustMapDao.persist(new LdapTrustMapVO(domainId, type, name, accountType)); + LinkDomainToLdapResponse response = new LinkDomainToLdapResponse(vo.getDomainId(), vo.getType(), vo.getName(), vo.getAccountType()); + return response; } @Override diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapTrustMapVO.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapTrustMapVO.java index e4a9407ec6b..1356df9b43c 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapTrustMapVO.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapTrustMapVO.java @@ -45,10 +45,18 @@ public class LdapTrustMapVO implements InternalIdentity { @Column(name = "domain_id") private long domainId; - public LdapTrustMapVO(long domainId, String type, String name) { + @Column(name = "account_type") + private short accountType; + + + public LdapTrustMapVO() { + } + + public LdapTrustMapVO(long domainId, String type, String name, short accountType) { this.domainId = domainId; this.type = type; this.name = name; + this.accountType = accountType; } @Override @@ -68,6 +76,7 @@ public class LdapTrustMapVO implements InternalIdentity { return domainId; } - public LdapTrustMapVO() { + public short getAccountType() { + return accountType; } } diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java index 763f1b79ef9..0c3e0d71705 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/OpenLdapUserManagerImpl.java @@ -153,7 +153,7 @@ public class OpenLdapUserManagerImpl implements LdapUserManager { final StringBuilder memberOfFilter = new StringBuilder(); if ("GROUP".equals(type)) { - memberOfFilter.append("(memberof="); + memberOfFilter.append("(").append(getMemberOfAttribute()).append("="); memberOfFilter.append(name); memberOfFilter.append(")"); } @@ -167,6 +167,11 @@ public class OpenLdapUserManagerImpl implements LdapUserManager { return searchUser(basedn, searchQuery.toString(), context); } + + protected String getMemberOfAttribute() { + return "memberof"; + } + @Override public List getUsers(final LdapContext context) throws NamingException, IOException { return getUsers(null, context); diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index a8745bb6e72..634c2996143 100644 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -2173,6 +2173,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M if (domain != null) { domainName = domain.getName(); } + if (userAccount == null) { + _userAccountDao.getUserAccount(username, domainId); + } if (!userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString()) || !userAccount.getAccountState().equalsIgnoreCase(Account.State.enabled.toString())) { @@ -2192,6 +2195,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M s_logger.debug("Unable to authenticate user with username " + username + " in domain " + domainId); } + if (userAccount == null) { + s_logger.warn("Unable to find an user with username " + username + " in domain " + domainId); + return null; + } + if (userAccount.getState().equalsIgnoreCase(Account.State.enabled.toString())) { if (!isInternalAccount(userAccount.getId())) { // Internal accounts are not disabled diff --git a/setup/db/db/schema-452to460.sql b/setup/db/db/schema-452to460.sql index af313646bde..bf0c5c5e3ae 100644 --- a/setup/db/db/schema-452to460.sql +++ b/setup/db/db/schema-452to460.sql @@ -404,6 +404,7 @@ CREATE TABLE `cloud`.`ldap_trust_map` ( `domain_id` bigint unsigned NOT NULL, `type` varchar(10) NOT NULL, `name` varchar(255) NOT NULL, + `account_type` int(1) unsigned NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_ldap_trust_map__domain_id` (`id`), KEY `fk_ldap_trust_map__domain_id` (`domain_id`),