Beispiel #1
0
        static void Main()
        {
            try
            {
                //Begin - Section 1: Enable Logging
                EnableLogging();
                //End - Section 1

                //Begin Section 2: - Get SSDP object
                var syncServDp   = new SynchronizationServiceDataProvider(_logger);
                var syncServices = syncServDp.GetServiceConfigurations();
                //End - Section 2

                //Begin Section 3: - Start The Service
                if (Debugger.IsAttached)
                {
                    var debugConfig = syncServDp.GetServiceConfiguration(DebugConfigID);
                    //Launch the Service
                    LDAPSyncService.Sync(debugConfig.DataItems[0].ConfigID);
                }
                else
                {
                    var servicesToRun = new List <ServiceBase>();

                    foreach (var serviceConfigurationModel in syncServices.DataItems)
                    {
                        switch (serviceConfigurationModel.ConfigTypeID)
                        {
                        //This determines all the service configuration for the LDAP that needs to be run
                        case ((int)ConfigType.LDAP):
                        {
                            if (debugMode)
                            {
                                EventLog.WriteEntry("SynchronizationService", "Adding service for ConfigXML " + serviceConfigurationModel.ConfigXML, EventLogEntryType.Information);
                            }

                            if (debugLogFileMode)
                            {
                                using (StreamWriter sw = File.AppendText("Log.txt"))
                                {
                                    sw.WriteLine("Adding service for ConfigXML " + serviceConfigurationModel.ConfigXML);
                                }
                            }

                            servicesToRun.Add(new LDAPSynchronizationService(serviceConfigurationModel.ConfigID));
                            break;
                        }
                        }
                    }
                    ;

                    ServiceBase.Run(servicesToRun.ToArray());
                }
                //End Section 3
            }
            catch (Exception e)
            {
                EventLog.WriteEntry("SynchronizationService", "Error launching services: " + e.Message, EventLogEntryType.Error);
            }
        }
Beispiel #2
0
        protected override void OnStart(string[] args)
        {
            var syncServ = new SynchronizationServiceDataProvider(_logger);
            var config   = syncServ.GetServiceConfiguration(_configID).DataItems[0];

            using (XmlReader reader = XmlReader.Create(new StringReader(config.ConfigXML)))
            {
                // get the services that need to be started, and their intervals, from the db
                reader.ReadToFollowing("Timer");
                reader.ReadToDescendant("Interval");
                reader.MoveToFirstAttribute();
                var interval = Convert.ToDouble(reader.Value);

                _timerClock.Elapsed += delegate { LDAPSyncService.Sync(_configID); };
                _timerClock.Interval = interval * 60 * 1000; // interval (in minutes) to execute process
                _timerClock.Enabled  = true;
            }
        }
        //public static void Sync(Object source, ElapsedEventArgs e)
        public static void Sync(int configID)
        {
            _debugMode        = ConfigurationManager.AppSettings["Debug"] != null && Convert.ToBoolean(ConfigurationManager.AppSettings["Debug"]);
            _debugLogFileMode = ConfigurationManager.AppSettings["DebugLogFile"] != null && Convert.ToBoolean(ConfigurationManager.AppSettings["DebugLogFile"]);

            // first lets get our current config, in case something has been updated
            var syncServ = new SynchronizationServiceDataProvider(_logger);
            var config   = syncServ.GetServiceConfiguration(configID).DataItems[0];


            // we only want to run this service is we have an active config for it
            // todo: the plan is at some point to have a network monitoring tool to set which configs are active, so services on multiple servers know if they should be running or not
            // NOTE: by having the services continue to check their configs, the configs can be changed
            if (_debugMode)
            {
                EventLog.WriteEntry("SynchronizationService", "Using the following ConfigXML: " + config.ConfigXML, EventLogEntryType.Information);
            }
            if (_debugLogFileMode)
            {
                using (StreamWriter sw = File.AppendText("Log.txt"))
                {
                    sw.WriteLine("Using the following ConfigXML: " + config.ConfigXML);
                }
            }

            if (config != null && config.IsActive != null && (bool)config.IsActive)
            {
                /*
                 * config.ConfigXML reads from the DB the configuration database containing
                 * SyncServer
                 *  - ProcessingServer
                 * Timer
                 *  - Interval
                 * LDAPServer
                 *  - LDAPPath
                 *  - LDAPUserFilter
                 *  - LDAPRoleFilter
                 *  - Name
                 *  - Port: Defaultvalue="389"
                 */
                using (XmlReader reader = XmlReader.Create(new StringReader(config.ConfigXML)))
                {
                    // create a directory identifier and connection,
                    reader.ReadToFollowing("SyncServer");
                    reader.ReadToDescendant("ProcessingServer");
                    reader.MoveToFirstAttribute();
                    var processingServer = reader.Value;

                    reader.ReadToFollowing("LDAPServer");
                    reader.ReadToDescendant("LDAPPath");
                    reader.MoveToFirstAttribute();
                    var ldapPath = reader.Value;
                    reader.ReadToFollowing("LDAPUserFilter");
                    reader.MoveToFirstAttribute();
                    var ldapUserFilterFromConfig = reader.Value;
                    reader.ReadToFollowing("LDAPRoleFilter");
                    reader.MoveToFirstAttribute();
                    var ldapRoleFilterFromConfig = reader.Value;

                    if (_debugMode)
                    {
                        EventLog.WriteEntry("SynchronizationService",
                                            "Sync Server host name should be " + System.Net.Dns.GetHostName() +
                                            ", ldap sync server configured is " + processingServer +
                                            ", ldap path configured is " + ldapPath +
                                            ", ldap user filter configured is " + ldapUserFilterFromConfig +
                                            ", ldap role filter from config is " + ldapRoleFilterFromConfig,
                                            EventLogEntryType.Information);
                    }

                    if (_debugLogFileMode)
                    {
                        using (StreamWriter sw = File.AppendText("Log.txt"))
                        {
                            sw.WriteLine("Sync Server host name should be " + System.Net.Dns.GetHostName() +
                                         ", ldap sync server configured is " + processingServer +
                                         ", ldap path configured is " + ldapPath +
                                         ", ldap user filter configured is " + ldapUserFilterFromConfig +
                                         ", ldap role filter from config is " + ldapRoleFilterFromConfig);
                        }
                    }
                    //Till here make sure that you have the right configuration on the right machine

                    // we need to look at the previous batch to know which updates to start requesting, as well as to make sure its completed before starting a new batch
                    var lastBatch = syncServ.GetLastBatch(config.ConfigID); // the batches are by config, not config type, as you can have more than 1 config for a given type
                    if (
                        processingServer == System.Net.Dns.GetHostName() &&

                        // we want to make sure we have the ldap info we need to pull what we need from AD
                        (
                            ldapPath != string.Empty && ldapUserFilterFromConfig != string.Empty && ldapRoleFilterFromConfig != string.Empty
                        )

                        &&

                        // only proceed w/ a new AD request, once the last request has been completed
                        (
                            lastBatch.DataItems.Count < 1 ||
                            (lastBatch.DataItems[0] != null && lastBatch.DataItems[0].BatchStatusID >= (int)BatchStatus.Completed)
                        )
                        )
                    {
                        var usnChanged = (lastBatch.DataItems.Count > 0) ? lastBatch.DataItems[0].USN : 0;

                        var ldapUserFilter = ldapUserFilterFromConfig.Replace(_usnChangedToken, usnChanged.ToString());
                        if (_debugMode)
                        {
                            EventLog.WriteEntry("SynchronizationService", "Searching AD for users using ldap filter string: " + ldapUserFilter, EventLogEntryType.Information);
                        }
                        if (_debugLogFileMode)
                        {
                            using (StreamWriter sw = File.AppendText("Log.txt"))
                            {
                                sw.WriteLine("Searching AD for users using ldap filter string: " + ldapUserFilter);
                            }
                        }
                        var resultsUsers = SearchAD(ldapPath, ldapUserFilter);

                        var ldapRolesFilter = ldapRoleFilterFromConfig.Replace(_usnChangedToken, usnChanged.ToString());
                        if (_debugMode)
                        {
                            EventLog.WriteEntry("SynchronizationService", "Searching AD for roles using ldap filter string: " + ldapRolesFilter, EventLogEntryType.Information);
                        }
                        if (_debugLogFileMode)
                        {
                            using (StreamWriter sw = File.AppendText("Log.txt"))
                            {
                                sw.WriteLine("Searching AD for roles using ldap filter string: " + ldapRolesFilter);
                            }
                        }
                        var resultsRoles = SearchAD(ldapPath, ldapRolesFilter);

                        // we only want to create a new batch, if there are actually results to be processed
                        if ((resultsUsers != null && resultsRoles != null) && (resultsUsers.Count > 0 || resultsRoles.Count > 0))
                        {
                            // add this new request to the db
                            var batch = new ServiceBatchModel {
                                BatchStatusID = (int)BatchStatus.Requesting, BatchTypeID = (int)BatchType.ADSynService, ConfigID = config.ConfigID, USN = _lastUSN + 1, IsActive = true
                            };
                            batch.BatchID = syncServ.AddBatch(batch).ID;
                            if (_debugMode)
                            {
                                EventLog.WriteEntry("SynchronizationService", "Batch created, ID: " + batch.BatchID, EventLogEntryType.Information);
                            }
                            if (_debugLogFileMode)
                            {
                                using (StreamWriter sw = File.AppendText("Log.txt"))
                                {
                                    sw.WriteLine("Batch created, ID: " + batch.BatchID);
                                }
                            }

                            var dtUsers = BuildUsersDataTable(resultsUsers, batch.BatchID, ldapPath);
                            if (_debugMode)
                            {
                                EventLog.WriteEntry("SynchronizationService", "Inserting users into UserStage table.", EventLogEntryType.Information);
                            }
                            if (_debugLogFileMode)
                            {
                                using (StreamWriter sw = File.AppendText("Log.txt"))
                                {
                                    sw.WriteLine("Inserting users into UserStage table.");
                                }
                            }
                            syncServ.BulkInsert(dtUsers, UserStageTable, _debugMode, _debugLogFileMode);

                            var dtRoles = BuildRolesDataTable(resultsRoles, batch.BatchID);
                            if (_debugMode)
                            {
                                EventLog.WriteEntry("SynchronizationService", "Inserting roles into RoleStage table.", EventLogEntryType.Information);
                            }
                            if (_debugLogFileMode)
                            {
                                using (StreamWriter sw = File.AppendText("Log.txt"))
                                {
                                    sw.WriteLine("Inserting roles into RoleStage table.");
                                }
                            }
                            syncServ.BulkInsert(dtRoles, RoleStageTable, _debugMode, _debugLogFileMode);

                            // also, lets populate which groups the users belong to
                            var dtUserRoles = BuildUserRolesDataTable(resultsRoles, batch.BatchID, ldapPath);
                            if (_debugMode)
                            {
                                EventLog.WriteEntry("SynchronizationService", "Inserting user's roles into RoleStage table.", EventLogEntryType.Information);
                            }
                            if (_debugLogFileMode)
                            {
                                using (StreamWriter sw = File.AppendText("Log.txt"))
                                {
                                    sw.WriteLine("Inserting user's roles into RoleStage table.");
                                }
                            }
                            syncServ.BulkInsert(dtUserRoles, UserRoleStageTable, _debugMode, _debugLogFileMode);

                            // if we've added any staging data to be processed, update the batch created for this interval for keeping up w/ the data to be processed
                            // NOTE: adding +1 to the last usn, as we are doing a >= to filter by usn, so we don't want to get the last usn again, the next time we look for updates
                            batch.BatchStatusID = (int)BatchStatus.Completed;
                            batch.BatchTypeID   = (int)BatchType.ADSynService;
                            batch.USN           = _lastUSN + 1;
                            if (_debugMode)
                            {
                                EventLog.WriteEntry("SynchronizationService", "Updating batch to Pending status with USN " + batch.USN + ".", EventLogEntryType.Information);
                            }
                            if (_debugLogFileMode)
                            {
                                using (StreamWriter sw = File.AppendText("Log.txt"))
                                {
                                    sw.WriteLine("Updating batch to Pending status with USN " + batch.USN + ".");
                                }
                            }
                            syncServ.UpdateBatch(batch);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// This function helps to authenticate the AD Users
        /// </summary>
        /// <param name="username"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public int IsAuthenticated(string username, string pwd)
        {
            int statusCode = -6;
            var syncServ   = new SynchronizationServiceDataProvider(_logger);

            var path            = syncServ.GetServiceConfiguration("ActiveDirectoryPath").DataItems[0].ConfigXML;
            var groupNameconfig = syncServ.GetServiceConfiguration("ActiveDirectoryGroupName").DataItems[0].ConfigXML;


            DirectoryEntry entry = new DirectoryEntry(path, username, pwd);

            if (entry == null)
            {
                statusCode = -7;
                return(statusCode);
            }
            try
            {
                DirectorySearcher search = new DirectorySearcher(entry);
                search.Filter = "(SAMAccountName=" + username.Split('\\')[1] + ")";

                // Instead of checking for the groups below this will be a faster approach to check for the group. It will have to wait for a bit.
                // search.Filter = "(&(objectClass = user)(sAMAccountName = " + username.Split('\\')[1] + ")" + ApplicationSettings.LDAPUserGroup;
                // Check for Group Currently we are loading the common name properties which points to the group.
                // Group Objects: cn https://msdn.microsoft.com/en-us/library/ms676913(v=vs.85).aspx
                // CN = Common Name //OU = Organizational Unit //DC = Domain Component

                search.PropertiesToLoad.Add("cn");
                search.PropertiesToLoad.Add("memberOf");

                SearchResult result = search.FindOne();

                if (result == null)
                {
                    // Set A message to display that User Does not exist
                    statusCode = -6;
                    return(statusCode);
                }

                int groupCount = result.Properties["memberOf"].Count;

                if (groupCount < 1 || (string)result.Properties["memberOf"][0] == "No Group")
                {
                    // Set A message to display that User Does not belong to a group
                    statusCode = -6;
                    return(statusCode);
                }

                for (int groupCounter = 0; groupCounter < groupCount; groupCounter++)
                {
                    if (((string)result.Properties["memberOf"][groupCounter]).Equals(groupNameconfig.ToString(), StringComparison.CurrentCultureIgnoreCase))
                    {
                        statusCode = 1;
                        return(statusCode);
                    }
                }
            }
            catch (Exception ex)
            {
                //There is no Exception Method but an Error Method.
                _logger.Error("Active Directory Communication is failing", ex);
                statusCode = -5;
            }

            return(statusCode);
        }