use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.
the class RightCommand method checkRight.
public static boolean checkRight(Provisioning prov, String targetType, TargetBy targetBy, String target, MailTarget grantee, String right, Map<String, Object> attrs, AccessManager.ViaGrant via) throws ServiceException {
verifyAccessManager();
// target
TargetType tt = TargetType.fromCode(targetType);
Entry targetEntry = TargetType.lookupTarget(prov, tt, targetBy, target);
// right
Right r = RightManager.getInstance().getRight(right);
if (r.getRightType() == Right.RightType.setAttrs) {
/*
if (attrs == null || attrs.isEmpty())
throw ServiceException.INVALID_REQUEST("attr map is required for checking a setAttrs right: " + r.getName(), null);
*/
} else {
if (attrs != null && !attrs.isEmpty())
throw ServiceException.INVALID_REQUEST("attr map is not allowed for checking a non-setAttrs right: " + r.getName(), null);
}
AccessManager am = AccessManager.getInstance();
// as admin if the grantee under testing is an admin account
boolean asAdmin = (grantee instanceof Account) ? am.isAdequateAdminAccount((Account) grantee) : false;
boolean result = am.canPerform(grantee, targetEntry, r, false, attrs, asAdmin, via);
return result;
}
use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.
the class ZimbraSoapContext method validateDelegatedAccess.
/**
* Validate delegation rights. Request for delegated access requires a grant on at least one object in the target
* account or admin login rights.
* @param targetAccount - Account which requested is targeted for
* @param requestedKey - The key sent in request which mapped to target account.
* Passed in so error only reports back what was requested (i.e. can't harvest accountId if
* you only know the email or vice-versa)
* @param requestName - The SOAP request name - may be null
* @throws ServiceException
*/
private void validateDelegatedAccess(Account targetAccount, DocumentHandler handler, QName requestName, String requestedKey) throws ServiceException {
if (!isDelegatedRequest()) {
return;
}
if ((handler != null) && handler.handlesAccountHarvesting()) {
return;
}
//if delegated one of the following MUST be true
//1. authed account is an admin AND has admin rights for the target
//2. authed account has been granted access (i.e. login) to the target account
//3. target account has shared at least one item with authed account or enclosing group/cos/domain
//4. target account has granted sendAs or sendOnBehalfOf right to authed account
Account authAccount = null;
boolean isAdmin = AuthToken.isAnyAdmin(mAuthToken);
if (!GuestAccount.GUID_PUBLIC.equals(mAuthToken.getAccountId())) {
authAccount = mAuthToken.getAccount();
if (isAdmin && AccessManager.getInstance().canAccessAccount(mAuthToken, targetAccount, true)) {
//case 1 - admin
return;
}
if (isAdmin && (handler != null) && handler.defendsAgainstDelegateAdminAccountHarvesting()) {
return;
}
if (AccessManager.getInstance().canAccessAccount(mAuthToken, targetAccount, false)) {
//case 2 - access rights
return;
}
}
String externalEmail = null;
if (authAccount != null && authAccount.getBooleanAttr(Provisioning.A_zimbraIsExternalVirtualAccount, false)) {
externalEmail = authAccount.getAttr(Provisioning.A_zimbraExternalUserMailAddress, externalEmail);
}
Provisioning prov = Provisioning.getInstance();
//case 3 - shared items
boolean needRecheck = false;
do {
String[] sharedItems = targetAccount.getSharedItem();
Set<String> groupIds = null;
for (String sharedItem : sharedItems) {
ShareInfoData shareData = AclPushSerializer.deserialize(sharedItem);
switch(shareData.getGranteeTypeCode()) {
case ACL.GRANTEE_USER:
if (authAccount != null && authAccount.getId().equals(shareData.getGranteeId())) {
return;
}
break;
case ACL.GRANTEE_GUEST:
if (shareData.getGranteeId().equals(externalEmail)) {
return;
}
break;
case ACL.GRANTEE_PUBLIC:
return;
case ACL.GRANTEE_GROUP:
if (authAccount != null) {
if (groupIds == null) {
groupIds = new HashSet<String>();
}
groupIds.add(shareData.getGranteeId());
}
break;
case ACL.GRANTEE_AUTHUSER:
if (authAccount != null) {
return;
}
break;
case ACL.GRANTEE_DOMAIN:
if (authAccount != null && authAccount.getDomainId() != null && authAccount.getDomainId().equals(shareData.getGranteeId())) {
return;
}
break;
case ACL.GRANTEE_COS:
if (authAccount != null && authAccount.getCOSId() != null && authAccount.getCOSId().equals(shareData.getGranteeId())) {
return;
}
break;
case ACL.GRANTEE_KEY:
if (authAccount instanceof GuestAccount && mAuthToken.getAccessKey() != null) {
return;
}
break;
}
}
if (groupIds != null) {
for (String groupId : groupIds) {
if (prov.inACLGroup(authAccount, groupId)) {
return;
}
}
}
if (needRecheck) {
break;
} else if (!Provisioning.onLocalServer(targetAccount)) {
//if target on different server we might not have up-to-date shared item list
//reload and check one more time to be sure
prov.reload(targetAccount);
needRecheck = true;
}
} while (needRecheck);
//case 4 - sendAs/sendOnBehalfOf
AccessManager accessMgr = AccessManager.getInstance();
if (accessMgr.canDo(authAccount, targetAccount, Rights.User.R_sendAs, isAdmin) || accessMgr.canDo(authAccount, targetAccount, Rights.User.R_sendOnBehalfOf, isAdmin)) {
return;
}
throw ServiceException.DEFEND_ACCOUNT_HARVEST(requestedKey);
}
use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.
the class LocalFreeBusyProvider method getFreeBusyList.
/**
*
* @param mbox
* @param start
* @param end
* @param folder folder to run free/busy search on; FreeBusyQuery.CALENDAR_FOLDER_ALL (-1) for all folders
* @param exAppt appointment to exclude; calculate free/busy assuming
* the specified appointment wasn't there
* @return
* @throws ServiceException
*/
public static FreeBusy getFreeBusyList(Account authAcct, boolean asAdmin, Mailbox mbox, String name, long start, long end, int folder, Appointment exAppt) throws ServiceException {
AccessManager accessMgr = AccessManager.getInstance();
boolean accountAceAllowed = accessMgr.canDo(authAcct, mbox.getAccount(), User.R_viewFreeBusy, asAdmin);
int numAllowedFolders = 0;
int exApptId = exAppt == null ? -1 : exAppt.getId();
IntervalList intervals = new IntervalList(start, end);
List<CalendarDataResult> calDataResultList;
if (folder == FreeBusyQuery.CALENDAR_FOLDER_ALL) {
calDataResultList = mbox.getAllCalendarsSummaryForRange(null, MailItem.Type.APPOINTMENT, start, end);
} else {
calDataResultList = new ArrayList<CalendarDataResult>(1);
calDataResultList.add(mbox.getCalendarSummaryForRange(null, folder, MailItem.Type.APPOINTMENT, start, end));
}
for (CalendarDataResult result : calDataResultList) {
int folderId = result.data.getFolderId();
Folder f = mbox.getFolderById(null, folderId);
if ((f.getFlagBitmask() & Flag.BITMASK_EXCLUDE_FREEBUSY) != 0) {
ZimbraLog.fb.debug("Calendar '%s' id=%s ignored - has EXCLUDE_FREEBUSY flag set", f.getName(), folderId);
continue;
}
// Free/busy must be allowed by folder or at account-level.
boolean folderFBAllowed = CalendarItem.allowFreeBusyAccess(f, authAcct, asAdmin);
if (folderFBAllowed)
++numAllowedFolders;
if (!folderFBAllowed && !accountAceAllowed) {
ZimbraLog.fb.debug("Calendar '%s' id=%s ignored - folderFBAllowed=%s accountAceAllowed=%s", f.getName(), folderId, folderFBAllowed, accountAceAllowed);
continue;
}
for (Iterator<CalendarItemData> iter = result.data.calendarItemIterator(); iter.hasNext(); ) {
CalendarItemData appt = iter.next();
int apptId = appt.getCalItemId();
if (apptId == exApptId)
continue;
FullInstanceData defaultInstance = appt.getDefaultData();
if (defaultInstance == null)
continue;
boolean isTransparent = false;
String transp = defaultInstance.getTransparency();
isTransparent = IcalXmlStrMap.TRANSP_TRANSPARENT.equals(transp);
long defaultDuration = 0;
if (defaultInstance.getDuration() != null)
defaultDuration = defaultInstance.getDuration().longValue();
String defaultFreeBusy = defaultInstance.getFreeBusyActual();
for (Iterator<InstanceData> instIter = appt.instanceIterator(); instIter.hasNext(); ) {
InstanceData instance = instIter.next();
long instStart = instance.getDtStart() != null ? instance.getDtStart().longValue() : 0;
// Skip instances that are outside the time range but were returned due to alarm being in range.
if (instStart >= end)
continue;
long dur = defaultDuration;
if (instance.getDuration() != null)
dur = instance.getDuration().longValue();
if (// Only consider instances with non-zero, positive duration.
dur <= 0)
continue;
long instEnd = instStart + dur;
long recurIdDt = 0;
// Skip if instance is TRANSPARENT to free/busy searches.
if (instance instanceof FullInstanceData) {
FullInstanceData fullInst = (FullInstanceData) instance;
String transpInst = fullInst.getTransparency();
recurIdDt = fullInst.getRecurrenceId();
if (IcalXmlStrMap.TRANSP_TRANSPARENT.equals(transpInst))
continue;
} else if (isTransparent) {
continue;
}
String freeBusy = instance.getFreeBusyActual();
if (freeBusy == null)
freeBusy = defaultFreeBusy;
if (!IcalXmlStrMap.FBTYPE_FREE.equals(freeBusy)) {
FBInstance fbInst = new FBInstance(freeBusy, instStart, instEnd, apptId, recurIdDt);
Interval ival = new Interval(instStart, instEnd, freeBusy, fbInst);
intervals.addInterval(ival);
}
}
}
}
if (!accountAceAllowed && numAllowedFolders == 0 && !LC.freebusy_disable_nodata_status.booleanValue()) {
Interval nodata = new Interval(start, end, IcalXmlStrMap.FBTYPE_NODATA);
intervals.addInterval(nodata);
}
return new FreeBusy(name, intervals, start, end);
}
use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.
the class MailSender method getSenderHeaders.
/** Determines an acceptable set of {@code From} and {@code Sender} header
* values for a message. The message's existing {@code from} and {@code
* sender} values are examined in light of the authenticated account's
* settings and are reset to the account's default return address if
* they aren't acceptable.
* @return a {@link Pair} containing the approved {@code from} and {@code
* sender} header addresses, in that order. */
public Pair<InternetAddress, InternetAddress> getSenderHeaders(InternetAddress from, InternetAddress sender, Account acct, Account authuser, boolean asAdmin) throws ServiceException {
if (from != null && authuser.isAllowAnyFromAddress()) {
return new Pair<InternetAddress, InternetAddress>(from, sender);
}
if (from == null && sender == null) {
return new Pair<InternetAddress, InternetAddress>(AccountUtil.getFriendlyEmailAddress(authuser), null);
}
if (Objects.equal(sender, from)) {
// no need for matching Sender and From addresses
sender = null;
}
if (from == null && sender != null) {
// if only one value is given, set From and unset Sender
from = sender;
sender = null;
}
AccessManager amgr = AccessManager.getInstance();
if (// send-as requested
sender == null && (// either it's my address
AccountUtil.addressMatchesAccount(authuser, from.getAddress()) || amgr.canSendAs(authuser, acct, from.getAddress(), asAdmin))) {
// or I've been granted permission
return new Pair<InternetAddress, InternetAddress>(from, null);
}
if (sender != null) {
// send-obo requested.
// Restrict Sender value to owned addresses. Not even zimbraAllowFromAddress is acceptable.
AccountAddressMatcher matcher = new AccountAddressMatcher(authuser, true);
if (!matcher.matches(sender.getAddress())) {
sender = AccountUtil.getFriendlyEmailAddress(authuser);
}
} else if (!isDataSourceSender()) {
// Downgrade disallowed send-as to send-obo.
sender = AccountUtil.getFriendlyEmailAddress(authuser);
}
if (mCalendarMode) {
// In calendar mode any user may send on behalf of any other user.
return new Pair<InternetAddress, InternetAddress>(from, sender);
} else if (amgr.canSendOnBehalfOf(authuser, acct, from.getAddress(), asAdmin)) {
// Allow based on rights granted.
return new Pair<InternetAddress, InternetAddress>(from, sender);
} else if (AccountUtil.isAllowedDataSourceSendAddress(authuser, from.getAddress())) {
// Allow send-obo if address is a pop/imap/caldav data source address. (bugs 38813/46378)
return new Pair<InternetAddress, InternetAddress>(from, sender);
} else {
// Not allowed to use the requested From value. Send as self.
return new Pair<InternetAddress, InternetAddress>(sender, null);
}
}
use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.
the class WorkingHours method getWorkingHours.
public static FreeBusy getWorkingHours(Account authAcct, boolean asAdmin, Account account, String name, long start, long end) throws ServiceException {
// If free/busy viewing is blocked, so is viewing working hours.
AccessManager accessMgr = AccessManager.getInstance();
boolean accountAceAllowed = accessMgr.canDo(authAcct, account, User.R_viewFreeBusy, asAdmin);
if (!accountAceAllowed)
return FreeBusy.nodataFreeBusy(account.getName(), start, end);
// Get the working hours preference and parse it.
String workingHoursPref = account.getPrefCalendarWorkingHours();
HoursByDay workingHoursByDay = new HoursByDay(workingHoursPref);
// Build a recurrence rule for each day of the week and expand over the time range.
IntervalList intervals = new IntervalList(start, end);
ICalTimeZone tz = Util.getAccountTimeZone(account);
TimeZoneMap tzmap = new TimeZoneMap(tz);
StartSpec startSpec = new StartSpec(start, tz);
for (int day = 1; day <= 7; ++day) {
TimeRange timeRange = workingHoursByDay.getHoursForDay(day);
if (timeRange.enabled) {
IRecurrence rrule = getRecurrenceForDay(day, startSpec, timeRange, tz, tzmap);
List<Instance> instances = rrule.expandInstances(0, start, end);
for (Instance inst : instances) {
Interval ival = new Interval(inst.getStart(), inst.getEnd(), IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE);
intervals.addInterval(ival);
}
}
}
// hours are shown as out-of-office.
for (Iterator<Interval> iter = intervals.iterator(); iter.hasNext(); ) {
Interval interval = iter.next();
String status = interval.getStatus();
interval.setStatus(invertStatus(status));
}
return new FreeBusy(name, intervals, start, end);
}
Aggregations