Dynamic distribution groups: Which DDGs is user part of? - active-directory

I know how to get all the members of a dynamic distribution group: I can take the distribution group, get the AD filters from msExchDynamicDLFilter and msExchQueryFilter properties and query the AD for the users who match that filter.
Now, how do I go the other way? E.g. show which dynamic distribution groups a user is part of? Is there any better way than taking all the hundreds of dynamic distribution groups from AD, resolving each of them, one after the other, and looking whether the user is in the resolved list?

No there is not. DDGs where created for Exchange. So upon message submission, the DDGs are resolved.
That being said, you can only retrieve all DDGs, do the queries and check to see which one yield the desired user.

Related

Ldapsearch and groups and Active Directory

I am trying to get a list of groups/users using ldapsearch.
Most the searches I have seen show that the way to only enabled/active users are to use a query similar to the following:
(&(objectCategory=person)
(objectClass=user)
(sAMAccountType=805306368)
(!(userAccountControl:1.2.840.113556.1.4.803:=2))
(sAMAccountName=<username>))
The issue I am having is I need a list of ALL AD Groups and their Users that are active with the disabled users removed.
Typically I have seen groups pulled with something like this
(&(objectClass=group)(member=*))
This query pulls the groups and users but pulls ALL users disabled and enabled.
What I need is a way to accomplish both.
So far I have tried combining the commands but it has proven to be unsuccessful.
(&(objectCategory=group)
(objectclass=group)
(!(isCriticalSystemObject=TRUE))
(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
Is there a way to accomplish the task of pulling only enabled users while still getting all the groups?
The problem is that by querying groups objectclass=group, you can only filter which groups, not which member (active or not) of those groups, so you would have to intersect the members (all) of each group with the set of active users, which implies another query to grab those users in the first place, and a bit more client code to process the results.
The good news is that AD implements the memberOf attribute, so you can do the other way around, searching for all active users and list the groups they belong to by reading this attribute.

Performant query to find all reacheable nodes

I'm studying AWS Neptune with Gremlin to build a permission system.
This system would have basically 3 types of vertices: Users, Permissions and Groups.
A group has 0..n permissions
A user can have 0..n groups
A user can be directly connected to 0..n permissions
A user can be connected to another user, in which case it "inheritates" that user permission's
A group can be inside of another group, that is inside of another group.... so on.
I'm looking for a performant query to find all permissions for a given user.
This graph may get really huge so to stress it out I have build a 17kk user vertices graph, created 10 random edges for each one of them and then created a few permissions.
Then the query I was using to get all permissions is obviouly running forever... n_n'
What I'm trying is simply:
g.V('u01')
.repeat(out())
.until(hasLabel('Permission'))
.simplePath()
Is there a better query to achieve it? Or maybe even a better modeling for this scenario?
I was thinking that maybe my 10 random edges have created a lot of cycles and connections that "make no sense" and thats why the query is slow. Does it make sense?
Thanks in advance!
You probably running in circles. You should write it like this:
g.V('u01')
.repeat(out().simplePath())
.until(hasLabel('Permission'))
It is also preferable the use specific label in the out step to avoid traversing irrelevant paths.

SOLR Permissions / Filtering Results depending on Access Rights

For example I have Documents A, B, C. User 1 must only be able to see Documents A, B. User 2 must only be able to see Document C. Is it possible to do it in SOLR without filtering by metadata? If I use metadata filter, everytime there are access right changes, I have to reindex.
[update 2/14/2012] Unfortunately, in the client's case, change is frequent. Data is confidential and usually only managed by the owners which are internal users. Then the specific case is they need to be able to share those documents to certain external users and specify access levels for those users. And most of the time this is an adhoc task, and not identified ahead of time
I would suggest storing the access roles (yes, its plural) as document metadata. Here the required field access_roles is a facet-able multi-valued string field.
Doc1: access_roles:[user_jane, manager_vienna] // Jane and the Vienna branch manager may see it
Doc2: access_roles:[user_john, manager_vienna, special_team] // Jane, the Vienna branch manager and a member of special team may see it
The user owning the document is a default access role for that document.
To change the access roles of a document, you edit access_roles.
When Jane searches, the access roles she belongs to will be part of the query. Solr will retrieve only the documents that match the user's access role.
When Jane (user_jane), manager at vienna office (manager_vienna) searches, her searches go like:
q=mainquery
&fq=access_roles:user_jane
&fq=access_roles:manager_vienna
&facet=on
&facet.field=access_roles
which fetches all documents which contains user_jane OR manager_vienna in access_roles; Doc1 and Doc2.
When Bob, (user_bob), member of a special team (specia_team) searches,
q=mainquery
&fq=access_roles:user_bob
&fq=access_roles:special_team
&facet=on
&facet.field=access_roles
which fetches Doc2 for him.
Queries adapted from http://wiki.apache.org/solr/SimpleFacetParameters#Multi-Select_Faceting_and_LocalParams
Might want to check the Document level Security patches.
https://issues.apache.org/jira/browse/SOLR-1872
https://issues.apache.org/jira/browse/SOLR-1834
I think my approach would be similar to #aitchnyu's answer. I would however NOT use individual users in the meta data.
If you create groups for each document, then you will have to reindex for security reason less often.
For a given document, you might have access_roles: group_1, group_3
In this way, the group_1 and group_3 always retain rights to the document. However, I can vary what groups each user belongs to and adjust the query accordingly.
When the query then is generated, it always passes as a part of the query the user's groups. If I belong to group_1 and group_2, my query will look like this:
q=mainquery
&fq=access_roles:group_1
&fq=access_roles:group_2
Since the groups are dynamically generated in the query, I simply remove a user from the group, and when a new query is issued, they will no longer include the removed group in the query. So removing the user from group_1 would new create a query like this:
q=mainquery
&fq=access_roles:group_2
All documents that require group 1 will no longer be accessible to the user.
This allows most changes to be done in real-time w/out the need to reindex the documents. The only reason you would have to reindex for security reasons is if you decided that a particular group should no longer have access to a document.
In many real-world scenarios, that should be a relatively uncommon occurrence. It seems much more likely that HR documents will always be available to the HR department, however a specific user may not always be part of the HR group.
Hope that helps.
You can implement your security model using Solr's PostFilter. For more information see http://searchhub.org/2012/02/22/custom-security-filtering-in-solr/
Note: you should probably cache your access rights otherwise performance will be terrible.
Keeping in mind that solr is pure text based search engine,indexing system,to facilitate fast searching, you should not expect RDMS style capabilities from it. solr does not provide security for documents being indexed, you have to write such an implementation if you want. In that case you have two options.
1)Just index documents into solr and keep authorization details into RDBMS.Now query solr for your search and collect the results returned.Now fire another query to DB for the doc ids returned by solr to see if the user has an access to them or not.Filter out those documents on which user in action has no access.You are done ! But not really, your problem starts from here only.Assume, what if all results returned by solr gets filtered out ? (Assuming you are not accessing all the documents at a time,means you are retrieving top 1000 results only from solr result set,otherwise you can not get fast search) You have to query solr again for next bunch of result set and have to iterate these steps until you get enough results to display.
2)Second approach to this is to index authorization meta data along with document in solr.Same as aitchnyu has explained.But to answer your query for document sharing to an external user,along with usergroup and role detail, you index these external user's userid into access_roles field or you can just add an another field to your schema 'access_user' too. Now you can modify search queries for external user's sharing to include access_user field into your filter query.
e.g
q=mainquery
&fq=access_roles:group_1
&fq=access_user:externaluserid
Now the most important thing, update to an indexed documents.Well its off course tedious task, but with careful design and async processing along with solrs partial document update feature(solr 4.0=>), you can achieve reasonably good TPS with solr. If you are using solr <4.0 you can have separate systems for both searching and updates and with care full use of load balancer and master slave replication strategies you will have smile on your face !
There are no built in mechanisms for Solr that I am aware of that will allow you to control access to documents without maintaining the rights in the metadata. The approach outlined by aitchnyu seems reasonable if you keep it a true role level and not assign user specific permissions to a document. That way you can assign roles to users and this will grant them the ability to see documents in the index. Granted you will still need to reindex documents when the roles change, but hopefully you can identify most of the needed roles ahead if time and reduce the need for frequent reindexing.

Is it possible to LDAP query users common to a set of groups

I need a list of all the users common to a known collection of groups, using a single LDAP query of our Active Directory. It would seem, from the our reading so far, that such is not possible, but I thought it best to ask the hive mind.
Try this:
(&(objectCategory=Person)
(&
(memberOf=CN=group1,dc=company,dc=local)
(memberOf=CN=group2,dc=company,dc=local)
(memberOf=CN=group3,dc=company,dc=local)
)
)
This is similar to my question, except there I wanted all users who were NOT members of groups. You'll need to delete all the whitespace for most query tools to work.
Yes it's possible with an attribute scoped query. It requires W2K3 AD or later but will give you the all of the users that have a particular attribue i.e. membership in a group or in your case multiple groups (intersection of groups). One of the best examples is from Joe Kaplan and Ryan Dunns book "The .NET Developers Guide to Directory Services Programming" for AD work it's hard to beat look at page 179 for a good walk through.
Caveat:At this point you are past trivial searches in AD and a number of things are becoming important like the search root, scope and the effect of searching through some potentially HUGE set of data for the items you want. Looking through 50 or 60K users to find the members of a group does have an effect on performance and be prepared to do paged results or similar in case the dataset is large. Kaplan/Ryan do an excellent job of down to earth work to get you where you need to be. That said, I have used them on two AD projects with great success. Being able retrieve the data from AD without recursive queries is VERY worth while and I found that it is fast as long as I control the size of my dataset.
It's not possible in a single query if your groups contain nested groups.
You would need to write some code that recursively resolves the group members and does the logical equivalent of an "inner join" on the results, producing a list of users that are common to all the original groups.

LDAP filter for searching students

I am fairly new to LDAP and AD. I want to create an LDAP filter to show all the students in the AD. But the problem is that the students are in different BASE DN:
OU=STUDENTS,OU=USERS,OU=SOE,OU=FOAE,OU=UNIVERSITY,DC=sepang
OU=STUDENTS,OU=USERS,OU=SOMLC,OU=FOAE,OU=UNIVERSITY,DC=sepang
OU=STUDENTS,OU=USERS,OU=SOCS,OU=FOS,OU=UNIVERSITY,DC=sepang
i.e for each student it is like
CN =khx72b,OU=STUDENTS,OU=USERS,OU=SOCS,OU=FOS,OU=UNIVERSITY,DC=sepang
As you can see students from different faculties are in different places.
Given an username how can I search and find if the given user is in the directory?
The objectClass for all the students is 'user'.
As it seems you are searching for objects of type 'user' which are in OUs called 'STUDENTS' but otherwise have no common parent.
This cannot be done in one step (i.e. with a single LDAP query).
You must either retrieve all OUs named 'STUDENTS' and use them as Base DNs one by one, like you've already indicated.
Or you find a property that all students share (a direct group membership, for example, or a special value somewhere) and use that as the filter. This is a more dangerous approach since nothing guarantees that every student actually has the feature you rely on - some might have been not entered into AD correctly.
Tomalak, is right, Microsoft does provide many attributes that you could use for this purpose such as "employeeType", "comment", "department", "company", "department", "divison", etc, but the problem with these is that they are not prepopulated with any information that can help you now. You can start using one of these for future purposes, but then you must maintain that practice in order for it to be consistent. I thing the easiest solution for you is to probably put each of the users into a group that is named similar to the OU name, which should be an really easy task if they're currently in the same OU. then once this is done you can easily create a LDAP query which will then look at the membership of that group like this:
((objectCategory=person)(objectClass=user)(memberOf=CN=STUDENTS GROUP,OU=USERS,OU=SOCS,OU=FOS,OU=UNIVERSITY,DC=sepang))
Please note when using the "memberOf" in an LDAP filter the search value must be a complete string to a group, and so you CAN'T use a wildcard such as: memberOf=CN=STUDENTS GROUP*).
You will still have to maintain a practice that you or someone or something (such as an automated schedule script task) which maintains the group membership to ensure that your LDAP query will be accurate.
I did see this post which says what your trying to do is possible without having to do anything extra by "Matching Components of Distinguished Names", but I have never seen this before and I could not get it to work. Also take a look at this tutorial on ADO searches to learn more about these things work
Search for objects in an OU by setting "searchRoot" to teh LDAP path to the OU. all searches will then be confined to that OU.

Resources