package br.com.centralit.citcorpore.util;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.AttributeInUseException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.NoSuchAttributeException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
public class LDAPManager {
/** The OU (organizational unit) to add users to */
private static final String USERS_OU =
"ou=administracao,dc=centralit,dc=com,dc=br";
/** The OU (organizational unit) to add groups to */
private static final String GROUPS_OU =
"ou=Groups,dc=centralit,dc=com,dc=br";
/** The OU (organizational unit) to add permissions to */
private static final String PERMISSIONS_OU =
"ou=Permissions,dc=centralit,dc=com,dc=br";
/** The default LDAP port */
private static final int DEFAULT_PORT = 389;
/** The LDAPManager instance object */
private static Map instances = new HashMap();
/** The connection, through a <code>DirContext</code>, to LDAP */
private DirContext context;
/** The hostname connected to */
private String hostname;
/** The port connected to */
private int port;
protected LDAPManager(String hostname, int port,
String username, String password)
throws NamingException {
context = getInitialContext(hostname, port, username, password);
// Only save data if we got connected
this.hostname = hostname;
this.port = port;
}
public static LDAPManager getInstance(String hostname,
int port,
String username,
String password)
throws NamingException {
// Construct the key for the supplied information
String key = new StringBuilder()
.append(hostname)
.append(":")
.append(port)
.append("|")
.append((username == null ? "" : username))
.append("|")
.append((password == null ? "" : password))
.toString();
if (!instances.containsKey(key)) {
synchronized (LDAPManager.class) {
if (!instances.containsKey(key)) {
LDAPManager instance =
new LDAPManager(hostname, port,
username, password);
instances.put(key, instance);
return instance;
}
}
}
return (LDAPManager)instances.get(key);
}
public static LDAPManager getInstance(String hostname, int port)
throws NamingException {
return getInstance(hostname, port, null, null);
}
public static LDAPManager getInstance(String hostname)
throws NamingException {
return getInstance(hostname, DEFAULT_PORT, null, null);
}
public void addUser(String username, String firstName,
String lastName, String password)
throws NamingException {
// Create a container set of attributes
Attributes container = new BasicAttributes();
// Create the objectclass to add
Attribute objClasses = new BasicAttribute("objectClass");
objClasses.add("top");
objClasses.add("person");
objClasses.add("organizationalPerson");
objClasses.add("inetOrgPerson");
// Assign the username, first name, and last name
String cnValue = new StringBuilder(firstName)
.append(" ")
.append(lastName)
.toString();
Attribute cn = new BasicAttribute("cn", cnValue);
Attribute givenName = new BasicAttribute("givenName", firstName);
Attribute sn = new BasicAttribute("sn", lastName);
Attribute uid = new BasicAttribute("uid", username);
// Add password
Attribute userPassword =
new BasicAttribute("userpassword", password);
// Add these to the container
container.put(objClasses);
container.put(cn);
container.put(sn);
container.put(givenName);
container.put(uid);
container.put(userPassword);
// Create the entry
context.createSubcontext(getUserDN(username), container);
}
public void deleteUser(String username) throws NamingException {
try {
context.destroySubcontext(getUserDN(username));
} catch (NameNotFoundException e) {
// If the user is not found, ignore the error
}
}
public boolean isValidUser(String username, String password)
throws Exception {
try {
this.context =
getInitialContext(hostname, port, username,
password);
//DirContext context =
// getInitialContext(hostname, port, getUserDN(username),
// password);
return true;
} catch (javax.naming.NameNotFoundException e) {
e.printStackTrace();
throw new Exception(username);
} catch (NamingException e) {
e.printStackTrace();
return false;
}
}
public void addGroup(String name, String description)
throws NamingException {
// Create a container set of attributes
Attributes container = new BasicAttributes();
// Create the objectclass to add
Attribute objClasses = new BasicAttribute("objectClass");
objClasses.add("top");
objClasses.add("groupOfUniqueNames");
objClasses.add("groupOfForethoughtNames");
// Assign the name and description to the group
Attribute cn = new BasicAttribute("cn", name);
Attribute desc = new BasicAttribute("description", description);
// Add these to the container
container.put(objClasses);
container.put(cn);
container.put(desc);
// Create the entry
context.createSubcontext(getGroupDN(name), container);
}
public void deleteGroup(String name) throws NamingException {
try {
context.destroySubcontext(getGroupDN(name));
} catch (NameNotFoundException e) {
// If the group is not found, ignore the error
}
}
public void addPermission(String name, String description)
throws NamingException {
// Create a container set of attributes
Attributes container = new BasicAttributes();
// Create the objectclass to add
Attribute objClasses = new BasicAttribute("objectClass");
objClasses.add("top");
objClasses.add("forethoughtPermission");
// Assign the name and description to the group
Attribute cn = new BasicAttribute("cn", name);
Attribute desc = new BasicAttribute("description", description);
// Add these to the container
container.put(objClasses);
container.put(cn);
container.put(desc);
// Create the entry
context.createSubcontext(getPermissionDN(name), container);
}
public void deletePermission(String name) throws NamingException {
try {
context.destroySubcontext(getPermissionDN(name));
} catch (NameNotFoundException e) {
// If the permission is not found, ignore the error
}
}
public void assignUser(String username, String groupName)
throws NamingException {
try {
ModificationItem[] mods = new ModificationItem[1];
Attribute mod =
new BasicAttribute("uniqueMember",
getUserDN(username));
mods[0] =
new ModificationItem(DirContext.ADD_ATTRIBUTE, mod);
context.modifyAttributes(getGroupDN(groupName), mods);
} catch (AttributeInUseException e) {
// If user is already added, ignore exception
}
}
public void removeUser(String username, String groupName)
throws NamingException {
try {
ModificationItem[] mods = new ModificationItem[1];
Attribute mod =
new BasicAttribute("uniqueMember",
getUserDN(username));
mods[0] =
new ModificationItem(DirContext.REMOVE_ATTRIBUTE, mod);
context.modifyAttributes(getGroupDN(groupName), mods);
} catch (NoSuchAttributeException e) {
// If user is not assigned, ignore the error
}
}
public boolean userInGroup(String username, String groupName)
throws NamingException {
// Set up attributes to search for
String[] searchAttributes = new String[1];
searchAttributes[0] = "uniqueMember";
Attributes attributes =
context.getAttributes(getGroupDN(groupName),
searchAttributes);
if (attributes != null) {
Attribute memberAtts = attributes.get("uniqueMember");
if (memberAtts != null) {
for (NamingEnumeration vals = memberAtts.getAll();
vals.hasMoreElements();
) {
if (username.equalsIgnoreCase(
getUserUID((String)vals.nextElement()))) {
return true;
}
}
}
}
return false;
}
public List getMembers(String groupName) throws NamingException {
List members = new LinkedList();
// Set up attributes to search for
String[] searchAttributes = new String[1];
searchAttributes[0] = "uniqueMember";
Attributes attributes =
context.getAttributes(getGroupDN(groupName),
searchAttributes);
if (attributes != null) {
Attribute memberAtts = attributes.get("uniqueMember");
if (memberAtts != null) {
for (NamingEnumeration vals = memberAtts.getAll();
vals.hasMoreElements();
members.add(
getUserUID((String)vals.nextElement()))) ;
}
}
return members;
}
public List getGroups(String username) throws NamingException {
List groups = new LinkedList();
Hashtable env = new Hashtable();
//String adminName = "CN=emauri,CN=Users,DC=centralit,DC=com,DC=br";
String adminName = "emauri";
String adminPassword = "pereba05";
String ldapURL = "ldap://10.100.100.30:389";
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,adminName);
env.put(Context.SECURITY_CREDENTIALS,adminPassword);
//connect to my domain controller
env.put(Context.PROVIDER_URL,ldapURL);
//specify attributes to be returned in binary format
env.put("java.naming.ldap.attributes.binary","tokenGroups");
//env.put(Context.REFERRAL, "follow");
LdapContext ctx = new InitialLdapContext(env,null);
// Search for groups the user belongs to in order to get their names
//Create the search controls
SearchControls groupsSearchCtls = new SearchControls();
//Specify the search scope
groupsSearchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
//Specify the Base for the search
String groupsSearchBase = "DC=centralit,DC=com,DC=br";
//Specify the attributes to return
//String groupsReturnedAtts[]={"sAMAccountName"};
// groupsSearchCtls.setReturningAttributes(groupsReturnedAtts);
//Search for objects using the filter
//NamingEnumeration results = ctx.search(groupsSearchBase, "(objectClass=Groups)", groupsSearchCtls);
NamingEnumeration results = null;
SearchControls search = new SearchControls();
search.setSearchScope(SearchControls.SUBTREE_SCOPE);
results = ctx.search("dc=centralit,dc=com,dc=br", "(&(objectClass=group)(member=cn=emauri,ou=Users,dc=centralit,dc=com,dc=br))",
search);
//NamingEnumeration results =
// context.search(base, filter, cons);
//NamingEnumeration results =
// context.search(GROUPS_OU, filter, cons);
while (results.hasMore()) {
SearchResult result = (SearchResult)results.next();
groups.add(getGroupCN(result.getName()));
}
return groups;
}
public List getGroups2(String username) throws NamingException {
List groups = new LinkedList();
// Set up criteria to search on
/*
String filter = new StringBuilder()
.append("(&")
.append("(objectClass=group)")
.append("(uniqueMember=")
.append(getUserDN(username))
.append(")")
.append(")")
.toString();*/
String filter = "(&(objectClass=group)(member=cn=emauri,ou=Users,dc=centralit,dc=com,dc=br))";
// Set up search constraints
SearchControls cons = new SearchControls();
cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration results =
context.search("dc=centralit,dc=com,dc=br", filter, cons);
while (results.hasMore()) {
SearchResult result = (SearchResult)results.next();
groups.add(getGroupCN(result.getName()));
}
return groups;
}
public void assignPermission(String groupName, String permissionName)
throws NamingException {
try {
ModificationItem[] mods = new ModificationItem[1];
Attribute mod =
new BasicAttribute("uniquePermission",
getPermissionDN(permissionName));
mods[0] =
new ModificationItem(DirContext.ADD_ATTRIBUTE, mod);
context.modifyAttributes(getGroupDN(groupName), mods);
} catch (AttributeInUseException e) {
// Ignore the attribute if it is already assigned
}
}
public void revokePermission(String groupName, String permissionName)
throws NamingException {
try {
ModificationItem[] mods = new ModificationItem[1];
Attribute mod =
new BasicAttribute("uniquePermission",
getPermissionDN(permissionName));
mods[0] =
new ModificationItem(DirContext.REMOVE_ATTRIBUTE, mod);
context.modifyAttributes(getGroupDN(groupName), mods);
} catch (NoSuchAttributeException e) {
// Ignore errors if the attribute doesn't exist
}
}
public boolean hasPermission(String groupName, String permissionName)
throws NamingException {
// Set up attributes to search for
String[] searchAttributes = new String[1];
searchAttributes[0] = "uniquePermission";
Attributes attributes =
context.getAttributes(getGroupDN(groupName),
searchAttributes);
if (attributes != null) {
Attribute permAtts = attributes.get("uniquePermission");
if (permAtts != null) {
for (NamingEnumeration vals = permAtts.getAll();
vals.hasMoreElements();
) {
if (permissionName.equalsIgnoreCase(
getPermissionCN((String)vals.nextElement()))) {
return true;
}
}
}
}
return false;
}
public List getPermissions(String groupName) throws NamingException {
List permissions = new LinkedList();
// Set up attributes to search for
String[] searchAttributes = new String[1];
searchAttributes[0] = "uniquePermission";
Attributes attributes =
context.getAttributes(getGroupDN(groupName),
searchAttributes);
if (attributes != null) {
Attribute permAtts = attributes.get("uniquePermission");
if (permAtts != null) {
for (NamingEnumeration vals = permAtts.getAll();
vals.hasMoreElements();
permissions.add(
getPermissionCN((String)vals.nextElement()))) ;
}
}
return permissions;
}
private String getUserDN(String username) {
return new StringBuilder()
.append("uid=")
.append(username)
.append(",")
.append(USERS_OU)
.toString();
}
private String getUserUID(String userDN) {
int start = userDN.indexOf("=");
int end = userDN.indexOf(",");
if (end == -1) {
end = userDN.length();
}
return userDN.substring(start+1, end);
}
private String getGroupDN(String name) {
return new StringBuilder()
.append("cn=")
.append(name)
.append(",")
.append(GROUPS_OU)
.toString();
}
private String getGroupCN(String groupDN) {
int start = groupDN.indexOf("=");
int end = groupDN.indexOf(",");
if (end == -1) {
end = groupDN.length();
}
return groupDN.substring(start+1, end);
}
private String getPermissionDN(String name) {
return new StringBuilder()
.append("cn=")
.append(name)
.append(",")
.append(PERMISSIONS_OU)
.toString();
}
private String getPermissionCN(String permissionDN) {
int start = permissionDN.indexOf("=");
int end = permissionDN.indexOf(",");
if (end == -1) {
end = permissionDN.length();
}
return permissionDN.substring(start+1, end);
}
private DirContext getInitialContext(String hostname, int port,
String username, String password)
throws NamingException {
String providerURL =
new StringBuilder("ldap://")
.append(hostname)
.append(":")
.append(port)
.toString();
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.PROVIDER_URL, providerURL);
if ((username != null) && (!username.equals(""))) {
props.put(Context.SECURITY_AUTHENTICATION, "simple");
props.put(Context.SECURITY_PRINCIPAL, username);
props.put(Context.SECURITY_CREDENTIALS,
((password == null) ? "" : password));
}
return new InitialDirContext(props);
}
public static final String binarySidToStringSid( byte[] SID ) {
String strSID = "";
//convert the SID into string format
long version;
long authority;
long count;
long rid;
strSID = "S";
version = SID[0];
strSID = strSID + "-" + Long.toString(version);
authority = SID[4];
for (int i = 0;i<4;i++) {
authority <<= 8;
authority += SID[4+i] & 0xFF;
}
strSID = strSID + "-" + Long.toString(authority);
count = SID[2];
count <<= 8;
count += SID[1] & 0xFF;
for (int j=0;j<count;j++) {
rid = SID[11 + (j*4)] & 0xFF;
for (int k=1;k<4;k++) {
rid <<= 8;
rid += SID[11-k + (j*4)] & 0xFF;
}
strSID = strSID + "-" + Long.toString(rid);
}
return strSID;
}
}