Active Directory Shared Mailbox user permissions - c#

I need to write a C# app that queries Active Directory and returns a list of users that have permission to use a certain Shared Mailbox.
I've spoken to our Support department and they say that each Shared Mailbox has an associated Security Group. And to grant a user access to a Shared Mailbox, they make the user a member of the associated Security Group.
My question is what is the link between a Shared Mailbox and a Security Group in AD? How can I work out which Security Group is associated to which Shared Mailbox?

You can use the msExchMailboxSecurityDescriptor attribute of the Shared Mailbox object in Active Directory which will give you the DACL of the Mailbox. eg How to read msExchMailboxSecurityDescriptor attribute in C#
How can I work out which Security Group is associated to which Shared Mailbox?
There is no direct way other then enumerated each DACL on each Shared Mailbox. Autodiscover will return all the Mailboxes a particular user has access to if the are automapped via the AlternativeMailbox element https://msdn.microsoft.com/en-us/library/ee237925(v=EXCHG.80).aspx.
Cheers
Glen
Edit See the Full assembly names you should be able to work the rest out yourself
byte[] DaclByte = (Byte[])DirectoryEntry.Properties["msExchMailBoxSecurityDescriptor"][0];
System.DirectoryServices.ActiveDirectorySecurity adDACL = new ActiveDirectorySecurity();
adDACL.SetSecurityDescriptorBinaryForm(DaclByte);
System.Security.AccessControl.AuthorizationRuleCollection aclCollection = adDACL.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier));
foreach (System.Security.AccessControl.AuthorizationRule ace in aclCollection)
{

I had a similar requirement. The AD field on the mailbox account that I ended up using was publicDelegates:
mailboxDirectoryEntry.publicDelegates
This contains a list of distinguishedNames of userids or groups that have been granted access via Outlook delegation capabilities.
For this specific question, you could then list the members of the group(s) you obtain from publicDelegates.
Transitive membership can be obtained with the
member:1.2.840.113556.1.4.1941:=
selector on your query. (Very handy if your organization uses nested groups)

Related

Does .IsInRole work for SIDS in the sidhistory attribute?

We are migrating to another network and are trying to prepare our code base. Our existing groups and members will be imported to new groups on our new domain, and the existing group SID will be in the SID history of the newly created groups.
We currently use IsInRole to check user membership in groups. Does this method also check the SID history attribute? We have no way of populating the SID History attribute ourselves to test this.
The source code for IsInRole is available. Lines 166 to 169 show how it works:
// CheckTokenMembership will check if the SID is both present and enabled in the access token.
if (!Interop.Advapi32.CheckTokenMembership((_identity.ImpersonationLevel != TokenImpersonationLevel.None ? _identity.AccessToken : token),
sid.BinaryForm,
ref isMember))
This looks for the group's SID in the access token of the user. The token is created when the user is authenticated and includes the SIDs of all security (not distribution) groups (and nested groups) that the user is a member of.
The documentation Using SID History to Preserve Resource Access says:
After migrating an account and maintaining the SID history of the source domain account, when a user logs on to the target domain, both the new SID and the original SID from the SID history attribute are added to the access token of the user and determine the local group memberships of the user. The SIDs of the groups in which the user is a member are then added to the access token, together with the SID history of those groups.
So that sounds like the SID history of both the user and the group are used when building the access token.

WindowsIdentity - Difference between Groups and Claims

I'm trying to check whether the User belongs to some groups by using SID-s.
I was using WindowsIdentity.Groups, but then noticed that sometimes it doesn't show that the user belongs to the Administrators group.
After searching a while, I've discovered that instead WindowsIdentity.Claims work fine (includes the admin group in the results as well).
I wasn't able to find proper documentation on Claims.
So, what is the difference between the Groups and Claims in WindowsIdentity, and why groups don't show administrators group while the Claims do?
And finally, can I safely use Claims instead of Groups?
Here's the code I have:
var wi = WindowsIdentity.GetCurrent();
var sidToFind = "S-1-5-32-544"; // Hardcoded the sid of administrators group for demo, but in general this is a parameter of a function on my side
// This will NOT include the sid S-1-5-32-544
var groupSids= wi.Groups
.Where(item => item.Value == sidToFind);
// This will include the sid S-1-5-32-544 and also all the other results that Groups provides.
var claimSids = wi.Claims
.Where(item => item.Value == sidToFind));
There are differencies between groups and claims.
Groups work with WORKGROUP and AD
Claims work with Active Directory Federation Services
Claims is more complex way to check user identity, because claims exists not only for ADFS, you can use or create additional claims token provider
When we call Groups method for WindowsIdentity, we have restriction:
// Ignore disabled, logon ID, and deny-only groups.
The role of claims
In the claims-based identity model, claims play a pivotal role in the
federation process, They are the key component by which the outcome of
all Web-based authentication and authorization requests are
determined. This model enables organizations to securely project
digital identity and entitlement rights, or claims, across security
and enterprise boundaries in a standardized way.
So, if you work only in NTLM - you can safty work with Groups, but if you want work via federation (for example SharePoint, Google, etc) - you must use claims. Claims contains groups, but groups not contain claims.
In order to answer the question why you do not see a certain group, you need to know its properties and location. As I wrote above and gave the link, there are restrictions on getting the list of groups. But here i found this info:
SID
Name
Description
S-1-5-32-544
Administrators
A built-in group. After the initial installation of the operating system, the only member of the group is the Administrator account. When a computer joins a domain, the Domain Admins group is added to the Administrators group. When a server becomes a domain controller, the Enterprise Admins group also is added to the Administrators group.
So, if your local admins group is disabled - you cannot see it when you get it via WindowsIdentity even if the user is included in it.

How can I securely ensure the current user belongs to an Active Directory Group?

I am creating a C# Winform Application which will be used in a corporate domain (Windows Active Directory). The app is to behave as the following:
When a user opens the App, the App checks if the current user is part of an Active Directory group.
If it is, the app then allows the user to use the app.
From google searches, I found several ways how to check if a user is part of an Active Directory group.
For example in the link here => How to check if a user belongs to an AD group?
My concern is the security part of this. What if someone spoofs a username and domain. He won't need to know the password to allow access to the app.
Don't do a look up. The SID of every group the user is a member of (recursively) is part of the user's login token. So you can just use WindowsPrincipal.IsInRole(). If you only have the name of the group, you can give it that:
var currentUser = new WindowsPrincipal(WindowsIdentity.GetCurrent());
currentUser.IsInRole("SomeGroup")
That translates the name into the SID and checks the login token for that SID. That requires a network request. If you can give it the SID of the group instead, then you can save that network request:
var groupSid = new SecurityIdentifier("S-1-5-21-blah");
currentUser.IsInRole(groupSid)

Finding user's groups SIDs inside Sharepoint

I need to find out all AD groups SIDs that current user belongs to inside my Sharepoint (2007) webpart.
I wanted to use System.DirectoryServices.AccountManagement namespace:
using (var context = new PrincipalContext( ContextType.Domain ))
{
using (var user = UserPrincipal.FindByIdentity( context, accountName ))
{
var groups = user.GetAuthorizationGroups();
...
}
}
, but I get the following error:
Event ID: 10016
Through the permission settings (application specific) is the SID (S-1-5-20) for user NT AUTHORITY \ NETWORK SERVICE of address localhost (Using LRPC) is not authorized to activate (Local) for the COM Server application with CLSID
{61738644-F196-11D0-9953-00C04FD919C1}
This might be fixed with this http://support.microsoft.com/kb/899965
but this approach requires changing registry values (the ownership of the application, so you can change apps values at dcomcnfg) and later User Permissions at dcomcnfg's COM security, which isn't an option for me.
Is there another way to access Current user's groups SIDs inside Sharepoint?
I really hoped I can find these values in SPContext.Current.Web.CurrentUser.Groups, but apparently not.
You need to go the SharePoint way here and not use System assemblies, but the SharePoint ones.
The SID of each user is in the SPUser.Sid Property. As you want to look for AD groups only you can check the .IsDomainGroup Property of SPUser.
Now all you need to do is check the current user: ´SPContext.Current.Web.CurrentUser(aSPUser` object).
To answer your question how to get all groups a user belongs to, you actually will need to use System.DirectoryServices. A solution for your problem is shown in the following stackoverflow posts:
In C#, how to access Active Directory to get the list of groups that a certain user belongs to?
Querying AD for finding all groups of a user - Missing one group
So in short: SPUser object as well as querying the Active Directory via DirectoryServices

How do you add an Active Directory user to SharePoint using WSS?

Is it possible to introduce existing AD users into SharePoint using WSS?
If I create a new list item manually, and there is a User / People Picker field in the list, if I type a username in the field and submit, SP finds the user and adds it in as a SP user.
Why does that not work when adding new items through WSS? I cannot get WSS to recognize a user by username, email, or first name last name.
Any ideas?
My guess is that your System Account is probably not in the AD Domain, check the Application Pool for your SharePoint site and see whether it is running with a domain account.
I found a way to avoid messing with the SharePoint System Account user.
I called the AddUserToGroup method in the UserGroup service.
A byproduct of calling the above method is the addition of the user as a SharePoint user.

Categories