public void Create(CreateOpContext context)
        {
            ExchangeConnector exconn = (ExchangeConnector)context.Connector;

            Command cmdNew = ExchangeUtility.GetCommand(
                new PSExchangeConnector.CommandInfo(GetNewCommandName()),
                context.Attributes, exconn.Configuration);

            try {
                context.Uid = _helper.InvokePipelineAndGetGuid(exconn, cmdNew);
            } catch (ProxyAddressExistsException e) {
                // This is a tricky exception. Sometimes when creating an object that is already there (e.g. DistributionGroup),
                // PowerShell reports "ProxyAddressExists" instead of something like "ObjectExists" :(
                // So we have to distinguish these situations somehow...
                Name nameAttribute = ConnectorAttributeUtil.GetNameFromAttributes(context.Attributes);
                if (nameAttribute == null || nameAttribute.Value == null || nameAttribute.Value.Count() != 1)
                {
                    LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "ProxyAddressExistsException reported; but no single-valued NAME attribute present -- reporting as is");
                    throw new ConnectorException(e.Message, e);
                }
                String name = (String)nameAttribute.Value[0];
                LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "ProxyAddressExistsException reported; trying to see if object named " + name + " exists");
                Command cmdGet = ExchangeUtility.GetCommand(
                    new PSExchangeConnector.CommandInfo(GetGetCommandName()), exconn.Configuration);
                cmdGet.Parameters.Add("Identity", name);
                ICollection <PSObject> objects;
                try {
                    objects = _helper.InvokePipeline(exconn, cmdGet);
                } catch (ObjectNotFoundException e1) {
                    objects = null;
                }
                if (objects == null || objects.Count == 0)
                {
                    LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "...it does not -- reporting as is");
                    throw new ConnectorException(e.Message, e);
                }
                else
                {
                    LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "...it exists -- reporting as AlreadyExistsException");
                    throw new AlreadyExistsException(e.Message, e);
                }
            }

            if (ExecuteSetAfterNew())
            {
                Command cmdSet = ExchangeUtility.GetCommand(
                    new PSExchangeConnector.CommandInfo(GetSetCommandName()),
                    context.Attributes, context.Uid, exconn.Configuration);
                try {
                    _helper.InvokePipeline(exconn, cmdSet);
                } catch {
                    // TODO rollback
                    // rethrow original exception
                    throw;
                }
            }
        }
Ejemplo n.º 2
0
        protected Uid ExecuteCreate(String scriptName, ObjectClass objectClass, ICollection <ConnectorAttribute> createAttributes, OperationOptions options)
        {
            var result    = new MsPowerShellUidHandler();
            var arguments = new Dictionary <String, Object> {
                { Result, result }
            };

            if (ConnectorAttributeUtil.GetNameFromAttributes(createAttributes) != null)
            {
                arguments.Add(Id, ConnectorAttributeUtil.GetNameFromAttributes(createAttributes).GetNameValue());
            }

            ExecuteScript(GetScript(scriptName), CreateBinding(arguments, OperationType.CREATE, objectClass, null, createAttributes, options));
            return(result.Uid.GetUidValue() != null ? result.Uid : null);
        }
        /// <summary>
        /// This does not work ... for now, don't handle container changes
        /// </summary>
        /// <param name="type"></param>
        /// <param name="directoryEntry"></param>
        /// <param name="attributes"></param>
        /// <param name="config"></param>
        private static void HandleContainerChange(UpdateType type,
                                                  DirectoryEntry directoryEntry, ICollection <ConnectorAttribute> attributes,
                                                  ActiveDirectoryConfiguration config)
        {
            Name nameAttribute = ConnectorAttributeUtil.GetNameFromAttributes(attributes);

            if (nameAttribute == null)
            {
                // no name, so must not be a container change
                return;
            }

            if (!type.Equals(UpdateType.REPLACE))
            {
                // this only make sense for replace.  you can't
                // add a name or delete a name
                return;
            }

            String oldContainer = GetParentDn(directoryEntry.Path);
            String newContainer = GetParentDn(nameAttribute.GetNameValue());

            if (!NormalizeLdapString(oldContainer).Equals(NormalizeLdapString(newContainer)))
            {
                if (newContainer != null)
                {
                    try
                    {
                        if (!NormalizeLdapString(oldContainer).Equals(
                                NormalizeLdapString(newContainer)))
                        {
                            String newContainerLdapPath = ActiveDirectoryUtils.GetLDAPPath(
                                config.LDAPHostName, newContainer);
                            DirectoryEntry newContainerDe = new DirectoryEntry(newContainerLdapPath,
                                                                               config.DirectoryAdminName, config.DirectoryAdminPassword);
                            directoryEntry.MoveTo(newContainerDe);
                        }
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                }
            }
        }
Ejemplo n.º 4
0
 public virtual Uid Create(ObjectClass objectClass, ICollection <ConnectorAttribute> createAttributes,
                           OperationOptions options)
 {
     if (ObjectClass.ACCOUNT.Equals(objectClass) || ObjectClass.GROUP.Equals(objectClass))
     {
         Name name = ConnectorAttributeUtil.GetNameFromAttributes(createAttributes);
         if (name != null)
         {
             // do real create here
             return(new Uid(ConnectorAttributeUtil.GetStringValue(name).ToLower()));
         }
         throw new InvalidAttributeValueException("Name attribute is required");
     }
     Trace.TraceWarning("Delete of type {0} is not supported",
                        _configuration.ConnectorMessages.Format(objectClass.GetDisplayNameKey(),
                                                                objectClass.GetObjectClassValue()));
     throw new NotSupportedException("Delete of type" + objectClass.GetObjectClassValue() + " is not supported");
 }
        private static void HandleNameChange(UpdateType type,
                                             DirectoryEntry directoryEntry,
                                             ICollection <ConnectorAttribute> attributes)
        {
            Name nameAttribute = ConnectorAttributeUtil.GetNameFromAttributes(attributes);

            if (nameAttribute != null)
            {
                // this only make sense for replace.  you can't
                // add a name or delete a name
                if (type.Equals(UpdateType.REPLACE))
                {
                    String oldName = directoryEntry.Name;
                    String newName = GetRelativeName(nameAttribute);
                    if (!NormalizeLdapString(oldName).Equals(NormalizeLdapString(newName)))
                    {
                        directoryEntry.Rename(newName);
                    }
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// </summary>
        /// <param name="type"></param>
        /// <param name="directoryEntry"></param>
        /// <param name="attributes"></param>
        /// <param name="config"></param>
        private static void HandleNameAndContainerChange(UpdateType type,
                                                         DirectoryEntry directoryEntry, ICollection <ConnectorAttribute> attributes,
                                                         ActiveDirectoryConfiguration config)
        {
            Name nameAttribute = ConnectorAttributeUtil.GetNameFromAttributes(attributes);

            if (nameAttribute == null)
            {
                // no name, so must not be a container change
                return;
            }

            if (!type.Equals(UpdateType.REPLACE))
            {
                // this only make sense for replace.  you can't
                // add a name or delete a name
                return;
            }

            String oldName     = directoryEntry.Name;
            String newName     = GetRelativeName(nameAttribute);
            bool   nameChanged = !NormalizeLdapString(oldName).Equals(NormalizeLdapString(newName), StringComparison.OrdinalIgnoreCase);

            String oldContainer     = GetParentDn(directoryEntry.Path);
            String newContainer     = GetParentDn(nameAttribute.GetNameValue());
            bool   containerChanged = !NormalizeLdapString(oldContainer).Equals(NormalizeLdapString(newContainer), StringComparison.OrdinalIgnoreCase);

            if (!nameChanged && !containerChanged)
            {
                return;
            }

            if (nameChanged && !containerChanged)           // rename without moving
            {
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Renaming {0} to {1}", oldName, newName);
                directoryEntry.Rename(newName);
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Rename OK");
                return;
            }

            // so this is move with or without rename

            // step 1: if WITH rename, we have to rename the entry to a temporary name first

            String temporaryName = null;

            if (nameChanged)
            {
                temporaryName = oldName + "-" + RandomStr();
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Renaming {0} to a temporary name of {1}", oldName, temporaryName);
                directoryEntry.Rename(temporaryName);
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Rename OK");
            }

            // step 2: do the move

            try
            {
                String         newContainerLdapPath = ActiveDirectoryUtils.GetLDAPPath(config.LDAPHostName, newContainer);
                DirectoryEntry newContainerDe       = new DirectoryEntry(newContainerLdapPath, config.DirectoryAdminName, config.DirectoryAdminPassword);
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Moving from {0} to {1} ({2})", oldContainer, newContainer, newContainerLdapPath);
                directoryEntry.MoveTo(newContainerDe);
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Move OK");
                newContainerDe.Dispose();
            }
            catch (Exception e)
            {
                LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Exception caught when moving: {0}", e);
                if (nameChanged)
                {
                    LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Renaming back from temporary name of {0} to {1}", temporaryName, oldName);
                    directoryEntry.Rename(oldName);
                    LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Rename OK");
                }
                throw e;
            }

            // step 3: if WITH rename, then rename from temporary name to the new name
            if (nameChanged)
            {
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Renaming from temporary name of {0} to a new name of {1}", temporaryName, newName);
                directoryEntry.Rename(newName);
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Rename OK");
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates command based on the commanf info, reading the calues from attributes
        /// </summary>
        /// <param name="cmdInfo">Command defition</param>
        /// <param name="attributes">Attribute values - UID in these is ignored! It should be passed as a separate parameter</param>
        /// <param name="config">Configuration object</param>
        /// <returns>
        /// Ready to execute Command
        /// </returns>
        /// <exception cref="ArgumentNullException">if some of the param is null</exception>
        internal static Command GetCommand(PSExchangeConnector.CommandInfo cmdInfo, ICollection <ConnectorAttribute> attributes, Uid uidAttribute, Name nameAttribute, ExchangeConfiguration config)
        {
            Assertions.NullCheck(cmdInfo, "cmdInfo");

            LOG.Trace("GetCommand: cmdInfo name = {0}", cmdInfo.Name);

            ISet <string> parametersSet = new HashSet <string>();

            // create command
            Command cmd = new Command(cmdInfo.Name);

            if (!string.IsNullOrEmpty(cmdInfo.UidParameter) && !parametersSet.Contains(cmdInfo.UidParameter))
            {
                Uid    uidAttr = uidAttribute != null ? uidAttribute : ConnectorAttributeUtil.GetUidAttribute(attributes);
                string uid     = uidAttr != null?uidAttr.GetUidValue() : null;

                if (uid != null)
                {
                    cmd.Parameters.Add(cmdInfo.UidParameter, ActiveDirectoryUtils.ConvertADGUIDtoObjectGUID(uid));
                    parametersSet.Add(cmdInfo.UidParameter);
                }
            }

            // map name attribute, if mapping specified
            if (!string.IsNullOrEmpty(cmdInfo.NameParameter) && !parametersSet.Contains(cmdInfo.NameParameter))
            {
                Name   nameAttr = nameAttribute != null ? nameAttribute : ConnectorAttributeUtil.GetNameFromAttributes(attributes);
                string name     = nameAttr != null?nameAttr.GetNameValue() : null;;
                if (name != null)
                {
                    cmd.Parameters.Add(cmdInfo.NameParameter, name);
                    parametersSet.Add(cmdInfo.NameParameter);
                }
            }

            if (cmdInfo.UsesConfirm)
            {
                cmd.Parameters.Add("confirm", false);
                parametersSet.Add("confirm");
            }

            if (cmdInfo.UsesDomainController)
            {
                cmd.Parameters.Add("DomainController", ActiveDirectoryUtils.GetDomainControllerName(config));
                parametersSet.Add("DomainController");
            }

            // TODO check this only for user-related operations
            bool emailAddressesPresent     = GetAttValues(ExchangeConnectorAttributes.AttEmailAddresses, attributes) != null;
            bool primarySmtpAddressPresent = GetAttValues(ExchangeConnectorAttributes.AttPrimarySmtpAddress, attributes) != null;

            if (emailAddressesPresent && primarySmtpAddressPresent)
            {
                throw new ArgumentException(ExchangeConnectorAttributes.AttEmailAddresses + " and " + ExchangeConnectorAttributes.AttPrimarySmtpAddress + " cannot be both set.");
            }

            if (attributes != null)
            {
                foreach (string attName in cmdInfo.Parameters)
                {
                    object valueToSet = null;

                    ConnectorAttribute attribute = ConnectorAttributeUtil.Find(attName, attributes);
                    if (attribute != null)
                    {
                        if (attribute.Value != null && attribute.Value.Count > 1)
                        {
                            List <string> stringValues = new List <string>();
                            foreach (object val in attribute.Value)
                            {
                                stringValues.Add(val.ToString());
                            }
                            valueToSet = stringValues.ToArray();
                        }
                        else
                        {
                            valueToSet = ConnectorAttributeUtil.GetSingleValue(attribute);
                        }
                        if (parametersSet.Contains(attName))
                        {
                            throw new InvalidOperationException("Parameter " + attName + " is already defined for command " + cmdInfo.Name);
                        }
                        cmd.Parameters.Add(attName, valueToSet);
                        parametersSet.Add(attName);
                    }
                }
            }

            LOG.Trace("GetCommand exit: cmdInfo name = {0}", cmdInfo.Name);
            return(cmd);
        }