Search in sources :

Example 1 with MailboxStore

use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.

the class ImapHandler method doLSUB.

private boolean doLSUB(String tag, String referenceName, String mailboxName) throws ImapException, IOException {
    checkCommandThrottle(new LsubCommand(referenceName, mailboxName));
    if (!checkState(tag, State.AUTHENTICATED)) {
        return true;
    }
    Pair<String, Pattern> resolved = resolvePath(referenceName, mailboxName);
    String resolvedPath = resolved.getFirst();
    Pattern pattern = resolved.getSecond();
    Pattern childPattern = Pattern.compile(pattern.pattern() + "/.*");
    ImapPath patternPath = new ImapPath(resolvedPath, credentials, ImapPath.Scope.UNPARSED);
    List<String> subscriptions = null;
    try {
        // you cannot access your own mailbox via the /home/username mechanism
        String owner = patternPath.getOwner();
        if (owner == null || owner.indexOf('*') != -1 || owner.indexOf('%') != -1 || !patternPath.belongsTo(credentials)) {
            Map<SubscribedImapPath, Boolean> hits = new HashMap<SubscribedImapPath, Boolean>();
            if (owner == null) {
                MailboxStore mbox = credentials.getMailbox();
                boolean isMailFolders = Provisioning.getInstance().getLocalServer().isImapDisplayMailFoldersOnly();
                for (FolderStore folder : mbox.getUserRootSubfolderHierarchy(getContext())) {
                    // chat has item type of message.hence ignoring the chat folder by name.
                    if ((isMailFolders) && (folder.isChatsFolder() || (folder.getName().equals("Chats")))) {
                        continue;
                    }
                    String fAcctId = folder.getFolderItemIdentifier().accountId;
                    if ((fAcctId != null) && !fAcctId.equals(credentials.getAccountId())) {
                        // ignore imapSubscribed flag on remote folders - they apply to the remote acct
                        continue;
                    }
                    if (folder.isIMAPSubscribed()) {
                        checkSubscription(new SubscribedImapPath(new ImapPath(null, folder, credentials)), pattern, childPattern, hits);
                    }
                }
            }
            Set<String> remoteSubscriptions = credentials.listSubscriptions();
            if (remoteSubscriptions != null && !remoteSubscriptions.isEmpty()) {
                for (String sub : remoteSubscriptions) {
                    ImapPath subscribed = new ImapPath(sub, credentials);
                    if ((owner == null) == (subscribed.getOwner() == null)) {
                        checkSubscription(new SubscribedImapPath(subscribed), pattern, childPattern, hits);
                    }
                }
            }
            subscriptions = new ArrayList<String>(hits.size());
            for (Entry<SubscribedImapPath, Boolean> hit : hits.entrySet()) {
                String attrs = hit.getValue() ? "" : "\\NoSelect";
                subscriptions.add("LSUB (" + attrs + ") \"/\" " + hit.getKey().asUtf7String());
            }
        }
    } catch (ServiceException e) {
        ZimbraLog.imap.warn("LSUB failed", e);
        sendNO(tag, "LSUB failed");
        return canContinue(e);
    }
    if (subscriptions != null) {
        for (String sub : subscriptions) {
            sendUntagged(sub);
        }
    }
    sendNotifications(true, false);
    sendOK(tag, "LSUB completed");
    return true;
}
Also used : Pattern(java.util.regex.Pattern) MailboxStore(com.zimbra.common.mailbox.MailboxStore) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) SearchFolderStore(com.zimbra.common.mailbox.SearchFolderStore) FolderStore(com.zimbra.common.mailbox.FolderStore) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException)

Example 2 with MailboxStore

use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.

the class ImapHandler method status.

private String status(ImapPath path, byte status) throws ImapException, ServiceException {
    StringBuilder data = new StringBuilder("STATUS ").append(path.asUtf7String()).append(" (");
    int empty = data.length();
    int messages;
    int recent;
    int uidnext;
    int uvv;
    int unread;
    int modseq;
    MailboxStore mboxStore = path.getOwnerMailbox();
    if (mboxStore != null) {
        FolderStore folder = path.getFolder();
        if (folder == null) {
            throw MailServiceException.NO_SUCH_FOLDER(path.asImapPath());
        }
        ImapFolder i4folder = getSelectedFolder();
        messages = folder.getImapMessageCount();
        if ((status & StatusDataItemNames.STATUS_RECENT) == 0) {
            recent = -1;
        } else if (messages == 0) {
            recent = 0;
        } else if (i4folder != null && i4folder.getItemIdentifier().sameAndFullyDefined(folder.getFolderItemIdentifier())) {
            recent = i4folder.getRecentCount();
        } else if (i4folder != null && path.isEquivalent(i4folder.getPath())) {
            recent = i4folder.getRecentCount();
        } else {
            ImapMailboxStore imapStore = path.getOwnerImapMailboxStore();
            recent = imapStore.getImapRECENT(this.getContext(), folder);
        }
        uidnext = folder.isSearchFolder() ? -1 : folder.getImapUIDNEXT();
        uvv = folder.getUIDValidity();
        unread = folder.getImapUnreadCount();
        modseq = folder.isSearchFolder() ? 0 : folder.getImapMODSEQ();
        ZimbraLog.imap.debug("STATUS for %s. unread %d, recent %d, count %d", folder.getPath(), unread, recent, messages);
    } else {
        throw AccountServiceException.NO_SUCH_ACCOUNT(path.getOwner());
    }
    if (messages >= 0 && (status & StatusDataItemNames.STATUS_MESSAGES) != 0) {
        data.append(data.length() != empty ? " " : "").append("MESSAGES ").append(messages);
    }
    if (recent >= 0 && (status & StatusDataItemNames.STATUS_RECENT) != 0) {
        data.append(data.length() != empty ? " " : "").append("RECENT ").append(recent);
    }
    // note: we're not supporting UIDNEXT for search folders; see the comments in selectFolder()
    if (uidnext > 0 && (status & StatusDataItemNames.STATUS_UIDNEXT) != 0) {
        data.append(data.length() != empty ? " " : "").append("UIDNEXT ").append(uidnext);
    }
    if (uvv > 0 && (status & StatusDataItemNames.STATUS_UIDVALIDITY) != 0) {
        data.append(data.length() != empty ? " " : "").append("UIDVALIDITY ").append(uvv);
    }
    if (unread >= 0 && (status & StatusDataItemNames.STATUS_UNSEEN) != 0) {
        data.append(data.length() != empty ? " " : "").append("UNSEEN ").append(unread);
    }
    if (modseq >= 0 && (status & StatusDataItemNames.STATUS_HIGHESTMODSEQ) != 0) {
        data.append(data.length() != empty ? " " : "").append("HIGHESTMODSEQ ").append(modseq);
    }
    return data.append(')').toString();
}
Also used : MailboxStore(com.zimbra.common.mailbox.MailboxStore) SearchFolderStore(com.zimbra.common.mailbox.SearchFolderStore) FolderStore(com.zimbra.common.mailbox.FolderStore)

Example 3 with MailboxStore

use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.

the class ImapHandler method doDELETEACL.

private boolean doDELETEACL(String tag, ImapPath path, String principal) throws IOException {
    if (!checkState(tag, State.AUTHENTICATED)) {
        return true;
    }
    try {
        // make sure the requester has sufficient permissions to make the request
        if ((path.getFolderRights() & ACL.RIGHT_ADMIN) == 0) {
            ZimbraLog.imap.info("DELETEACL failed: user does not have admin access: " + path);
            sendNO(tag, "DELETEACL failed");
            return true;
        }
        // figure out whose permissions are being revoked
        GranteeIdAndType grantee = getPrincipalGranteeInfo(principal);
        if (grantee.id == null) {
            ZimbraLog.imap.info("DELETEACL failed: cannot resolve principal: %s", principal);
            sendNO(tag, "DELETEACL failed");
            return true;
        }
        // and revoke the permissions appropriately
        MailboxStore mboxStore = path.getOwnerMailbox();
        if (mboxStore != null) {
            FolderStore folder = path.getFolder();
            if (!folder.getACLGrants().isEmpty()) {
                mboxStore.modifyFolderRevokeGrant(getContext(), folder.getFolderIdAsString(), grantee.id);
                if (grantee.id == GuestAccount.GUID_AUTHUSER) {
                    mboxStore.modifyFolderRevokeGrant(getContext(), folder.getFolderIdAsString(), GuestAccount.GUID_PUBLIC);
                }
            }
        }
    } catch (ServiceException e) {
        if (e.getCode().equals(ServiceException.PERM_DENIED)) {
            ZimbraLog.imap.info("DELETEACL failed: permission denied on folder: %s", path);
        } else if (e.getCode().equals(MailServiceException.NO_SUCH_FOLDER)) {
            ZimbraLog.imap.info("DELETEACL failed: no such folder: %s", path);
        } else if (e.getCode().equals(AccountServiceException.NO_SUCH_ACCOUNT)) {
            ZimbraLog.imap.info("DELETEACL failed: no such account: %s", principal);
        } else {
            ZimbraLog.imap.warn("DELETEACL failed", e);
        }
        sendNO(tag, "DELETEACL failed");
        return true;
    }
    sendNotifications(true, false);
    sendOK(tag, "DELETEACL 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)

Example 4 with MailboxStore

use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.

the class ImapHandler method sendNotifications.

public void sendNotifications(boolean notifyExpunges, boolean flush) throws IOException {
    ImapProxy proxy = imapProxy;
    if (proxy != null) {
        proxy.fetchNotifications();
        return;
    }
    ImapListener i4selected = getCurrentImapListener();
    if (i4selected == null || !i4selected.hasNotifications()) {
        return;
    }
    MailboxStore mbox = i4selected.getMailbox();
    if (mbox == null) {
        return;
    }
    ImapFolder i4folder;
    try {
        i4folder = i4selected.getImapFolder();
    } catch (ImapSessionClosedException e) {
        return;
    }
    List<String> notifications = new ArrayList<String>();
    // XXX: is this the right thing to synchronize on?
    mbox.lock(true);
    try {
        if (i4folder.areTagsDirty()) {
            notifications.add("FLAGS (" + StringUtil.join(" ", i4folder.getFlagList(false)) + ')');
            i4folder.setTagsDirty(false);
        }
        int oldRecent = i4folder.getRecentCount();
        boolean removed = false;
        boolean received = i4folder.checkpointSize();
        if (notifyExpunges) {
            List<Integer> expunged = i4folder.collapseExpunged(sessionActivated(ImapExtension.QRESYNC));
            removed = !expunged.isEmpty();
            if (removed) {
                if (sessionActivated(ImapExtension.QRESYNC)) {
                    notifications.add("VANISHED " + ImapFolder.encodeSubsequence(expunged));
                } else {
                    for (Integer index : expunged) {
                        notifications.add(index + " EXPUNGE");
                    }
                }
            }
        }
        i4folder.checkpointSize();
        // notify of any message flag changes
        boolean sendModseq = sessionActivated(ImapExtension.CONDSTORE);
        for (Iterator<ImapFolder.DirtyMessage> it = i4folder.dirtyIterator(); it.hasNext(); ) {
            ImapFolder.DirtyMessage dirty = it.next();
            if (dirty.i4msg.isAdded()) {
                dirty.i4msg.setAdded(false);
            } else {
                notifications.add(dirty.i4msg.sequence + " FETCH (" + dirty.i4msg.getFlags(i4folder) + (sendModseq && dirty.modseq > 0 ? " MODSEQ (" + dirty.modseq + ')' : "") + ')');
            }
        }
        i4folder.clearDirty();
        if (received || removed) {
            notifications.add(i4folder.getSize() + " EXISTS");
        }
        if (received || oldRecent != i4folder.getRecentCount()) {
            notifications.add(i4folder.getRecentCount() + " RECENT");
        }
    } finally {
        mbox.unlock();
    }
    // no I/O while the Mailbox is locked...
    for (String ntfn : notifications) {
        sendUntagged(ntfn);
    }
    if (flush) {
        output.flush();
    }
}
Also used : MailboxStore(com.zimbra.common.mailbox.MailboxStore) ArrayList(java.util.ArrayList)

Example 5 with MailboxStore

use of com.zimbra.common.mailbox.MailboxStore in project zm-mailbox by Zimbra.

the class ImapHandler method doCREATE.

private boolean doCREATE(String tag, ImapPath path) throws IOException, ImapThrottledException {
    checkCommandThrottle(new CreateCommand(path));
    if (!checkState(tag, State.AUTHENTICATED)) {
        return true;
    }
    if (!path.isCreatable()) {
        ZimbraLog.imap.info("CREATE failed: hidden folder or parent: " + path);
        sendNO(tag, "CREATE failed");
        return true;
    }
    try {
        MailboxStore mbox = path.getOwnerMailbox();
        if (mbox != null) {
            mbox.createFolderForMsgs(getContext(), path.asResolvedPath());
        } else {
            throw AccountServiceException.NO_SUCH_ACCOUNT(path.getOwner());
        }
    } catch (ServiceException e) {
        String cause = "CREATE failed";
        if (e.getCode().equals(MailServiceException.CANNOT_CONTAIN)) {
            cause += ": superior mailbox has \\Noinferiors set";
        } else if (e.getCode().equals(MailServiceException.ALREADY_EXISTS)) {
            cause += ": mailbox already exists";
        } else if (e.getCode().equals(MailServiceException.INVALID_NAME)) {
            cause += ": invalid mailbox name";
        } else if (e.getCode().equals(ServiceException.PERM_DENIED)) {
            cause += ": permission denied";
        }
        if ("CREATE failed".equals(cause)) {
            ZimbraLog.imap.warn(cause, e);
        } else {
            ZimbraLog.imap.info("%s: %s", cause, path);
        }
        sendNO(tag, cause);
        return canContinue(e);
    }
    sendNotifications(true, false);
    sendOK(tag, "CREATE 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)

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