Search in sources :

Example 6 with MailboxStore

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;
}
Also used : MailboxStore(com.zimbra.common.mailbox.MailboxStore) ItemId(com.zimbra.cs.service.util.ItemId) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 7 with MailboxStore

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;
}
Also used : MailboxStore(com.zimbra.common.mailbox.MailboxStore) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) SearchFolderStore(com.zimbra.common.mailbox.SearchFolderStore) FolderStore(com.zimbra.common.mailbox.FolderStore) ACLGrant(com.zimbra.common.mailbox.ACLGrant)

Example 8 with MailboxStore

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());
}
Also used : MailboxStore(com.zimbra.common.mailbox.MailboxStore) Mailbox(com.zimbra.cs.mailbox.Mailbox)

Example 9 with MailboxStore

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);
}
Also used : Account(com.zimbra.cs.account.Account) GuestAccount(com.zimbra.cs.account.GuestAccount) TimeZone(java.util.TimeZone) MailboxStore(com.zimbra.common.mailbox.MailboxStore) ZimbraSearchParams(com.zimbra.common.mailbox.ZimbraSearchParams)

Example 10 with MailboxStore

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;
}
Also used : MailboxStore(com.zimbra.common.mailbox.MailboxStore) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) SearchFolderStore(com.zimbra.common.mailbox.SearchFolderStore) FolderStore(com.zimbra.common.mailbox.FolderStore)

Aggregations

MailboxStore (com.zimbra.common.mailbox.MailboxStore)34 ServiceException (com.zimbra.common.service.ServiceException)22 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)17 AccountServiceException (com.zimbra.cs.account.AccountServiceException)14 SearchFolderStore (com.zimbra.common.mailbox.SearchFolderStore)10 FolderStore (com.zimbra.common.mailbox.FolderStore)9 ArrayList (java.util.ArrayList)6 ItemIdentifier (com.zimbra.common.mailbox.ItemIdentifier)5 Account (com.zimbra.cs.account.Account)4 ZimbraMailItem (com.zimbra.common.mailbox.ZimbraMailItem)3 ImapMessageSet (com.zimbra.cs.imap.ImapMessage.ImapMessageSet)3 Mailbox (com.zimbra.cs.mailbox.Mailbox)3 IOException (java.io.IOException)3 ZMailbox (com.zimbra.client.ZMailbox)2 ZSharedFolder (com.zimbra.client.ZSharedFolder)2 MountpointStore (com.zimbra.common.mailbox.MountpointStore)2 ZimbraQueryHit (com.zimbra.common.mailbox.ZimbraQueryHit)2 ZimbraQueryHitResults (com.zimbra.common.mailbox.ZimbraQueryHitResults)2 ZimbraSearchParams (com.zimbra.common.mailbox.ZimbraSearchParams)2 GuestAccount (com.zimbra.cs.account.GuestAccount)2