I can't use the "print/println" functions - java

I'm using IntelliJ IDEA.
I've done all that my Googling has provided me with as potential solutions.
I've tried doing the File -> Invalidate Caches/Restart, it still doesn't fix it.
This is the entire code;
This was copied from the OCI documentation, and I've already made some amendments to the code, but I don't know how to fix this.
I'm a junior yes, but am I wrong to be annoyed over how much of the documentation through the use of which I'm to be developing myself has these kinds of issues..
This is the entire code.
package com;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.codec.binary.Base64;
import static java.lang.System.out;
import static com.sun.org.apache.xalan.internal.xsltc.cmdline.Compile.printUsage;
public class ociAuth {
private static String server;
private static String user;
private static String password;
private static String port = "8443";
private static String response_format = "json";
private static String server_url;
public static void main(String[] args) {
if(args.length < 3 || args.length > 4) {
printUsage();
System.exit(1);
}
setUserArguments(args);
server_url = "https://" + server + ":" + port + "/rest/v1/assets/storages";
try {
HttpsURLConnection connection =
getAllTrustingHttpsUrlConnection();
if(connection == null) {
System.err.println("FATAL: Failed to create HTTPS connection to URL: " + server_url);
System.exit(1);
}
System.out.println("Invoking API: " + server_url);
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/" + response_format);
String authString = getAuthorizationString();
connection.setRequestProperty("Authorization", "Basic " +
authString);
if (connection.getResponseCode() != 200) {
System.err.println("API Invocation Failed : HTTP error code : "
+ connection.getResponseCode());
System.exit(1);
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(connection.getInputStream())));
String response;
System.out.println("Response:");
while ((response = br.readLine()) != null) {
System.out.println(response);
}
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
//THESE PRINTS HERE BELLOW
//THESE PRINTS HERE BELLOW
//THESE PRINTS HERE BELLOW
System.out.print("\nUsage:\n\tHelloApiServices <api-server host[:port]> <user> <password> [json|xml]\n");
System.out.print("\nExamples:\n\tHelloApiServices localhost admin mypassword");
System.out.print("\tHelloApiServices 10.22.12.34:8320 admin password");
System.out.print("\tHelloApiServices 10.22.12.34 admin password xml");
System.out.print("\tHelloApiServices 10.22.12.34:8212 admin password xml\n");
System.out.print("\nNote:\n\t(1) When port number is not provided, 8443 is chosen by default.");
System.out.print("\t(2) When response format (json or xml) is not provided, json is chosen by default. \n");
}
//THESE PRINTS HERE ABOVE
//THESE PRINTS HERE ABOVE
//THESE PRINTS HERE ABOVE
private static void setUserArguments(String[] args) {
server = args[0];
user = args[1];
password = args[2];
if(args.length == 4) {
response_format = args[3];
if(!response_format.equals("json") && ! response_format.equals("xml")) {
printUsage();
System.exit(1);
}
}
if(server.contains(":")) {
String[] parts = server.split(":");
server = parts[0];
port = parts[1];
}
}
private static HttpsURLConnection getAllTrustingHttpsUrlConnection() {
HttpsURLConnection conn = null;
try {
TrustManager[] trustAllCertificatesManager = new
TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return
null;
}
public void checkClientTrusted(X509Certificate[]
certs, String authType) {
}
public void checkServerTrusted(X509Certificate[]
certs, String authType) {
}
}};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCertificatesManager, new
SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
URL url = new URL(server_url);
conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String host, SSLSession
session) {
return true;
}
});
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
private static String getAuthorizationString() {
String userPassword = user + ":" + password;
byte[] authEncodedBytes =
Base64.encodeBase64(userPassword.getBytes());
String ajdeovako = new String(authEncodedBytes);
return ajdeovako;
}
}

You have an extra bracket. The System.out.print calls are not inside you main method, but are instead between methods and the closing bracket after the print calls shouldn't be there. Move the print calls up inside your main method and it should compile fine.

You have one extra }, removing it will fix your error.
} <-- remove this
//THESE PRINTS HERE BELLOW
//THESE PRINTS HERE BELLOW
//THESE PRINTS HERE BELLOW
System.out.print("\nUsage:\n\tHelloApiServices <api-server host[:port]> <user> <password> [json|xml]\n");
System.out.print("\nExamples:\n\tHelloApiServices localhost admin mypassword");
System.out.print("\tHelloApiServices 10.22.12.34:8320 admin password");
System.out.print("\tHelloApiServices 10.22.12.34 admin password xml");
System.out.print("\tHelloApiServices 10.22.12.34:8212 admin password xml\n");
System.out.print("\nNote:\n\t(1) When port number is not provided, 8443 is chosen by default.");
System.out.print("\t(2) When response format (json or xml) is not provided, json is chosen by default. \n");
}

Related

Socket connection succeeds even with wrong/null URL

I am running a test using the Java socket class, but somehow my socket.connect ALWAYS connects successfully to something, even if my url variable is null or incorrect. Does anyone know why?
package ping_run_send;
import java.util.*;
import java.lang.*;
import java.net.*;
import java.io.*
import java.security.cert.*;
import javax.net.ssl.*;
public class tcpping {
private String url, status;
private Date timestamp;
private long rtime;
tcpping(String input_url){
this.url = input_url;
}
void ping() {
try{
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("my proxy", 80));
Socket socket = new Socket(proxy);
long tStart = System.currentTimeMillis();
socket.connect(new InetSocketAddress(url, 80),2000);
long tEnd = System.currentTimeMillis();
rtime = tEnd-tStart;
timestamp = new Date(tStart);
InputStream sIn = socket.getInputStream();
if (sIn != null) {
status = "normal";
socket.close();
}else {
status = "error";
}
} catch(final MalformedURLException e){
status = "error";
} catch(IOException e){
status = "error";
}
}
Long get_rtime() {
return rtime;
}
Date get_timestamp() {
return timestamp;
}
String get_status() {
return status;
}
}
I also tried changing the if statement from isConnected() to
InputStream sIn = socket.getInputStream();
if (sIn != null) {
status = "normal";
socket.close();
}else {
status = "error";
}
But nothing seems to be have changed on its ability to detect connection error.
my testing file:
package ping_run_send;
import java.lang.*;
import java.util.*;
import java.io.*;
import ping_run_send.httpping;
public class main {
public static void main(String[] args){
String url = "http://google.com";
//urls like "",http://gowegwgwoJOIJOI03OINEPJPogle.#(*%" all works somehow
tcpping testTcp = new tcpping(url);
testTcp.ping();
System.out.println("tcp ping:");
System.out.println(testTcp.get_rtime());
System.out.println(testTcp.get_timestamp());
System.out.println(testTcp.get_status());
}
}
It is connecting to the Proxy. When you specify a Proxy the connection is made to the Proxy and the Proxy itself handles the connections to the real endpoint.

How to correct Invalid Protocol: null sending mail and Could not to SMTP host: using javax.mail?

I have a problem, I am using slack and mail.
I have got a method to create a folder with header "chan", but it doesn't work:
method getMessage()
for (String chan : channels){
sentMessage(chan);//поменять куда вставить
System.out.println(chan);
Enter:
"Что то пошло не такjavax.mail.MessagingException: Could not to SMTP host: localhost, port 25; nested exception is : java.net.Connection refused connect"
If I comment out
sentMessage(chan);//поменять куда вставить
I have got send message from slack to mail.
This is my program on java.
package ru.slacks;
import com.github.seratch.jslack.*;
import com.github.seratch.jslack.api.methods.SlackApiException;
import com.github.seratch.jslack.api.methods.request.channels.ChannelsListRequest;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
import com.github.seratch.jslack.api.methods.request.im.ImListRequest;
import com.ullink.slack.simpleslackapi.*;
import com.ullink.slack.simpleslackapi.SlackSession;
import com.ullink.slack.simpleslackapi.events.SlackMessagePosted;
import com.ullink.slack.simpleslackapi.impl.ChannelHistoryModuleFactory;
import static java.util.stream.Collectors.toList;
import com.ullink.slack.simpleslackapi.impl.SlackSessionFactory;
import org.glassfish.grizzly.http.server.util.StringParser;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.swing.*;
public class SlackTools {
public SlackTools() throws IOException, SlackApiException {
}
private String token=".....our_token......";
static final Slack slack = Slack.getInstance();
List<String> channels = slack.methods().channelsList(ChannelsListRequest.builder().token(token).build())
.getChannels().stream().map(c -> c.getId()).collect(toList());
public void getChannels() throws IOException, SlackApiException {
System.out.println("---------------Channels---------------");
for (String chan : channels){
sentMessage(chan);//поменять куда вставить
System.out.println(chan);
}
}
public class EmailAuthenticator extends javax.mail.Authenticator
{
private String login;
private String password;
public EmailAuthenticator (final String login, final String password)
{
this.login = login;
this.password = password;
}
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(login, password);
}
}
public void sentMessage(String chanel) throws IOException {
Properties imap = new Properties();
imap.put("mail.debug" , "false" );
imap.put("mail.store.protocol" , "imaps" );//для доступа и обработки сообщений
imap.put("mail.imap.ssl.enable", true);
imap.put("mail.imap.port", 993);
Authenticator auth = new EmailAuthenticator("tm12018#yandex.ru",
"test123456");
Session session = Session.getDefaultInstance(imap, auth);
session.setDebug(false);
try {
Store store = session.getStore();
// Подключение к почтовому серверу
store.connect("imap.yandex.ru", "tm12018#yandex.ru", "test123456");
// Папка входящих сообщений
Folder inbox = store.getFolder(chanel);
if (!inbox.exists())
if (inbox.create(Folder.HOLDS_MESSAGES))
System.out.println("Folder was created successfully");
// Открываем папку в режиме только для чтения
//inbox.open(Folder.READ_ONLY);
inbox.open(Folder.READ_WRITE);
System.out.println("Количество сообщений : " +
String.valueOf(inbox.getMessageCount()));
if (inbox.getMessageCount() == 0)
return;
} catch (NoSuchProviderException e) {
System.err.println(e.getMessage());
} catch (MessagingException e) {
System.err.println(e.getMessage());
}
}
public void getMessage() throws IOException {
Properties p = new Properties();
p.put("mail.smtp.host", "smtp.yandex.ru");//протокол передачи сообщений, или smtp.gmail.com
p.put("mail.smtp.socketFactory.port", 465);
p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
p.put("mail.smtp.auth", true);
p.put("mail.smtp.port", 465);
// p.put("mail.transport.protocol", "smtp");
Scanner in = new Scanner(System.in);
System.out.print("Enter your e-mail ");
String user = in.nextLine();
System.out.println("Enter your password");
String password = in.nextLine();
Session s = Session.getDefaultInstance(p,
new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(user, password);}});
System.out.print("Enter usernameto ");
String userto = in.nextLine();
for(String chan : channels ){
SlackSession sessiont = SlackSessionFactory.createWebSocketSlackSession(token);
sessiont.connect();
ChannelHistoryModule channelHistoryModule = ChannelHistoryModuleFactory.createChannelHistoryModule(sessiont);
List<SlackMessagePosted> messages = channelHistoryModule.fetchHistoryOfChannel(chan).stream().collect(toList());
System.out.println("---------------Messages- " + chan + "--------------");
for (SlackMessagePosted message : messages) {
System.out.println("E-mail:" + message.getUser().getUserMail() + ", message: " + message.getMessageContent() );
try {
Message mess = new MimeMessage(s);
mess.setFrom(new InternetAddress(user));
mess.setRecipients(Message.RecipientType.TO, InternetAddress.parse(userto));
mess.setSubject(message.getMessageContent().toString());
mess.setText(chan);
Transport.send(mess);
JOptionPane.showMessageDialog(null, "Письмо отправлено" );
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Что то пошло не так" + ex);
}
}
}
}
public static void main(String[] args) throws IOException, SlackApiException, MessagingException {
SlackTools sl = new SlackTools();
sl.getChannels();
sl.getMessage();
System.exit(0);
}
}
Looks like the response is telling you that there is no process (or at least not a email host) listening on your localhost port 25. Are you sure it's there? What happens when you do telnet localhost 25 ?

Java. Server don't send proper HTML

I wrote little app in Java but it don't serv HTML properly.
Problem occurs when method checkCookies return false. Normally an "else" clause should be executed but this doesn't happen. Some intresting thing - the app is going 3 times from start of handle() method to first condition (counter is increasing). I don't know how to repair it. If i got a cookie with name "Login" or i manually modify method to always return true it's working good.
Main file:
Loginpage.java
import com.sun.net.httpserver.HttpServer;
import java.net.InetSocketAddress;
public class Loginpage {
public static void main (String[] args) throws Exception{
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/form", new Form());
server.setExecutor(null);
server.start();
}
}
Form.java
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.*;
import java.net.HttpCookie;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Form implements HttpHandler {
int counter = 0;
#Override
public void handle(HttpExchange httpExchange) throws IOException {
counter++;
System.out.println(counter);
List<String> cookies = httpExchange.getRequestHeaders().get("Cookie");
HttpCookie cookie;
String response = "<html><body>system</body></html>";
String method = httpExchange.getRequestMethod();
if (checkCookies(cookies)) {
response = "<html><body> Hello! </body></html>";
} else {
if (method.equals("GET")) {
response = "<html><body><form method='post'>" +
"<input type='text' name='username'><br>" +
"<input type='password' name='pass'><br>" +
"<input type='submit' value='login'<br>" +
"</form></body></html>";
} else if (method.equals("POST")) {
InputStreamReader isr = new InputStreamReader(httpExchange.getRequestBody(), "utf-8");
BufferedReader br = new BufferedReader(isr);
String formData = br.readLine();
Map data = parseFormData(formData);
if (checkData(data)) {
cookie = new HttpCookie("Login", String.valueOf(counter + (counter * 12)));
httpExchange.getResponseHeaders().add("Set-Cookie", cookie.toString());
}
}
}
httpExchange.sendResponseHeaders(200, response.length());
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
private boolean checkCookies(List<String> cookies) {
boolean isValid = false;
for (String s : cookies) {
System.out.println(s);
if (s.matches("Login.*")) {
isValid = true;
}
}
System.out.println(isValid);
return isValid;
}
private boolean checkData(Map<String, String> data) {
DAO dao = new DAO();
String username = data.get("username");
System.out.println(username);
String password = data.get("pass");
System.out.println(password);
if (dao.checkData(username, password)) {
return true;
} else return false;
}
private static Map<String, String> parseFormData(String formData) throws UnsupportedEncodingException {
Map<String, String> map = new HashMap<>();
String[] pairs = formData.split("&");
for (String pair : pairs) {
String[] keyValue = pair.split("=");
String value = new URLDecoder().decode(keyValue[1], "UTF-8");
map.put(keyValue[0], value);
}
return map;
}
}
UPDATE
I found the cause of my problem. If I send a empty List to the checkCookies() method the program "hangs". Adding the condition
if (cookies == null) return false;
in checkCookies() method solved the problem but I do not know why it was not just return false before fix.
Can anyone explain it?

HttpClient set credentials for Kerberos authentication

I am trying to authenticate with a kerberos/HTTP host. Using Apache HttpClient as my client - and a slightly modified version of this source.
My Kerberos authentication goes perfectly fine, and I wish to know how to set the login credentials programatically. At the moment, the credentials are entered manually through the console, but I want to have it chosen by me at run time. [ As I wish to automate and load test the server with a large number of users, actually. ].
EDIT : Here is a code snippet of the relevant parts :
..
NegotiateSchemeFactory nsf = new NegotiateSchemeFactory();
httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf);
Credentials use_jaas_creds = new Credentials() {
public String getPassword() {
return null;
}
public Principal getUserPrincipal() {
return null;
}
};
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(null, -1, null),
use_jaas_creds);
HttpUriRequest request = new HttpGet("http://kerberoshost/");
HttpResponse response = httpclient.execute(request);
..
The interface Credentials has two methods - getPassword() and getUserPrincipal(), but from some debugging I did, they don't seem to be invoked at all.
What am I missing here ? What is a cleaner way to statically set the credentials ?
A very similar question had been asked before, but keytabs/login.conf hack is too cumbersome and not a practical option for an automated load test with a large number of user credentials.
Appreciate any help on this.
Because of SPNEGO the snippet code you post (Credentials class stuff setup) is not used by httpclient to authenticate.
You can use a DoAs + a CallBackhandler to pass user & password at runtime.
Then you need a login.conf or whatever the name with this inside:
KrbLogin{
com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=false debug=true useTicketCache=false;
};
You can change the name from "KrbLogin" to the name you like (remember to use the same name in your java code)
and set this with java system properties:
System.setProperty("java.security.auth.login.config", "login.conf");
or with a
-Djava.security.auth.login.config=login.config
Then you need a krb5 config file (usually krb5.ini or krb5.conf with correct configuration inside)
If your workstation (or server) is properly configured for Kerberos this class should works as is (with propper file login.conf and krb5.ini) I used httpclient 4.3.3 and java 1.7 to test it:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthSchemeProvider;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.impl.auth.SPNegoSchemeFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.io.IOException;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Set;
public class HttpClientKerberosDoAS {
public static void main(String[] args) throws Exception {
System.setProperty("java.security.auth.login.config", "login.conf");
System.setProperty("java.security.krb5.conf", "krb5.conf");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
String user = "";
String password = "";
String url = "";
if (args.length == 3) {
user = args[0];
password = args[1];
url = args[2];
HttpClientKerberosDoAS kcd = new HttpClientKerberosDoAS();
System.out.println("Loggin in with user [" + user + "] password [" + password + "] ");
kcd.test(user, password, url);
} else {
System.out.println("run with User Password URL");
}
}
public void test(String user, String password, final String url) {
try {
LoginContext loginCOntext = new LoginContext("KrbLogin", new KerberosCallBackHandler(user, password));
loginCOntext.login();
PrivilegedAction sendAction = new PrivilegedAction() {
#Override
public Object run() {
try {
Subject current = Subject.getSubject(AccessController.getContext());
System.out.println("----------------------------------------");
Set<Principal> principals = current.getPrincipals();
for (Principal next : principals) {
System.out.println("DOAS Principal: " + next.getName());
}
System.out.println("----------------------------------------");
call(url);
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
};
Subject.doAs(loginCOntext.getSubject(), sendAction);
} catch (LoginException le) {
le.printStackTrace();
}
}
private void call(String url) throws IOException {
HttpClient httpclient = getHttpClient();
try {
HttpUriRequest request = new HttpGet(url);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println("STATUS >> " + response.getStatusLine());
if (entity != null) {
System.out.println("RESULT >> " + EntityUtils.toString(entity));
}
System.out.println("----------------------------------------");
EntityUtils.consume(entity);
} finally {
httpclient.getConnectionManager().shutdown();
}
}
private HttpClient getHttpClient() {
Credentials use_jaas_creds = new Credentials() {
public String getPassword() {
return null;
}
public Principal getUserPrincipal() {
return null;
}
};
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(null, -1, null), use_jaas_creds);
Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create().register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory(true)).build();
CloseableHttpClient httpclient = HttpClients.custom().setDefaultAuthSchemeRegistry(authSchemeRegistry).setDefaultCredentialsProvider(credsProvider).build();
return httpclient;
}
class KerberosCallBackHandler implements CallbackHandler {
private final String user;
private final String password;
public KerberosCallBackHandler(String user, String password) {
this.user = user;
this.password = password;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof NameCallback) {
NameCallback nc = (NameCallback) callback;
nc.setName(user);
} else if (callback instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callback;
pc.setPassword(password.toCharArray());
} else {
throw new UnsupportedCallbackException(callback, "Unknown Callback");
}
}
}
}
}
Note:
you can use:
System.setProperty("sun.security.krb5.debug", "true");
or:
-Dsun.security.krb5.debug=true
to investigate problems.

Change AD Password with Java

I have a good connection to AD. I can authenticate and check error messages from failed auths.
The issue I'm having comes from trying to change the password. I have an LDAPContext established at this point (yes it is an SSL connection). The issue comes from not knowing what value to use in the "username" parameter. I've tried all variations I can think of and end up getting one of three errors:
A) NO_OBJECT - I'm assuming this means it is connecting to AD properly but can't find what I'm looking for.
B) DIR_ERROR - I'm assuming this means it can get into AD properly but doesn't know wtf I want it to do after that.
C) Some type of ref error that only happens when I don't qualify the DC, so I think that's pretty much a given.
Here is the code I am using:
public void changePassword(String username, String password) {
ModificationItem[] mods = new ModificationItem[1];
String newQuotedPassword = "\"" + password + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes();
try {
newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));
try {
ldapContext.modifyAttributes(username, mods);
} catch (NamingException e) {
System.out.println("Error changing password for '" + username + "': " + e.getMessage());
e.printStackTrace();
}
}
Spring has an LDAP module that works very nicely. I'll bet it will do what you need.
Here is a working example:
Main.java:
package io.fouad.ldap;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
public class Main
{
public static void main(String[] args)
{
final String LDAP_SERVERS = "ldap://AD_SERVER:636 ldap://AD_SERVER2:636"; // separated by single spaces
final String LDAP_CONNECT_TIMEOUT_MS = "10000"; // 10 seconds
final String LDAP_READ_TIMEOUT_MS = "10000"; // 10 seconds
final String AUTHENTICATION_DOMAIN = "domain.com";
final String USERNAME = "username";
final String OLD_PASSWORD = "123";
final String NEW_PASSWORD = "456";
final String TARGET_BASE_DN = "dc=domain,dc=com";
Hashtable<String, String> ldapEnv = new Hashtable<>();
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, LDAP_SERVERS);
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put("java.naming.ldap.version", "3");
ldapEnv.put(Context.SECURITY_PRINCIPAL, USERNAME + "#" + AUTHENTICATION_DOMAIN);
ldapEnv.put(Context.SECURITY_CREDENTIALS, OLD_PASSWORD);
ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
ldapEnv.put("java.naming.ldap.factory.socket", "io.fouad.ldap.MySSLSocketFactory");
//ldapEnv.put("com.sun.jndi.ldap.connect.timeout", LDAP_CONNECT_TIMEOUT_MS);
//ldapEnv.put("com.sun.jndi.ldap.read.timeout", LDAP_READ_TIMEOUT_MS);
DirContext ldapContext = null;
try
{
ldapContext = new InitialDirContext(ldapEnv);
}
catch(AuthenticationException e)
{
System.out.println("Wrong username/password!");
e.printStackTrace();
}
catch(NamingException e)
{
e.printStackTrace();
}
if(ldapContext == null) return;
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration objects = null;
try
{
objects = ldapContext.search(TARGET_BASE_DN, String.format("(&(objectClass=user)(sAMAccountName=%s))", USERNAME), searchControls);
}
catch(NamingException e)
{
e.printStackTrace();
}
if(objects == null) return;
try
{
if(objects.hasMore())
{
SearchResult entry = (SearchResult) objects.next();
ModificationItem[] mods = new ModificationItem[2];
mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute("unicodePwd", getPasswordByteArray(OLD_PASSWORD)));
mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("unicodePwd", getPasswordByteArray(NEW_PASSWORD)));
ldapContext.modifyAttributes(entry.getName() + "," + TARGET_BASE_DN, mods);
System.out.println("Successfully changed the password!");
}
else
{
System.out.println("User (" + USERNAME + ") was not found!");
}
}
catch(NamingException e)
{
e.printStackTrace();
}
System.out.println("DONE!");
}
private static byte[] getPasswordByteArray(String password)
{
String quotedPassword = "\"" + password + "\"";
try
{
return quotedPassword.getBytes("UTF-16LE");
}
catch(UnsupportedEncodingException e)
{
e.printStackTrace();
return null;
}
}
}
MySSLSocketFactory.java: (Use it at your own risk)
package io.fouad.ldap;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
public class MySSLSocketFactory extends SSLSocketFactory
{
private SSLSocketFactory socketFactory;
public MySSLSocketFactory()
{
try
{
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[] {new X509TrustManager()
{
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s){}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s){}
#Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}}, new SecureRandom());
socketFactory = ctx.getSocketFactory();
}
catch(Exception ex)
{
ex.printStackTrace(System.err);
}
}
public static SocketFactory getDefault()
{
return new MySSLSocketFactory();
}
#Override
public String[] getDefaultCipherSuites()
{
return socketFactory.getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites()
{
return socketFactory.getSupportedCipherSuites();
}
#Override
public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException
{
return socketFactory.createSocket(socket, string, i, bln);
}
#Override
public Socket createSocket(String string, int i) throws IOException
{
return socketFactory.createSocket(string, i);
}
#Override
public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException
{
return socketFactory.createSocket(string, i, ia, i1);
}
#Override
public Socket createSocket(InetAddress ia, int i) throws IOException
{
return socketFactory.createSocket(ia, i);
}
#Override
public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException
{
return socketFactory.createSocket(ia, i, ia1, i1);
}
}
We have a reference for Java fro JNDI here http://ldapwiki.willeke.com/wiki/Set%20Active%20Directory%20Password%20From%20Java
You cannot change the password of a user by just modifying the property that stores it. Instead, you need to use a special LDAP operation SetPassword. I couldn't find a Java reference, but a C# one, and a Perl one.

Categories

Resources