use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapPath method getFolder.
@VisibleForTesting
public FolderStore getFolder() throws ServiceException {
if (useReferent()) {
return getReferent().getFolder();
}
if (mCredentials != null && mCredentials.isFolderHidden(this)) {
throw MailServiceException.NO_SUCH_FOLDER(asImapPath());
}
if (folder == null) {
MailboxStore mboxStore = getOwnerMailbox();
if (null == mboxStore) {
throw AccountServiceException.NO_SUCH_ACCOUNT(getOwner());
}
String zimbraPath = asZimbraPath();
folder = mboxStore.getFolderByPath(getContext(), zimbraPath);
if (folder == null) {
// If the folder is not found, it's possible that it was created
// by a non-imap client. Issue a noOp request to get latest changes and try again.
mboxStore.noOp();
folder = mboxStore.getFolderByPath(getContext(), zimbraPath);
}
if (folder == null) {
throw MailServiceException.NO_SUCH_FOLDER(asImapPath());
}
mItemId = new ItemId(folder.getFolderIdAsString(), accountIdFromCredentials());
}
return folder;
}
use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method doSETACL.
private boolean doSETACL(String tag, ImapPath path, String principal, String i4rights, StoreAction action) throws IOException {
if (!checkState(tag, State.AUTHENTICATED))
return true;
// RFC 4314 2: "If rights are tied in an implementation, the implementation must be
// conservative in granting rights in response to SETACL commands--unless
// all rights in a tied set are specified, none of that set should be
// included in the ACL entry for that identifier."
short rights = 0;
for (int i = 0; i < i4rights.length(); i++) {
char c = i4rights.charAt(i);
if (IMAP_READ_RIGHTS.indexOf(c) != -1) {
if (allRightsPresent(i4rights, IMAP_READ_RIGHTS))
rights |= ACL.RIGHT_READ;
} else if (IMAP_WRITE_RIGHTS.indexOf(c) != -1) {
if (allRightsPresent(i4rights, IMAP_WRITE_RIGHTS))
rights |= ACL.RIGHT_WRITE;
} else if (IMAP_INSERT_RIGHTS.indexOf(c) != -1) {
if (allRightsPresent(i4rights, IMAP_INSERT_RIGHTS))
rights |= ACL.RIGHT_INSERT;
} else if (IMAP_DELETE_RIGHTS.indexOf(c) != -1) {
if (allRightsPresent(i4rights, IMAP_DELETE_RIGHTS))
rights |= ACL.RIGHT_DELETE;
} else if (IMAP_ADMIN_RIGHTS.indexOf(c) != -1) {
if (allRightsPresent(i4rights, IMAP_ADMIN_RIGHTS))
rights |= ACL.RIGHT_ADMIN;
} else {
// RFC 4314 3.1: "Note that an unrecognized right MUST cause the command to return
// the BAD response. In particular, the server MUST NOT silently
// ignore unrecognized rights."
ZimbraLog.imap.info("SETACL failed: invalid rights string: %s", i4rights);
sendBAD(tag, "SETACL failed: invalid right");
return true;
}
}
try {
// make sure the requester has sufficient permissions to make the request
if ((path.getFolderRights() & ACL.RIGHT_ADMIN) == 0) {
ZimbraLog.imap.info("SETACL failed: user does not have admin access: %s", path);
sendNO(tag, "SETACL failed");
return true;
}
// detect a no-op early and short-circuit out here
if (action != StoreAction.REPLACE && rights == 0) {
sendNotifications(true, false);
sendOK(tag, "SETACL completed");
return true;
}
// figure out who's being granted permissions
GranteeIdAndType grantee = getPrincipalGranteeInfo(principal);
if (grantee.id == null) {
ZimbraLog.imap.info("SETACL failed: cannot resolve principal: %s", principal);
sendNO(tag, "SETACL failed");
return true;
}
// figure out the rights already granted on the folder
short oldRights = 0;
FolderStore folderStore = path.getFolder();
if (null != folderStore) {
for (ACLGrant grant : folderStore.getACLGrants()) {
if (grantee.id.equalsIgnoreCase(grant.getGranteeId()) || (grantee.type == ACL.GRANTEE_AUTHUSER && (grant.getGrantGranteeType() == GrantGranteeType.all || grant.getGrantGranteeType() == GrantGranteeType.pub))) {
oldRights |= ACL.stringToRights(grant.getPermissions());
}
}
}
// calculate the new rights we want granted on the folder
short newRights;
if (action == StoreAction.REMOVE) {
newRights = (short) (oldRights & ~rights);
} else if (action == StoreAction.ADD) {
newRights = (short) (oldRights | rights);
} else {
newRights = rights;
}
// and update the folder appropriately, if necessary
if (newRights != oldRights) {
MailboxStore mboxStore = path.getOwnerMailbox();
mboxStore.modifyFolderGrant(getContext(), folderStore, GrantGranteeType.fromByte(grantee.type), grantee.id, ACL.rightsToString(newRights), null);
}
} catch (ServiceException e) {
if (e.getCode().equals(ServiceException.PERM_DENIED)) {
ZimbraLog.imap.info("SETACL failed: permission denied on folder: %s", path);
} else if (e.getCode().equals(MailServiceException.NO_SUCH_FOLDER)) {
ZimbraLog.imap.info("SETACL failed: no such folder: %s", path);
} else if (e.getCode().equals(AccountServiceException.NO_SUCH_ACCOUNT)) {
ZimbraLog.imap.info("SETACL failed: no such account: %s", principal);
} else {
ZimbraLog.imap.warn("SETACL failed", e);
}
sendNO(tag, "SETACL failed");
return true;
}
sendNotifications(true, false);
sendOK(tag, "SETACL completed");
return true;
}
use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method setLoggingContext.
protected void setLoggingContext() {
ZimbraLog.clearContext();
ImapListener i4selected = selectedFolderListener;
MailboxStore mbox = i4selected == null ? null : i4selected.getMailbox();
if (credentials != null) {
ZimbraLog.addAccountNameToContext(credentials.getUsername());
}
if (mbox != null) {
if (mbox instanceof Mailbox) {
ZimbraLog.addMboxToContext(((Mailbox) mbox).getId());
} else {
// TODO - for ZMailbox, could put account id of mailbox there? Not an int though, which might matter
}
}
if (origRemoteIp != null) {
ZimbraLog.addOrigIpToContext(origRemoteIp);
}
if (via != null) {
ZimbraLog.addViaToContext(via);
}
if (userAgent != null) {
ZimbraLog.addUserAgentToContext(userAgent);
}
ZimbraLog.addIpToContext(getRemoteIp());
}
use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method runSearch.
private ZimbraQueryHitResults runSearch(ImapSearch i4search, ImapFolder i4folder, SortBy sort, SearchParams.Fetch fetch) throws ImapParseException, ServiceException {
MailboxStore mbox = i4folder.getMailbox();
if (mbox == null) {
throw ServiceException.FAILURE("unexpected session close during search", null);
}
Account acct = credentials == null ? null : credentials.getAccount();
TimeZone tz = acct == null ? null : WellKnownTimeZones.getTimeZoneById(acct.getAttr(Provisioning.A_zimbraPrefTimeZoneId));
String search;
mbox.lock(false);
try {
search = i4search.toZimbraSearch(i4folder);
if (!i4folder.isVirtual()) {
search = "in:" + i4folder.getQuotedPath() + ' ' + search;
} else if (i4folder.getSize() <= LARGEST_FOLDER_BATCH) {
search = ImapSearch.sequenceAsSearchTerm(i4folder, i4folder.getAllMessages(), false) + ' ' + search;
} else {
search = '(' + i4folder.getQuery() + ") " + search;
}
ZimbraLog.imap.info("[ search is: " + search + " ]");
} finally {
mbox.unlock();
}
ZimbraSearchParams params = mbox.createSearchParams(search);
params.setIncludeTagDeleted(true);
params.setMailItemTypes(MailItem.Type.toCommon(i4folder.getTypeConstraint()));
params.setZimbraSortBy(sort.toZimbraSortBy());
params.setLimit(2000);
params.setPrefetch(false);
params.setZimbraFetchMode(fetch.toZimbraFetchMode());
params.setTimeZone(tz);
return mbox.searchImap(getContext(), params);
}
use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.
the class ImapHandler method doDELETE.
private boolean doDELETE(String tag, ImapPath path) throws IOException {
if (!checkState(tag, State.AUTHENTICATED)) {
return true;
}
try {
if (!path.isVisible()) {
throw ImapServiceException.FOLDER_NOT_VISIBLE(path.asImapPath());
}
// don't want the DELETE to cause *this* connection to drop if the deleted folder is currently selected
if (getState() == State.SELECTED) {
ImapListener i4selected = getCurrentImapListener();
if (i4selected != null && path.isEquivalent(i4selected.getPath())) {
unsetSelectedFolder(true);
} else if (imapProxy != null && path.isEquivalent(imapProxy.getPath())) {
unsetSelectedFolder(true);
}
}
MailboxStore mboxStore = path.getOwnerMailbox();
if (path.useReferent()) {
// when users try to remove mountpoints, the IMAP client hard-deletes the subfolders!
// deal with this by only *pretending* to delete subfolders of mountpoints
credentials.hideFolder(path);
// even pretend-deleting the folder also unsubscribes from it...
credentials.unsubscribe(path);
} else if (null != mboxStore) {
FolderStore folder = path.getFolder();
if (!folder.isDeletable()) {
throw ImapServiceException.CANNOT_DELETE_SYSTEM_FOLDER(folder.getPath());
}
if (!folder.hasSubfolders()) {
mboxStore.deleteFolder(getContext(), folder.getFolderIdAsString());
// deleting the folder also unsubscribes from it...
credentials.unsubscribe(path);
} else {
// 6.3.4: "It is permitted to delete a name that has inferior hierarchical
// names and does not have the \Noselect mailbox name attribute.
// In this case, all messages in that mailbox are removed, and the
// name will acquire the \Noselect mailbox name attribute."
mboxStore.emptyFolder(getContext(), folder.getFolderIdAsString(), false);
// FIXME: add \Deleted flag to folder
}
} else {
throw AccountServiceException.NO_SUCH_ACCOUNT(path.getOwner());
}
} catch (ServiceException e) {
if (e.getCode().equals(MailServiceException.NO_SUCH_FOLDER)) {
ZimbraLog.imap.info("DELETE failed: no such folder: %s", path);
} else if (e.getCode().equals(AccountServiceException.NO_SUCH_ACCOUNT)) {
ZimbraLog.imap.info("DELETE failed: no such account: %s", path);
} else if (e.getCode().equals(ImapServiceException.FOLDER_NOT_VISIBLE)) {
ZimbraLog.imap.info("DELETE failed: folder not visible: %s", path);
} else if (e.getCode().equals(ImapServiceException.CANT_DELETE_SYSTEM_FOLDER)) {
ZimbraLog.imap.info("DELETE failed: system folder cannot be deleted: %s", path);
} else if (e.getCode().equals(ServiceException.PERM_DENIED)) {
ZimbraLog.imap.info("DELETE failed: permission denied: %s", path);
} else {
ZimbraLog.imap.warn("DELETE failed", e);
}
sendNO(tag, "DELETE failed");
return canContinue(e);
}
sendNotifications(true, false);
sendOK(tag, "DELETE completed");
return true;
}
Aggregations