rana_b 2002/10/10 09:01:19
Modified: ftpserver/src/java/org/apache/avalon/ftpserver/usermanager
LdapUserManager.java
Log:
LDAP user manager refactored
Revision Changes Path
1.9 +117 -85
jakarta-avalon-apps/ftpserver/src/java/org/apache/avalon/ftpserver/usermanager/LdapUserManager.java
Index: LdapUserManager.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-apps/ftpserver/src/java/org/apache/avalon/ftpserver/usermanager/LdapUserManager.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- LdapUserManager.java 22 May 2002 20:41:36 -0000 1.8
+++ LdapUserManager.java 10 Oct 2002 16:01:19 -0000 1.9
@@ -1,3 +1,4 @@
+//$Id$
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
@@ -27,18 +28,52 @@
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.ftpserver.util.StringUtils;
/**
* Ldap based user manager class. Tested using Netscape Directory Server 4.1.
* The LDAP requires the password to be nonempty for simple authentication. So
* instead of using empty string password (""), we will be using single space (" ").
+ * <br>
+ * The required LDAP attribute types:
+ * <ul>
+ * <li>memberuid</li>
+ * <li>uid</li>
+ * <li>cn</li>
+ * <li>sn</li>
+ * <li>userpassword</li>
+ * <li>objectclass</li>
+ * <li>enableflag (created by ftp-db.ldif file)</li>
+ * <li>homedirectory</li>
+ * <li>writepermission (created by ftp-db.ldif file)</li>
+ * <li>idletime (created by ftp-db.ldif file)</li>
+ * <li>uploadrate (created by ftp-db.ldif file)</li>
+ * <li>downloadrate (created by ftp-db.ldif file)</li>
+ * </ul>
+ *
+ * Some of the above mentioned attribute types are created by ftd-db.ldif schema
file.
+ * The schema file also creates an object class called ftpUsers derived from
+ * inetOrgPerson and have all these attributes.<br>
+ * Assumed LDAP objectclass hierarchy:<br>
+ * <pre>
+ * top
+ * |
+ * person
+ * |
+ * organizationalPerson
+ * |
+ * inetOrgPerson
+ * |
+ * ftpUsers
+ * </pre>
*
* @phoenix:block
* @phoenix:service
name="org.apache.avalon.ftpserver.usermanager.UserManagerInterface"
*
* @author <a href="mailto:[EMAIL PROTECTED]">Rana Bhattacharyya</a>
*/
-public class LdapUserManager extends AbstractUserManager {
+public
+class LdapUserManager extends AbstractUserManager {
// LDAP attributes
@@ -56,8 +91,7 @@
private static final String DOWN_RATE = "downloadrate";
private static final String[] ALL_ATTRS = {
- CN,
- LOGIN,
+ UID,
ENABLE,
ROOT_DIR,
WRITE_PERM,
@@ -66,14 +100,20 @@
DOWN_RATE
};
- private static final Attribute OBJCLASS_ATTR = new BasicAttribute(OBJ_CLASS,
true);
+ private final static String[] UID_ATTRS = {
+ UID
+ };
// Currently we are using only one connection.
- // This will be replaced by LDAP connection pool.
+ // So all the methods are synchronized.
private DirContext mAdminContext;
private Properties mAdminEnv;
- private String mstLdapRoot;
+ private String mstRoot;
+ private String mstDnPrefix;
+ private String mstDnSuffix;
+ private Attribute mObjClassAttr;
+
/**
* Default constructor
@@ -91,11 +131,14 @@
// get ldap parameters
String url = conf.getChild("url").getValue();
- String ldapRoot = conf.getChild("root").getValue();
String admin = conf.getChild("admin").getValue();
String password = conf.getChild("password").getValue();
String auth = conf.getChild("authentication").getValue();
+ String ldapRoot = conf.getChild("root").getValue();
+ String prefix = conf.getChild("prefix").getValue();
+ String suffix = conf.getChild("suffix").getValue();
+
try {
mAdminEnv = new Properties();
mAdminEnv.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
@@ -103,55 +146,46 @@
mAdminEnv.setProperty(Context.SECURITY_AUTHENTICATION, auth);
mAdminEnv.setProperty(Context.SECURITY_PRINCIPAL, admin);
mAdminEnv.setProperty(Context.SECURITY_CREDENTIALS, password);
-
mAdminContext = new InitialDirContext(mAdminEnv);
- mstLdapRoot = ldapRoot;
+
+ mstRoot = ldapRoot;
+ mstDnPrefix = prefix;
+ mstDnSuffix = suffix;
+
+ // create objectClass attribute
+ mObjClassAttr = new BasicAttribute(OBJ_CLASS, false);
+ mObjClassAttr.add("ftpUsers");
+ mObjClassAttr.add("inetOrgPerson");
+ mObjClassAttr.add("organizationalPerson");
+ mObjClassAttr.add("person");
+ mObjClassAttr.add("top");
+
getLogger().info("LDAP user manager opened.");
}
catch(NamingException ex) {
- getLogger().error(ex.getMessage(), ex);
- throw new ConfigurationException(ex.getMessage(), ex);
- }
- }
-
-
- /**
- * Get common name
- */
- private synchronized String getCommonName(String login) throws NamingException {
- Attributes matchAttrs = new BasicAttributes(true);
- matchAttrs.put(new BasicAttribute(LOGIN, login));
- matchAttrs.put(OBJCLASS_ATTR);
- NamingEnumeration answers = mAdminContext.search("ou=people," +
mstLdapRoot, matchAttrs, ALL_ATTRS);
-
- String cn = null;
- if (answers.hasMore()) {
- SearchResult sr = (SearchResult)answers.next();
- cn = sr.getAttributes().get(CN).get().toString();
+ throw new ConfigurationException("LdapUserManager.configure()", ex);
}
- answers.close();
- return cn;
}
/**
- * Get all user names
+ * Get all user names.
*/
public synchronized List getAllUserNames() {
ArrayList allUsers = new ArrayList();
try {
Attributes matchAttrs = new BasicAttributes(true);
- matchAttrs.put(OBJCLASS_ATTR);
- NamingEnumeration answers = mAdminContext.search("ou=people," +
mstLdapRoot, matchAttrs, ALL_ATTRS);
+ matchAttrs.put(mObjClassAttr);
+ NamingEnumeration answers = mAdminContext.search(mstRoot, matchAttrs,
UID_ATTRS);
while (answers.hasMore()) {
SearchResult sr = (SearchResult)answers.next();
- String login = sr.getAttributes().get(LOGIN).get().toString();
- allUsers.add(login);
+ String uid = sr.getAttributes().get(UID).get().toString();
+ allUsers.add(uid);
}
}
- catch(NamingException ex) {
- getLogger().error(ex.getMessage(), ex);
+ catch(Exception ex) {
+ getLogger().error("LdapUserManager.getAllUserNames()", ex);
}
Collections.sort(allUsers);
@@ -166,27 +200,20 @@
User user = null;
try {
- Attributes matchAttrs = new BasicAttributes(true);
- matchAttrs.put(new BasicAttribute(LOGIN, name));
- matchAttrs.put(OBJCLASS_ATTR);
- NamingEnumeration answers = mAdminContext.search("ou=people," +
mstLdapRoot, matchAttrs, ALL_ATTRS);
- if (answers.hasMore()) {
- SearchResult sr = (SearchResult)answers.next();
- Attributes attrs = sr.getAttributes();
+ String dn = getDN(name);
+ Attributes attrs = mAdminContext.getAttributes(dn, ALL_ATTRS);
- user = new User();
- user.setName(attrs.get(LOGIN).get().toString());
- user.getVirtualDirectory().setRootDirectory(new
File(attrs.get(ROOT_DIR).get().toString()));
-
user.setEnabled(Boolean.TRUE.toString().equals(attrs.get(ENABLE).get().toString()));
-
user.getVirtualDirectory().setWritePermission(Boolean.TRUE.toString().equals(attrs.get(WRITE_PERM).get().toString()));
- user.setMaxIdleTime(
Integer.parseInt(attrs.get(IDLE_TIME).get().toString()) );
- user.setMaxUploadRate(
Integer.parseInt(attrs.get(UP_RATE).get().toString()) );
- user.setMaxDownloadRate(
Integer.parseInt(attrs.get(DOWN_RATE).get().toString()) );
- }
- answers.close();
+ user = new User();
+ user.setName(attrs.get(UID).get().toString());
+ user.getVirtualDirectory().setRootDirectory(new
File(attrs.get(ROOT_DIR).get().toString()));
+
user.setEnabled(Boolean.TRUE.toString().equals(attrs.get(ENABLE).get().toString()));
+
user.getVirtualDirectory().setWritePermission(Boolean.TRUE.toString().equals(attrs.get(WRITE_PERM).get().toString()));
+ user.setMaxIdleTime(
Integer.parseInt(attrs.get(IDLE_TIME).get().toString()) );
+ user.setMaxUploadRate(
Integer.parseInt(attrs.get(UP_RATE).get().toString()) );
+ user.setMaxDownloadRate(
Integer.parseInt(attrs.get(DOWN_RATE).get().toString()) );
}
- catch(NamingException ex) {
- getLogger().error(ex.getMessage(), ex);
+ catch(Exception ex) {
+ getLogger().error("LdapUserManager.getUserByName()", ex);
user = null;
}
@@ -197,7 +224,7 @@
/**
* User authentication.
*/
- public boolean authenticate(String name, String password) {
+ public boolean authenticate(String login, String password) {
// empty password string is not allowed
if (password == null) {
@@ -208,12 +235,12 @@
}
try {
- String cn = getCommonName(name);
- if (cn != null) {
+ if( doesExist(login) ) {
Properties userProp = (Properties)mAdminEnv.clone();
- String dn = CN + '=' + cn + ",ou=people," + mstLdapRoot;
+ String dn = getDN(login);
userProp.setProperty(Context.SECURITY_PRINCIPAL, dn);
userProp.setProperty(Context.SECURITY_CREDENTIALS, password);
+
DirContext userContext = new InitialDirContext(userProp);
userContext.close();
return true;
@@ -251,16 +278,17 @@
user.setPassword(" ");
}
- String cn = user.getName() + "-" + System.currentTimeMillis();
- String path = CN + '=' + cn + ",ou=people," + mstLdapRoot;
+ String dn = getDN(user.getName());
Attributes attrs = new BasicAttributes(true);
attrs.put(new BasicAttribute(LOGIN, user.getName()));
attrs.put(new BasicAttribute(UID, user.getName()));
- attrs.put(new BasicAttribute(CN, cn));
+ attrs.put(new BasicAttribute(CN, user.getName()));
attrs.put(new BasicAttribute(SN, user.getName()));
attrs.put(new BasicAttribute(PASSWORD, user.getPassword()));
- attrs.put(OBJCLASS_ATTR);
+
+ attrs.put(mObjClassAttr);
+
attrs.put(new BasicAttribute(ENABLE, String.valueOf(user.getEnabled())));
attrs.put(new BasicAttribute(ROOT_DIR,
user.getVirtualDirectory().getRootDirectory()));
attrs.put(new BasicAttribute(WRITE_PERM,
String.valueOf(user.getVirtualDirectory().getWritePermission())));
@@ -268,7 +296,7 @@
attrs.put(new BasicAttribute(UP_RATE,
String.valueOf(user.getMaxUploadRate())));
attrs.put(new BasicAttribute(DOWN_RATE,
String.valueOf(user.getMaxDownloadRate())));
- mAdminContext.bind(path, null, attrs);
+ mAdminContext.bind(dn, null, attrs);
}
@@ -276,8 +304,7 @@
* Update an existing user
*/
private synchronized void update(User user) throws NamingException {
- String cn = getCommonName(user.getName());
- String dn = CN + '=' + cn + ",ou=people," + mstLdapRoot;
+ String dn = getDN(user.getName());
ArrayList mods = new ArrayList();
if (user.getPassword() != null) {
@@ -306,14 +333,15 @@
* User existance check
*/
public synchronized boolean doesExist(String name) {
- String cn = null;
+ boolean bExist = false;
try {
- cn = getCommonName(name);
+ String dn = getDN(name);
+ mAdminContext.getAttributes(dn, UID_ATTRS);
+ bExist = true;
}
catch(NamingException ex) {
- getLogger().error(ex.getMessage(), ex);
}
- return cn != null;
+ return bExist;
}
@@ -321,11 +349,8 @@
* Delete user
*/
public synchronized void delete(String userName) throws NamingException {
- String cn = getCommonName(userName);
- if (cn != null) {
- String dn = CN + '=' + cn + ",ou=people," + mstLdapRoot;
- mAdminContext.unbind(dn);
- }
+ String dn = getDN(userName);
+ mAdminContext.unbind(dn);
}
@@ -333,7 +358,6 @@
* Close user manager
*/
public synchronized void dispose() {
- getLogger().info("Closing ldap user manager...");
if (mAdminContext != null) {
try {
mAdminContext.close();
@@ -344,13 +368,21 @@
}
}
- // static block
- static {
- OBJCLASS_ATTR.add("top");
- OBJCLASS_ATTR.add("person");
- OBJCLASS_ATTR.add("organizationalPerson");
- OBJCLASS_ATTR.add("inetOrgPerson");
- OBJCLASS_ATTR.add("ftpUsers");
+ /**
+ * Get the distinguished name (DN) for this user name
+ */
+ private String getDN(String userName) throws NamingException {
+
+ //escape special characters
+ userName = StringUtils.replaceString(userName, "\\", "\\\\");
+ userName = StringUtils.replaceString(userName, ",", "\\,");
+ userName = StringUtils.replaceString(userName, "+", "\\+");
+ userName = StringUtils.replaceString(userName, "\"", "\\\"");
+ userName = StringUtils.replaceString(userName, "<", "\\<");
+ userName = StringUtils.replaceString(userName, ">", "\\>");
+ userName = StringUtils.replaceString(userName, ";", "\\;");
+
+ return mstDnPrefix + userName + mstDnSuffix;
}
+
}
-
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>