Search in sources :

Example 1 with AdminAccessControl

use of com.zimbra.cs.service.admin.AdminAccessControl in project zm-mailbox by Zimbra.

the class ExtensionHttpHandler method checkRight.

/**
     * This API is for checking ACL rights for REST handlers that are added through server extensions.
     *
     * @param authToken
     * @param target
     * @param needed
     * @return
     * @throws ServiceException
     */
protected static AdminAccessControl checkRight(AuthToken authToken, Entry target, Object needed) throws ServiceException {
    AdminAccessControl aac = AdminAccessControl.getAdminAccessControl(authToken);
    aac.checkRight(target, needed);
    return aac;
}
Also used : AdminAccessControl(com.zimbra.cs.service.admin.AdminAccessControl)

Example 2 with AdminAccessControl

use of com.zimbra.cs.service.admin.AdminAccessControl in project zm-mailbox by Zimbra.

the class SoapEngine method dispatchRequest.

/**
     * Handles individual requests, either direct or from a batch
     */
Element dispatchRequest(DocumentHandler handler, Element soapReqElem, Map<String, Object> context, ZimbraSoapContext zsc) {
    long startTime = System.currentTimeMillis();
    SoapProtocol soapProto = zsc.getResponseProtocol();
    if (soapReqElem == null) {
        return soapFault(soapProto, "cannot dispatch request", ServiceException.INVALID_REQUEST("no document specified", null));
    }
    if (handler == null) {
        return soapFault(soapProto, "cannot dispatch request", ServiceException.UNKNOWN_DOCUMENT(soapReqElem.getQualifiedName(), null));
    }
    if (RedoLogProvider.getInstance().isSlave() && !handler.isReadOnly()) {
        return soapFault(soapProto, "cannot dispatch request", ServiceException.NON_READONLY_OPERATION_DENIED());
    }
    AuthToken at = zsc.getAuthToken();
    boolean needsAuth = handler.needsAuth(context);
    boolean needsAdminAuth = handler.needsAdminAuth(context);
    if ((needsAuth || needsAdminAuth) && at == null) {
        return soapFault(soapProto, "cannot dispatch request", ServiceException.AUTH_REQUIRED());
    }
    Element response = null;
    SoapTransport.setVia(zsc.getNextVia());
    try {
        Provisioning prov = Provisioning.getInstance();
        if (!prov.getLocalServer().getBooleanAttr(Provisioning.A_zimbraUserServicesEnabled, true) && !(handler instanceof AdminDocumentHandler)) {
            return soapFault(soapProto, "cannot dispatch request", ServiceException.TEMPORARILY_UNAVAILABLE());
        }
        if (needsAdminAuth) {
            AdminAccessControl aac = AdminAccessControl.getAdminAccessControl(at);
            if (!aac.isSufficientAdminForSoap(context, handler)) {
                return soapFault(soapProto, "cannot dispatch request", ServiceException.PERM_DENIED("need adequate admin token"));
            }
        }
        String acctId = null;
        boolean isGuestAccount = true;
        boolean delegatedAuth = false;
        if (at != null) {
            acctId = at.getAccountId();
            isGuestAccount = acctId.equals(GuestAccount.GUID_PUBLIC);
            delegatedAuth = at.isDelegatedAuth();
        }
        if (!isGuestAccount) {
            Account acct = null;
            if (needsAuth || needsAdminAuth) {
                try {
                    acct = AuthProvider.validateAuthToken(prov, at, false);
                } catch (ServiceException e) {
                    return soapFault(soapProto, null, e);
                }
                // also, make sure that the target account (if any) is active
                if (zsc.isDelegatedRequest() && !handler.isAdminCommand()) {
                    Account target = DocumentHandler.getRequestedAccount(zsc);
                    // treat the account as inactive if (a) it doesn't exist, (b) it's in maintenance mode, or (c) we're non-admins and it's not "active"
                    boolean inactive = target == null || Provisioning.ACCOUNT_STATUS_MAINTENANCE.equals(target.getAccountStatus(prov));
                    if (!inactive && (!at.isAdmin() || !AccessManager.getInstance().canAccessAccount(at, target))) {
                        inactive = !target.getAccountStatus(prov).equals(Provisioning.ACCOUNT_STATUS_ACTIVE);
                    }
                    if (inactive) {
                        return soapFault(soapProto, "target account is not active", AccountServiceException.ACCOUNT_INACTIVE(target == null ? zsc.getRequestedAccountId() : target.getName()));
                    }
                }
            }
            // fault in a session for this handler (if necessary) before executing the command
            context.put(ZIMBRA_SESSION, handler.getSession(zsc));
            // try to proxy the request if necessary (don't proxy commands that don't require auth)
            if ((needsAuth || needsAdminAuth) && acct != null) {
                response = handler.proxyIfNecessary(soapReqElem, context);
            }
        }
        // if no proxy, execute the request locally
        if (response == null) {
            if (delegatedAuth) {
                handler.logAuditAccess(at.getAdminAccountId(), acctId, acctId);
            }
            response = handler.handle(soapReqElem, context);
            ZimbraPerf.SOAP_TRACKER.addStat(getStatName(soapReqElem), startTime);
            long duration = System.currentTimeMillis() - startTime;
            if (LC.zimbra_slow_logging_enabled.booleanValue() && duration > LC.zimbra_slow_logging_threshold.longValue() && !soapReqElem.getQName().getName().equals(MailConstants.SYNC_REQUEST.getName())) {
                ZimbraLog.soap.warn("Slow SOAP request (start=" + startTime + "):\n" + soapReqElem.prettyPrint(true));
                ZimbraLog.soap.warn("Slow SOAP response (time=" + duration + "):\n" + response.prettyPrint());
            }
        }
    } catch (SoapFaultException e) {
        response = e.getFault() != null ? e.getFault().detach() : soapProto.soapFault(ServiceException.FAILURE(e.toString(), e));
        if (!e.isSourceLocal()) {
            LOG.debug("handler exception", e);
        }
    } catch (AuthFailedServiceException e) {
        HttpServletRequest httpReq = (HttpServletRequest) context.get(SoapServlet.SERVLET_REQUEST);
        httpReq.setAttribute(ZimbraInvalidLoginFilter.AUTH_FAILED, Boolean.TRUE);
        String clientIp = (String) context.get(SoapEngine.REQUEST_IP);
        httpReq.setAttribute(SoapEngine.REQUEST_IP, clientIp);
        response = soapProto.soapFault(e);
        if (LOG.isDebugEnabled()) {
            LOG.debug("handler exception: %s%s", e.getMessage(), e.getReason(", %s"), e);
        } else {
            // Don't log stack trace for auth failures, since they commonly happen
            LOG.info("handler exception: %s%s", e.getMessage(), e.getReason(", %s"));
        }
    } catch (ServiceException e) {
        response = soapFault(soapProto, "handler exception", e);
    // XXX: if the session was new, do we want to delete it?
    } catch (Throwable e) {
        // don't interfere with Jetty Continuations -- pass the exception on up
        if (e.getClass().getName().equals("org.eclipse.jetty.continuation.ContinuationThrowable")) {
            throw (Error) e;
        }
        // TODO: better exception stack traces during develope?
        response = soapProto.soapFault(ServiceException.FAILURE(e.toString(), e));
        if (e instanceof OutOfMemoryError) {
            Zimbra.halt("handler exception", e);
        }
        LOG.warn("handler exception", e);
    // XXX: if the session was new, do we want to delete it?
    } finally {
        SoapTransport.clearVia();
    }
    return response;
}
Also used : GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) Element(com.zimbra.common.soap.Element) SoapProtocol(com.zimbra.common.soap.SoapProtocol) AdminAccessControl(com.zimbra.cs.service.admin.AdminAccessControl) Provisioning(com.zimbra.cs.account.Provisioning) SoapFaultException(com.zimbra.common.soap.SoapFaultException) HttpServletRequest(javax.servlet.http.HttpServletRequest) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) AdminDocumentHandler(com.zimbra.cs.service.admin.AdminDocumentHandler) AuthToken(com.zimbra.cs.account.AuthToken)

Aggregations

AdminAccessControl (com.zimbra.cs.service.admin.AdminAccessControl)2 ServiceException (com.zimbra.common.service.ServiceException)1 Element (com.zimbra.common.soap.Element)1 SoapFaultException (com.zimbra.common.soap.SoapFaultException)1 SoapProtocol (com.zimbra.common.soap.SoapProtocol)1 Account (com.zimbra.cs.account.Account)1 AccountServiceException (com.zimbra.cs.account.AccountServiceException)1 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)1 AuthToken (com.zimbra.cs.account.AuthToken)1 GuestAccount (com.zimbra.cs.account.GuestAccount)1 Provisioning (com.zimbra.cs.account.Provisioning)1 AdminDocumentHandler (com.zimbra.cs.service.admin.AdminDocumentHandler)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1