UserPrincipal.FindByIdentity returns null if SQL related calls are present else it returns the correct Principal object

StackOverflow https://stackoverflow.com/questions/9287350

Question

I have this weird issue. I am trying to create a service that synchs the users in database to users in Email groups in Active Directory(AD). So if A, B, C are in database and the active directory email group has A & E, I will synch the AD. So I will add 'E' and remove 'B' & 'C'.

To get users from database I execute SQL calls. And after that if I try to add the user I get UserPrincipal.FindByIdentity as null. Here is a test code I have put up.

        int tries = 0;
        List<string> dbUsers = new List<string>();
        dbUsers.Add("12345");//test user id's
        dbUsers.Add("67891");

        int k = 0;
        for (k = 0; k < dbUsers.Count; k++)
        {
            AddUserToGroup(tries, dbUsers[k]);
        }

     public void AddUserToGroup(int tries, string userid)
     {
        try
        {
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain,      domainName, Container, userName, Password);

            Principal user = Principal.FindByIdentity(ctx, userid); 
            string groupName = "TestGroup";

            using (ctx)
            {
                GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, groupName);
                if (!user.IsMemberOf(group))
                {
                    group.Members.Add(ctx, IdentityType.UserPrincipalName, user.UserPrincipalName);
                    group.Save();
                }
            }
        }
        catch (AppDomainUnloadedException ex)
        {
            if (tries > 5)
            {
                throw;
            }
            tries += 1;
            Thread.Sleep(1000);
            AddUserToGroup(tries, userid);
        }
    }

This piece works perfectly and I get the 'user' object correctly and I can successfully add it to AD email group. Problem is when I have SQL call to get userId's from Database instead of hard coding.

So the code that is problematic is:

      List<string> dbUsers = GetActiveMembersFromDB('id')
      public List<string> GetActiveMembersFromDB(string practiceGroupId)
      {
        List<string> outpt = new List<string>();
        string SQLstring = string.Empty;

        string SQL_CONNECTION_STRING = "connectionString"; 
        SQLstring = "SELECT * from dbo.test";//whatever query

        using (SqlConnection cn = new SqlConnection(SQL_CONNECTION_STRING))
        {
            cn.Open();
            try
            {
                SqlCommand cm = new SqlCommand(SQLstring, cn);

                using (SqlDataReader dr = cm.ExecuteReader())
                {
                    if (dr.HasRows)
                    {
                        while (dr.Read())
                        {
                            outpt.Add(dr["userId"].ToString());
                        }
                        return outpt;
                    }
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                if (cn != null)
                {
                    SqlConnection.ClearPool(cn);
                    cn.Close();
                }
            }
        }
        return outpt;
    }

So after fetching users from DB, if I call:

        int k = 0;
        for (k = 0; k < dbUsers.Count; k++)
        {
            AddUserToGroup(tries, dbUsers[k]);
        }

My 'user' is coming back as null.

Has anyone else encountered the same problem. What's wrong with DB calls and AD calls together. I mean, I close all connections in my db calls and then try to access the Active Directory(AD).

Any help is appreciated.

Thanks, Deeksha

Was it helpful?

Solution

There should be no problem mixing AD and SQL. Your only coupling is List<string>. If the strings work in one case and the same string don't work in another, it shouldn't have anything to do with how you got the strings, but something different in the environment or on the thread, like the security context or similar.

I think you need to distill it down to the smallest test case which shows the problem.

I notice that your username and password are defined outside of the code given - have you checked and made sure you aren't overwriting them?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top