Search in sources :

Example 1 with LdapDomain

use of com.zimbra.cs.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.

the class LdapProvisioning method createDomain.

@Override
public Domain createDomain(String name, Map<String, Object> domainAttrs) throws ServiceException {
    name = name.toLowerCase().trim();
    name = IDNUtil.toAsciiDomainName(name);
    NameUtil.validNewDomainName(name);
    ZLdapContext zlc = null;
    try {
        zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_DOMAIN);
        LdapDomain d = (LdapDomain) getDomainByAsciiName(name, zlc);
        if (d != null) {
            throw AccountServiceException.DOMAIN_EXISTS(name);
        }
        // Attribute checking can not express "allow setting on
        // creation, but do not allow modifies afterwards"
        String domainType = (String) domainAttrs.get(A_zimbraDomainType);
        if (domainType == null) {
            domainType = DomainType.local.name();
        } else {
            // add back later
            domainAttrs.remove(A_zimbraDomainType);
        }
        String domainStatus = (String) domainAttrs.get(A_zimbraDomainStatus);
        if (domainStatus == null) {
            domainStatus = DOMAIN_STATUS_ACTIVE;
        } else {
            // add back later
            domainAttrs.remove(A_zimbraDomainStatus);
        }
        String smimeLdapURL = (String) domainAttrs.get(A_zimbraSMIMELdapURL);
        if (!StringUtil.isNullOrEmpty(smimeLdapURL)) {
            // add back later
            domainAttrs.remove(A_zimbraSMIMELdapURL);
        }
        String smimeLdapStartTlsEnabled = (String) domainAttrs.get(A_zimbraSMIMELdapStartTlsEnabled);
        if (!StringUtil.isNullOrEmpty(smimeLdapStartTlsEnabled)) {
            // add back later
            domainAttrs.remove(A_zimbraSMIMELdapStartTlsEnabled);
        }
        String smimeLdapBindDn = (String) domainAttrs.get(A_zimbraSMIMELdapBindDn);
        if (!StringUtil.isNullOrEmpty(smimeLdapBindDn)) {
            // add back later
            domainAttrs.remove(A_zimbraSMIMELdapBindDn);
        }
        String smimeLdapBindPassword = (String) domainAttrs.get(A_zimbraSMIMELdapBindPassword);
        if (!StringUtil.isNullOrEmpty(smimeLdapBindPassword)) {
            // add back later
            domainAttrs.remove(A_zimbraSMIMELdapBindPassword);
        }
        String smimeLdapSearchBase = (String) domainAttrs.get(A_zimbraSMIMELdapSearchBase);
        if (!StringUtil.isNullOrEmpty(smimeLdapSearchBase)) {
            // add back later
            domainAttrs.remove(A_zimbraSMIMELdapSearchBase);
        }
        String smimeLdapFilter = (String) domainAttrs.get(A_zimbraSMIMELdapFilter);
        if (!StringUtil.isNullOrEmpty(smimeLdapFilter)) {
            // add back later
            domainAttrs.remove(A_zimbraSMIMELdapFilter);
        }
        String smimeLdapAttribute = (String) domainAttrs.get(A_zimbraSMIMELdapAttribute);
        if (!StringUtil.isNullOrEmpty(smimeLdapAttribute)) {
            // add back later
            domainAttrs.remove(A_zimbraSMIMELdapAttribute);
        }
        CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
        AttributeManager.getInstance().preModify(domainAttrs, null, callbackContext, true);
        // Add back attrs we circumvented from attribute checking
        domainAttrs.put(A_zimbraDomainType, domainType);
        domainAttrs.put(A_zimbraDomainStatus, domainStatus);
        domainAttrs.put(A_zimbraSMIMELdapURL, smimeLdapURL);
        domainAttrs.put(A_zimbraSMIMELdapStartTlsEnabled, smimeLdapStartTlsEnabled);
        domainAttrs.put(A_zimbraSMIMELdapBindDn, smimeLdapBindDn);
        domainAttrs.put(A_zimbraSMIMELdapBindPassword, smimeLdapBindPassword);
        domainAttrs.put(A_zimbraSMIMELdapSearchBase, smimeLdapSearchBase);
        domainAttrs.put(A_zimbraSMIMELdapFilter, smimeLdapFilter);
        domainAttrs.put(A_zimbraSMIMELdapAttribute, smimeLdapAttribute);
        String[] parts = name.split("\\.");
        String[] dns = mDIT.domainToDNs(parts);
        createParentDomains(zlc, parts, dns);
        ZMutableEntry entry = LdapClient.createMutableEntry();
        entry.mapToAttrs(domainAttrs);
        Set<String> ocs = LdapObjectClass.getDomainObjectClasses(this);
        entry.addAttr(A_objectClass, ocs);
        String zimbraIdStr = LdapUtil.generateUUID();
        entry.setAttr(A_zimbraId, zimbraIdStr);
        entry.setAttr(A_zimbraCreateTimestamp, LdapDateUtil.toGeneralizedTime(new Date()));
        entry.setAttr(A_zimbraDomainName, name);
        String mailStatus = (String) domainAttrs.get(A_zimbraMailStatus);
        if (mailStatus == null)
            entry.setAttr(A_zimbraMailStatus, MAIL_STATUS_ENABLED);
        if (domainType.equalsIgnoreCase(DomainType.alias.name())) {
            entry.setAttr(A_zimbraMailCatchAllAddress, "@" + name);
        }
        entry.setAttr(A_o, name + " domain");
        entry.setAttr(A_dc, parts[0]);
        String dn = dns[0];
        entry.setDN(dn);
        //NOTE: all four of these should be in a transaction...
        try {
            zlc.createEntry(entry);
        } catch (LdapEntryAlreadyExistException e) {
            zlc.replaceAttributes(dn, entry.getAttributes());
        }
        String acctBaseDn = mDIT.domainDNToAccountBaseDN(dn);
        if (!acctBaseDn.equals(dn)) {
            /*
                 * create the account base dn entry only if if is not the same as the domain dn
                 *
                 * TODO, the objectclass(organizationalRole) and attrs(ou and cn) for the account
                 * base dn entry is still hardcoded,  it should be parameterized in LdapDIT
                 * according the BASE_RDN_ACCOUNT.  This is actually a design decision depending
                 * on how far we want to allow the DIT to be customized.
                 */
            zlc.createEntry(mDIT.domainDNToAccountBaseDN(dn), "organizationalRole", new String[] { A_ou, "people", A_cn, "people" });
            // create the base DN for dynamic groups
            zlc.createEntry(mDIT.domainDNToDynamicGroupsBaseDN(dn), "organizationalRole", new String[] { A_cn, "groups", A_description, "dynamic groups base" });
        }
        Domain domain = getDomainById(zimbraIdStr, zlc);
        AttributeManager.getInstance().postModify(domainAttrs, domain, callbackContext);
        return domain;
    } catch (LdapEntryAlreadyExistException nabe) {
        throw AccountServiceException.DOMAIN_EXISTS(name);
    } catch (LdapException e) {
        throw e;
    } catch (AccountServiceException e) {
        throw e;
    } catch (ServiceException e) {
        throw ServiceException.FAILURE("unable to create domain: " + name, e);
    } finally {
        LdapClient.closeContext(zlc);
    }
}
Also used : ZMutableEntry(com.zimbra.cs.ldap.ZMutableEntry) LdapEntryAlreadyExistException(com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Date(java.util.Date) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) CallbackContext(com.zimbra.cs.account.callback.CallbackContext) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain) LdapException(com.zimbra.cs.ldap.LdapException)

Example 2 with LdapDomain

use of com.zimbra.cs.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.

the class LdapProvisioning method getDomainByForeignNameInternal.

private Domain getDomainByForeignNameInternal(String foreignName, GetFromDomainCacheOption option) throws ServiceException {
    Domain d = domainCache.getByForeignName(foreignName, option);
    if (d instanceof DomainCache.NonExistingDomain)
        return null;
    LdapDomain domain = (LdapDomain) d;
    if (domain == null) {
        domain = getDomainByQuery(filterFactory.domainByForeignName(foreignName), null);
        domainCache.put(Key.DomainBy.foreignName, foreignName, domain);
    }
    return domain;
}
Also used : LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain)

Example 3 with LdapDomain

use of com.zimbra.cs.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.

the class LdapProvisioning method getDomainByIdInternal.

private Domain getDomainByIdInternal(String zimbraId, ZLdapContext zlc, GetFromDomainCacheOption option) throws ServiceException {
    if (zimbraId == null) {
        return null;
    }
    Domain d = domainCache.getById(zimbraId, option);
    if (d instanceof DomainCache.NonExistingDomain) {
        return null;
    }
    LdapDomain domain = (LdapDomain) d;
    if (domain == null) {
        domain = getDomainByQuery(filterFactory.domainById(zimbraId), zlc);
        domainCache.put(Key.DomainBy.id, zimbraId, domain);
    }
    return domain;
}
Also used : LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain)

Example 4 with LdapDomain

use of com.zimbra.cs.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.

the class LdapProvisioning method getDomainByAsciiNameInternal.

private Domain getDomainByAsciiNameInternal(String name, ZLdapContext zlc, GetFromDomainCacheOption option) throws ServiceException {
    Domain d = domainCache.getByName(name, option);
    if (d instanceof DomainCache.NonExistingDomain)
        return null;
    LdapDomain domain = (LdapDomain) d;
    if (domain == null) {
        domain = getDomainByQuery(filterFactory.domainByName(name), zlc);
        domainCache.put(Key.DomainBy.name, name, domain);
    }
    return domain;
}
Also used : LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain)

Example 5 with LdapDomain

use of com.zimbra.cs.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.

the class LdapProvisioning method createDynamicGroup.

private DynamicGroup createDynamicGroup(String groupAddress, Map<String, Object> groupAttrs, Account creator) throws ServiceException {
    SpecialAttrs specialAttrs = mDIT.handleSpecialAttrs(groupAttrs);
    String baseDn = specialAttrs.getLdapBaseDn();
    groupAddress = groupAddress.toLowerCase().trim();
    EmailAddress addr = new EmailAddress(groupAddress);
    String localPart = addr.getLocalPart();
    String domainName = addr.getDomain();
    domainName = IDNUtil.toAsciiDomainName(domainName);
    groupAddress = EmailAddress.getAddress(localPart, domainName);
    validEmailAddress(groupAddress);
    CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
    callbackContext.setCreatingEntryName(groupAddress);
    // remove zimbraIsACLGroup from attrs if provided, to avoid the immutable check
    Object providedZimbraIsACLGroup = groupAttrs.get(A_zimbraIsACLGroup);
    if (providedZimbraIsACLGroup != null) {
        groupAttrs.remove(A_zimbraIsACLGroup);
    }
    AttributeManager.getInstance().preModify(groupAttrs, null, callbackContext, true);
    // put zimbraIsACLGroup back
    if (providedZimbraIsACLGroup != null) {
        groupAttrs.put(A_zimbraIsACLGroup, providedZimbraIsACLGroup);
    }
    ZLdapContext zlc = null;
    try {
        zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_DYNAMICGROUP);
        Domain domain = getDomainByAsciiName(domainName, zlc);
        if (domain == null) {
            throw AccountServiceException.NO_SUCH_DOMAIN(domainName);
        }
        if (!domain.isLocal()) {
            throw ServiceException.INVALID_REQUEST("domain type must be local", null);
        }
        String domainDN = ((LdapDomain) domain).getDN();
        /*
             * ====================================
             * create the main dynamic group entry
             * ====================================
             */
        ZMutableEntry entry = LdapClient.createMutableEntry();
        entry.mapToAttrs(groupAttrs);
        Set<String> ocs = LdapObjectClass.getGroupObjectClasses(this);
        entry.addAttr(A_objectClass, ocs);
        String zimbraId = LdapUtil.generateUUID();
        // create a UUID for the static unit entry
        String staticUnitZimbraId = LdapUtil.generateUUID();
        String createTimestamp = LdapDateUtil.toGeneralizedTime(new Date());
        entry.setAttr(A_zimbraId, zimbraId);
        entry.setAttr(A_zimbraCreateTimestamp, createTimestamp);
        entry.setAttr(A_mail, groupAddress);
        entry.setAttr(A_dgIdentity, LC.zimbra_ldap_userdn.value());
        // unlike accounts (which have a zimbraMailDeliveryAddress for the primary,
        // and zimbraMailAliases only for aliases), DLs use zimbraMailAlias for both.
        // Postfix uses these two attributes to route mail, and zimbraMailDeliveryAddress
        // indicates that something has a physical mailbox, which DLs don't.
        entry.setAttr(A_zimbraMailAlias, groupAddress);
        /*
            // allow only users in the same domain
            String memberURL = String.format("ldap:///%s??one?(zimbraMemberOf=%s)",
                    mDIT.domainDNToAccountBaseDN(domainDN), groupAddress);
            */
        String specifiedIsACLGroup = entry.getAttrString(A_zimbraIsACLGroup);
        boolean isACLGroup;
        if (!entry.hasAttribute(A_memberURL)) {
            String memberURL = LdapDynamicGroup.getDefaultMemberURL(zimbraId, staticUnitZimbraId);
            entry.setAttr(Provisioning.A_memberURL, memberURL);
            // or specified to be TRUE;
            if (specifiedIsACLGroup == null) {
                entry.setAttr(A_zimbraIsACLGroup, ProvisioningConstants.TRUE);
            } else if (ProvisioningConstants.FALSE.equals(specifiedIsACLGroup)) {
                throw ServiceException.INVALID_REQUEST("No custom " + A_memberURL + " is provided, " + A_zimbraIsACLGroup + " cannot be set to FALSE", null);
            }
            isACLGroup = true;
        } else {
            // We want to be able to use dynamic groups as ACLs, for instance when sharing a folder with a group
            // This used to be disallowed via a requirement that zimbraIsACLGroup be specified and set to FALSE.
            // That requirement has been dropped.
            isACLGroup = !ProvisioningConstants.FALSE.equals(specifiedIsACLGroup);
        }
        // by default a dynamic group is always created enabled
        if (!entry.hasAttribute(Provisioning.A_zimbraMailStatus)) {
            entry.setAttr(A_zimbraMailStatus, MAIL_STATUS_ENABLED);
        }
        String mailStatus = entry.getAttrString(A_zimbraMailStatus);
        entry.setAttr(A_cn, localPart);
        // entry.setAttr(A_uid, localPart); need to use uid if we move dynamic groups to the ou=people tree
        setGroupHomeServer(entry, creator);
        String dn = mDIT.dynamicGroupNameLocalPartToDN(localPart, domainDN);
        entry.setDN(dn);
        zlc.createEntry(entry);
        if (isACLGroup) {
            /*
                 * ===========================================================
                 * create the dynamic group unit entry, for internal addresses
                 * ===========================================================
                 */
            String dynamicUnitLocalpart = dynamicGroupDynamicUnitLocalpart(localPart);
            String dynamicUnitAddr = EmailAddress.getAddress(dynamicUnitLocalpart, domainName);
            entry = LdapClient.createMutableEntry();
            ocs = LdapObjectClass.getGroupDynamicUnitObjectClasses(this);
            entry.addAttr(A_objectClass, ocs);
            String dynamicUnitZimbraId = LdapUtil.generateUUID();
            entry.setAttr(A_cn, DYNAMIC_GROUP_DYNAMIC_UNIT_NAME);
            entry.setAttr(A_zimbraId, dynamicUnitZimbraId);
            // id of the main group
            entry.setAttr(A_zimbraGroupId, zimbraId);
            entry.setAttr(A_zimbraCreateTimestamp, createTimestamp);
            entry.setAttr(A_mail, dynamicUnitAddr);
            entry.setAttr(A_zimbraMailAlias, dynamicUnitAddr);
            entry.setAttr(A_zimbraMailStatus, mailStatus);
            entry.setAttr(A_dgIdentity, LC.zimbra_ldap_userdn.value());
            // id of the main group
            String memberURL = LdapDynamicGroup.getDefaultDynamicUnitMemberURL(zimbraId);
            entry.setAttr(Provisioning.A_memberURL, memberURL);
            String dynamicUnitDN = mDIT.dynamicGroupUnitNameToDN(DYNAMIC_GROUP_DYNAMIC_UNIT_NAME, dn);
            entry.setDN(dynamicUnitDN);
            zlc.createEntry(entry);
            /*
                 * ==========================================================
                 * create the static group unit entry, for external addresses
                 * ==========================================================
                 */
            entry = LdapClient.createMutableEntry();
            ocs = LdapObjectClass.getGroupStaticUnitObjectClasses(this);
            entry.addAttr(A_objectClass, ocs);
            entry.setAttr(A_cn, DYNAMIC_GROUP_STATIC_UNIT_NAME);
            entry.setAttr(A_zimbraId, staticUnitZimbraId);
            // id of the main group
            entry.setAttr(A_zimbraGroupId, zimbraId);
            entry.setAttr(A_zimbraCreateTimestamp, createTimestamp);
            String staticUnitDN = mDIT.dynamicGroupUnitNameToDN(DYNAMIC_GROUP_STATIC_UNIT_NAME, dn);
            entry.setDN(staticUnitDN);
            zlc.createEntry(entry);
        }
        /*
             * all is well, get the group by id
             */
        DynamicGroup group = getDynamicGroupBasic(DistributionListBy.id, zimbraId, zlc);
        if (group != null) {
            AttributeManager.getInstance().postModify(groupAttrs, group, callbackContext);
            removeExternalAddrsFromAllDynamicGroups(group.getAllAddrsSet(), zlc);
            allDLs.addGroup(group);
        } else {
            throw ServiceException.FAILURE("unable to get dynamic group after creating LDAP entry: " + groupAddress, null);
        }
        return group;
    } catch (LdapEntryAlreadyExistException nabe) {
        throw AccountServiceException.DISTRIBUTION_LIST_EXISTS(groupAddress);
    } catch (LdapException e) {
        throw e;
    } catch (AccountServiceException e) {
        throw e;
    } finally {
        LdapClient.closeContext(zlc);
    }
}
Also used : ZMutableEntry(com.zimbra.cs.ldap.ZMutableEntry) DynamicGroup(com.zimbra.cs.account.DynamicGroup) LdapDynamicGroup(com.zimbra.cs.account.ldap.entry.LdapDynamicGroup) LdapEntryAlreadyExistException(com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) EmailAddress(com.zimbra.cs.account.names.NameUtil.EmailAddress) Date(java.util.Date) AccountServiceException(com.zimbra.cs.account.AccountServiceException) CallbackContext(com.zimbra.cs.account.callback.CallbackContext) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain) LdapException(com.zimbra.cs.ldap.LdapException)

Aggregations

LdapDomain (com.zimbra.cs.account.ldap.entry.LdapDomain)16 Domain (com.zimbra.cs.account.Domain)12 Account (com.zimbra.cs.account.Account)4 ServiceException (com.zimbra.common.service.ServiceException)3 AccountServiceException (com.zimbra.cs.account.AccountServiceException)3 DynamicGroup (com.zimbra.cs.account.DynamicGroup)3 NamedEntry (com.zimbra.cs.account.NamedEntry)3 LdapException (com.zimbra.cs.ldap.LdapException)3 LdapEntryAlreadyExistException (com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException)3 ZLdapContext (com.zimbra.cs.ldap.ZLdapContext)3 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)2 DistributionList (com.zimbra.cs.account.DistributionList)2 Group (com.zimbra.cs.account.Group)2 SearchDirectoryOptions (com.zimbra.cs.account.SearchDirectoryOptions)2 ObjectType (com.zimbra.cs.account.SearchDirectoryOptions.ObjectType)2 CallbackContext (com.zimbra.cs.account.callback.CallbackContext)2 ZLdapFilter (com.zimbra.cs.ldap.ZLdapFilter)2 ZMutableEntry (com.zimbra.cs.ldap.ZMutableEntry)2 ProvTest (com.zimbra.qa.unittest.prov.ProvTest)2 Date (java.util.Date)2