use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method createIdentity.
private Identity createIdentity(Account account, String identityName, Map<String, Object> identityAttrs, boolean restoring) throws ServiceException {
removeAttrIgnoreCase("objectclass", identityAttrs);
validateIdentityAttrs(identityAttrs);
LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));
if (ldapEntry == null)
throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());
if (identityName.equalsIgnoreCase(ProvisioningConstants.DEFAULT_IDENTITY_NAME))
throw AccountServiceException.IDENTITY_EXISTS(identityName);
List<Identity> existing = getAllIdentities(account);
if (existing.size() >= account.getLongAttr(A_zimbraIdentityMaxNumEntries, 20))
throw AccountServiceException.TOO_MANY_IDENTITIES();
account.setCachedData(IDENTITY_LIST_CACHE_KEY, null);
boolean checkImmutable = !restoring;
CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
AttributeManager.getInstance().preModify(identityAttrs, null, callbackContext, checkImmutable);
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_IDENTITY);
String dn = getIdentityDn(ldapEntry, identityName);
ZMutableEntry entry = LdapClient.createMutableEntry();
entry.setDN(dn);
entry.mapToAttrs(identityAttrs);
entry.setAttr(A_objectClass, "zimbraIdentity");
if (!entry.hasAttribute(A_zimbraPrefIdentityId)) {
String identityId = LdapUtil.generateUUID();
entry.setAttr(A_zimbraPrefIdentityId, identityId);
}
entry.setAttr(Provisioning.A_zimbraCreateTimestamp, LdapDateUtil.toGeneralizedTime(new Date()));
zlc.createEntry(entry);
Identity identity = getIdentityByName(ldapEntry, identityName, zlc);
AttributeManager.getInstance().postModify(identityAttrs, identity, callbackContext);
return identity;
} catch (LdapEntryAlreadyExistException nabe) {
throw AccountServiceException.IDENTITY_EXISTS(identityName);
} catch (LdapException e) {
throw e;
} catch (AccountServiceException e) {
throw e;
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to create identity " + identityName, e);
} finally {
LdapClient.closeContext(zlc);
}
}
use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method getAllDataSources.
@Override
public List<DataSource> getAllDataSources(Account account) throws ServiceException {
@SuppressWarnings("unchecked") List<DataSource> result = (List<DataSource>) account.getCachedData(DATA_SOURCE_LIST_CACHE_KEY);
if (result != null) {
return result;
}
LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));
if (ldapEntry == null)
throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());
result = getDataSourcesByQuery(ldapEntry, filterFactory.allDataSources(), null);
result = Collections.unmodifiableList(result);
account.setCachedData(DATA_SOURCE_LIST_CACHE_KEY, result);
return result;
}
use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method deleteSignature.
@Override
public void deleteSignature(Account account, String signatureId) throws ServiceException {
LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));
if (ldapEntry == null)
throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());
account.setCachedData(SIGNATURE_LIST_CACHE_KEY, null);
if (LdapSignature.isAccountSignature(account, signatureId)) {
LdapSignature.deleteAccountSignature(this, account);
} else {
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.DELETE_SIGNATURE);
Signature signature = getSignatureById(account, ldapEntry, signatureId, zlc);
if (signature == null)
throw AccountServiceException.NO_SUCH_SIGNATURE(signatureId);
String dn = getSignatureDn(ldapEntry, signature.getName());
zlc.deleteEntry(dn);
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to delete signarure: " + signatureId, e);
} finally {
LdapClient.closeContext(zlc);
}
}
if (signatureId.equals(account.getPrefDefaultSignatureId())) {
account.unsetPrefDefaultSignatureId();
}
}
use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method renameAccount.
@Override
public void renameAccount(String zimbraId, String newName) throws ServiceException {
newName = IDNUtil.toAsciiEmail(newName);
validEmailAddress(newName);
ZLdapContext zlc = null;
Account acct = getAccountById(zimbraId, zlc, true);
// prune cache
accountCache.remove(acct);
LdapEntry entry = (LdapEntry) acct;
if (acct == null)
throw AccountServiceException.NO_SUCH_ACCOUNT(zimbraId);
String oldEmail = acct.getName();
boolean domainChanged = false;
Account oldAccount = acct;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.RENAME_ACCOUNT);
String oldDn = entry.getDN();
String[] parts = EmailUtil.getLocalPartAndDomain(oldEmail);
String oldLocal = parts[0];
String oldDomain = parts[1];
newName = newName.toLowerCase().trim();
parts = EmailUtil.getLocalPartAndDomain(newName);
if (parts == null) {
throw ServiceException.INVALID_REQUEST("bad value for newName", null);
}
String newLocal = parts[0];
String newDomain = parts[1];
Domain domain = getDomainByAsciiName(newDomain, zlc);
if (domain == null) {
throw AccountServiceException.NO_SUCH_DOMAIN(newDomain);
}
domainChanged = !newDomain.equals(oldDomain);
if (domainChanged) {
validate(ProvisioningValidator.RENAME_ACCOUNT, newName, acct.getMultiAttr(Provisioning.A_objectClass, false), acct.getAttrs(false));
validate(ProvisioningValidator.RENAME_ACCOUNT_CHECK_DOMAIN_COS_AND_FEATURE, newName, acct.getAttrs(false));
// make sure the new domain is a local domain
if (!domain.isLocal()) {
throw ServiceException.INVALID_REQUEST("domain type must be local", null);
}
}
String newDn = mDIT.accountDNRename(oldDn, newLocal, domain.getName());
boolean dnChanged = (!newDn.equals(oldDn));
Map<String, Object> newAttrs = acct.getAttrs(false);
if (dnChanged) {
// uid will be changed during renameEntry, so no need to modify it
// OpenLDAP is OK modifying it, as long as it matches the new DN, but
// InMemoryDirectoryServer does not like it.
newAttrs.remove(Provisioning.A_uid);
} else {
newAttrs.put(Provisioning.A_uid, newLocal);
}
newAttrs.put(Provisioning.A_zimbraMailDeliveryAddress, newName);
if (oldEmail.equals(newAttrs.get(Provisioning.A_zimbraPrefFromAddress))) {
newAttrs.put(Provisioning.A_zimbraPrefFromAddress, newName);
}
ReplaceAddressResult replacedMails = replaceMailAddresses(acct, Provisioning.A_mail, oldEmail, newName);
if (replacedMails.newAddrs().length == 0) {
// Set mail to newName if the account currently does not have a mail
newAttrs.put(Provisioning.A_mail, newName);
} else {
newAttrs.put(Provisioning.A_mail, replacedMails.newAddrs());
}
ReplaceAddressResult replacedAliases = replaceMailAddresses(acct, Provisioning.A_zimbraMailAlias, oldEmail, newName);
if (replacedAliases.newAddrs().length > 0) {
newAttrs.put(Provisioning.A_zimbraMailAlias, replacedAliases.newAddrs());
String newDomainDN = mDIT.domainToAccountSearchDN(newDomain);
String[] aliasNewAddrs = replacedAliases.newAddrs();
// (if domain also got changed)
if (domainChanged && addressExistsUnderDN(zlc, newDomainDN, aliasNewAddrs)) {
throw AccountServiceException.ALIAS_EXISTS(Arrays.toString(aliasNewAddrs));
}
// it won't be caught by the above check, do a separate check.
for (int i = 0; i < aliasNewAddrs.length; i++) {
if (newName.equalsIgnoreCase(aliasNewAddrs[i])) {
throw AccountServiceException.ACCOUNT_EXISTS(newName);
}
}
}
ReplaceAddressResult replacedAllowAddrForDelegatedSender = replaceMailAddresses(acct, Provisioning.A_zimbraPrefAllowAddressForDelegatedSender, oldEmail, newName);
if (replacedAllowAddrForDelegatedSender.newAddrs().length > 0) {
newAttrs.put(Provisioning.A_zimbraPrefAllowAddressForDelegatedSender, replacedAllowAddrForDelegatedSender.newAddrs());
}
if (newAttrs.get(Provisioning.A_displayName) == null && oldLocal.equals(newAttrs.get(Provisioning.A_cn)))
newAttrs.put(Provisioning.A_cn, newLocal);
if (dnChanged) {
zlc.renameEntry(oldDn, newDn);
// re-get the acct object, make sure we don't get it from cache
// Note: this account object contains the old address, it should never
// be cached
acct = getAccountByQuery(mDIT.mailBranchBaseDN(), filterFactory.accountById(zimbraId), zlc, true);
if (acct == null) {
throw ServiceException.FAILURE("cannot find account by id after modrdn", null);
}
}
// rename the account and all it's renamed aliases to the new name in all
// distribution lists. Doesn't throw exceptions, just logs
renameAddressesInAllDistributionLists(oldEmail, newName, replacedAliases);
// doesn't throw exceptions, just logs
if (domainChanged) {
moveAliases(zlc, replacedAliases, newDomain, null, oldDn, newDn, oldDomain, newDomain);
}
modifyLdapAttrs(acct, zlc, newAttrs);
// re-get the account again, now attrs contains new addrs
acct = getAccountByQuery(mDIT.mailBranchBaseDN(), filterFactory.accountById(zimbraId), zlc, true);
if (acct == null) {
throw ServiceException.FAILURE("cannot find account by id after modrdn", null);
}
removeExternalAddrsFromAllDynamicGroups(acct.getAllAddrsSet(), zlc);
} catch (LdapEntryAlreadyExistException nabe) {
throw AccountServiceException.ACCOUNT_EXISTS(newName);
} catch (LdapException e) {
throw e;
} catch (AccountServiceException e) {
throw e;
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to rename account: " + newName, e);
} finally {
LdapClient.closeContext(zlc);
// prune cache
accountCache.remove(oldAccount);
}
// reload it to cache using the master, bug 45736
Account renamedAcct = getAccountById(zimbraId, null, true);
if (domainChanged) {
PermissionCache.invalidateCache(renamedAcct);
}
}
use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method deleteDataSource.
@Override
public void deleteDataSource(Account account, String dataSourceId) throws ServiceException {
LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));
if (ldapEntry == null)
throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());
account.setCachedData(DATA_SOURCE_LIST_CACHE_KEY, null);
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.DELETE_DATASOURCE);
DataSource dataSource = getDataSourceById(ldapEntry, dataSourceId, zlc);
if (dataSource == null)
throw AccountServiceException.NO_SUCH_DATA_SOURCE(dataSourceId);
String dn = getDataSourceDn(ldapEntry, dataSource.getName());
zlc.deleteEntry(dn);
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to delete data source: " + dataSourceId, e);
} finally {
LdapClient.closeContext(zlc);
}
}
Aggregations