Search in sources :

Example 1 with AccessManager

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;
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) Account(com.zimbra.cs.account.Account) NamedEntry(com.zimbra.cs.account.NamedEntry) Entry(com.zimbra.cs.account.Entry)

Example 2 with AccessManager

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);
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) GuestAccount(com.zimbra.cs.account.GuestAccount) ShareInfoData(com.zimbra.cs.account.ShareInfoData) Provisioning(com.zimbra.cs.account.Provisioning)

Example 3 with AccessManager

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);
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) FullInstanceData(com.zimbra.cs.mailbox.calendar.cache.FullInstanceData) CalendarDataResult(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult) Folder(com.zimbra.cs.mailbox.Folder) InstanceData(com.zimbra.cs.mailbox.calendar.cache.InstanceData) FullInstanceData(com.zimbra.cs.mailbox.calendar.cache.FullInstanceData) IntervalList(com.zimbra.cs.fb.FreeBusy.IntervalList) CalendarItemData(com.zimbra.cs.mailbox.calendar.cache.CalendarItemData) FBInstance(com.zimbra.cs.fb.FreeBusy.FBInstance) Interval(com.zimbra.cs.fb.FreeBusy.Interval)

Example 4 with AccessManager

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);
    }
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) AccountAddressMatcher(com.zimbra.cs.util.AccountUtil.AccountAddressMatcher) Pair(com.zimbra.common.util.Pair)

Example 5 with AccessManager

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);
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) IntervalList(com.zimbra.cs.fb.FreeBusy.IntervalList) TimeZoneMap(com.zimbra.common.calendar.TimeZoneMap) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone) Interval(com.zimbra.cs.fb.FreeBusy.Interval)

Aggregations

AccessManager (com.zimbra.cs.account.AccessManager)11 Account (com.zimbra.cs.account.Account)4 NamedEntry (com.zimbra.cs.account.NamedEntry)4 Element (com.zimbra.common.soap.Element)3 Entry (com.zimbra.cs.account.Entry)3 Provisioning (com.zimbra.cs.account.Provisioning)3 TargetType (com.zimbra.cs.account.accesscontrol.TargetType)3 UserRight (com.zimbra.cs.account.accesscontrol.UserRight)3 GuestAccount (com.zimbra.cs.account.GuestAccount)2 Interval (com.zimbra.cs.fb.FreeBusy.Interval)2 IntervalList (com.zimbra.cs.fb.FreeBusy.IntervalList)2 AccountAddressMatcher (com.zimbra.cs.util.AccountUtil.AccountAddressMatcher)2 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)2 ArrayList (java.util.ArrayList)2 Key (com.zimbra.common.account.Key)1 AccountBy (com.zimbra.common.account.Key.AccountBy)1 PrefCalendarApptVisibility (com.zimbra.common.account.ZAttrProvisioning.PrefCalendarApptVisibility)1 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)1 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)1 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)1