Performing DNS "ANY" Lookup using Java JNDI - java

I am using Java JNDI to perform DNS lookups using the following basic syntax as per the SSCCE below, but I am trying to query all records using the "ANY" attribute:
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
public class SSCCE {
public static void main(String[] args) {
try {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
InitialDirContext idc = new InitialDirContext(p);
Attributes attrs = idc.getAttributes("netnix.org", new String[] { "* *" });
Attribute attr = attrs.get("* *");
if (attr != null) {
for (int i = 0; i < attr.size(); i++) {
System.out.println("Found " + (String)attr.get(i));
}
}
else {
System.out.println("Found nothing");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
My question is around being able to query a resource type of "ANY" which should return all the DNS resource records associated with a specific domain - example below using the "host" utility.
chrixm#puffy(:):~$ host -t ANY netnix.org
netnix.org has SPF record "v=spf1 include:_spf.google.com ~all"
netnix.org mail is handled by 10 aspmx2.googlemail.com.
netnix.org mail is handled by 5 alt1.aspmx.l.google.com.
netnix.org mail is handled by 1 aspmx.l.google.com.
netnix.org mail is handled by 5 alt2.aspmx.l.google.com.
netnix.org mail is handled by 10 aspmx3.googlemail.com.
netnix.org name server ns-1154.awsdns-16.org.
netnix.org name server ns-941.awsdns-53.net.
netnix.org name server ns-61.awsdns-07.com.
netnix.org name server ns-1880.awsdns-43.co.uk.
I have read http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/jndi-dns.html, which says:
Superclass attribute identifiers are also defined. These may be useful when querying records using the DirContext.getAttributes() method. If an attribute name has "*" in place of a type name (or class name), it represents records of any type (or class). For example, the attribute identifier "IN *" may be passed to the getAttributes() method to find all internet class records. The attribute identifier "* *" represents records of any class or type.
However, Java JNDI doesn't understand a resource record of "*" or "* *" as the above code doesn't return any records (I am able to query "NS" or "SOA", etc individually) - has anyone had any experience of getting this working. I can of course query each individual resource type, but considering there is a valid record type of "ANY" as per RFC 1035 (Type ID 255) this seems very inefficient?

After examining the methods of the Attributes class I noticed a getAll() method. After further searching I was able to implement the following which now allows you to search using "*" as the record type and print all the records.
Attributes attrs = idc.getAttributes("netnix.org", new String[] { "*" });
NamingEnumeration<?> ae = attrs.getAll();
while (ae.hasMore()) {
Attribute attr = (Attribute)ae.next();
for (int i = 0; i < attr.size(); i++) {
Object a = attr.get(i);
if (a instanceof String) {
System.out.println(attr.getID() + " " + a);
}
else {
System.out.println(attr.getID() + " NOT ASCII");
}
}
}
ae.close();

You're inventing semantics here. There is no support anywhere in JNDI for "* *" as either an attribute set or an attribute name. The correct syntax for 'all attributes' as an attribute set to return is "*", and the correct way to enumerate them all is via Attributes.getAll().

Related

Ldap search by email value can't find records

I have written a Java application that searches Active directory via LDAP for user information. I have a list of instances of custom Person class that is passed in. In it I have either DN or email defined. I am modifying the search criteria accordingly. Here is the code:
for (Person person : members) {
boolean ready = false;
String filter = getConfig().getUserSearchFilter();
// (&(|(objectclass=user)(objectclass=person)(objectclass=inetOrgPerson)(objectclass=organizationalPerson)))
String base = person.getDistinguishedName();
if (base != null && !base.isEmpty()) {
ready = true;
} else if (person.getEmail() != null) {
base = getConfig().getMemberSearchBase();
// ou=Users,ou=Managed,dc=division,dc=company,dc=com
String mail = person.getEmail();
StringBuilder filterBuilder = new StringBuilder(filter);
int pIdx = filterBuilder.lastIndexOf(")");
filterBuilder.insert(pIdx, "(|(mail=" + mail + ")(x-personalmail=" + mail + "))");
filter = filterBuilder.toString();
LOG.debug("New value of a filter = {}", filter);
ready = true;
}
if (ready) {
try {
NamingEnumeration<SearchResult> search = getContext().search(base, filter, searchControls);
...
} catch (NamingException nex) {
throw new IOException(nex);
}
} else {
LOG.error("Incorrect search criteria for user {} of group {}. Person skipped", person.getName(), this.group.getName());
}
}
Code is working without errors, but when DN is specified it does find a person, but when email is defined it finds nothing.
However, If I copy generated filter string and pass it to ldapsearch command in a form of:
ldapsearch -LLL -x -H ldaps://my.ldap.server.com -D 'svc-acct#corp-dev.company.com' -W -b "ou=Users,ou=Managed,dc=division,dc=company,dc=com" '(&(|(objectclass=user)(objectclass=person)(objectclass=inetOrgPerson)(objectclass=organizationalPerson))(|(mail=person#domain.com)(x-personalmail=person#domain.com)))'
It does find this person perfectly.
Did anyone faced similar problem? Do you see any flaws in my code?
Please, do help me.
I did find the cause of my problem.
In the search control I had scope defined as OBJECT_SCOPE.
It does work when you are specifying DN, but with the search per one of the fields it fails finding the object.
I changed the scope to SUBTREE_SCOPE and everything started working as expected.

EWS Java - hasAttachments return false for inline/Embedded attachments

I'm reading email with inline/embedded images, mostly sender signature image.
But when I try to find if the email.hasAttachments() it returns false, but If I Inspect email.getAttachments(); it shows me the inline attachments. here is my code, am I doing something wrong.
try {
Item itm = Item.bind(service, itemId, new PropertySet(
BasePropertySet.FirstClassProperties,
ItemSchema.Attachments,ItemSchema.HasAttachments,
ItemSchema.extendedProperties));
emailMessage = EmailMessage.bind(service, itm.getId(),
new PropertySet(BasePropertySet.FirstClassProperties,
EmailMessageSchema.Attachments, EmailMessageSchema.HasAttachments));
log.info(From: " + emailMessage.getFrom());
log.info(Subject: " + emailMessage.getSubject());
log.info(Received: " + emailMessage.getDateTimeReceived());
//get email attachments.
attachments = getEmailAttachments(emailMessage, properties);
}
//getEmailAttachments() method.
try {
//check if the email has attachments.
if (emailMessage.getHasAttachments()) { //returns false here
//get all the attachments
AttachmentCollection attachmentsCol = emailMessage.getAttachments();// will return the attachments
log.info("File Count: " +attachmentsCol.getCount());
//loop over the attachments
for (int i = 0; i < attachmentsCol.getCount(); i++) {
Attachment attchment = attachmentsCol.getPropertyAtIndex(i);
if (attchment.getIsInline()) {
log.info("There is an inline attachment.");
}
//FileAttachment - Represents a file that is attached to an email item
if (attchment instanceof FileAttachment) {
//my code here
} else if (attchment instanceof ItemAttachment) { //ItemAttachment - Represents an Exchange item that is attached to another Exchange item.
//my code here
}
}
HasAttachments is a calculated property who's value is based on other props. One property that Outlook can set that affects this is the SmartNoAttach property (you can see the value of this prop in a Mapi Editor) which effectively hides the Paperclip in outlook where a message has an Inline attachment like signature (and no real attachments). But it will also affect this properties value in EWS.

accountExpires attribute not listed when read from Java

Hello Java and AD experts..
I am having an issue while reading accountExpires attribute value from AD. When I read this attribute using Java code, I got the result null.
Then I thought of checking various attributes provided by AD by printing the all the AD attributes using the following code:
Attributes allAttrs = ldapCtx.getAttributes(distinguishedName);
System.out.println("Total no.of properties: " + allAttrs.size());
try{
String attrs = "";
for (NamingEnumeration ae = allAttrs.getAll(); ae.hasMore();) {
Attribute attr = (Attribute) ae.next();
attrs = attrs+"\nFor attribute: "+ attr.getID()+" values are - ";
/* print each value */
for (NamingEnumeration e = attr.getAll(); e.hasMore(); attrs = attrs + e.next()+";");
}
System.out.println(attrs);
}
catch(Exception e){
System.out.println("Exception in getAttribute: " + e);
}
It had listed 72 properties. And accountExpires property itself is not present there :(
Can anyone guide me why this property is not available in my case and how to get rid of this
Regards,
FH
It wont list any account expiration attribute. You need to calculate it. Suppose your password expiration limit is 90 days and you need to send a warning mail to the user when there is 10 days left for expiration. You will get account created date, find the number of days between the account created date and current date if the difference is 80 then send a warning mail.

Lotus Notes - Mail Document - Principal/From,INetFrom, SentTime, ReceivedTime fields

I have a requirement to fetch the SenderName,SenderEmail,ToNames,ToEmails,CCNames,CcEmails from a lotus notes document instance.
Issue1
Looking into lotus.domino.Document API I found out the method getItems. When I write the elements to the system.out values for SenderEmail, ToEmails and CcEmails can be found.
However values for SenderName(a.k.a From), ToNames cannot be derived that easily.
The values seems to be using an common name format. For example check check my system.output below.
Principal = "CN=Amaw Scritz/O=fictive"
$MessageID = "<OF0FF3779B.36590F8A-ON80257D15.001DBC47-65257D15.001DC804#LocalDomain>"
INetFrom = "AmawScritz#fictive.com"
Recipients = "CN=Girl1/O=fictive#fictive"
MailOptions = "0"
SaveOptions = "1"
From = "CN=Amaw Scritz/O=fictive"
AltFrom = "CN=Amaw Scritz/O=fictive"
SendTo = "CN=Girl1/O=fictive#fictive"
CopyTo = "CN=Girl2/O=fictive#fictive"
BlindCopyTo = ""
InetSendTo = "Girl1#fictive.com"
InetCopyTo = "Girl2#fictive.com"
$Abstract = "sasdasda"
$UpdatedBy = "CN=Amaw Scritz/O=fictive"
Body = "Hello World"
The question is how can I get 'Amaw Scritz' from the common name 'CN=Amaw Scritz/O=fictive'. Is there any look up mechanism that can be used. (I would prefer to have a option other than doing a substring of the common name)
Issue2
is it possible to retrieve SentTime and ReceivedTime from mail document instance?
I know that there are two methods called getCreated and getLastModified. getCreated can be loosely associated with the SentTime and getLastModified can be loosely associated with ReceivedTime. Are there are other ways to get times for SentTime and ReceivedTime.
Issue3
How can one distinguish whether a mail document is a Sent mail or a Received Mail?
Issue1
You can use Name class.
Here example from this link:
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
// Create a hierarchical name
Name nam = session.createName(
"CN=John B Goode/OU=Sales/OU=East/O=Acme/C=US");
// Returns:
// John B Goode
// John B Goode/Sales/East/Acme/US
// CN=John B Goode/OU=Sales/OU=East/O=Acme/C=US
System.out.println(nam.getCommon());
System.out.println(nam.getAbbreviated());
System.out.println(nam.getCanonical());
} catch(Exception e) {
e.printStackTrace();
}
}
}
Issue2
Use values of PostedDate field and DeliveredDate field of mail document.
Issue3
Check that $Inbox folder contains your mail document. Or take a look at Dave Delay answer.
I agree with #nempoBu4 on Issues 1 and 2. I disagree with the answer to Issue 3. A received message can be removed from the inbox, so checking $Inbox doesn't help you distinguish between sent and received messages.
Assuming you have the document open, the best approach is to check two items. Sent and received messages both have a PostedDate item, but only a received message has a DeliveredDate item. Incidentally, a draft message has neither PostedDate or DeliveredDate.

Get all values from LDAP entries (with same names) and store them in Lotus Notes with Java

I am retrieving account information from an LDAP/AD via JNDI from an agent in Lotus Notes. That works just fine. My problem are the atrributes/values with equal names e.g. there are ObjectClass and ObjectType which are availible multiple times in the entry. I want to store the values as a multitext entry in LotusNotes with the following code
for (NamingEnumeration ae = atts.getAll(); ae.hasMore();) {
Attribute attr = (Attribute) ae.next();
Item mItem = newDoc.getFirstItem(fPre + "_" + attr.getID());
if(mItem == null){
newDoc.replaceItemValue(fPre + "_" + attr.getID(), attr.get());
}else{
mItem.appendToTextList("" + attr.get());
}
}
But I only get always one value. So do I accessing the entry in the LDAP/AD the wrong way or is the storing in Notes wrong (is not possible to access the Item without saving, like it is possible with LotusScript)?
Thanks
Armin

Categories