/// <summary> /// Creates CSEntryChange objects for each result returned from the import operation /// </summary> /// <param name="result">The result of the import operation</param> /// <param name="schemaType">The definition of the type of object to get the CSEntryChanges for</param> /// <returns>An enumeration of CSEntryChange objects</returns> public static IEnumerable <CSEntryChange> GetCSEntryChanges(OperationResult result, SchemaType schemaType) { ImportOperationBase operation = result.ExecutedOperation as ImportOperationBase; if (result.ExecutedCommandsWithObjects.Count == 0) { throw new FailedSearchException("No commands were executed that contained import results"); } foreach (SshCommand command in result.ExecutedCommandsWithObjects) { MatchCollection matchCollection = Regex.Matches(command.Result, operation.ImportMapping, RegexOptions.ExplicitCapture | RegexOptions.Multiline); foreach (Match match in matchCollection) { CSEntryChange csentry = CSEntryChange.Create(); ObjectModificationType modifcationType = GetObjectChangeTypeFromMatchCollection(match, operation); if (modifcationType == ObjectModificationType.None) { Logger.WriteLine("Discarding object due to invalid modification type: " + match.Value); continue; } else { csentry.ObjectModificationType = modifcationType; } csentry.ObjectType = schemaType.Name; if (modifcationType == ObjectModificationType.Delete) { // We need to create a temporary CSEntryChange here because a CSEntryChange with an // object modification type of 'delete' cannot contain attribute changes // This stops us from being able to construct a DN for the CSEntryChange CSEntryChange temporaryChange = CSEntryChange.Create(); temporaryChange.ObjectModificationType = ObjectModificationType.Update; temporaryChange.ObjectType = csentry.ObjectType; PopulateCSEntryWithMatches(schemaType, operation, match, temporaryChange); csentry.DN = MASchema.Objects[schemaType.Name].DNFormat.ExpandDeclaration(temporaryChange, true, false); csentry.AnchorAttributes.Add(AnchorAttribute.Create("entry-dn", csentry.DN)); } else { PopulateCSEntryWithMatches(schemaType, operation, match, csentry); csentry.DN = MASchema.Objects[schemaType.Name].DNFormat.ExpandDeclaration(csentry, true, false); csentry.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("entry-dn", csentry.DN)); } if (string.IsNullOrEmpty(csentry.DN)) { Logger.WriteLine("Discarding object from result as no DN could be derived: " + match.Value, LogLevel.Debug); continue; } if (operation.IsFiltered(csentry)) { Logger.WriteLine("Filtering object: " + csentry.DN, LogLevel.Debug); } else { yield return(csentry); } } } }
/// <summary> /// Executes an asynchronous command /// </summary> /// <param name="csentry">The CSEntry to apply to this command</param> /// <param name="result">The result object for the current operation</param> /// <param name="command">The definition of the command to execute</param> /// <param name="oldPassword">The old password, or null if performing a password set as opposed to a password change</param> /// <param name="newPassword">The new password</param> private static void ExecuteAsyncCommand(CSEntry csentry, OperationResult result, AsyncCommand command, string oldPassword, string newPassword) { string output = string.Empty; try { ShellStream shell = client.CreateShellStream("lithnet.sshma", 80, 24, 800, 600, 1024); output += shell.ReadLine(); foreach (AsyncCommandSend sendCommand in command.Commands) { if (sendCommand is AsyncCommandSendExpect) { AsyncCommandSendExpect expectCommand = sendCommand as AsyncCommandSendExpect; string expectText = expectCommand.Expect.ExpandDeclaration(csentry, oldPassword, newPassword, false); TimeSpan timeout = new TimeSpan(0, 0, expectCommand.Timeout); bool expectedArrived = false; shell.Expect( timeout, new ExpectAction( expectText, (s) => { expectedArrived = true; System.Diagnostics.Debug.WriteLine(s); output += s; shell.Write(expectCommand.Command.ExpandDeclaration(csentry, oldPassword, newPassword, false) + "\n"); })); if (!expectedArrived) { output += shell.Read(); throw new UnexpectedDataException("The expected value was not found in the session in the specified timeout period"); } } else { shell.Write(sendCommand.Command.ExpandDeclaration(csentry, oldPassword, newPassword, false) + "\n"); } } if (command.ExpectSuccess != null) { if (!string.IsNullOrWhiteSpace(command.ExpectSuccess.Expect.DeclarationText)) { TimeSpan timeout = new TimeSpan(0, 0, command.ExpectSuccess.Timeout); string expectResult = shell.Expect(command.ExpectSuccess.Expect.ExpandDeclaration(csentry, oldPassword, newPassword, false), timeout); output += expectResult ?? string.Empty; if (expectResult == null) { output += shell.Read(); throw new Microsoft.MetadirectoryServices.ExtensibleExtensionException("The asynchronous command did not return the expected result"); } } } output += shell.Read(); } finally { Logger.WriteLine("Shell session log:", LogLevel.Debug); Logger.WriteLine(output, LogLevel.Debug); } }