Check attribute change permission before doing context.Update() ?

Jul 16, 2012 at 2:31 PM

Hi there,

Do you know of a way to check if the currently logged on user has permission to change an AD attribute, before doing a context.Update()?

For example: an application allows users to update their own mobile phone number in AD, but we cannot know in advance if every user has permission to do so. I would like to be able to enable/disable an update button according to permissions, instead of catching a DirectoryOperationException and check the inner exception (The user has insufficient access rights).

Ideas welcome, thanks!

Coordinator
Jul 18, 2012 at 5:14 AM
Edited Jul 18, 2012 at 5:16 AM

Hi,

You are in luck.  There's an excellent answer to this on StackOverflow here.  The tricky part is the connection has to be made as the user.  If you have integrated authentication setup for your app then you shouldn't have to do anything special.  If not, then the connection has to be made as that user.  Here's a code sample demonstrating both ways.  I hope this helps.

//no integrated authentication
string userName = "user name";
string password = "password";
var connectionFactory = new LdapConnectionFactory("localhost")
    .AuthenticateAs(new NetworkCredential(userName, password));

using (var connection = connectionFactory.GetConnection())
{
    var user = connection.Query("OU=Users,DC=server,DC=com", log: _configuration.Log)
        .Where(da => Filter.Equal(da, "sAMAccountName", userName))
        .Select("allowedAttributesEffective")
        .FirstOrDefault();

    var editableAttributes = user.GetStrings("allowedAttributesEffective");

    if (editableAttributes != null && editableAttributes.Contains("mobilePhone", StringComparer.OrdinalIgnoreCase))
    {
        //user can edit mobile phone
    }
}

//integrated authentication
using (var context = new DirectoryContext()) //or however you get your context
{
    var editableAttributes = context.Query<User>()
        .Where(u => u.SamAccountName == "user name")
        .Select(u => u.EditableAttributes) //this should be mapped as a string[] or Collection<string>
        .FirstOrDefault();

    if (editableAttributes != null && editableAttributes.Contains("mobilePhone", StringComparer.OrdinalIgnoreCase))
    {
        //user can edit mobile phone
    }
}
Jul 19, 2012 at 9:43 AM

Thank you! I got it working. I'm using integrated authentication, your solution is a lot easier than I hoped for. I will create an extension method for the properties in my User class, so I can call a .CanEdit on all properties. Thanks for your great work on LINQ to LDAP (and your comprehensive blog).