List a Users Server Access via Active Directory

One of our readers asked the question, "how do I get the list of servers a user has access to out of Active Directory?".  Sadly, there are so many problems with that question, I'm not sure where to begin.  The question highlights the shortcomings of Active Directory, Windows in general, and how administrators approach access control.  Before we can answer, we need to ask, "what kind of access?".  Are we talking about administrator rights? The right to logon via remote desktop?  The right to access a file share?  An application?

For that matter, not every application uses Windows rights to begin with.  Take Microsoft SQL Server for example.  It might be configured to use native SQL accounts, in which case the user may have an account that is not tied to their Windows credentials, certainly not reflected in Active Directory in any way.

A user can be granted administrator rights by adding them to the local Administrators group on that server. Active Directory won't know anything about it.  The same is true if you add the user to the Remote Desktop Users group, or you add them to the ACL of a file share, or the access list within an Active Directory enabled application.  None of it will show up in Active Directory.  This is why granting a user direct access to any resource is considered a very bad practice.

Rule: Never grant a user direct access to a resource.  Instead, put the user in an Active Directory group, and grant the group access to the resource (there are exceptions to this of course. A user's home directory and their email mailbox location are examples of places where it's OK to grant them direct access).

If you want (and you do!) to be able to see what a user has access to from within Active Directory, all access should be granted using Active Directory groups.  To grant a user administrator access to a server, an Active Directory group should be created, the group should be granted access (by making the AD group a member of the local administrators group on the server), and the user should be made a member of the group.

If all access is granted using groups, then you can simply list the groups a user is a member of, and thereby infer what they have access to.  Again, there are exceptions like the user's home directory and mailbox, that you will have to tack onto any report that you are producing.

I've seen some organizations that create an Active Directory group for every server that grants admin access, named something like servername-admin, then put a user in the groups for the servers they need admin access to.  That's fine, in that looking at their group list quickly show what they have admin access to.  However, what if the user needs admin access to hundreds of servers?  Do you add them to hundreds of groups?  Talk about token bloat!

Enter role-based access control.  If you've got a set of users that needs admin rights to a set of servers, why not create one group that grants rights to all of those servers?  Of course, it's less clear what this group grants access to by looking at the name, and if it grants access to lots of servers, you might not be able to store the server list in the description, or any other AD attribute of the group object.  So, when using role-based groups, you'll need to establish a mapping of groups to the resources they grant access to, outside of Active Directory.  Maybe you'll keep this mapping in a spreadsheet, a database, post-it notes all over the edge of your monitor (not recommended).

Hopefully, your mapping will be stored in a format that you can refer to programmatically.  Then, if you write a script to get the user's group memberships out of Active Directory, you can then have your script refer to your map to get the ultimate access that those groups provide.  This, my friends, is proper access control methodology in Active Directory.

Establishing role-based access control can be quite a challenge.  The alternative one resource/one group model makes it easy: build a server, make an admin group; make a file share, make an access group.  The complexity comes in when a new hire comes in and you have to put the user in a whole bunch of groups to grant them access to everything they need.

With the role-based model you define roles, such as Accounting Users.  You then might create an AccountingUsers group, and grant that group access to all of the servers, shares and applications that those users need.  When you build a new server or create a new share, you'll need to identify which roles need what level of access to the new server or share, and grant that role's group access.

Often, a new server or resource doesn't align with an existing role, forcing you to create a new role.  Users will end up in several role groups.  That's fine, there should be a balance between the number of group a user is in and the number of resources a group grants access to.  If you achieve such a balance, you should find that the users are members of a relatively small number of groups, and groups grant access to a relatively small number of resources.

Finally, back to the question at hand, how do you get the list of things a user has access to by querying Active Directory?  Assuming that you've already followed the advice above?  That's easy.  Get the list of groups out of Active Directory that the user is a member of.  Please read List Forest-wide Active Directory Group Memberships Using PowerShell for an example script.  The script returns a list of group memberships for a given user.  It doesn't refer to any external group-to-resource mapping database/file, that'll take a little more work on your part.

For more on token bloat and the role-based group model, please also read Avoiding Token Bloat in your Active Directory.


Anonymous said...

Actually I have an requirement for displaying all the servers for which user is having access from Active Directory/Centrify Direct Control. User is having access permission and user is assigned to some specific groups.
I need the script for getting the list of servers.

Could you please help me in this.

Thanks in advance.

Brian said...

Sorry, I know nothing of Centrify, other than it is a product for Linux/Active Directory integration. As for Active Directory, as described above, if you don't have a rational group model to show what users have access to, then the alternative is to trawl all of your servers for group memberships, ACLs, application-layer permissions, etc. Not really a feasible approach. My only advice is to do as above.

Post a Comment

Related Posts Plugin for WordPress, Blogger...