Private and shared address book with LDAP? - ldap

For a set of users belonging to some organisation, I want to provide the following:
each user should have a private address book
each user should have access to a company address book
I wonder how to model this scenario in LDAP so that:
user connects to LDAP server with some client
user performs a search for some string
all matching entries from the global address book are returned
all matching entries from the user's private address book are returned
Is searching the global and private address book possible with a single query? I guess the user would provide his path in LDAP as DN, but the global address book would be located at a different DN. I imagine something like that:
/
/OU=private-address-books
/CN=user1
/CN=entry1
...
/OU=global-address-book
/CN=entryABC
So is it possible to somehow automatically reference the global address book under the user's private address book?

You would probably be best off to arrange your DIT Structure to be more like:
ou=private,ou=Addressbooks...
ou=public,ou=Addressbooks...
You then could search using the the ou=addressbooks as the baseDN.
Or better, assign an Attribute boolean type private=TRUE to each entry.
So for all addressbooks,
(objectClass=Entry)
And for private
(&(objectClass=Entry)(private=TRUE))
And then finally, you may be able to use an ExtensibleMatch search filter to search both containers.
-jim

Related

Finding duplicate users in a user list (Asked in an Interview)

I was recently asked this in an interview for a SDE role.
Suppose you have a list of User objects
class User {
String userId;
String email;
String ip_addr;
}
where userId field is unique among all users, while ip_addr and email are not necessarily so.
and you know some users have more than one user account (if any two User objects share a common email OR an ip_addr, you classify them as belonging to the same user).
you are required to write a function, whose signature is given as:
List<List<User>> findDups(User[] userList) {
// code here
}
[EDIT] so for example, if there are 7 users, only 2 of which are unique, the function can return something like the following (not necessarily in this specific order):
{
{user1, ip1, email1},
{user5, ip5, email1},
{user24, ip5, email2}
},
{
{user2, ip2, email2},
{user7, ip2, email7},
{user8, ip2, email0},
{user19, ip19, email7}
}
here, in this first group, the first user (user1) is the same user as the second one (user5) as they share the same email address. We also know that the third user (user24) is also the same user as it shares the same ip address (ip5) as the second user in the list.
[/END EDIT]
what data structure would you use and what would be the time complexity of the proposed solution?
I tried to use disjoint set union (quick union), which would give me linear complexity, however the interviewer constantly tried to steer me away from that and said just the Collection API would be enough (Using Lists and Sets and maps).
What would be your approach and solution and the corresponding time complexity?

how to recognize object's responsibility?

I'm new in OOP and I just started learning it. Its too complicated to determine the functionality of classes. Let's take an example:
We have an Address-book and an user want to add a new contact to it.
In this scenario we have 2 classes:
User: that determine the user that logged in.
Contact: A contact object that consists of Name, Address, Phone Number, etc
And the questions:
Who have to save a new contact?User class or Contact Class
If we try to check the user's permission before doing anything where is the best place for it?
Is it OK that these classes have a access to database?(Is it better to create 3rd class for doing query stuffs?)
Thanks for any good idea ;)
Usable distribution of "responsibility" is an OOP design and architecture decision with no single simple correct answer. For discussion refer to Stack Overflow question What is the single most influential book every programmer should read?
You'll learn the pros/cons by coding (using someone's design or creating your own design which does not work well).
However there are some useful/frequent distributions of responsibility already known as http://en.wikipedia.org/wiki/Software_design_pattern
In my opinion the only fixed fact is that each class/function/structure should have its responsibility clearly defined/documented - since the very first lines of code - and "do one thing and do it well"
Contacts are user specific. Thus every user object (class instance) should contain its own contacts object which is a container of contact (other user) objects, comprising in turn of name, address, phone etc.
class User {
String name;
String phone;
String address;
Contacts contacts;
....
}
class Contacts {
List<User> items;
}
The Contacts class should have the implementation of saving a new contact, which needs to be called from a User method, something like the following.
User u;
Contacts c = u.getContacts();
c.addContact(name, address, phone);
User's permissions should be checked in the User class.
The methods of these classes should interface with the database. For this each class method can open a new connection to a database and execute SQL queries. Example method of User cass:
User getContact(String name) {
Connection conn = getConnection();
....
PreparedStatement ps = con.prepareStatement("select * from Contacts where name = ?");
...
return userRcd;
}
1) Save new contact must the separate class, which working directly with database
2) Best place to check user permission - in user class of course
3) See the item 1:)
I recommend you get strong knowledge about SOLID principles, it's basics for good design.

How do ldap search for email address in contacts' 2nd/3rd alternate email addresses?

I have an LDAP server with my email contacts so that I can lookup contacts by name/email, etc. However, it only seems to search and find the first email address for any contact.
For example, if I have a person:
LastName: Doe
FirstName: John
Email: jdoe#work.com
Email2: johndoe#home.com
Email3: johndoe#fun.com
It only searches through or returns the first email. For example, if I search for "John", it will return only the "jdoe#work.com" even though the other two email addresses have "john" in them. The search filters I've tried are:
//This one will both look through and match the first email but ignores the 2nd/3rd
(|(displayName=*%v*)(mail=*%v*)(uid=*%v*)(givenname=*%v*)(sn=*%v*)(cn=*%v*))
//This one throws an error saying "mail2" and "mail3" are invalid filters.
(|(displayName=*%v*)(mail=*%v*)(mail2=*%v*)(mail3=*%v*)(uid=*%v*)(givenname=*%v*)(sn=*%v*)(cn=*%v*))
What should I be using?
Also, does anyone have a link to some page that lists all the possible filters I can put in an ldap person search?
Exchange does not store additional mailaddresses in fields like mail2 or mail3. All addresses are stored in the multi-valued field "proxyAddresses". This field contains one line for each address in the form of
address-type:address
Example:
smtp:test#contoso.local
SMTP:user#contoso.local
The second entry in the example would be main address for that account, because the SMTP prefix is all uppercase.
So you would search for (proxyAddress=%v) or something like that. I don't know the LDAP search syntax out of my head.
Edit: Another option is to use the ResolveNames operation of the EWS webservices (see http://www.infinitec.de/post/2009/04/13/Resolving-the-primary-email-address-with-Exchange-WebServices-ResolveNames-operation.aspx and http://msdn.microsoft.com/en-us/library/aa563518(v=exchg.140).aspx).
The filter:
(|(displayName=*%v*)(mail=*%v*)(uid=*%v*)(givenname=*%v*)(sn=*%v*)(cn=*%v*))
will not match the entry:
LastName: Doe
FirstName: John
Email: jdoe#work.com
Email2: johndoe#home.com
Email3: johndoe#fun.com
because none of the filter assertions match any of the attribute names in the given entry.
(|(Email=jd*)(Email2=john*)(Email3=john*)(lastName=Do*))
would match. Have you considered using the standard names for the example entry you give?
Active Directory was released with some schema choices that are questionable. Now it is hard to fix them.
One of those is that mail, was flagged as single valued. This should have been a multivalued attribute. Thus the use of proxyAddresses, where it tries to overload a string syntax attribute with more information by using smtp: or x500: or SIP: to indicate a protocol for the address. Then upper case (SMTP) means primary and lower case (smtp) means secondary.
This also occured for telephoneNumber being single valued, and extra values now overflow into the attribute otherPhone.
Same for:
facsimileTelephoneNumber and otherFacsimileTelephoneNumber
labelledUri and url
homePhone and otherHomePhone
pager and otherPager
mobile and otherMobile

What is used to login in LDAP mail server?

If I added data on LDAP in this way:
$ldapserver = "mail";
$ds = ldap_connect($ldapserver);
$r = ldap_bind($ds, $ldaprootun, $ldaprootpw);
add = ldap_add($ds, "cn=$full_name,ou=$domain,o=mygroup.com", $infonew);
Then does that mean that when I log in to my account I will use:
`cn="mynameHere",ou="domainIused",o=mygroup.com`
as my username? Or just my uid?
My account cannot login but I'm sure that it exists in LDAP.
Answers are very much appreciated. =)
Typically in LDAP applications you only ned to login with your UID, not your full X.500 name.
Try calling ldap_bind() with your creds and see what it returns?
Usually, the user provides a simple name. Then the app searches the LDAP source for some attribute that has that value. Then you bind or password compare in your code, as that full DN.
You can use uid which is Unique ID, which is required to be unique. I.e. If you find more than one instance of it, that is an error.
You can try CN, but that can often be multi valued depending on your LDAP implementations schema.
If you know you are going against eDirectory, then uid is fine, or CN just do something if it is multi valued.
If you know you are going against Active Directory, you can assume sAMAccountName is unique since the system enforces uniqueness. userPrinicpalName ought to be unique, but nothing actually enforces it.
You can always use mail, which is the email address pretty uniformly.

How to get the recipient addresses within an IPM.DistList?

I'm trying to get the recipient addresses within an IPM.DistList that is stored in a public folder (of type contacts) in Exchange 2003.
The typeName of the object is a Message (with a parent object being a Messages collection) and the messageType is "IPM.DistList".
I can find documentation about IPM.DistListItems. DistListItems documentation lists no parent possibilities in MSDN.
We have an Exchange 2003 info store with Public Folders. Within those Public Folders is a [sub]folder (that holds items of type "Contact") that has distribution lists (IPM.DistList's) that have contact entries, members of the list essentially.
I need to get the addresses of the members of the lists in the Public Folder sub-folder.
Well, it's been over a year, but I feel some obligation to answer this question now that I've found it. The answer was, I think, that no documentation exists on this secret bit of Exchange, but was able to iterate through the list of addresses within each ipm.distlist by something like this:
for a = 0 to list.count-1
emladdress = list(a)(a).value
next
I don't know why "(a)(a)" works, but you have to have both of them there. And I don't actually remember if it was a zero-based index, so that's a guess. Good luck, and hopefully you can migrate your users off Exchange and into google apps. Seriously!