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;
}
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;
}
Aggregations