Search in sources :

Example 6 with AccessManager

use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.

the class CheckRights method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Provisioning prov = Provisioning.getInstance();
    List<RequestedTarget> requestedTargets = Lists.newArrayList();
    for (Element eTarget : request.listElements(AccountConstants.E_TARGET)) {
        TargetType targetType = TargetType.fromCode(eTarget.getAttribute(AccountConstants.A_TYPE));
        TargetBy targetBy = TargetBy.fromString(eTarget.getAttribute(AccountConstants.A_BY));
        String key = eTarget.getAttribute(AccountConstants.A_KEY);
        Entry entry = findEntry(prov, targetType, targetBy, key);
        RequestedTarget target = new RequestedTarget(entry, targetType, targetBy, key);
        requestedTargets.add(target);
        for (Element eRight : eTarget.listElements(AccountConstants.E_RIGHT)) {
            // can only be user right, not admim rights
            target.addRight(RightManager.getInstance().getUserRight(eRight.getText()));
        }
        if (target.getRights().size() == 0) {
            throw ServiceException.INVALID_REQUEST("missing right for target: " + key, null);
        }
    }
    Element response = zsc.createElement(AccountConstants.CHECK_RIGHTS_RESPONSE);
    AccessManager accessMgr = AccessManager.getInstance();
    for (RequestedTarget target : requestedTargets) {
        Entry targetEntry = target.getTargetEntry();
        Element eTarget = response.addElement(AccountConstants.E_TARGET);
        eTarget.addAttribute(AccountConstants.A_TYPE, target.getTargetType().getCode());
        eTarget.addAttribute(AccountConstants.A_BY, target.getTargetBy().name());
        eTarget.addAttribute(AccountConstants.A_KEY, target.getTargetKey());
        boolean combinedResult = true;
        for (UserRight right : target.getRights()) {
            boolean allow = accessMgr.canDo(zsc.getAuthToken(), targetEntry, right, false);
            if (allow && DiscoverRights.isDelegatedSendRight(right) && TargetBy.name == target.getTargetBy()) {
                allow = AccountUtil.isAllowedSendAddress((NamedEntry) targetEntry, target.getTargetKey());
            }
            eTarget.addElement(AccountConstants.E_RIGHT).addAttribute(AccountConstants.A_ALLOW, allow).setText(right.getName());
            combinedResult = combinedResult & allow;
        }
        eTarget.addAttribute(AccountConstants.A_ALLOW, combinedResult);
    }
    return response;
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) UserRight(com.zimbra.cs.account.accesscontrol.UserRight) Element(com.zimbra.common.soap.Element) TargetBy(com.zimbra.soap.type.TargetBy) Provisioning(com.zimbra.cs.account.Provisioning) NamedEntry(com.zimbra.cs.account.NamedEntry) NamedEntry(com.zimbra.cs.account.NamedEntry) Entry(com.zimbra.cs.account.Entry) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) TargetType(com.zimbra.cs.account.accesscontrol.TargetType)

Example 7 with AccessManager

use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.

the class DiscoverRights method discoverRights.

public static void discoverRights(Account account, Set<Right> rights, Element eParent, boolean onMaster) throws ServiceException {
    AccessManager accessMgr = AccessManager.getInstance();
    Map<Right, Set<Entry>> discoveredRights = accessMgr.discoverUserRights(account, rights, onMaster);
    Locale locale = account.getLocale();
    for (Map.Entry<Right, Set<Entry>> targetsForRight : discoveredRights.entrySet()) {
        Right right = targetsForRight.getKey();
        Set<Entry> targets = targetsForRight.getValue();
        List<Entry> sortedTargets = Entry.sortByDisplayName(targets, locale);
        boolean isDelegatedSendRight = isDelegatedSendRight(right);
        Element eTargets = eParent.addElement(AccountConstants.E_TARGETS);
        eTargets.addAttribute(AccountConstants.A_RIGHT, right.getName());
        for (Entry target : sortedTargets) {
            TargetType targetType = TargetType.getTargetType(target);
            Element eTarget = eTargets.addElement(AccountConstants.E_TARGET);
            eTarget.addAttribute(AccountConstants.A_TYPE, targetType.getCode());
            if (isDelegatedSendRight) {
                if (target instanceof Account || target instanceof Group) {
                    String[] addrs = AccountUtil.getAllowedSendAddresses((NamedEntry) target);
                    NamedEntry entry = (NamedEntry) target;
                    for (String addr : addrs) {
                        Element eEmail = eTarget.addElement(AccountConstants.E_EMAIL);
                        eEmail.addAttribute(AccountConstants.A_ADDR, addr);
                    }
                    if (target instanceof Account) {
                        eTarget.addAttribute(AccountConstants.A_DISPLAY, ((Account) entry).getDisplayName());
                    } else if (target instanceof Group) {
                        eTarget.addAttribute(AccountConstants.A_DISPLAY, ((Group) entry).getDisplayName());
                    }
                } else {
                    throw ServiceException.FAILURE("internal error, target for " + " delegated send rights must be account or group", null);
                }
            } else {
                if (target instanceof NamedEntry) {
                    NamedEntry entry = (NamedEntry) target;
                    eTarget.addAttribute(AccountConstants.A_ID, entry.getId());
                    eTarget.addAttribute(AccountConstants.A_NAME, entry.getName());
                    if (target instanceof Account) {
                        eTarget.addAttribute(AccountConstants.A_DISPLAY, ((Account) entry).getDisplayName());
                    } else if (target instanceof Group) {
                        eTarget.addAttribute(AccountConstants.A_DISPLAY, ((Group) entry).getDisplayName());
                    }
                } else {
                    eTarget.addAttribute(AccountConstants.A_NAME, target.getLabel());
                }
            }
        }
    }
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) Locale(java.util.Locale) Account(com.zimbra.cs.account.Account) Group(com.zimbra.cs.account.Group) Set(java.util.Set) Element(com.zimbra.common.soap.Element) UserRight(com.zimbra.cs.account.accesscontrol.UserRight) Right(com.zimbra.cs.account.accesscontrol.Right) NamedEntry(com.zimbra.cs.account.NamedEntry) NamedEntry(com.zimbra.cs.account.NamedEntry) Entry(com.zimbra.cs.account.Entry) TargetType(com.zimbra.cs.account.accesscontrol.TargetType) Map(java.util.Map)

Example 8 with AccessManager

use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.

the class CheckPermission method handle.

public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Provisioning prov = Provisioning.getInstance();
    Element eTarget = request.getElement(MailConstants.E_TARGET);
    String targetType = eTarget.getAttribute(MailConstants.A_TARGET_TYPE);
    TargetType tt = TargetType.fromCode(targetType);
    String targetBy = eTarget.getAttribute(MailConstants.A_TARGET_BY);
    String targetValue = eTarget.getText();
    NamedEntry entry = null;
    Element response = zsc.createElement(MailConstants.CHECK_PERMISSION_RESPONSE);
    if (TargetType.account == tt) {
        AccountBy acctBy = AccountBy.fromString(targetBy);
        entry = prov.get(acctBy, targetValue, zsc.getAuthToken());
        if (entry == null && acctBy == AccountBy.id) {
            throw AccountServiceException.NO_SUCH_ACCOUNT(targetValue);
        }
    // otherwise, the target could be an external user, let it fall through
    // to return the default permission.
    } else if (TargetType.calresource == tt) {
        Key.CalendarResourceBy crBy = Key.CalendarResourceBy.fromString(targetBy);
        entry = prov.get(crBy, targetValue);
        if (entry == null && crBy == Key.CalendarResourceBy.id) {
            throw AccountServiceException.NO_SUCH_CALENDAR_RESOURCE(targetValue);
        }
    } else if (TargetType.dl == tt) {
        Key.DistributionListBy dlBy = Key.DistributionListBy.fromString(targetBy);
        entry = prov.getGroupBasic(dlBy, targetValue);
        if (entry == null && dlBy == Key.DistributionListBy.id) {
            throw AccountServiceException.NO_SUCH_CALENDAR_RESOURCE(targetValue);
        }
    } else {
        throw ServiceException.INVALID_REQUEST("invalid target type: " + targetType, null);
    }
    List<UserRight> rights = new ArrayList<UserRight>();
    for (Element eRight : request.listElements(MailConstants.E_RIGHT)) {
        UserRight r = RightManager.getInstance().getUserRight(eRight.getText());
        rights.add(r);
    }
    boolean finalResult = true;
    AccessManager am = AccessManager.getInstance();
    for (UserRight right : rights) {
        boolean allow = am.canDo(zsc.getAuthToken(), entry, right, false);
        if (allow && DiscoverRights.isDelegatedSendRight(right) && TargetBy.name.name().equals(targetBy)) {
            allow = AccountUtil.isAllowedSendAddress(entry, targetValue);
        }
        response.addElement(MailConstants.E_RIGHT).addAttribute(MailConstants.A_ALLOW, allow).setText(right.getName());
        finalResult = finalResult & allow;
    }
    return returnResponse(response, finalResult);
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) UserRight(com.zimbra.cs.account.accesscontrol.UserRight) Element(com.zimbra.common.soap.Element) ArrayList(java.util.ArrayList) Provisioning(com.zimbra.cs.account.Provisioning) AccountBy(com.zimbra.common.account.Key.AccountBy) NamedEntry(com.zimbra.cs.account.NamedEntry) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) TargetType(com.zimbra.cs.account.accesscontrol.TargetType) Key(com.zimbra.common.account.Key)

Example 9 with AccessManager

use of com.zimbra.cs.account.AccessManager in project zm-mailbox by Zimbra.

the class RightCommand method validateGrant.

private static void validateGrant(Account authedAcct, TargetType targetType, Entry targetEntry, GranteeType granteeType, NamedEntry granteeEntry, String secret, Right right, RightModifier rightModifier, boolean revoking) throws ServiceException {
    /*
         * check grantee if the right is an admin right, or if the right is an
         * user right with can_delegate modifier
         */
    if (!right.isUserRight() || RightModifier.RM_CAN_DELEGATE == rightModifier) {
        /*
             * check if the grantee is an admin account or admin group
             *
             * If this is revoking, skip this check, just let the revoke through.
             * The grantee could have been taken away the admin privilege.
             */
        if (!revoking) {
            boolean isCDARight = CrossDomain.validateCrossDomainAdminGrant(right, granteeType);
            if (!isCDARight && !RightBearer.isValidGranteeForAdminRights(granteeType, granteeEntry)) {
                throw ServiceException.INVALID_REQUEST("grantee for admin right or " + "for user right with the canDelegate modifier must be a " + "delegated admin account or admin group, it cannot be a " + "global admin account or a regular user account.", null);
            }
        }
        /*
             * check if the grantee type can be used for an admin right
             */
        if (!granteeType.allowedForAdminRights()) {
            throw ServiceException.INVALID_REQUEST("grantee type " + granteeType.getCode() + " is not allowed for admin right", null);
        }
    }
    // first the "normal" checking
    if (!right.grantableOnTargetType(targetType)) {
        throw ServiceException.INVALID_REQUEST("right " + right.getName() + " cannot be granted on a " + targetType.getCode() + " entry. " + "It can only be granted on target types: " + right.reportGrantableTargetTypes(), null);
    }
    /*
         * then the ugly special group target checking
         */
    if (targetType.isGroup() && !CheckRight.allowGroupTarget(right)) {
        throw ServiceException.INVALID_REQUEST("group target is not supported for right: " + right.getName(), null);
    }
    /*
         * check if the right modifier is applicable on the target and right
         */
    if (RightModifier.RM_SUBDOMAIN == rightModifier) {
        // can only be granted on domain targets
        if (targetType != TargetType.domain) {
            throw ServiceException.INVALID_REQUEST("right modifier " + RightModifier.RM_SUBDOMAIN.getModifier() + " can only be granted on domain targets", null);
        }
        if (!right.allowSubDomainModifier()) {
            throw ServiceException.INVALID_REQUEST("right modifier " + RightModifier.RM_SUBDOMAIN.getModifier() + " is not allowed for the right: " + right.getName(), null);
        }
    } else if (RightModifier.RM_DISINHERIT_SUB_GROUPS == rightModifier) {
        // can only be granted on group targets
        if (targetType != TargetType.dl) {
            throw ServiceException.INVALID_REQUEST("right modifier " + RightModifier.RM_DISINHERIT_SUB_GROUPS.getModifier() + " can only be granted on group targets", null);
        }
        if (!right.allowDisinheritSubGroupsModifier()) {
            throw ServiceException.INVALID_REQUEST("right modifier " + RightModifier.RM_DISINHERIT_SUB_GROUPS.getModifier() + " is not allowed for the right: " + right.getName(), null);
        }
    }
    /*
         * check if the authed account can grant this right on this target
         *
         * A grantor can only delegate the whole or part of his delegable rights
         * (rights with t he canDelegate modifier) on the same target or a subset
         * of targets on which the grantor's own rights were granted.
         *
         * Once that check is passed, the admin can grant the right to any grantees
         * (e.g. to a group, or for user rights to pub, all, guest, ...).
         *
         * The same rule applies when and admin is granting an user right.
         * e.g. if and admin is granting the invite right on a domain, the
         *      admin must have effective +invite right on the domain.
         *
         * Only a global admin can grant/revoke rights for external group grantees.
         *
         * if authedAcct==null, the call site is either LdapProvisioning or internal code,
         * treat it as a system admin and skip this check.
         */
    if (authedAcct != null) {
        AccessManager am = AccessManager.getInstance();
        if (granteeType == GranteeType.GT_EXT_GROUP) {
            // must be system admin
            if (!AccessControlUtil.isGlobalAdmin(authedAcct)) {
                throw ServiceException.PERM_DENIED("only global admins can grant to external group");
            }
        } else {
            boolean canGrant = am.canPerform(authedAcct, targetEntry, right, true, null, true, null);
            if (!canGrant) {
                throw ServiceException.PERM_DENIED(String.format("insufficient right to %s '%s' right", (revoking ? "revoke" : "grant"), right.getName()));
            }
            ParticallyDenied.checkPartiallyDenied(authedAcct, targetType, targetEntry, right);
        }
    }
    if (secret != null && !granteeType.allowSecret()) {
        throw ServiceException.PERM_DENIED("password is not allowed for grantee type " + granteeType.getCode());
    }
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager)

Example 10 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