Search in sources :

Example 1 with ACLGrant

use of com.zimbra.common.mailbox.ACLGrant 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 2 with ACLGrant

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

the class ImapHandler method doGETACL.

private boolean doGETACL(String tag, ImapPath path) throws IOException {
    if (!checkState(tag, State.AUTHENTICATED)) {
        return true;
    }
    StringBuilder i4acl = new StringBuilder("ACL ").append(path.asUtf7String());
    try {
        // make sure the requester has sufficient permissions to make the request
        if ((path.getFolderRights() & ACL.RIGHT_ADMIN) == 0) {
            ZimbraLog.imap.info("GETACL failed: user does not have admin access: %s", path);
            sendNO(tag, "GETACL failed");
            return true;
        }
        // the target folder's owner always has full rights
        Account owner = path.getOwnerAccount();
        if (owner != null) {
            i4acl.append(" \"").append(owner.getName()).append("\" ").append(IMAP_CONCATENATED_RIGHTS);
        }
        // write out the grants to all users and groups
        Short anyoneRights = null;
        FolderStore folderStore = path.getFolder();
        if (null != folderStore) {
            for (ACLGrant grant : folderStore.getACLGrants()) {
                GrantGranteeType gType = grant.getGrantGranteeType();
                short rights = ACL.stringToRights(grant.getPermissions());
                if (gType == GrantGranteeType.pub || gType == GrantGranteeType.all) {
                    anyoneRights = (short) ((anyoneRights == null ? 0 : anyoneRights) | rights);
                } else if (gType == GrantGranteeType.usr || gType == GrantGranteeType.grp) {
                    NamedEntry entry = FolderAction.lookupGranteeByZimbraId(grant.getGranteeId(), gType.asByte());
                    if (entry != null) {
                        i4acl.append(" \"").append(entry.getName()).append("\" ").append(exportRights(rights));
                    }
                }
            }
        }
        // aggregate all the "public" and "auth user" grants into the "anyone" IMAP ACL
        if (anyoneRights != null) {
            i4acl.append(" anyone ").append(exportRights(anyoneRights));
        }
    } catch (ServiceException e) {
        if (e.getCode().equals(ServiceException.PERM_DENIED)) {
            ZimbraLog.imap.info("GETACL failed: permission denied on folder: %s", path);
        } else if (e.getCode().equals(MailServiceException.NO_SUCH_FOLDER)) {
            ZimbraLog.imap.info("GETACL failed: no such folder: %s", path);
        } else {
            ZimbraLog.imap.warn("GETACL failed", e);
        }
        sendNO(tag, "GETACL failed");
        return true;
    }
    sendUntagged(i4acl.toString());
    sendNotifications(true, false);
    sendOK(tag, "GETACL completed");
    return true;
}
Also used : Account(com.zimbra.cs.account.Account) GuestAccount(com.zimbra.cs.account.GuestAccount) NamedEntry(com.zimbra.cs.account.NamedEntry) 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) GrantGranteeType(com.zimbra.common.mailbox.GrantGranteeType) ACLGrant(com.zimbra.common.mailbox.ACLGrant)

Aggregations

ACLGrant (com.zimbra.common.mailbox.ACLGrant)2 FolderStore (com.zimbra.common.mailbox.FolderStore)2 SearchFolderStore (com.zimbra.common.mailbox.SearchFolderStore)2 ServiceException (com.zimbra.common.service.ServiceException)2 AccountServiceException (com.zimbra.cs.account.AccountServiceException)2 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)2 GrantGranteeType (com.zimbra.common.mailbox.GrantGranteeType)1 MailboxStore (com.zimbra.common.mailbox.MailboxStore)1 Account (com.zimbra.cs.account.Account)1 GuestAccount (com.zimbra.cs.account.GuestAccount)1 NamedEntry (com.zimbra.cs.account.NamedEntry)1