public void Delete(ObjectClass objClass, Uid uid, OperationOptions options)
        {
            const string operation = "Delete";

            plugins.OnBeforeDelete(objClass, uid, options, _configuration);

            ExchangeUtility.NullCheck(objClass, "objClass", this._configuration);
            ExchangeUtility.NullCheck(uid, "uid", this._configuration);

            LOG.Info("Exchange.Delete method; uid:\n{0}", uid.GetUidValue());

            DeleteOpContext context = new DeleteOpContext()
            {
                Connector = this,
                ConnectorConfiguration = _configuration,
                ObjectClass            = objClass,
                OperationName          = operation,
                Uid     = uid,
                Options = options
            };

            try {
                _scripting.ExecutePowerShell(context, Scripting.Position.BeforeMain);

                if (!_scripting.ExecutePowerShell(context, Scripting.Position.InsteadOfMain))
                {
                    DeleteMain(context);
                }

                _scripting.ExecutePowerShell(context, Scripting.Position.AfterMain);
            } catch (Exception e) {
                LOG.Error(e, "Exception while executing Delete operation: {0}");
                throw;
            }
        }
Exemplo n.º 2
0
        public virtual Uid Update(ObjectClass objectClass, Uid uid, ICollection <ConnectorAttribute> replaceAttributes,
                                  OperationOptions options)
        {
            var  attributesAccessor = new ConnectorAttributesAccessor(replaceAttributes);
            Name newName            = attributesAccessor.GetName();
            Uid  uidAfterUpdate     = uid;

            if (newName != null)
            {
                Trace.TraceInformation("Rename the object {0}:{1} to {2}", objectClass.GetObjectClassValue(),
                                       uid.GetUidValue(), newName.GetNameValue());
                uidAfterUpdate = new Uid(newName.GetNameValue().ToLower());
            }

            if (ObjectClass.ACCOUNT.Equals(objectClass))
            {
            }
            else if (ObjectClass.GROUP.Is(objectClass.GetObjectClassValue()))
            {
                if (attributesAccessor.HasAttribute("members"))
                {
                    throw new InvalidAttributeValueException("Requested to update a read only attribute");
                }
            }
            else
            {
                Trace.TraceWarning("Update of type {0} is not supported",
                                   _configuration.ConnectorMessages.Format(objectClass.GetDisplayNameKey(),
                                                                           objectClass.GetObjectClassValue()));
                throw new NotSupportedException("Update of type" + objectClass.GetObjectClassValue() +
                                                " is not supported");
            }
            return(uidAfterUpdate);
        }
Exemplo n.º 3
0
        internal virtual void Delete(ObjectClass objectClass, Uid uid)
        {
            ConcurrentDictionary <string, Pair <ConnectorObject, DateTime> > storage = GetStore(objectClass);
            Pair <ConnectorObject, DateTime> removedValue;

            if (!storage.TryRemove(uid.GetUidValue(), out removedValue))
            {
                throw new UnknownUidException(uid, objectClass);
            }
        }
Exemplo n.º 4
0
        internal virtual Pair <ConnectorObject, DateTime> Get(ObjectClass objectClass, Uid uid)
        {
            ConcurrentDictionary <string, Pair <ConnectorObject, DateTime> > storage = GetStore(objectClass);
            Pair <ConnectorObject, DateTime> entry;

            if (!storage.TryGetValue(uid.GetUidValue(), out entry))
            {
                throw new UnknownUidException(uid, objectClass);
            }
            return(entry);
        }
        public void TestCreateTestRunAs()
        {
            ICollection <ConnectorAttribute> createAttributes = GetTestCreateConnectorObject("TEST5");
            var builder = new OperationOptionsBuilder();

            builder.RunAsUser       = "******";
            builder.RunWithPassword = new GuardedString(GetSecure(Password));
            Uid uid = GetFacade().Create(Test, createAttributes, builder.Build());

            Assert.AreEqual(uid.GetUidValue(), "TEST5");
        }
        /// <summary>
        /// Finds a DirectoryEntry by it's uid
        /// </summary>
        /// <param name="serverName"></param>
        /// <param name="uid"></param>
        /// <param name="adminUserName"></param>
        /// <param name="adminPassword"></param>
        /// <returns></returns>
        internal static DirectoryEntry GetDirectoryEntryFromUid(String serverName,
                                                                Uid uid, string adminUserName, string adminPassword)
        {
            DirectoryEntry foundDirectoryEntry = new DirectoryEntry(
                ActiveDirectoryUtils.GetLDAPPath(serverName, uid.GetUidValue()),
                adminUserName, adminPassword);
            string dn = (string)foundDirectoryEntry.Properties["distinguishedName"][0];

            foundDirectoryEntry = new DirectoryEntry(
                ActiveDirectoryUtils.GetLDAPPath(serverName, dn),
                adminUserName, adminPassword);
            return(foundDirectoryEntry);
        }
        public void TestCreateTestRunAsFailed()
        {
            ICollection <ConnectorAttribute> createAttributes = GetTestCreateConnectorObject("TEST5");
            var builder = new OperationOptionsBuilder();

            builder.RunAsUser = "******";
            var secret = new SecureString();

            "__FAKE__".ToCharArray().ToList().ForEach(secret.AppendChar);
            builder.RunWithPassword = new GuardedString(secret);
            Uid uid = GetFacade().Create(Test, createAttributes, builder.Build());

            Assert.AreEqual(uid.GetUidValue(), "TEST5");
        }
        public void TestScriptOnConnector()
        {
            var builder = new ScriptContextBuilder();

            builder.ScriptLanguage = "POWERShell";
            builder.ScriptText     = "Write-Warning \"Test\"; return $Connector.Arguments.uid.GetUidValue()";
            var uid = new Uid("foo", "12345");

            builder.AddScriptArgument("uid", uid);
            var res = GetFacade().RunScriptOnConnector(builder.Build(), null) as Collection <object>;

            if (res != null)
            {
                Assert.AreEqual(res[0], uid.GetUidValue());
            }
        }
Exemplo n.º 9
0
        public static String ConvertUIDToSearchString(Uid uid)
        {
            // e.g. <GUID=8184d4af97d9ed4c949c21665768881b>
            string uidValue = uid.GetUidValue().ToLowerInvariant();

            if (!uidValue.StartsWith("<guid=") || !uidValue.EndsWith(">") || uidValue.Length != 39)
            {
                throw new ArgumentException("Unsupported UID format: " + uidValue);
            }
            string        raw = uidValue.Substring(6, 32);
            StringBuilder rv  = new StringBuilder();

            for (int i = 0; i < raw.Length; i += 2)
            {
                rv.Append("\\").Append(raw.Substring(i, 2));
            }
            return(rv.ToString());
        }
        public void TestSyncTokenResults()
        {
            foreach (ConnectorFacade facade in CreateStateFulFacades())
            {
                Uid uid = facade.Create(ObjectClass.ACCOUNT, CollectionUtil.NewReadOnlySet <ConnectorAttribute>(), null);

                SyncToken latest = facade.GetLatestSyncToken(ObjectClass.ACCOUNT);
                Assert.AreEqual(uid.GetUidValue(), latest.Value);

                for (int i = 0; i < 10; i++)
                {
                    SyncToken lastToken = facade.Sync(ObjectClass.ACCOUNT, null, new SyncResultsHandler()
                    {
                        Handle = obj =>
                        {
                            return(true);
                        }
                    }, null);
                    Assert.IsNotNull(lastToken);
                    Assert.AreEqual(lastToken.Value, latest.Value);
                }
            }
        }
        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);
        }
Exemplo n.º 12
0
 // implementation of CreateSpiOp
 public virtual Uid Create(ObjectClass objectClass, ICollection <ConnectorAttribute> createAttributes, OperationOptions options)
 {
     Trace.TraceInformation("Invoke Create ObjectClass:{0}", objectClass.GetObjectClassValue());
     try
     {
         Uid uid = ExecuteCreate(_configuration.CreateScriptFileName, objectClass, createAttributes, options);
         if (uid == null)
         {
             throw new ConnectorException("Create script didn't return with a valid uid (__UID__) string value");
         }
         Trace.TraceInformation("{0}:{1} created", objectClass.GetObjectClassValue(), uid.GetUidValue());
         return(uid);
     }
     catch (Exception e)
     {
         if (e.InnerException != null)
         {
             throw e.InnerException;
         }
         throw;
     }
 }
        public void TestMVCCControl()
        {
            foreach (ConnectorFacade facade in CreateStateFulFacades())
            {
                Uid uid = facade.Create(ObjectClass.ACCOUNT, CollectionUtil.NewReadOnlySet <ConnectorAttribute>(), null);


                if (facade is LocalConnectorFacadeImpl)
                {
                    try
                    {
                        facade.Delete(ObjectClass.ACCOUNT, uid, null);
                    }
                    catch (PreconditionRequiredException)
                    {
                        // Expected
                    }
                    catch (Exception)
                    {
                        Assert.Fail("Expecting PreconditionRequiredException");
                    }
                    try
                    {
                        facade.Delete(ObjectClass.ACCOUNT, new Uid(uid.GetUidValue(), "0"), null);
                    }
                    catch (PreconditionFailedException)
                    {
                        // Expected
                    }
                    catch (Exception)
                    {
                        Assert.Fail("Expecting PreconditionFailedException");
                    }
                    facade.Delete(ObjectClass.ACCOUNT, new Uid(uid.GetUidValue(), uid.GetUidValue()), null);
                }
                else
                {
                    try
                    {
                        facade.Delete(ObjectClass.ACCOUNT, uid, null);
                    }
                    catch (RemoteWrappedException e)
                    {
                        if (!e.Is(typeof(PreconditionRequiredException)))
                        {
                            Assert.Fail("Expecting PreconditionRequiredException");
                        }
                    }
                    catch (Exception)
                    {
                        Assert.Fail("Expecting RemoteWrappedException");
                    }
                    try
                    {
                        facade.Delete(ObjectClass.ACCOUNT, new Uid(uid.GetUidValue(), "0"), null);
                    }
                    catch (RemoteWrappedException e)
                    {
                        if (!e.Is(typeof(PreconditionFailedException)))
                        {
                            Assert.Fail("Expecting PreconditionFailedException");
                        }
                    }
                    catch (Exception)
                    {
                        Assert.Fail("Expecting RemoteWrappedException");
                    }
                    facade.Delete(ObjectClass.ACCOUNT, new Uid(uid.GetUidValue(), uid.GetUidValue()), null);
                }
            }
        }
        private void AddOrReplaceDatabase(ObjectClass oclass, Uid uid, ICollection <ConnectorAttribute> attributes, OperationOptions options, AbstractConfiguration connectorConfiguration)
        {
            if (!ObjectClass.ACCOUNT.Equals(oclass))
            {
                LOG.Info("Nothing to do");
                return;
            }
            // вычисляем значение атрибута Database только если он не был передан
            // и дополнительно пришёл атрибут RecipientType со значением UserMailbox
            ConnectorAttribute database      = GetAttribute(attributes, "Database");
            ConnectorAttribute recipientType = GetAttribute(attributes, "RecipientType");

            if (database != null || recipientType == null || !recipientType.Value.First().ToString().Equals("UserMailbox"))
            {
                LOG.Info("Nothing to do");
                return;
            }

            DirectoryEntry container = null;

            try
            {
                ActiveDirectoryConfiguration config = (ActiveDirectoryConfiguration)connectorConfiguration;

                // вычисляем dn, для update'а находим по uid
                string dn = "";
                if (uid != null)
                {
                    DirectoryEntry entry = new DirectoryEntry(ActiveDirectoryUtils.GetLDAPPath(config.LDAPHostName, uid.GetUidValue()), config.DirectoryAdminName, config.DirectoryAdminPassword);
                    dn = (string)entry.Properties["distinguishedName"][0];
                    entry.Dispose();
                }
                else
                {
                    dn = GetAttribute(attributes, "__NAME__").Value.First().ToString();
                }
                string parentDn          = ActiveDirectoryUtils.GetParentDn(dn);
                string ldapContainerPath = ActiveDirectoryUtils.GetLDAPPath(config.LDAPHostName, parentDn);

                container = new DirectoryEntry(ldapContainerPath, config.DirectoryAdminName, config.DirectoryAdminPassword);

                // поиск значения Database в родительских OU
                string defaultHomeMdb = null;
                while (defaultHomeMdb == null && container != null)
                {
                    LOG.Info("Looking for DefaultHomeMdb in {0}", container.Path);
                    defaultHomeMdb = GetDefaultHomeMdb(container);
                    if (defaultHomeMdb != null)
                    {
                        LOG.Info("Found! DefaultHomeMdb = {0} (in container {1})", defaultHomeMdb, container.Path);
                    }
                    else
                    {
                        LOG.Info("Did not found DefaultHomeMdb in container {0}", container.Path);
                    }
                    try
                    {
                        container = container.Parent;
                    }
                    catch (Exception e)
                    {
                        LOG.Info("Error: " + e.Message);
                        container = null;
                    }
                }

                // установка значения атрибута, если не нашли указываем значение по умолчанию
                if (defaultHomeMdb != null)
                {
                    LOG.Info("Setting DefaultHomeMdb: " + defaultHomeMdb);
                    AddOrReplaceAttribute(attributes, "Database", defaultHomeMdb);
                }
                else
                {
                    LOG.Info("Did not found DefaultHomeMdb, will set default value");
                    AddOrReplaceAttribute(attributes, "Database", "MSK-RN-DAG01-1GB-02");
                }
            }
            finally
            {
                if (container != null)
                {
                    container.Dispose();
                }
            }
        }
Exemplo n.º 15
0
        // implementation of DeleteSpiOp
        public virtual void Delete(ObjectClass objectClass, Uid uid, OperationOptions options)
        {
            Trace.TraceInformation("Invoke Delete ObjectClass:{0}/{1}", objectClass.GetObjectClassValue(), uid.GetUidValue());

            try
            {
                ExecuteDelete(_configuration.DeleteScriptFileName, objectClass, uid, options);
                Trace.TraceInformation("Delete ok");
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    throw e.InnerException;
                }
                throw;
            }
        }
Exemplo n.º 16
0
 public Uid Update(ObjectClass objectClass, Uid uid, ICollection <ConnectorAttribute> valuesToReplace, OperationOptions options)
 {
     Trace.TraceInformation("Invoke Update ObjectClass: {0}/{1}", objectClass.GetObjectClassValue(), uid.GetUidValue());
     try
     {
         Uid uidAfter = ExecuteUpdate(_configuration.UpdateScriptFileName, objectClass, uid, valuesToReplace, options);
         if (uidAfter == null)
         {
             throw new ConnectorException("Update script didn't return with a valid uid (__UID__) value");
         }
         Trace.TraceInformation("{0}:{1} updated", objectClass.GetObjectClassValue(), uidAfter.GetUidValue());
         return(uidAfter);
     }
     catch (Exception e)
     {
         if (e.InnerException != null)
         {
             throw e.InnerException;
         }
         throw;
     }
 }
Exemplo n.º 17
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);
        }
        /// <summary>
        /// Implementation of CreateOp.Create
        /// </summary>
        /// <param name="oclass">Object class</param>(oc
        /// <param name="attributes">Object attributes</param>
        /// <param name="options">Operation options</param>
        /// <returns>Uid of the created object</returns>
        public override Uid Create(
            ObjectClass oclass, ICollection <ConnectorAttribute> attributes, OperationOptions options)
        {
            ExchangeUtility.NullCheck(oclass, "oclass", this.configuration);
            ExchangeUtility.NullCheck(attributes, "attributes", this.configuration);

            // we handle accounts only
            if (!oclass.Is(ObjectClass.ACCOUNT_NAME))
            {
                return(base.Create(oclass, attributes, options));
            }

            const string METHOD = "Create";

            Debug.WriteLine(METHOD + ":entry", ClassName);

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

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

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

            case RcptTypeUser:
                break;

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

            // first create the object in AD
            Uid uid = base.Create(oclass, FilterOut(attributes, cmdInfoEnable, cmdInfoSet), options);

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

            // prepare the command
            Command cmdEnable = ExchangeUtility.GetCommand(cmdInfoEnable, attributes, this.configuration);
            Command cmdSet    = ExchangeUtility.GetCommand(cmdInfoSet, attributes, this.configuration);

            try
            {
                this.InvokePipeline(cmdEnable);
                this.InvokePipeline(cmdSet);
            }
            catch
            {
                Trace.TraceWarning("Rolling back AD create for UID: " + uid.GetUidValue());

                // rollback AD create
                try
                {
                    Delete(oclass, uid, options);
                }
                catch
                {
                    Trace.TraceWarning("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;
            }

            Debug.WriteLine(METHOD + ":exit", ClassName);
            return(uid);
        }
Exemplo n.º 19
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;
        }