public Uid Create(ObjectClass objectClass, ICollection <ConnectorAttribute> createAttributes, OperationOptions options)
        {
            ConnectorAttributesAccessor accessor = new ConnectorAttributesAccessor(createAttributes);

            if (accessor.HasAttribute("fail"))
            {
                throw new ConnectorException("Test Exception");
            }
            else if (accessor.HasAttribute("exist") && accessor.FindBoolean("exist") == true)
            {
                throw new AlreadyExistsException(accessor.GetName().GetNameValue());
            }
            else if (accessor.HasAttribute("emails"))
            {
                object value = ConnectorAttributeUtil.GetSingleValue(accessor.Find("emails"));
                if (value is IDictionary)
                {
                    return(new Uid((string)((IDictionary)value)["email"]));
                }
                else
                {
                    throw new InvalidAttributeValueException("Expecting Map");
                }
            }
            return(new Uid(_config.Guid.ToString()));
        }
Ejemplo n.º 2
0
 public virtual ConnectorAttribute NormalizeAttribute(ObjectClass oclass, ConnectorAttribute attribute)
 {
     if (ConnectorAttributeUtil.NamesEqual(attribute.Name, Uid.NAME))
     {
         return(new Uid(ConnectorAttributeUtil.GetStringValue(attribute).ToLower()));
     }
     return(attribute);
 }
        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.º 4
0
        public string DetermineOrigAndNewAttributeValue(UpdateOpContext context, ConnectorObject origObject, ICollection <ConnectorAttribute> attributesForReplace, string attributeName, out string origAttributeValue)
        {
            ConnectorAttribute originalAttribute = origObject.GetAttributeByName(attributeName);

            if (originalAttribute != null)
            {
                origAttributeValue = ConnectorAttributeUtil.GetAsStringValue(originalAttribute);
            }
            else
            {
                origAttributeValue = null;
            }

            ConnectorAttribute newAttribute = ConnectorAttributeUtil.Find(attributeName, attributesForReplace);

            if (newAttribute != null)
            {
                return(ConnectorAttributeUtil.GetAsStringValue(newAttribute));
            }
            else
            {
                return(origAttributeValue);
            }

            /*
             * string deltaValue = ConnectorAttributeUtil.GetAsStringValue(attribute);
             * if (attribute == null) {
             *  return origAttributeValue;
             * }
             * switch (context.UpdateType) {
             *  case UpdateType.ADD:
             *      if (deltaValue == null) {
             *          return origAttributeValue;
             *      }
             *      if (origAttributeValue != null && !origAttributeValue.Equals(deltaValue)) {
             *          throw new ArgumentException("Multiple values for " + attribute.Name + " are not allowed: existing = " + origAttributeValue + ", one being added = " + deltaValue);
             *      } else {
             *          return deltaValue;
             *      }
             *  case UpdateType.REPLACE:
             *      return deltaValue;
             *  case UpdateType.DELETE:
             *      if (deltaValue == null) {
             *          return origAttributeValue;
             *      }
             *      if (origAttributeValue == null || !origAttributeValue.Equals(deltaValue)) {
             *          LOGGER.TraceEvent(TraceEventType.Warning, CAT_DEFAULT, "Trying to remove value from " + attribute.Name + " that is not there: " + deltaValue);
             *          return origAttributeValue;
             *      } else {
             *          return null;
             *      }
             *  default:
             *      throw new ArgumentException("Invalid update type: " + context.UpdateType);
             * } */
        }
Ejemplo n.º 5
0
 public ConnectorAttribute NormalizeAttribute(ObjectClass oclass, ConnectorAttribute attribute)
 {
     if (attribute.Is("foo"))
     {
         String val = ConnectorAttributeUtil.GetStringValue(attribute);
         return(ConnectorAttributeBuilder.Build("foo", val.Trim()));
     }
     else
     {
         return(attribute);
     }
 }
Ejemplo n.º 6
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);
        }
        public void TestCaseInsensitiveMap()
        {
            HashSet <ConnectorAttribute> set = new HashSet <ConnectorAttribute>();

            set.Add(ConnectorAttributeBuilder.Build("foo1"));
            set.Add(ConnectorAttributeBuilder.Build("foo2"));
            IDictionary <String, ConnectorAttribute> map = ConnectorAttributeUtil.ToMap(set);

            Assert.IsTrue(map.ContainsKey("Foo1"));
            Assert.IsTrue(map.ContainsKey("Foo2"));
            IDictionary <String, object> map2 = (IDictionary <String, object>)CloneObject(map);

            Assert.IsTrue(map2.ContainsKey("Foo1"));
            Assert.IsTrue(map2.ContainsKey("Foo2"));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Helper method: Gets attribute value from the attribute collection
        /// </summary>
        /// <param name="attName">attribute name</param>
        /// <param name="attributes">collection of attribute</param>
        /// <returns>Attribute value as object, null if not found</returns>
        /// <exception cref="ArgumentNullException">If some of the params is null</exception>
        internal static object GetAttValue(string attName, ICollection <ConnectorAttribute> attributes)
        {
            Assertions.NullCheck(attName, "attName");
            Assertions.NullCheck(attributes, "attributes");

            object             value     = null;
            ConnectorAttribute attribute = ConnectorAttributeUtil.Find(attName, attributes);

            if (attribute != null)
            {
                value = ConnectorAttributeUtil.GetSingleValue(attribute) ?? string.Empty;
            }

            return(value);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// This will do a basic replace.
        /// </summary>
        ///
        /// <seealso cref="UpdateOp.Update"/>
        ///
        public Uid Update(ObjectClass objclass, Uid uid, ICollection <ConnectorAttribute> attrs, OperationOptions options)
        {
            string val = ConnectorAttributeUtil.GetAsStringValue(uid);
            int    idx = Convert.ToInt32(val);
            //.Get out the object..
            ConnectorObject        baseObject = objects[idx];
            ConnectorObjectBuilder bld        = new ConnectorObjectBuilder();

            bld.Add(baseObject);
            bld.AddAttributes(attrs);
            ConnectorObject obj = bld.Build();

            objects[idx] = obj;
            return(obj.Uid);
        }
Ejemplo n.º 10
0
            private IList <object> GetValuesSorted(ConnectorObject resource, string field)
            {
                ConnectorAttribute value = ConnectorAttributeUtil.Find(field, resource.GetAttributes());

                if (value == null || value.Value == null || value.Value.Count == 0)
                {
                    return(CollectionUtil.NullAsEmpty <object>(null));
                }
                if (value.Value.Count > 1)
                {
                    var results = new List <object>(value.Value);
                    results.Sort(ValueComparator);
                    return(results);
                }
                return(value.Value);
            }
Ejemplo n.º 11
0
        /// <summary>
        /// Helper method: Sets attribute value in the attribute collection
        /// </summary>
        /// <param name="attName">attribute name</param>
        /// <param name="attValue">attribute value (if null, we will remove the attribute from the collection)</param>
        /// <param name="attributes">collection of attribute</param>
        /// <exception cref="ArgumentNullException">If some of the params is null</exception>
        internal static void SetAttValue(string attName, object attValue, ICollection <ConnectorAttribute> attributes)
        {
            Assertions.NullCheck(attName, "attName");
            Assertions.NullCheck(attributes, "attributes");

            ConnectorAttribute attribute = ConnectorAttributeUtil.Find(attName, attributes);

            if (attribute != null)
            {
                attributes.Remove(attribute);
            }
            if (attValue != null)
            {
                attributes.Add(ConnectorAttributeBuilder.Build(attName, new object[] { attValue }));
            }
        }
Ejemplo n.º 12
0
        private static IDictionary <String, Object> CreateFilter(String operation, AttributeFilter filter, bool not)
        {
            IDictionary <String, Object> dic = new Dictionary <String, Object>();
            var name  = filter.GetAttribute().Name;
            var value = ConnectorAttributeUtil.GetStringValue(filter.GetAttribute());

            if (StringUtil.IsBlank(value))
            {
                return(null);
            }
            dic.Add(Not, not);
            dic.Add(Operation, operation);
            dic.Add(Left, name);
            dic.Add(Right, value);
            return(dic);
        }
        /// <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.º 14
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");
 }
        public virtual void TestSearch2()
        {
            ConnectorFacade search = GetFacade();

            for (int i = 0; i < 100; i++)
            {
                ICollection <ConnectorAttribute> co = GetTestCreateConnectorObject(string.Format("TEST{0:D5}", i));
                co.Add(ConnectorAttributeBuilder.Build("sortKey", i));
                search.Create(ObjectClass.ACCOUNT, co, null);
            }

            OperationOptionsBuilder builder = new OperationOptionsBuilder {
                PageSize = 10, SortKeys = new[] { new SortKey("sortKey", false) }
            };
            SearchResult result = null;

            ICollection <ConnectorObject> resultSet = new HashSet <ConnectorObject>();
            int pageIndex = 0;
            int index     = 101;

            while ((result = search.Search(ObjectClass.ACCOUNT, FilterBuilder.StartsWith(ConnectorAttributeBuilder.Build(Name.NAME, "TEST")), new ResultsHandler()
            {
                Handle = connectorObject =>
                {
                    int?idx = ConnectorAttributeUtil.GetIntegerValue(connectorObject.GetAttributeByName("sortKey"));
                    Assert.IsTrue(idx < index);
                    if (idx != null)
                    {
                        index = (int)idx;
                    }
                    resultSet.Add(connectorObject);
                    return(true);
                }
            }, builder.Build())).PagedResultsCookie != null)
            {
                builder = new OperationOptionsBuilder(builder.Build())
                {
                    PagedResultsCookie = result.PagedResultsCookie
                };
                Assert.AreEqual(10 * ++pageIndex, resultSet.Count);
            }
            Assert.AreEqual(9, pageIndex);
            Assert.AreEqual(100, resultSet.Count);
        }
Ejemplo n.º 16
0
        public void TestGetSingleValue()
        {
            object             TEST_VALUE = 1L;
            ConnectorAttribute attr       = ConnectorAttributeBuilder.Build("long", TEST_VALUE);
            object             value      = ConnectorAttributeUtil.GetSingleValue(attr);

            Assert.AreEqual(TEST_VALUE, value);

            // test null
            attr  = ConnectorAttributeBuilder.Build("long");
            value = ConnectorAttributeUtil.GetSingleValue(attr);
            Assert.IsNull(value);
            // test empty
            attr  = ConnectorAttributeBuilder.Build("long", new List <object>());
            value = ConnectorAttributeUtil.GetSingleValue(attr);
            Assert.IsNull(value);
            // test illegal argument exception
            ConnectorAttributeUtil.GetSingleValue(ConnectorAttributeBuilder.Build("bob", 1, 2, 3));
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Helper method: Gets attribute values from the attribute collection
        /// </summary>
        /// <param name="attName">attribute name</param>
        /// <param name="attributes">collection of attribute</param>
        /// <returns>Attribute value as collection of objects, null if not found</returns>
        /// <exception cref="ArgumentNullException">If some of the params is null</exception>
        internal static IList <object> GetAttValues(string attName, ICollection <ConnectorAttribute> attributes)
        {
            Assertions.NullCheck(attName, "attName");

            if (attributes == null)
            {
                return(null);
            }

            ConnectorAttribute attribute = ConnectorAttributeUtil.Find(attName, attributes);

            if (attribute != null)
            {
                return(attribute.Value);
            }
            else
            {
                return(null);
            }
        }
        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);
                    }
                }
            }
        }
        /**
         * Get the LDAP name or names for a given connector attribute used in a
         * search filter.
         *
         * @param attr The connector attribute used in a search filter.
         *
         * @return The name or names of the corresponding LDAP attribute.
         *         Returns null if the attribute cannot be specified in an LDAP
         *         filter.
         */

        protected virtual String[] GetLdapNamesForAttribute(ConnectorAttribute attr)
        {
            // Special processing for certain connector attributes.
            String[] attrNames = null;
            if (attr is Uid)
            {
                /*
                 * attrNames = new String[] {
                 *   configCache.getConfiguration().getUuidAttribute() };
                 */
                attrNames = new String[] { "objectGUID" };
            }
            else if (attr is Name)
            {
                /*
                 * attrNames = configCache.getNamingAttributes();
                 */
                attrNames = new String [] { "distinguishedName" };
            }
            else if (attr.Is(OperationalAttributes.PASSWORD_NAME))
            {
                /*
                 * attrNames = new String[] {
                 *   configCache.getConfiguration().getPasswordAttribute()
                 * };
                 */
                attrNames = new String[] { "userPassword" };
            }
            else if (ConnectorAttributeUtil.IsSpecial(attr))
            {
                return(null);
            }
            else
            {
                attrNames = new String[] { attr.Name };
            }

            return(attrNames);
        }
Ejemplo n.º 20
0
        public Uid Create(ObjectClass objClass, ICollection <ConnectorAttribute> attrs, OperationOptions options)
        {
            StringBuilder      sb            = new StringBuilder();
            ConnectorAttribute NameAttribute = ConnectorAttributeUtil.Find(Name.NAME, attrs);

            if (NameAttribute == null)
            {
                throw new ConnectorException("The name operational attribute cannot be null");
            }

            string parameter = ConnectorAttributeUtil.GetAsStringValue(NameAttribute);

            string[] login = parameter.Split('@');

            PowerShell PowerShellInstance = PowerShell.Create();

            PowerShellInstance.AddCommand(this.config.createScript + "create.ps1");
            PowerShellInstance.AddArgument(login[0]);

            Collection <PSObject>    results;
            Collection <ErrorRecord> errors;

            results = PowerShellInstance.Invoke();
            errors  = PowerShellInstance.Streams.Error.ReadAll();

            if (errors.Count > 0)
            {
                foreach (ErrorRecord error in errors)
                {
                    sb.AppendLine(error.ToString());
                }

                throw new ConnectorException(sb.ToString());
            }
            else
            {
                return(new Uid(ConnectorAttributeUtil.GetAsStringValue(NameAttribute)));
            }
        }
        public void TestAttributeTypeMap()
        {
            ConnectorPoolManager.Dispose();
            ConnectorInfoManager manager = GetConnectorInfoManager();
            ConnectorInfo        info1   = FindConnectorInfo(manager, "1.0.0.0", "org.identityconnectors.testconnector.TstStatefulConnector");

            Assert.IsNotNull(info1);

            APIConfiguration config = info1.CreateDefaultAPIConfiguration();

            config.ConnectorPoolConfiguration.MinIdle = 0;
            config.ConnectorPoolConfiguration.MaxIdle = 0;

            ConnectorFacade facade = ConnectorFacadeFactory.GetInstance().NewInstance(config);

            HashSet <ConnectorAttribute> createAttributes = new HashSet <ConnectorAttribute>();
            IDictionary <string, object> mapAttribute     = new Dictionary <string, object>();

            mapAttribute["email"]   = "*****@*****.**";
            mapAttribute["primary"] = true;
            mapAttribute["usage"]   = new List <String>()
            {
                "home", "work"
            };
            createAttributes.Add(ConnectorAttributeBuilder.Build("emails", mapAttribute));

            Uid uid = facade.Create(ObjectClass.ACCOUNT, createAttributes, null);

            Assert.AreEqual(uid.GetUidValue(), "*****@*****.**");

            ConnectorObject co    = facade.GetObject(ObjectClass.ACCOUNT, new Uid("0"), null);
            object          value = ConnectorAttributeUtil.GetSingleValue(co.GetAttributeByName("emails"));

            Assert.IsTrue(value is IDictionary);
            Assert.IsTrue(((IDictionary)value)["usage"] is IList);
        }
Ejemplo n.º 22
0
        public void UpdateMergeTests()
        {
            ConnectorAttribute     expected, actual;
            Configuration          config  = new MockConfiguration(false);
            ConnectorFacadeFactory factory = ConnectorFacadeFactory.GetInstance();
            SafeType <Connector>   clazz   = SafeType <Connector> .Get <MockUpdateConnector>();

            // **test only**
            APIConfiguration impl = TestHelpers.CreateTestConfiguration(clazz, config);

            impl.SetTimeout(SafeType <APIOperation> .Get <GetApiOp>(), APIConstants.NO_TIMEOUT);
            impl.SetTimeout(SafeType <APIOperation> .Get <UpdateApiOp>(), APIConstants.NO_TIMEOUT);
            impl.SetTimeout(SafeType <APIOperation> .Get <SearchApiOp>(), APIConstants.NO_TIMEOUT);
            ConnectorFacade facade = factory.NewInstance(impl);
            // sniff test to make sure we can get an object..
            ConnectorObject obj = facade.GetObject(ObjectClass.ACCOUNT, NewUid(1), null);

            Assert.AreEqual(NewUid(1), obj.Uid);
            // ok lets add an attribute that doesn't exist..
            String ADDED     = "somthing to add to the object";
            String ATTR_NAME = "added";
            ICollection <ConnectorAttribute> addAttrSet;

            addAttrSet = CollectionUtil.NewSet((IEnumerable <ConnectorAttribute>)obj.GetAttributes());
            addAttrSet.Add(ConnectorAttributeBuilder.Build(ATTR_NAME, ADDED));
            Name name = obj.Name;

            addAttrSet.Remove(name);
            Uid uid = facade.AddAttributeValues(ObjectClass.ACCOUNT, obj.Uid, ConnectorAttributeUtil.FilterUid(addAttrSet), null);

            // get back the object and see if there are the same..
            addAttrSet.Add(name);
            ConnectorObject addO = new ConnectorObject(ObjectClass.ACCOUNT, addAttrSet);

            obj = facade.GetObject(ObjectClass.ACCOUNT, NewUid(1), null);
            Assert.AreEqual(addO, obj);
            // attempt to add on to an existing attribute..
            addAttrSet.Remove(name);
            uid = facade.AddAttributeValues(ObjectClass.ACCOUNT, obj.Uid, ConnectorAttributeUtil.FilterUid(addAttrSet), null);
            // get the object back out and check on it..
            obj      = facade.GetObject(ObjectClass.ACCOUNT, uid, null);
            expected = ConnectorAttributeBuilder.Build(ATTR_NAME, ADDED, ADDED);
            actual   = obj.GetAttributeByName(ATTR_NAME);
            Assert.AreEqual(expected, actual);
            // attempt to delete a value from an attribute..
            ICollection <ConnectorAttribute> deleteAttrs = CollectionUtil.NewSet((IEnumerable <ConnectorAttribute>)addO.GetAttributes());

            deleteAttrs.Remove(name);
            uid      = facade.RemoveAttributeValues(ObjectClass.ACCOUNT, addO.Uid, ConnectorAttributeUtil.FilterUid(deleteAttrs), null);
            obj      = facade.GetObject(ObjectClass.ACCOUNT, uid, null);
            expected = ConnectorAttributeBuilder.Build(ATTR_NAME, ADDED);
            actual   = obj.GetAttributeByName(ATTR_NAME);
            Assert.AreEqual(expected, actual);
            // attempt to delete an attribute that doesn't exist..
            ICollection <ConnectorAttribute> nonExist = new HashSet <ConnectorAttribute>();

            nonExist.Add(NewUid(1));
            nonExist.Add(ConnectorAttributeBuilder.Build("does not exist", "asdfe"));
            uid = facade.RemoveAttributeValues(ObjectClass.ACCOUNT, addO.Uid, ConnectorAttributeUtil.FilterUid(nonExist), null);
            obj = facade.GetObject(ObjectClass.ACCOUNT, NewUid(1), null);
            Assert.IsTrue(obj.GetAttributeByName("does not exist") == null);
        }
Ejemplo n.º 23
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);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Updates an AD object (also called by create after object is created)
        /// </summary>
        /// <param name="oclass"></param>
        /// <param name="directoryEntry"></param>
        /// <param name="attributes"></param>
        /// <param name="type"></param>
        /// <param name="config"></param>
        internal void UpdateADObject(ObjectClass oclass,
                                     DirectoryEntry directoryEntry, ICollection <ConnectorAttribute> attributes,
                                     UpdateType type, ActiveDirectoryConfiguration config)
        {
            if (oclass.Equals(ObjectClass.ACCOUNT))
            {
                // translate attribute passed in
                foreach (ConnectorAttribute attribute in attributes)
                {
                    // encountered problems when processing change password at the same time
                    // as setting expired.  It would be set to expired, but the change would
                    // clear that.  So we must ensure that expired comes last.
                    if (OperationalAttributes.PASSWORD_EXPIRED_NAME.Equals(attribute.Name))
                    {
                        continue;
                    }

                    AddConnectorAttributeToADProperties(oclass,
                                                        directoryEntry, attribute, type);

                    //  Uncommenting the next line is very helpful in
                    //  finding mysterious errors.
                    // Trace.TraceInformation("Committing after setting attribute {0} to {1}", attribute.Name, attribute.Value);
                    // directoryEntry.CommitChanges();
                }

                directoryEntry.CommitChanges();

                // now do the password change.  This is handled separately, because
                // it might be a user changing his own password, or it might be an
                // administrative change.

                GuardedString gsNewPassword = ConnectorAttributeUtil.GetPasswordValue(attributes);
                if (gsNewPassword != null)
                {
                    GuardedString         gsCurrentPassword = ConnectorAttributeUtil.GetCurrentPasswordValue(attributes);
                    PasswordChangeHandler changeHandler     = new PasswordChangeHandler(_configuration);
                    if (gsCurrentPassword == null)
                    {
                        // just a normal password change
                        changeHandler.changePassword(directoryEntry, gsNewPassword);
                    }
                    else
                    {
                        changeHandler.changePassword(directoryEntry,
                                                     gsCurrentPassword, gsNewPassword);
                    }


                    UserAccountControl.Set(directoryEntry.Properties[ActiveDirectoryConnector.ATT_USER_ACOUNT_CONTROL],
                                           UserAccountControl.PASSWD_NOTREQD, false);
                    directoryEntry.CommitChanges();
                }

                // see note in loop above for explaination of this
                ConnectorAttribute expirePasswordAttribute = ConnectorAttributeUtil.Find(
                    OperationalAttributes.PASSWORD_EXPIRED_NAME, attributes);

                if (expirePasswordAttribute != null)
                {
                    AddConnectorAttributeToADProperties(oclass,
                                                        directoryEntry, expirePasswordAttribute, type);
                    directoryEntry.CommitChanges();
                }

                /*
                 * UserAccountControl.Set(directoryEntry.Properties[ActiveDirectoryConnector.ATT_USER_ACOUNT_CONTROL],
                 *  UserAccountControl.PASSWD_NOTREQD, false);
                 */
                directoryEntry.CommitChanges();

                HandleNameAndContainerChange(type, directoryEntry, attributes, config);
            }
            else if (oclass.Equals(ActiveDirectoryConnector.groupObjectClass))
            {
                // translate attribute passed in
                foreach (ConnectorAttribute attribute in attributes)
                {
                    // Temporary
                    // Trace.TraceInformation(String.Format("Setting attribute {0} to {1}",
                    //    attribute.Name, attribute.Value));
                    AddConnectorAttributeToADProperties(oclass,
                                                        directoryEntry, attribute, type);
                    //                  Uncommenting the next line is very helpful in
                    //                  finding mysterious errors.
                    //                 directoryEntry.CommitChanges();
                }

                directoryEntry.CommitChanges();
                HandleNameAndContainerChange(type, directoryEntry, attributes, config);
            }
            else if (oclass.Equals(ActiveDirectoryConnector.ouObjectClass))
            {
                // translate attribute passed in
                foreach (ConnectorAttribute attribute in attributes)
                {
                    // Temporary
                    // Trace.TraceInformation(String.Format("Setting attribute {0} to {1}",
                    //    attribute.Name, attribute.Value));
                    AddConnectorAttributeToADProperties(oclass,
                                                        directoryEntry, attribute, type);
                    //                  Uncommenting the next line is very helpful in
                    //                  finding mysterious errors.
                    // directoryEntry.CommitChanges();
                }

                directoryEntry.CommitChanges();
                HandleNameAndContainerChange(type, directoryEntry, attributes, config);
            }
            else
            {
                String objectClassName = GetADObjectClass(oclass);
                // translate attribute passed in
                foreach (ConnectorAttribute attribute in attributes)
                {
                    // Temporary
                    // Trace.TraceInformation(String.Format("Setting attribute {0} to {1}",
                    //    attribute.Name, attribute.Value));
                    AddConnectorAttributeToADProperties(oclass,
                                                        directoryEntry, attribute, type);
                    //                  Uncommenting the next line is very helpful in
                    //                  finding mysterious errors.
                    // directoryEntry.CommitChanges();
                }

                directoryEntry.CommitChanges();
                HandleNameAndContainerChange(type, directoryEntry, attributes, config);
            }
        }
Ejemplo n.º 25
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.º 26
0
 public void TestNamesEqual()
 {
     Assert.IsTrue(ConnectorAttributeUtil.NamesEqual("givenName", "givenname"));
 }
Ejemplo n.º 27
0
        /// <summary>
        /// DeduplicatesEmailAddresses.
        ///  - on REPLACE (i.e. update/replace or create) the situation is easy: we just remove duplicate entries (SMTP:x & smtp:x result in SMTP:x)
        ///  - on DELETE we currently do nothing
        ///  - on ADD we have one additional rule:
        ///     "If we are adding SMTP:x, we first convert all SMTP:y in existing records to smtp:y because we see the intent of having x to be a new primary"
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="attributes">these are attributes to be set (already resolved if we have update of type ADD or DELETE)</param>
        /// <returns></returns>
        private ICollection <ConnectorAttribute> DeduplicateEmailAddresses(CreateUpdateOpContext context, ICollection <ConnectorAttribute> attributes)
        {
            // trivial cases

            if (context is UpdateOpContext && ((UpdateOpContext)context).UpdateType == UpdateType.DELETE)
            {
                return(attributes);
            }

            ConnectorAttribute attribute = ConnectorAttributeUtil.Find(ExchangeConnectorAttributes.AttEmailAddresses, attributes);

            if (attribute == null || attribute.Value == null)
            {
                return(attributes);      // missing or empty EmailAddresses - nothing to deduplicate
            }
            ConnectorAttribute attributeDelta = ConnectorAttributeUtil.Find(ExchangeConnectorAttributes.AttEmailAddresses, context.Attributes);

            if (attributeDelta == null || attributeDelta.Value == null)
            {
                return(attributes);      // missing or empty changed EmailAddresses - nothing to deduplicate
            }

            // now the main part

            IList <string> valuesToDeduplicate = new List <string>();

            foreach (object o in attribute.Value)
            {
                if (o != null)
                {
                    valuesToDeduplicate.Add(o.ToString());
                }
            }
            bool changed = false;

            // special rule: if ADD with SMTP:, let us change all other "SMTP:x" to "smtp:x"
            Boolean isUpdateAdd = context is UpdateOpContext && ((UpdateOpContext)context).UpdateType == UpdateType.ADD;

            if (isUpdateAdd)
            {
                string newPrimary = null;
                foreach (object o in attributeDelta.Value)
                {
                    if (((string)o).StartsWith("SMTP:"))
                    {
                        newPrimary = (string)o;
                        break;
                    }
                }
                if (newPrimary != null)
                {
                    foreach (string address in new List <string>(valuesToDeduplicate))      // to eliminate concurrent access
                    {
                        if (address.StartsWith("SMTP:") && !address.Equals(newPrimary))
                        {
                            string replacement = "smtp:" + address.Substring(5);
                            LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Changing duplicate primary-candidate address {0} to {1}", address, replacement);
                            valuesToDeduplicate.Remove(address);
                            valuesToDeduplicate.Add(replacement);
                            changed = true;
                        }
                    }
                }
            }

            IDictionary <string, string> values = new Dictionary <string, string>();       // normalized->most-recent-original e.g. SMTP:[email protected] -> SMTP:[email protected] (if primary is present)

            foreach (object v in valuesToDeduplicate)
            {
                string address    = (string)v;
                string normalized = address.ToUpper();
                if (values.ContainsKey(normalized))
                {
                    changed = true;
                    string existing = values[normalized];
                    if (address.StartsWith("SMTP:") && existing.StartsWith("smtp:"))
                    {
                        LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Removing redundant address {0}, keeping {1}", existing, address);
                        values[normalized] = address;
                    }
                    else
                    {
                        LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Removing redundant address {0}, keeping {1}", address, existing);
                    }
                }
                else
                {
                    values.Add(normalized, address);
                }
            }
            if (changed)
            {
                ConnectorAttributeBuilder cab = new ConnectorAttributeBuilder();
                cab.Name = ExchangeConnectorAttributes.AttEmailAddresses;
                foreach (string value in values.Values)
                {
                    cab.AddValue(value);
                }
                ICollection <ConnectorAttribute> rv = new List <ConnectorAttribute>(attributes);          // the original is (sometimes) a read-only collection
                rv.Remove(attribute);
                rv.Add(cab.Build());
                return(rv);
            }
            else
            {
                return(attributes);
            }
        }
Ejemplo n.º 28
0
        public Uid Update(ObjectClass objclass, Uid uid, ICollection <ConnectorAttribute> replaceAttributes, OperationOptions options)
        {
            StringBuilder sb = new StringBuilder();
            PowerShell    PowerShellInstance = PowerShell.Create();

            ConnectorAttribute StatusAttribute = ConnectorAttributeUtil.Find(OperationalAttributes.ENABLE_NAME, replaceAttributes);
            String             enable          = ConnectorAttributeUtil.GetAsStringValue(StatusAttribute).ToLower();

            string parameter = ConnectorAttributeUtil.GetAsStringValue(uid);

            string[] login = parameter.Split('@');

            if (enable.Equals("false"))
            {
                PowerShellInstance.AddCommand(this.config.createScript + "disable.ps1");
                PowerShellInstance.AddArgument(login[0]);

                Collection <PSObject>    results;
                Collection <ErrorRecord> errors;

                results = PowerShellInstance.Invoke();
                errors  = PowerShellInstance.Streams.Error.ReadAll();

                if (errors.Count > 0)
                {
                    foreach (ErrorRecord error in errors)
                    {
                        sb.AppendLine(error.ToString());
                    }

                    throw new ConnectorException(sb.ToString());
                }
                else
                {
                    return(uid);
                }
            }
            else if (enable.Equals("true"))
            {
                PowerShellInstance.AddCommand(this.config.createScript + "enable.ps1");
                PowerShellInstance.AddArgument(login[0]);

                Collection <PSObject>    results;
                Collection <ErrorRecord> errors;

                results = PowerShellInstance.Invoke();
                errors  = PowerShellInstance.Streams.Error.ReadAll();

                if (errors.Count > 0)
                {
                    foreach (ErrorRecord error in errors)
                    {
                        sb.AppendLine(error.ToString());
                    }

                    throw new ConnectorException(sb.ToString());
                }
                else
                {
                    return(uid);
                }
            }
            else
            {
                return(uid);
            }
        }
Ejemplo n.º 29
0
        public void Create(CreateOpContext context)
        {
            context.Attributes = DeduplicateEmailAddresses(context, context.Attributes);

            // get recipient type
            string rcptType = ExchangeUtility.GetAttValue(ExchangeConnectorAttributes.AttRecipientType, context.Attributes) as string;

            if (rcptType == null || rcptType.Equals(""))
            {
                rcptType = ExchangeConnectorAttributes.RcptTypeUser;
            }

            ExchangeConnector        exconn = (ExchangeConnector)context.Connector;
            ActiveDirectoryConnector adconn = exconn.ActiveDirectoryConnector;

            PSExchangeConnector.CommandInfo cmdInfoEnable = null;
            PSExchangeConnector.CommandInfo cmdInfoSet    = null;
            switch (rcptType)
            {
            case ExchangeConnectorAttributes.RcptTypeMailBox:
                cmdInfoEnable = PSExchangeConnector.CommandInfo.EnableMailbox;
                cmdInfoSet    = PSExchangeConnector.CommandInfo.SetMailbox;
                break;

            case ExchangeConnectorAttributes.RcptTypeMailUser:
                cmdInfoEnable = PSExchangeConnector.CommandInfo.EnableMailUser;
                cmdInfoSet    = PSExchangeConnector.CommandInfo.SetMailUser;
                break;

            case ExchangeConnectorAttributes.RcptTypeUser:
                break;

            default:
                throw new ArgumentException(
                          context.ConnectorConfiguration.ConnectorMessages.Format(
                              "ex_bad_rcpt", "Recipient type [{0}] is not supported", rcptType));
            }

            // first create the object in AD
            ICollection <ConnectorAttribute> adAttributes = ExchangeUtility.FilterOut(context.Attributes,
                                                                                      PSExchangeConnector.CommandInfo.EnableMailbox,
                                                                                      PSExchangeConnector.CommandInfo.SetMailbox,
                                                                                      PSExchangeConnector.CommandInfo.EnableMailUser,
                                                                                      PSExchangeConnector.CommandInfo.SetMailUser);
            Uid uid = adconn.Create(context.ObjectClass, adAttributes, context.Options);

            if (rcptType == ExchangeConnectorAttributes.RcptTypeUser)
            {
                // AD account only, we do nothing
                context.Uid = uid;
                return;
            }

            // add a empty "EmailAddresses" attribute if needed (address policy is disabled and no addresses are provided)
            ICollection <ConnectorAttribute> enhancedAttributes;
            ConnectorAttribute policyEnabledAttribute = ConnectorAttributeUtil.Find(ExchangeConnectorAttributes.AttEmailAddressPolicyEnabled, context.Attributes);

            if (policyEnabledAttribute != null &&
                ConnectorAttributeUtil.GetBooleanValue(policyEnabledAttribute).HasValue&&
                ConnectorAttributeUtil.GetBooleanValue(policyEnabledAttribute).Value == false &&
                ConnectorAttributeUtil.Find(ExchangeConnectorAttributes.AttPrimarySmtpAddress, context.Attributes) == null &&
                ConnectorAttributeUtil.Find(ExchangeConnectorAttributes.AttEmailAddresses, context.Attributes) == null)
            {
                enhancedAttributes = new HashSet <ConnectorAttribute>(context.Attributes);
                enhancedAttributes.Add(ConnectorAttributeBuilder.Build(ExchangeConnectorAttributes.AttEmailAddresses));
                LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Added empty EmailAddresses attribute because address policy use is disabled and no addresses were provided");
            }
            else
            {
                enhancedAttributes = context.Attributes;        // no change
            }

            // prepare the command
            Command cmdEnable = ExchangeUtility.GetCommand(cmdInfoEnable, enhancedAttributes, uid, (ExchangeConfiguration)context.ConnectorConfiguration);
            Command cmdSet    = ExchangeUtility.GetCommand(cmdInfoSet, enhancedAttributes, uid, (ExchangeConfiguration)context.ConnectorConfiguration);

            try {
                _helper.InvokePipeline(exconn, cmdEnable);
                _helper.InvokePipeline(exconn, cmdSet);
            }
            catch {
                LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Rolling back AD create for UID: " + uid.GetUidValue());

                // rollback AD create
                try {
                    adconn.Delete(context.ObjectClass, uid, context.Options);
                } catch {
                    LOGGER.TraceEvent(TraceEventType.Warning, CAT_DEFAULT, "Not able to rollback AD create for UID: " + uid.GetUidValue());
                    // note: this is not perfect, we hide the original exception
                    throw;
                }

                // rethrow original exception
                throw;
            }

            context.Uid = uid;
        }