How to programmatically add user account to openDS? - java

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>

Related

Issues with adding user to LDAP server in Java using JNDI

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.

How to read weblogic configured myrealm users and passwords using java

I am trying to read user name and password which are configured in myrealm. Is there any way? Or If I create the user in myrealm where it is going to be store. Can I find the file location or file name.
Getting user names code was available in List all the user in weblogic by java
link. But I am expecting password also.
You could try the following approach. It still would need your weblogic password, but it should give you access to all the users you need.
import javax.naming.*;
import javax.management.MBeanInfo;
import weblogic.jndi.Environment;
import weblogic.management.runtime.ServerRuntimeMBean;
import weblogic.security.providers.authentication.DefaultAuthenticatorMBean;
import weblogic.management.security.authentication.UserReaderMBean;
import weblogic.management.security.authentication.GroupReaderMBean;
import weblogic.management.MBeanHome;
import weblogic.management.WebLogicMBean;
import weblogic.management.tools.Info;
import weblogic.management.Helper;
import weblogic.management.security.authentication.*;
public class ListUsersAndGroups { public static void main(String[]args) {
MBeanHome home = null; try {
Environment env = new Environment();
env.setProviderUrl(“t3://localhost:7001?);
env.setSecurityPrincipal(“weblogic”);
env.setSecurityCredentials(“weblogic”);
Context ctx = env.getInitialContext();
home = (MBeanHome)ctx.lookup(“weblogic.management.adminhome”);
weblogic.management.security.RealmMBean rmBean = home.getActiveDomain().getSecurityConfiguration().getDefaultRealm();
AuthenticationProviderMBean[] authenticationBeans =
rmBean.getAuthenticationProviders();
DefaultAuthenticatorMBean defaultAuthenticationMBean =
(DefaultAuthenticatorMBean)authenticationBeans[0];
UserReaderMBean userReaderMBean =
(UserReaderMBean)defaultAuthenticationMBean;
String userCurName = userReaderMBean.listUsers(“*”, 100);
while (userReaderMBean.haveCurrent(userCurName) )
{
String user = userReaderMBean.getCurrentName(userCurName);
System.out.println(“\n User: ” + user);
userReaderMBean.advance(userCurName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Mentions to here

Retrieve data from active directory

I am developing a project in java and JSP that needs to access an active directory for login and retrieving some values. I have done the login part(authentication) but i am not able to get help over the retrieval part.I am completely new to active directory concept, so please aid me accordingly.
I am giving the code of the java class that i have used for user authentication:
package classes;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
public class AD_Auth {
private static final String CONTEXT_FACTORY_CLASS ="com.sun.jndi.ldap.LdapCtxFactory";
private static final String domainName = "#xyz.IN";
private static final String providerUrl = "ldap://srdeladc02.xyz.in:123";
public static boolean authenticate(String username, String password) {
try {
Hashtable<Object, Object> env = new Hashtable<Object, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, CONTEXT_FACTORY_CLASS);
env.put(Context.PROVIDER_URL, providerUrl);
env.put(Context.SECURITY_PRINCIPAL, username + domainName);
env.put(Context.SECURITY_CREDENTIALS, password);
env.put(Context.SECURITY_AUTHENTICATION, "strong");
DirContext ctx = new InitialDirContext(env);
ctx.close();
return true;
} catch (NamingException e) {
System.out.println("Dear User, The username or password you have entered is in correct, please try again.");
}
return false;
}
public static void main(String[] args) {
// if someone emailid is myemail#icar.gov.in then username will be myemail
//System.out.println(AD_Auth.authenticate("username", "password"));
}
}

How to get all Ldap Groups of a user including nested groups in JAVA

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;
}
}

Execute a script on remote server from a java application authenticating via kerberos keytabs

This has been most likely answered earlier, but all my searches did not get me a definite answer. What I've got is a Java application that currently uses ssh keys to run a script on a remote machine and save the results. I'm in the process of changing this to a Kerberos authentication using keytabs. I have the keytab set up and tested it using a perl script. If someone could point me to examples that tell me how to use kerberos keytabs in a Java application, that would be very helpful.
Thanks,
Kiran
Here's a full implementation of using a keytab in Java.
import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.security.Principal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class SecurityUtils {
public static class LoginConfig extends Configuration {
private String keyTabLocation;
private String servicePrincipalName;
private boolean debug;
public LoginConfig(String keyTabLocation, String servicePrincipalName, boolean debug) {
this.keyTabLocation = keyTabLocation;
this.servicePrincipalName = servicePrincipalName;
this.debug = debug;
}
#Override
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("useKeyTab", "true");
options.put("keyTab", this.keyTabLocation);
options.put("principal", this.servicePrincipalName);
options.put("storeKey", "true");
options.put("doNotPrompt", "true");
if (this.debug) {
options.put("debug", "true");
}
options.put("isInitiator", "false");
return new AppConfigurationEntry[]{new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options),};
}
}
public static Subject loginAs(String keyTabLocation, String servicePrincipal) {
try {
LoginConfig loginConfig = new LoginConfig(keyTabLocation, servicePrincipal, true);
Set<Principal> princ = new HashSet<Principal>(1);
princ.add(new KerberosPrincipal(servicePrincipal));
Subject sub = new Subject(false, princ, new HashSet<Object>(), new HashSet<Object>());
LoginContext lc;
lc = new LoginContext("", sub, null, loginConfig);
lc.login();
return lc.getSubject();
} catch (LoginException e) {
e.printStackTrace();
}
return null;
}
}
The loginAs method will return you a Subject which can be used to execute a privileged action:
result = Subject.doAs(subject,
new PrivilegedExceptionAction<NamingEnumeration<SearchResult>>() {
public NamingEnumeration<SearchResult> run() throws NamingException {
return context.search(directoryBase, filterBuilder.toString(), searchCtls);
}
});

Categories