Esempio n. 1
0
        public string ResolveGroupName(string name)
        {
            ImportedPrincipalInfo info = ResolveInfo(name, this.Groups);

            if (info == null)
            {
                return(null);
            }
            return(info.LoginName);
        }
Esempio n. 2
0
        public Principal ResolveGroup(ClientContext ctx, string name)
        {
            ImportedPrincipalInfo info = ResolveInfo(name, this.Groups);

            if (info == null)
            {
                return(null);
            }
            return(info.Resolve(ctx));
        }
Esempio n. 3
0
        public Principal ResolveUser(ClientContext ctx, string name)
        {
            // dm_group is ignored because there is no analog in SharePoint
            if (name == DM_GROUP)
            {
                return(null);
            }
            ImportedPrincipalInfo info = ResolveInfo(name, this.Users);

            if (info == null)
            {
                return(null);
            }
            return(info.Resolve(ctx));
        }
Esempio n. 4
0
        public string ResolveUserName(string name)
        {
            // The "special" names get...well..."specialed handling"
            switch (name)
            {
            case DM_OWNER:
            case DM_GROUP:
            case DM_WORLD:
                return(name);

            default:
                break;
            }
            ImportedPrincipalInfo info = ResolveInfo(name, this.Users);

            if (info == null)
            {
                return(null);
            }
            return(info.Name);
        }
Esempio n. 5
0
        private Dictionary <string, ImportedPrincipalInfo> generateGroupMappings(DirectoryEntry ldapDirectory, string ldapSyncAlias, string fallbackName, string internalName)
        {
            Dictionary <string, ImportedPrincipalInfo> groups = new Dictionary <string, ImportedPrincipalInfo>();
            string domain = ((string)ldapDirectory.Properties["name"][0]).ToUpper();

            Log.Info(string.Format("Loading LDAP Groups from {0}", ldapDirectory.Path));
            Dictionary <string, ImportedPrincipalInfo> groupsByGUID  = new Dictionary <string, ImportedPrincipalInfo>();
            Dictionary <string, ImportedPrincipalInfo> groupsByLogin = new Dictionary <string, ImportedPrincipalInfo>();

            XmlReader cache       = LoadCache(ldapDirectory, "groups");
            bool      cacheLoaded = false;

            if (cache != null)
            {
                try
                {
                    using (cache)
                    {
                        int c = 0;
                        Log.Info("Loading groups from the cache...");
                        while (cache.ReadToFollowing("entry"))
                        {
                            ImportedPrincipalInfo info = new ImportedPrincipalInfo(XElement.Load(cache.ReadSubtree()));
                            groupsByGUID[info.Guid]       = info;
                            groupsByLogin[info.LoginName] = info;
                            if ((++c % PAGE_SIZE) == 0)
                            {
                                Log.Info(string.Format("Loaded {0} users from the cache", c));
                            }
                        }
                        cacheLoaded = true;
                    }
                }
                catch (Exception e)
                {
                    groupsByGUID.Clear();
                    groupsByLogin.Clear();
                    Log.Warn(string.Format("Failed to load data from the group cache for LDAP directory [{0}] (for {1})", ldapDirectory.Path, domain), e);
                }
                finally
                {
                    cache = null;
                }
            }

            if (!cacheLoaded)
            {
                using (DirectorySearcher ldapSearch = new DirectorySearcher(ldapDirectory))
                {
                    ldapSearch.Filter   = "(objectClass=group)";
                    ldapSearch.PageSize = PAGE_SIZE;
                    using (SearchResultCollection ldapResults = ldapSearch.FindAll())
                    {
                        int c = 0;
                        foreach (SearchResult r in ldapResults)
                        {
                            ImportedPrincipalInfo info = new ImportedPrincipalInfo(r, domain);
                            groupsByGUID[info.Guid]       = info;
                            groupsByLogin[info.LoginName] = info;
                            if ((++c % ldapSearch.PageSize) == 0)
                            {
                                Log.Info(string.Format("Loaded {0} groups", c));
                            }
                        }
                    }
                }

                List <string> logins = new List <string>(groupsByLogin.Keys);
                List <ImportedPrincipalInfo> items = new List <ImportedPrincipalInfo>(groupsByLogin.Count);
                logins.Sort();
                foreach (string l in logins)
                {
                    items.Add(groupsByLogin[l]);
                }
                try
                {
                    StoreCache(ldapDirectory, "groups", items);
                }
                catch (Exception e)
                {
                    Log.Warn(string.Format("Failed to write the group cache for the LDAP directory at [{0}] (domain {1})", ldapDirectory.Path, ldapDirectory.Name), e);
                }
            }

            // Step 2: sanitize the fallback groups.  Their non-existance is an error
            if ((fallbackName != null) && !groupsByLogin.ContainsKey(fallbackName))
            {
                fallbackName = null;
            }
            if ((internalName != null) && !groupsByLogin.ContainsKey(internalName))
            {
                internalName = null;
            }

            // Step 3: Scan through the XML file generating the mappings for the groups being referenced
            using (XmlReader groupsXml = this.ImportContext.LoadIndex("groups"))
            {
                Log.Info(string.Format("Loaded {0} LDAP groups, resolving the groups in XML...", groupsByGUID.Count));
                while (groupsXml.ReadToFollowing("group"))
                {
                    using (XmlReader groupxml = groupsXml.ReadSubtree())
                    {
                        XElement   group  = XElement.Load(groupxml);
                        XNamespace ns     = group.GetDefaultNamespace();
                        string     name   = (string)group.Element(ns + "name");
                        string     source = (string)group.Element(ns + "source");
                        string     type   = (string)group.Element(ns + "type");

                        IEnumerable <XElement> attributes = group.Element(ns + "attributes").Elements(ns + "attribute");
                        ImportedPrincipalInfo  info       = null;
                        switch (source)
                        {
                        case "LDAP":
                            string ldapGuid = ((string)attributes.FirstOrDefault(a => a.Attribute("name").Value == "dctm:group_global_unique_id")).ToLower().Trim();
                            // ldapGuid will be of the form DIRECTORY:hexGuid, so we have to parse the directory name.  If it's the same directory
                            // as our domain uses, then we can search by guid directly.  Otherwise, we have to search by samaccountname
                            string[] data = ldapGuid.Split(':');
                            if (data[0] == ldapSyncAlias && groupsByGUID.ContainsKey(data[1]))
                            {
                                info = groupsByGUID[data[1]];
                            }

                            if (info == null)
                            {
                                // Either not the same domain, or couldn't find the GUID in question, so...
                                if (groupsByLogin.ContainsKey(name))
                                {
                                    info = groupsByLogin[name];
                                }
                                else
                                if (fallbackName != null)
                                {
                                    info = groupsByLogin[fallbackName];
                                }
                            }
                            break;

                        default:
                            string key = (name.StartsWith("dm_") || name.StartsWith("${") ? internalName : fallbackName);
                            if (key != null)
                            {
                                info = groupsByLogin[key];
                            }
                            break;
                        }

                        if (info != null)
                        {
                            groups[name] = info;
                        }
                    }
                }
                // Make sure the fallbacks are in place
                if (fallbackName != null && !groups.ContainsKey(fallbackName))
                {
                    groups[fallbackName] = groupsByLogin[fallbackName];
                }
                if (internalName != null && !groups.ContainsKey(internalName))
                {
                    groups[internalName] = groupsByLogin[internalName];
                }
            }
            return(groups);
        }
Esempio n. 6
0
        private Dictionary <string, ImportedPrincipalInfo> generateUserMappings(DirectoryEntry ldapDirectory, string ldapSyncAlias, string fallbackName, string internalName)
        {
            Dictionary <string, ImportedPrincipalInfo> users = new Dictionary <string, ImportedPrincipalInfo>();
            // Step 1: Get all the AD users in one pass - this is quicker
            string domain = ((string)ldapDirectory.Properties["name"][0]).ToUpper();

            Log.Info(string.Format("Loading LDAP Users from {0} (domain = {1})", ldapDirectory.Path, domain));
            Dictionary <string, ImportedPrincipalInfo> usersByGUID       = new Dictionary <string, ImportedPrincipalInfo>();
            Dictionary <string, ImportedPrincipalInfo> usersByLogin      = new Dictionary <string, ImportedPrincipalInfo>();
            Dictionary <string, ImportedPrincipalInfo> usersByKerberosId = new Dictionary <string, ImportedPrincipalInfo>();

            XmlReader cache       = LoadCache(ldapDirectory, "users");
            bool      cacheLoaded = false;

            if (cache != null)
            {
                try
                {
                    using (cache)
                    {
                        int c = 0;
                        Log.Info("Loading users from the cache...");
                        while (cache.ReadToFollowing("entry"))
                        {
                            ImportedPrincipalInfo info = new ImportedPrincipalInfo(XElement.Load(cache.ReadSubtree()));
                            if (info.Enabled)
                            {
                                usersByGUID[info.Guid]       = info;
                                usersByLogin[info.LoginName] = info;
                                if (info.KerberosId != null)
                                {
                                    usersByKerberosId[info.KerberosId] = info;
                                }
                            }
                            if ((++c % PAGE_SIZE) == 0)
                            {
                                Log.Info(string.Format("Loaded {0} users from the cache", c));
                            }
                        }
                        cacheLoaded = true;
                    }
                }
                catch (Exception e)
                {
                    usersByGUID.Clear();
                    usersByLogin.Clear();
                    usersByKerberosId.Clear();
                    Log.Warn(string.Format("Failed to load data from the user cache for LDAP directory [{0}] (for {1})", ldapDirectory.Path, domain), e);
                }
                finally
                {
                    cache = null;
                }
            }

            if (!cacheLoaded)
            {
                using (DirectorySearcher ldapSearch = new DirectorySearcher(ldapDirectory))
                {
                    ldapSearch.Filter   = "(&(objectClass=user)(objectCategory=person))";
                    ldapSearch.PageSize = PAGE_SIZE;
                    using (SearchResultCollection ldapResults = ldapSearch.FindAll())
                    {
                        int c = 0;
                        foreach (SearchResult r in ldapResults)
                        {
                            ImportedPrincipalInfo info = new ImportedPrincipalInfo(r, domain);
                            if (info.Enabled)
                            {
                                usersByGUID[info.Guid]       = info;
                                usersByLogin[info.LoginName] = info;
                                if (info.KerberosId != null)
                                {
                                    usersByKerberosId[info.KerberosId] = info;
                                }
                            }
                            if ((++c % ldapSearch.PageSize) == 0)
                            {
                                Log.Info(string.Format("Loaded {0} users", c));
                            }
                        }
                    }
                }

                List <string> logins = new List <string>(usersByLogin.Keys);
                List <ImportedPrincipalInfo> items = new List <ImportedPrincipalInfo>(usersByLogin.Count);
                logins.Sort();
                foreach (string l in logins)
                {
                    items.Add(usersByLogin[l]);
                }
                try
                {
                    StoreCache(ldapDirectory, "users", items);
                }
                catch (Exception e)
                {
                    Log.Warn(string.Format("Failed to write the user cache for the LDAP directory at [{0}] (domain {1})", ldapDirectory.Path, ldapDirectory.Name), e);
                }
            }

            // Step 2: sanitize the fallback users.
            if ((fallbackName != null) && !usersByLogin.ContainsKey(fallbackName))
            {
                fallbackName = null;
            }
            if ((internalName != null) && !usersByLogin.ContainsKey(internalName))
            {
                internalName = null;
            }

            // Step 3: Scan through the XML file generating the mappings for the users being referenced
            using (XmlReader usersXml = this.ImportContext.LoadIndex("users"))
            {
                Log.Info(string.Format("Loaded {0} LDAP users, resolving the users in XML...", usersByGUID.Count));
                while (usersXml.ReadToFollowing("user"))
                {
                    using (XmlReader userXml = usersXml.ReadSubtree())
                    {
                        XElement   user      = XElement.Load(userXml);
                        XNamespace ns        = user.GetDefaultNamespace();
                        string     name      = (string)user.Element(ns + "name");
                        string     source    = (string)user.Element(ns + "source");
                        string     loginName = (string)user.Element(ns + "loginName");
                        string     osName    = (string)user.Element(ns + "osName");

                        IEnumerable <XElement> attributes = user.Element(ns + "attributes").Elements(ns + "attribute");
                        ImportedPrincipalInfo  info       = null;
                        switch (source)
                        {
                        case "LDAP":
                            string ldapGuid = ((string)attributes.FirstOrDefault(a => a.Attribute("name").Value == "dctm:user_global_unique_id")).ToLower().Trim();
                            // ldapGuid will be of the form DIRECTORY:hexGuid, so we have to parse the directory name.  If it's the same directory
                            // as our domain uses, then we can search by guid directly.  Otherwise, we have to search by samaccountname
                            string[] data = ldapGuid.Split(':');
                            if (data[0] == ldapSyncAlias && usersByGUID.ContainsKey(data[1]))
                            {
                                info = usersByGUID[data[1]];
                            }

                            if (info == null)
                            {
                                // Either not the same domain, or couldn't find the GUID in question, so...
                                if (usersByLogin.ContainsKey(loginName))
                                {
                                    info = usersByLogin[loginName];
                                }
                                else
                                if (usersByLogin.ContainsKey(osName))
                                {
                                    info = usersByLogin[osName];
                                }
                                else
                                if (fallbackName != null)
                                {
                                    info = usersByLogin[fallbackName];
                                }
                            }
                            break;

                        case "dm_krb":
                            // We do things differently here...
                            if (usersByKerberosId.ContainsKey(osName))
                            {
                                info = usersByKerberosId[osName];
                            }
                            else
                            if (usersByLogin.ContainsKey(loginName))
                            {
                                info = usersByLogin[loginName];
                            }
                            else
                            if (fallbackName != null)
                            {
                                info = usersByLogin[fallbackName];
                            }
                            break;

                        default:
                            if (name.StartsWith("dm_"))
                            {
                                if (internalName != null)
                                {
                                    info = usersByLogin[internalName];
                                }
                            }
                            else
                            {
                                if (usersByLogin.ContainsKey(loginName))
                                {
                                    info = usersByLogin[loginName];
                                }
                                else
                                if (usersByLogin.ContainsKey(osName))
                                {
                                    info = usersByLogin[osName];
                                }
                                else
                                {
                                    string key = (name.StartsWith("${") ? internalName : fallbackName);
                                    if (key != null)
                                    {
                                        info = usersByLogin[key];
                                    }
                                }
                            }
                            break;
                        }

                        if (info != null)
                        {
                            users[name] = info;
                            if (name.StartsWith("${"))
                            {
                                users[loginName] = info;
                            }
                        }
                    }
                }
                // Make sure the fallbacks are in place
                if (fallbackName != null && !users.ContainsKey(fallbackName))
                {
                    users[fallbackName] = usersByLogin[fallbackName];
                }
                if (internalName != null && !users.ContainsKey(internalName))
                {
                    users[internalName] = usersByLogin[internalName];
                }

                // Add the DM_WORLD mapping
                users[DM_WORLD] = new ImportedPrincipalInfo(EVERYONE_NAME, null, EVERYONE_ID);
            }
            return(users);
        }