CLOUDSTACK-1172: LDAP enhancements

This commit is contained in:
Abhinandan Prateek 2013-02-19 15:36:39 +05:30
parent c94a75c0a6
commit f2b97db0f9
6 changed files with 99 additions and 17 deletions

View File

@ -264,6 +264,8 @@ public interface ConfigurationService {
boolean removeLDAP(LDAPRemoveCmd cmd);
LDAPConfigCmd listLDAPConfig(LDAPConfigCmd cmd);
/**
* @param offering
* @return

View File

@ -31,6 +31,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
@APICommand(name = "ldapConfig", description="Configure the LDAP context for this site.", responseObject=LDAPConfigResponse.class, since="3.0.0")
@ -43,7 +44,10 @@ public class LDAPConfigCmd extends BaseCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.HOST_NAME, type=CommandType.STRING, required=true, description="Hostname or ip address of the ldap server eg: my.ldap.com")
@Parameter(name=ApiConstants.LIST_ALL, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com")
private String listall;
@Parameter(name=ApiConstants.HOST_NAME, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com")
private String hostname;
@Parameter(name=ApiConstants.PORT, type=CommandType.INTEGER, description="Specify the LDAP port if required, default is 389.")
@ -52,10 +56,10 @@ public class LDAPConfigCmd extends BaseCmd {
@Parameter(name=ApiConstants.USE_SSL, type=CommandType.BOOLEAN, description="Check Use SSL if the external LDAP server is configured for LDAP over SSL.")
private Boolean useSSL;
@Parameter(name=ApiConstants.SEARCH_BASE, type=CommandType.STRING, required=true, description="The search base defines the starting point for the search in the directory tree Example: dc=cloud,dc=com.")
@Parameter(name=ApiConstants.SEARCH_BASE, type=CommandType.STRING, description="The search base defines the starting point for the search in the directory tree Example: dc=cloud,dc=com.")
private String searchBase;
@Parameter(name=ApiConstants.QUERY_FILTER, type=CommandType.STRING, required=true, description="You specify a query filter here, which narrows down the users, who can be part of this domain.")
@Parameter(name=ApiConstants.QUERY_FILTER, type=CommandType.STRING, description="You specify a query filter here, which narrows down the users, who can be part of this domain.")
private String queryFilter;
@Parameter(name=ApiConstants.BIND_DN, type=CommandType.STRING, description="Specify the distinguished name of a user with the search permission on the directory.")
@ -74,6 +78,10 @@ public class LDAPConfigCmd extends BaseCmd {
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getListAll() {
return listall == null ? "false" : listall;
}
public String getBindPassword() {
return bindPassword;
}
@ -82,30 +90,56 @@ public class LDAPConfigCmd extends BaseCmd {
return bindDN;
}
public void setBindDN(String bdn) {
this.bindDN=bdn;
}
public String getQueryFilter() {
return queryFilter;
}
public void setQueryFilter(String queryFilter) {
this.queryFilter=queryFilter;
}
public String getSearchBase() {
return searchBase;
}
public void setSearchBase(String searchBase) {
this.searchBase=searchBase;
}
public Boolean getUseSSL() {
return useSSL == null ? Boolean.FALSE : Boolean.TRUE;
return useSSL == null ? Boolean.FALSE : useSSL;
}
public void setUseSSL(Boolean useSSL) {
this.useSSL=useSSL;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname=hostname;
}
public Integer getPort() {
return port <= 0 ? 389 : port;
}
public void setPort(Integer port) {
this.port=port;
}
public String getTrustStore() {
return trustStore;
}
public void setTrustStore(String trustStore) {
this.trustStore=trustStore;
}
public String getTrustStorePassword() {
return trustStorePassword;
@ -122,12 +156,25 @@ public class LDAPConfigCmd extends BaseCmd {
InsufficientCapacityException, ServerApiException,
ConcurrentOperationException, ResourceAllocationException {
try {
boolean result = _configService.updateLDAP(this);
if (result){
LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(getHostname(), getPort(), getUseSSL(), getQueryFilter(), getSearchBase(), getBindDN());
if ("true".equalsIgnoreCase(getListAll())){
// return the existing conf
LDAPConfigCmd cmd = _configService.listLDAPConfig(this);
LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(),
cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN());
lr.setResponseName(getCommandName());
this.setResponseObject(lr);
}
else if (getHostname()==null || getSearchBase() == null || getQueryFilter() == null) {
throw new InvalidParameterValueException("You need to provide hostname, serachbase and queryfilter to configure your LDAP server");
}
else {
boolean result = _configService.updateLDAP(this);
if (result){
LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(getHostname(), getPort(), getUseSSL(), getQueryFilter(), getSearchBase(), getBindDN());
lr.setResponseName(getCommandName());
this.setResponseObject(lr);
}
}
}
catch (NamingException ne){
ne.printStackTrace();

View File

@ -30,7 +30,7 @@ public class LDAPConfigResponse extends BaseResponse {
@SerializedName(ApiConstants.PORT) @Param(description="Specify the LDAP port if required, default is 389")
private String port;
@SerializedName(ApiConstants.PORT) @Param(description="Check Use SSL if the external LDAP server is configured for LDAP over SSL")
@SerializedName(ApiConstants.USE_SSL) @Param(description="Check Use SSL if the external LDAP server is configured for LDAP over SSL")
private String useSSL;
@SerializedName(ApiConstants.SEARCH_BASE) @Param(description="The search base defines the starting point for the search in the directory tree Example: dc=cloud,dc=com")

View File

@ -66,7 +66,7 @@ public class LDAPUserAuthenticator extends DefaultUserAuthenticator {
String port = _configDao.getValue(LDAPParams.port.toString());
String queryFilter = _configDao.getValue(LDAPParams.queryfilter.toString());
String searchBase = _configDao.getValue(LDAPParams.searchbase.toString());
String useSSL = _configDao.getValue(LDAPParams.usessl.toString());
Boolean useSSL = Boolean.valueOf(_configDao.getValue(LDAPParams.usessl.toString()));
String bindDN = _configDao.getValue(LDAPParams.dn.toString());
String bindPasswd = _configDao.getValue(LDAPParams.passwd.toString());
String trustStore = _configDao.getValue(LDAPParams.truststore.toString());
@ -77,7 +77,7 @@ public class LDAPUserAuthenticator extends DefaultUserAuthenticator {
Hashtable<String, String> env = new Hashtable<String, String>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
String protocol = "ldap://" ;
if (new Boolean(useSSL)){
if (useSSL){
env.put(Context.SECURITY_PROTOCOL, "ssl");
protocol="ldaps://" ;
System.setProperty("javax.net.ssl.trustStore", trustStore);
@ -123,7 +123,7 @@ public class LDAPUserAuthenticator extends DefaultUserAuthenticator {
env = new Hashtable<String, String>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
protocol = "ldap://" ;
if (new Boolean(useSSL)){
if (useSSL){
env.put(Context.SECURITY_PROTOCOL, "ssl");
protocol="ldaps://" ;
}
@ -135,8 +135,7 @@ public class LDAPUserAuthenticator extends DefaultUserAuthenticator {
ctx.close();
} catch (NamingException ne) {
ne.printStackTrace();
s_logger.warn("Authentication failed due to " + ne.getMessage());
s_logger.warn("Authentication Failed ! " + ne.getMessage() + (ne.getCause() != null ? ("; Caused by:" + ne.getCause().getMessage()) : ""));
return false;
}
catch (Exception e){

View File

@ -1246,6 +1246,27 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
return true;
}
@Override
@DB
public LDAPConfigCmd listLDAPConfig(LDAPConfigCmd cmd) {
String hostname = _configDao.getValue(LDAPParams.hostname.toString());
cmd.setHostname(hostname == null ? "" : hostname);
String port = _configDao.getValue(LDAPParams.port.toString());
cmd.setPort(port == null ? 0 : Integer.valueOf(port));
String queryFilter = _configDao.getValue(LDAPParams.queryfilter.toString());
cmd.setQueryFilter(queryFilter == null ? "" : queryFilter);
String searchBase = _configDao.getValue(LDAPParams.searchbase.toString());
cmd.setSearchBase(searchBase == null ? "" : searchBase);
String useSSL = _configDao.getValue(LDAPParams.usessl.toString());
cmd.setUseSSL(useSSL == null ? Boolean.FALSE : Boolean.valueOf(useSSL));
String binddn = _configDao.getValue(LDAPParams.dn.toString());
cmd.setBindDN(binddn == null ? "" : binddn);
String truststore = _configDao.getValue(LDAPParams.truststore.toString());
cmd.setTrustStore(truststore == null ? "" : truststore);
return cmd;
}
@Override
@DB
public boolean updateLDAP(LDAPConfigCmd cmd) {
@ -1265,11 +1286,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
throw new InvalidParameterValueException("If you specify a bind name then you need to provide bind password too.");
}
// check query filter if it contains valid substitution
if (!queryFilter.contains("%u") && !queryFilter.contains("%n") && !queryFilter.contains("%e")){
throw new InvalidParameterValueException("QueryFilter should contain at least one of the substitutions: %u, %n or %e: " + queryFilter);
}
// check if the info is correct
Hashtable<String, String> env = new Hashtable<String, String>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
String protocol = "ldap://";
if (new Boolean(useSSL)) {
if (useSSL) {
env.put(Context.SECURITY_PROTOCOL, "ssl");
protocol = "ldaps://";
if (trustStore == null || trustStorePassword == null) {
@ -1288,7 +1314,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
DirContext ctx = new InitialDirContext(env);
ctx.close();
// store the result in DB COnfiguration
// store the result in DB Configuration
ConfigurationVO cvo = _configDao.findByName(LDAPParams.hostname.toString());
if (cvo == null) {
cvo = new ConfigurationVO("Hidden", "DEFAULT", "management-server", LDAPParams.hostname.toString(), null, "Hostname or ip address of the ldap server eg: my.ldap.com");
@ -1356,8 +1382,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
s_logger.debug("The ldap server is configured: " + hostname);
} catch (NamingException ne) {
ne.printStackTrace();
throw new InvalidParameterValueException("Naming Exception, check you ldap data ! " + ne.getMessage() + (ne.getCause() != null ? ("Caused by:" + ne.getCause().getMessage()) : ""));
throw new InvalidParameterValueException("Naming Exception, check you ldap data ! " + ne.getMessage() + (ne.getCause() != null ? ("; Caused by:" + ne.getCause().getMessage()) : ""));
}
return true;
}

View File

@ -365,6 +365,15 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
return false;
}
/* (non-Javadoc)
* @see com.cloud.configuration.ConfigurationService#listLDAPConfig(org.apache.cloudstack.api.commands.LDAPConfigCmd)
*/
@Override
public LDAPConfigCmd listLDAPConfig(LDAPConfigCmd cmd) {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see com.cloud.configuration.ConfigurationService#isOfferingForVpc(com.cloud.offering.NetworkOffering)
*/