// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package com.netscape.cmscore.authentication; import netscape.ldap.LDAPConnection; import netscape.ldap.LDAPEntry; import netscape.ldap.LDAPException; import netscape.ldap.LDAPSearchResults; import netscape.ldap.LDAPv2; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.authentication.AuthToken; import com.netscape.certsrv.authentication.EInvalidCredentials; import com.netscape.certsrv.authentication.EMissingCredential; import com.netscape.certsrv.authentication.IAuthCredentials; import com.netscape.certsrv.authentication.IAuthManager; import com.netscape.certsrv.authentication.IAuthToken; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.ldap.ELdapException; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.usrgrp.IUser; import com.netscape.cmscore.dbs.DBSubsystem; import com.netscape.cmscore.ldapconn.LdapAnonConnFactory; import com.netscape.cmscore.ldapconn.LdapBoundConnFactory; import com.netscape.cmscore.ldapconn.LdapConnInfo; import com.netscape.cmscore.usrgrp.UGSubsystem; import com.netscape.cmscore.util.Debug; /** * Certificate Server admin authentication. * Used to authenticate administrators in the Certificate Server Console. * Authentications by checking the uid and password against the * database. *
* * @author lhsiao, cfu * @version $Revision$, $Date$ */ public class PasswdUserDBAuthentication implements IAuthManager { /* required credentials. uid, pwd are strings */ public static final String CRED_UID = "uid"; public static final String CRED_PWD = "pwd"; protected static String[] mRequiredCred = { CRED_UID, CRED_PWD }; /* attribute in returned token */ public static final String TOKEN_USERDN = "userdn"; public static final String TOKEN_USERID = "userid"; /* configuration params to pass to console (none) */ protected static String[] mConfigParams = null; private String mName = null; private String mImplName = null; private IConfigStore mConfig; private String mBaseDN = null; private LdapBoundConnFactory mConnFactory = null; private LdapAnonConnFactory mAnonConnFactory = null; private ILogger mLogger = CMS.getLogger(); public PasswdUserDBAuthentication() { } /** * initializes the PasswdUserDBAuthentication auth manager *
* called by AuthSubsystem init() method, when initializing all available authentication managers. * * @param name - Name assigned to this authentication manager instance. * @param implName - Name of the authentication plugin. * @param config - The configuration store used by the * authentication subsystem. */ public void init(String name, String implName, IConfigStore config) throws EBaseException { mName = name; mImplName = implName; mConfig = config; /* internal database directory used */ DBSubsystem dbs = (DBSubsystem) DBSubsystem.getInstance(); LdapConnInfo ldapinfo = dbs.getLdapConnInfo(); if (ldapinfo == null && CMS.isPreOpMode()) return; mBaseDN = dbs.getBaseDN(); mConnFactory = new LdapBoundConnFactory(3, 20, ldapinfo, dbs.getLdapAuthInfo()); mAnonConnFactory = new LdapAnonConnFactory(3, 20, ldapinfo); log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_INIT_AUTH", mName)); } /** * authenticates administratrators by LDAP uid/pwd *
* called by other subsystems or their servlets to authenticate administrators
*
* @param authCred Authentication credentials.
* "uid" and "pwd" are required.
* @return the authentication token (authToken) that contains the following
* userdn = [userdn, in case of success]
* authMgrName = [authMgrName]
* @exception com.netscape.certsrv.base.MissingCredential If either
* "uid" or "pwd" is missing from the given credentials.
* @exception com.netscape.certsrv.base.InvalidCredentials If the
* the credentials failed to authenticate.
* @exception com.netscape.certsrv.base.EBaseException If an internal
* error occurred.
*/
public IAuthToken authenticate(IAuthCredentials authCred)
throws EMissingCredential, EInvalidCredentials, EBaseException {
AuthToken authToken = new AuthToken(this);
// make sure the required credentials are provided
String uid = (String) authCred.get(CRED_UID);
CMS.debug("Authentication: UID=" + uid);
if (uid == null) {
log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_MISSING_UID"));
throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_UID));
}
String pwd = (String) authCred.get(CRED_PWD);
if (pwd == null) {
log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_NULL_PW", uid));
throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_PWD));
}
// don't allow anonymous binding
if (pwd == "") {
log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_EMPTY_PW", uid));
throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
}
String userdn = null;
LDAPConnection conn = null;
LDAPConnection anonConn = null;
try {
conn = mConnFactory.getConn();
// do anonymous search for the user's dn.
LDAPSearchResults res = conn.search(mBaseDN,
LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false);
if (res.hasMoreElements()) {
LDAPEntry entry = (LDAPEntry) res.nextElement();
userdn = entry.getDN();
}
if (userdn == null) {
log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_NOT_FOUND", uid));
throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
}
anonConn = mAnonConnFactory.getConn();
anonConn.authenticate(userdn, pwd);
} catch (LDAPException e) {
log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_AUTH_FAILED", uid, e.toString()));
throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
} finally {
if (conn != null)
mConnFactory.returnConn(conn);
if (anonConn != null)
mAnonConnFactory.returnConn(anonConn);
}
UGSubsystem ug = UGSubsystem.getInstance();
authToken.set(TOKEN_USERDN, userdn);
authToken.set(CRED_UID, uid); // return original uid for info
IUser user = null;
try {
user = ug.getUser(uid);
} catch (EBaseException e) {
if (Debug.ON)
e.printStackTrace();
// not a user in our user/group database.
log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_UID_NOT_FOUND", uid, e.toString()));
throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + " " + e.getMessage());
}
if (user == null) {
throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR",
"Failure in User Group subsystem."));
}
authToken.set(TOKEN_USERDN, user.getUserDN());
authToken.set(TOKEN_USERID, user.getUserID());
log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_AUTHENTICATED", uid));
return authToken;
}
/**
* gets the name of this authentication manager instance
*/
public String getName() {
return mName;
}
/**
* gets the name of the authentication manager plugin
*/
public String getImplName() {
return mImplName;
}
/**
* get the list of authentication credential attribute names
* required by this authentication manager. Generally used by
* servlets that use this authentication manager, to retrieve
* required credentials from the user (e.g. Javascript form data)
*
* @return attribute names in Vector
*/
public String[] getRequiredCreds() {
return (mRequiredCred);
}
/**
* Get the list of configuration parameter names
* required by this authentication manager. In this case, an empty list.
*
* @return String array of configuration parameters.
*/
public String[] getConfigParams() {
return (mConfigParams);
}
/**
* disconnects the member connection
*/
public void shutdown() {
try {
// disconnect all outstanding connections in the factory
if (mConnFactory != null) mConnFactory.reset();
} catch (ELdapException e) {
log(ILogger.LL_FAILURE, e.toString());
}
}
/**
* gets the configuretion substore used by this authentication
* manager
*
* @return configuration store
*/
public IConfigStore getConfigStore() {
return mConfig;
}
/**
* Log a message.
*
* @param level The logging level.
* @param msg The message to log.
*/
private void log(int level, String msg) {
if (mLogger == null)
return;
mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION,
level, msg);
}
}