I'm having an issue with adding a user to my LDAP server in Java.
Here's what my code looks like
import java.util.Hashtable;
import java.util.Properties;
import java.util.jar.Attributes;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
public class LdapProgram {
public static void main(String[] args) {
String dn = "";
String password = "";
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
properties.put(Context.PROVIDER_URL, "ldap://127.0.0.1");
properties.put(Context.SECURITY_AUTHENTICATION,"none");
properties.put(Context.SECURITY_PRINCIPAL,password);
properties.put(Context.SECURITY_CREDENTIALS,dn);
// TODO code application logic here
// entry's DN
String entryDN = "uid=test_user,ou=people,dc=test123,dc=com";
// entry's attributes
Attribute cn = new BasicAttribute("cn", "tester");
Attribute uid = new BasicAttribute("uid", "tester");
Attribute gecos = new BasicAttribute("gecos", "test");
Attribute oc = new BasicAttribute("objectClass");
oc.add("top");
oc.add("person");
oc.add("organizationalPerson");
oc.add("inetOrgPerson");
DirContext ctx = null;
try {
// get a handle to an Initial DirContext
ctx = new InitialDirContext(properties);
// build the entry
BasicAttributes entry = new BasicAttributes();
entry.put(cn);
entry.put(uid);
entry.put(gecos);
entry.put(oc);
// Add the entry
ctx.createSubcontext(entryDN, entry);
// System.out.println( "AddUser: added entry " + entryDN + ".");
} catch (NamingException e) {
System.err.println("AddUser: error adding entry.\n" + e);
}
}
}
Here is the error code I get: javax.naming.AuthenticationNotSupportedException: [LDAP: error code 8 - modifications require authentication]; remaining name 'uid=test_user,ou=people,dc=test123,dc=com'
I'm not understanding why it's saying it requires authentication when I'm already binded to the server with the admin user and password.
Related
This is my Java Code, I created a domain named: trial.com, in which I created a user named "test1#trial.com".
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.AuthenticationException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.ldap.LdapContext;
import javax.naming.directory.DirContext;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.BasicAttribute;
import java.util.Hashtable;
public class Password_ADTesting{
public static void main(String[] args){
LdapContext ctx = null;
try{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "Simple");
env.put(Context.SECURITY_PRINCIPAL, "test1#trial.com"); //"tom#trial.com"
env.put(Context.SECURITY_CREDENTIALS, "Panda123*"); //"Panda123*"
env.put(Context.PROVIDER_URL, "ldap://localhost:389/dc=trial,dc=com");
ctx = new InitialLdapContext(env,null);
System.out.println("Connection Successfull");
ModificationItem[] mods = new ModificationItem[1];
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("userPassword","Panda23*"));
ctx.modifyAttributes("CN=Test1,CN=Users,DC=trial,DC=com", mods);
//"CN=Test1,CN=Users,DC=trial,DC=com"
System.out.println("Success");
}catch(AuthenticationException authEx) {
System.out.println("Active Directory Authentication failed");
authEx.printStackTrace();
}catch(Exception e){
System.out.println("Password Cannot be Changed");
e.printStackTrace();
}
}
}
When I run the code I get the following error:
C:\Users\Administrator\Desktop>java Password_ADTesting
Connection Successfull
Password Cannot be Changed
javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310028C, problem 2001 (NO_OBJECT), data 0, best match of:
'DC=trial,DC=com'
]; remaining name 'CN=Test1,CN=Users,DC=trial,DC=com'
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3284)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3205)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2996)
at com.sun.jndi.ldap.LdapCtx.c_modifyAttributes(LdapCtx.java:1504)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_modifyAttributes(ComponentDirContext.java:277)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(PartialCompositeDirContext.java:192)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(PartialCompositeDirContext.java:181)
at javax.naming.directory.InitialDirContext.modifyAttributes(InitialDirContext.java:167)
at Password_ADTesting.main(Password_ADTesting.java:30)
I get authenticated, but not able to change the password. It shows name not found exception. But when I find the distinguished name attribute, it's correct as shown below:
Could someone help me out with this???
I have an swing application that connects to a Jboss 7 AS.
Invoking some background threads causes a no such ejb error on client side.
Here is an example
package com.asf.capone.client.util;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.asf.capone.common.exception.AppException;
import ro.asf.capone.ejb.beans.security.SecurityController;
import ro.asf.capone.ejb.beans.security.SecurityControllerRemote;
public class TestJndi {
public static void main(final String[] args) throws AppException {
final Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
env.put("java.naming.provider.url", "remote://localhost:4447");
env.put("java.naming.security.credentials", "c4ca4238a0b923820dcc509a6f75849b");
env.put("java.naming.security.principal", "capone");
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
env.put("jboss.naming.client.ejb.context", "true");
env.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
try {
final InitialContext ctx = new InitialContext(env);
System.out.println("ctx: " + ctx);
final SecurityController o = (SecurityControllerRemote) ctx.lookup(
"ejb:agency-ear/agency-ejb/SecurityControllerBean!ro.asf.capone.ejb.beans.security.SecurityControllerRemote");
System.out.println("1outcome: " + o.getServerTimeMillis());
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("2outcome: " + o.getServerTimeMillis());
}
}).start();
} catch (final NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The output for this is:
ctx: javax.naming.InitialContext#307f6b8c
1outcome: 1443465336127
Exception in thread "Thread-4" java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:agency-ear, moduleName:agency-ejb, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext#381dfddb
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:754)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186)
at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:253)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:198)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:181)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:144)
at com.sun.proxy.$Proxy2.getServerTimeMillis(Unknown Source)
at com.asf.capone.client.util.TestJndi$1.run(TestJndi.java:36)
at java.lang.Thread.run(Thread.java:745)
I am missing something that should allow me to get the same output on both calls but I cannot figure what is the problem. Thanks!
It looks like this doesn't work on that version of Jboss (they've changed the remote) because my initial code worked in Jboss 7.3.0. My current Jboss version is JBoss EAP 6.4.0.GA (AS 7.5.0.Final-redhat-21)
The code that works now is:
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.ejb.client.ContextSelector;
import org.jboss.ejb.client.EJBClientConfiguration;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;
import ro.asf.capone.ejb.beans.security.SecurityControllerRemote;
public class AppJboss {
public static void main(String[] args) throws NamingException {
System.out.println("Hello World!");
final String lookup = "ejb:agency-ear/agency-ejb//SecurityControllerBean!ro.asf.capone.ejb.beans.security.SecurityControllerRemote";
final Properties clientProperties = new Properties();
clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS",
"JBOSS-LOCAL-USER");
clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT",
"false");
clientProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
clientProperties.put("remote.connections", "default");
clientProperties.put("endpoint.name", "client-endpoint");
clientProperties.put("remote.connection.default.port", "4447");
clientProperties.put("remote.connection.default.host", "127.0.0.1");
clientProperties.put("remote.connection.default.username", "capone");
clientProperties.put("remote.connection.default.password", "c4ca4238a0b923820dcc509a6f75849b");
clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS",
"false");
final EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(
clientProperties);
final ContextSelector<EJBClientContext> contextSelector = new ConfigBasedEJBClientContextSelector(
ejbClientConfiguration);
EJBClientContext.setSelector(contextSelector);
final Properties properties = new Properties();
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(properties);
final SecurityControllerRemote myBean = (SecurityControllerRemote) context.lookup(lookup);
final long result = myBean.getServerTimeMillis();
System.out.println("result " + result);
new Thread(new Runnable() {
public void run() {
final long result = myBean.getServerTimeMillis();
System.out.println(result);
}
}).start();
}
}
The client library was taken from jboss/bin/client/jboss-client.jar
The same code works in Wildfly also, just with the change of port and client library. Hope this helps others.
I want to find all the groups a user is part of, including nested groups.
Like if user is part of group A1 and group A1 is part of A, then I want to get A as well.
Following is code , I have tried variuos filterstrings... but nothing is given expected output.
String samAccountName = "group";
String searchFilter = "(&(objectclass=user)(memberof: 1.2.840.113556.1.4.1941:="+samAccountName+"))";
//String searchFilter = "(&(objectCategory=person)(memberOf=CN="+samAccountName+"))";
//String searchFilter = "(&(objectcategory=user)(memberof=CN="+samAccountName+",OU=Users,DC=new,DC=com))";
String searchBase = "DC=new,DC=com";
NamingEnumeration answer = ctx.search(searchBase, searchFilter, ontrols);
List rolesList = new ArrayList();
while(answer.hasMoreElements()){
SearchResult sr = (SearchResult)answer.next();
...
Any help is appreciated.
I expect you'll have to recursively search the memberOf attribute list for a user. e.g. if a user has the following ldif-style result from an ldapsearch call:
cn: user1
memberOf: CN=group1,DC=foo,DC=example,DC=com
memberOf: CN=group2,DC=foo,DC=example,DC=com
..then you'll want to recursively look up group1 and group2 with additional ldap searches, and so on for groups which those groups are membersOf.
I'm doing something similar right now, but in perl and to get flat lists of all members of all groups from Active Directory. AD uses objectClass: group whereas OpenLDAP tends to use objectClass: groupOfUniqueNames or perhaps objectClass: posixGroup, depending on the use (posix groups for unix-y clients such as Linux boxes, groupOfUniqueNames groups for more general information. It depends entirely on the clients using the information from the directory).
Edit: In AD there is also supposed to be an attribute called tokenGroups which contains the SIDs of security groups for users, but this didn't work for me. I'm guessing it's optional and not enabled on my site's AD server.
Below code works finding the list of groups that the user belongs to.Sun LDAP implementation is being used
package pack;
import static javax.naming.directory.SearchControls.SUBTREE_SCOPE;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import com.sun.jndi.ldap.LdapCtxFactory;
class App4
{
public static void main(String[] args)
{
String username = "userName";
String password = "password";
String serverName = "server";
String domainName = "comp.BIZ";
System.out.println("Authenticating " + username + "#" + domainName
+ " through " + serverName + "." + domainName);
// bind by using the specified username/password
Hashtable<String,String> props = new Hashtable<String,String>();
String principalName = username + "#" + domainName;
props.put(Context.SECURITY_PRINCIPAL, principalName);
props.put(Context.SECURITY_CREDENTIALS, password);
DirContext context;
try {
context = LdapCtxFactory.getLdapCtxInstance("ldap://" + serverName
+ "." + domainName + '/', props);
System.out.println("Authentication succeeded!");
// locate this user's record
SearchControls controls = new SearchControls();
controls.setSearchScope(SUBTREE_SCOPE);
NamingEnumeration<SearchResult> renum = context.search(
toDC(domainName), "(& (userPrincipalName=" + principalName
+ ")(objectClass=user))", controls);
if (!renum.hasMore())
{
System.out.println("Cannot locate user information for "
+ username);
System.exit(1);
}
SearchResult result = renum.next();
List<GrantedAuthority> groups = new ArrayList<GrantedAuthority>();
Attribute memberOf = result.getAttributes().get("memberOf");
if (memberOf != null)
{// null if this user belongs to no group at
// all
for (int i = 0; i < memberOf.size(); i++)
{
Attributes atts = context.getAttributes(memberOf.get(i)
.toString(), new String[] { "CN" });
Attribute att = atts.get("CN");
groups.add(new GrantedAuthorityImpl(att.get().toString()));
}
}
context.close();
System.out.println();
System.out.println("User belongs to: ");
Iterator<GrantedAuthority> ig = groups.iterator();
while (ig.hasNext())
{
System.out.println(" " + ig.next().toString());
}
} catch (AuthenticationException a)
{
System.out.println("Authentication failed: " + a);
System.exit(1);
} catch (NamingException e)
{
System.out
.println("Failed to bind to LDAP / get account information: "
+ e);
System.exit(1);
}
}
private static String toDC(String domainName)
{
StringBuilder buf = new StringBuilder();
for (String token : domainName.split("\\."))
{
if (token.length() == 0)
continue; // defensive check
if (buf.length() > 0)
buf.append(",");
buf.append("DC=").append(token);
}
return buf.toString();
}
}
String searchFilter ="(&(objectClass=person)(samaccountname="+userName+"))"
I modidfied the searchFilter and it works.
In LDAP we can query if a User belongs to a given group once you have established a connection you can query using either member or memberOf attribute.
Query for memberOf Attribute :
filter used : (&(Group Member Attribute=Group DN)(objectClass=Group Object class))
Ex : (&(memberOf=CN=group,ou=qa_ou,dc=ppma,dc=org)(objectClass=group))
Using member Attribute :
filter used : (&(Group Member Attribute=User DN)(objectClass=Group Object class))
Ex : (&(member=CN=user,ou=qa_ou,dc=ppma,dc=org)(objectClass=group))
But You'll have to search recursively using the member or memberOf attribute list for a user. e.g. if a user has the following group hierarchy :
cn: user1
memberOf: CN=group1,DC=foo,DC=example,DC=com
memberOf: CN=group2,DC=foo,DC=example,DC=com
then you'll want to recursively lookup group1 and group2 with additional LDAP searches, and so on for groups which those groups are members of.
Below is the sample code to query all the nested groups a User belongs to :
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
public class MemberDemo {
private static final String contextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
private static final String connectionURL = "ldap://10.224.243.133:389";
private static final String connectionName = "CN=administrator,CN=users,DC=ppma,DC=org";
private static final String connectionPassword = "Conleyqa12345";
public static int nestLevel = 3;
public static int level = 1;
// Optional
private static final String authentication = null;
private static final String protocol = null;
private static String userBase = "OU=qa_OU,DC=ppma,DC=org";
public static void main(String[] args) throws NamingException {
long start = System.currentTimeMillis();
Hashtable<String, String> env = new Hashtable<String, String>();
// Configure our directory context environment.
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
env.put(Context.PROVIDER_URL, connectionURL);
env.put(Context.SECURITY_PRINCIPAL, connectionName);
env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
if (authentication != null)
env.put(Context.SECURITY_AUTHENTICATION, authentication);
if (protocol != null)
env.put(Context.SECURITY_PROTOCOL, protocol);
InitialDirContext context = new InitialDirContext(env);
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
Set<String> traversedGroups = new HashSet<String>();
Set<String> relatedGroups = new HashSet<String>();
List<String> tempParentColl = new CopyOnWriteArrayList<String>();
List<String> tempGroups = new ArrayList<String>();
String loginUser = "CN=qa20Nest,OU=qa_OU,DC=ppma,DC=org";
String filter = "(&(member=" + loginUser + ")(objectClass=group))";
tempGroups = findNestedGroups(tempGroups, context, filter, loginUser, constraints,
tempParentColl, traversedGroups, getUserName(loginUser));
relatedGroups.addAll(tempGroups);
System.out.println("Parent Groups :");
for (String group : relatedGroups) {
System.out.println(group);
}
long end = System.currentTimeMillis();
long elapsedTime = end - start;
System.out.println("Total time taken in sec : " + elapsedTime / 1000);
}
#SuppressWarnings("rawtypes")
public static List<String> findNestedGroups(List<String> tempGrpRelations, InitialDirContext context, String filter,
String groupName, SearchControls constraints, List<String> tempParentColl, Set<String> traversedGrp,
String groupIdentifier) {
NamingEnumeration results;
try {
traversedGrp.add(groupName);
results = context.search(userBase, filter, constraints);
// Fail if no entries found
if (results == null || !results.hasMore()) {
System.out.println("No result found for :" + groupName);
if (tempParentColl.isEmpty()) {
return tempGrpRelations;
} else {
tempParentColl.remove(groupName);
}
}
while (results.hasMore()) {
SearchResult result = (SearchResult) results.next();
System.out.println("DN - " + result.getNameInNamespace());
tempParentColl.add(result.getNameInNamespace());
tempGrpRelations.add(result.getNameInNamespace());
}
Iterator<String> itr = tempParentColl.iterator();
while (itr.hasNext()) {
String groupDn = itr.next();
String nfilter = "(&(member=" + groupDn + ")(objectClass=group))";
tempParentColl.remove(groupDn);
if (!traversedGrp.contains(groupDn)) {
findNestedGroups(tempGrpRelations, context, nfilter, groupDn, constraints, tempParentColl,
traversedGrp, getUserName(groupDn));
}
}
} catch (NamingException e) {
e.printStackTrace();
}
return tempGrpRelations;
}
public static String getUserName(String cnName) {
String name = cnName.substring(cnName.indexOf("CN=")).split(",")[0].split("=")[1];
return name;
}
}
I am facing some difficulties while listing all the users in the Active Directory. I reached to the group, but unfortunately, I could not retrieve all the users. I am looking for the user Full Names, usernames, directorate. My code is:
package client;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.*;
import java.util.Enumeration;
import javax.naming.NamingEnumeration;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.directory.*;
public class AD1 {
public AD1() {
super();
}
public static String usersContainer = "cn=XX,ou=XX,ou=Groups,dc=XX,dc=XX,dc=XXX";
public static void main(String[] args) {
try {
LdapContext ctx = null;
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "Simple");
//it can be <domain\\userid> something that you use for windows login
//it can also be
env.put(Context.SECURITY_PRINCIPAL, "username");
// env.put(Context.SECURITY_CREDENTIALS, "password");
try {
env.put(Context.SECURITY_CREDENTIALS, "password".getBytes("UTF8"));
}
catch (java.io.UnsupportedEncodingException e) { /* ignore */ }
//in following property we specify ldap protocol and connection url.
//generally the port is 389
env.put(Context.PROVIDER_URL, "ldap://IP:PORT");
ctx = new InitialLdapContext(env, null);
System.out.println("Connection Successful.");
DirContext ctx1 = new InitialDirContext(env);
SearchControls ctls = new SearchControls();
String[] attrIDs = { "distinguishedName","cn","name","uid",
"sn",
"givenname",
"memberOf",
"samaccountname",
"userPrincipalName" };
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
//ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
NamingEnumeration answer = ctx1.search( usersContainer, "(objectClass=user)", ctls );
System.out.print("Out while loop");
while(answer.hasMore()) {
System.out.print("while loop11");
SearchResult rslt = (SearchResult)answer.next();
Attributes attrs = rslt.getAttributes();
System.out.println(attrs.get("uid"));
ctx1.close();
}
} catch(NamingException nex) {
System.out.println("Active Directory Connection: FAILED");
nex.printStackTrace();
}
}
}
Can anyone help.
As it's active directory and not real ldap your talking about, can you help us with more details about ldap/active directory configuration ?
It's kind hard to help you with informations you give
Edit 1:
your problem is here no ?
while(answer.hasMore()) {
System.out.print("while loop11");
SearchResult rslt = (SearchResult)answer.next();
Attributes attrs = rslt.getAttributes();
//System.out.println(attrs.get("uid"));
System.out.println(attrs.get("cn"));
ctx1.close();
}
I need to add some user accounts to a openDS server programmatically, but I don't know how to do it even after look through the openDS wiki. Could anyone help me?
The below code is using jndi. This will just add an user object with provided password. This is not much. But this might help you to get started.
Also I would prefer to stick with jndi compared to opends-sdk.
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.DirContext;
import javax.naming.directory.Attributes;
import javax.naming.directory.Attribute;
import javax.naming.NamingException;
public class App {
/* Ugly HardCoded stuff */
public static String ldapUri = "ldap://localhost:2389";
public static String admindn = "cn=Directory Manager";
public static String admincred = "password";
public static String usersContainer = "ou=users,dc=example,dc=com";
public static void main(String args[]){
if (args.length != 2) {
System.out.println("Usage: App userName password");
return;
}
String username = args[0];
String password = args[1];
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapUri);
env.put( Context.SECURITY_PRINCIPAL, admindn );
env.put( Context.SECURITY_CREDENTIALS, admincred );
try {
DirContext ctx = new InitialDirContext(env);
Attributes attrs = new BasicAttributes(true);
Attribute objclass = new BasicAttribute("objectclass");
objclass.add("top");
objclass.add("inetorgperson");
Attribute surname = new BasicAttribute("sn");
surname.add(username);
Attribute pwd = new BasicAttribute("userpassword");
pwd.add(password);
attrs.put(objclass);
attrs.put(surname);
attrs.put(pwd);
ctx.createSubcontext("cn="+username+","+usersContainer, attrs);
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
}
To add programmatically user accounts in OpenDS, you need to use an LDAP client library for your OS and preferred programming language.
OpenDS has an LDAP library for Java, with many sample code.
http://www.opends.org/promoted-builds/sdk/20110126210001/
Sample are in the Example directory.
Here the code used in php working fine for me
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
</head>
<body>
<?php
$ldapconfig['host'] = 'PC100';
$ldapconfig['port'] = 1389;
$ldapconfig['basedn'] = 'dc=company,dc=com';
$ds=ldap_connect($ldapconfig['host'], $ldapconfig['port']);
$password=1;
$username="cn=Directory Manager";
if ($bind=ldap_bind($ds, $username, $password)) {
echo("Login correct");
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // IMPORTANT
$dn = "cn=roshanis,dc=example,dc=com";
$ldaprecord['cn'] = "roshanis";
$ldaprecord['givenName'] = "mkljl";
$ldaprecord['sn'] = "roshan";
$ldaprecord['objectclass'][0] = "inetOrgPerson";
$ldaprecord['objectclass'][1] = "test";
$ldaprecord['mail'] = "lkl#fh.com";
// add data to directory
$r = ldap_add($ds, $dn, $ldaprecord);
// $r= ldap_modify($ds, $dn, $ldaprecord);
} else {
echo("Unable to bind to server.</br>");
}
?>
</body>
</html>