Search in sources :

Example 1 with AdminDocumentHandler

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

the class TestServerEnumeration method testModifyCalresSufficientPermissions.

@Test
public void testModifyCalresSufficientPermissions() throws Exception {
    List<AdminRight> relatedRights = new ArrayList<AdminRight>();
    List<String> notes = new ArrayList<String>();
    AdminDocumentHandler handler = new ModifyCalendarResource();
    handler.docRights(relatedRights, notes);
    createDelegatedAdmin(relatedRights);
    grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.calresource.toString()), MY_CALRES, DELEGATED_ADMIN_NAME, Admin.R_modifyCalendarResource.getName());
    grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.global.toString()), null, DELEGATED_ADMIN_NAME, Admin.R_listServer.getName());
    adminSoapProv.flushCache(CacheEntryType.acl, null);
    ModifyCalendarResourceRequest req = new ModifyCalendarResourceRequest(myCalRes.getId());
    req.addAttr(new Attr(Provisioning.A_zimbraMailHost, NON_EXISTING_SERVER));
    req.addAttr(new Attr(Provisioning.A_description, "test description"));
    try {
        delegatedSoapProv.invokeJaxb(req);
        fail("should have caught an exception");
    } catch (SoapFaultException e) {
        assertEquals("should be getting 'no such server' response", AccountServiceException.NO_SUCH_SERVER, e.getCode());
    }
}
Also used : ModifyCalendarResourceRequest(com.zimbra.soap.admin.message.ModifyCalendarResourceRequest) AdminRight(com.zimbra.cs.account.accesscontrol.AdminRight) ModifyCalendarResource(com.zimbra.cs.service.admin.ModifyCalendarResource) ArrayList(java.util.ArrayList) AdminDocumentHandler(com.zimbra.cs.service.admin.AdminDocumentHandler) Attr(com.zimbra.soap.admin.type.Attr) SoapFaultException(com.zimbra.common.soap.SoapFaultException) Test(org.junit.Test)

Example 2 with AdminDocumentHandler

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

the class TestServerEnumeration method testModifyAccount.

@Test
public void testModifyAccount() throws Exception {
    List<AdminRight> relatedRights = new ArrayList<AdminRight>();
    List<String> notes = new ArrayList<String>();
    AdminDocumentHandler handler = new ModifyAccount();
    handler.docRights(relatedRights, notes);
    createDelegatedAdmin(relatedRights);
    grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.account.toString()), MY_USER, DELEGATED_ADMIN_NAME, Admin.R_modifyAccount.getName());
    adminSoapProv.flushCache(CacheEntryType.acl, null);
    ModifyAccountRequest req = new ModifyAccountRequest(myUser.getId());
    req.addAttr(new Attr(Provisioning.A_zimbraMailHost, NON_EXISTING_SERVER));
    req.addAttr(new Attr(Provisioning.A_description, "test description"));
    try {
        delegatedSoapProv.invokeJaxb(req);
        fail("should have caught an exception");
    } catch (SoapFaultException e) {
        assertEquals("should be getting 'Permission Denied' response", ServiceException.PERM_DENIED, e.getCode());
    }
}
Also used : ModifyAccount(com.zimbra.cs.service.admin.ModifyAccount) AdminRight(com.zimbra.cs.account.accesscontrol.AdminRight) ModifyAccountRequest(com.zimbra.soap.admin.message.ModifyAccountRequest) ArrayList(java.util.ArrayList) AdminDocumentHandler(com.zimbra.cs.service.admin.AdminDocumentHandler) Attr(com.zimbra.soap.admin.type.Attr) SoapFaultException(com.zimbra.common.soap.SoapFaultException) Test(org.junit.Test)

Example 3 with AdminDocumentHandler

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

the class TestServerEnumeration method testModifyAccountSufficientPermissions.

@Test
public void testModifyAccountSufficientPermissions() throws Exception {
    List<AdminRight> relatedRights = new ArrayList<AdminRight>();
    List<String> notes = new ArrayList<String>();
    AdminDocumentHandler handler = new ModifyAccount();
    handler.docRights(relatedRights, notes);
    createDelegatedAdmin(relatedRights);
    grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.account.toString()), MY_USER, DELEGATED_ADMIN_NAME, Admin.R_modifyAccount.getName());
    grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.global.toString()), null, DELEGATED_ADMIN_NAME, Admin.R_listServer.getName());
    adminSoapProv.flushCache(CacheEntryType.acl, null);
    ModifyAccountRequest req = new ModifyAccountRequest(myUser.getId());
    req.addAttr(new Attr(Provisioning.A_zimbraMailHost, NON_EXISTING_SERVER));
    req.addAttr(new Attr(Provisioning.A_description, "test description"));
    try {
        delegatedSoapProv.invokeJaxb(req);
        fail("should have caught an exception");
    } catch (SoapFaultException e) {
        assertEquals("should be getting 'no such server' response", AccountServiceException.NO_SUCH_SERVER, e.getCode());
    }
}
Also used : ModifyAccount(com.zimbra.cs.service.admin.ModifyAccount) AdminRight(com.zimbra.cs.account.accesscontrol.AdminRight) ModifyAccountRequest(com.zimbra.soap.admin.message.ModifyAccountRequest) ArrayList(java.util.ArrayList) AdminDocumentHandler(com.zimbra.cs.service.admin.AdminDocumentHandler) Attr(com.zimbra.soap.admin.type.Attr) SoapFaultException(com.zimbra.common.soap.SoapFaultException) Test(org.junit.Test)

Example 4 with AdminDocumentHandler

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

the class DocumentDispatcher method registerHandler.

public void registerHandler(QName qname, DocumentHandler handler) {
    if (handler instanceof AdminDocumentHandler) {
        if (!(includeList == null) && !includeList.isEmpty() && !includeList.contains(String.format("%s::%s", qname.getNamespaceURI(), qname.getQualifiedName()))) {
            ZimbraLog.soap.debug("skipping %s::%s", qname.getNamespaceURI(), qname.getQualifiedName());
            return;
        }
        ZimbraLog.soap.debug("Registering %s::%s", qname.getNamespaceURI(), qname.getQualifiedName());
    }
    handlers.put(qname, handler);
    QName respQName = responses.get(qname);
    if (respQName == null) {
        String reqName = qname.getName();
        String respName;
        if (reqName.endsWith(REQUEST_SUFFIX)) {
            respName = reqName.substring(0, reqName.length() - REQUEST_SUFFIX.length()) + RESPONSE_SUFFIX;
        } else {
            respName = reqName + RESPONSE_SUFFIX;
        }
        respQName = new QName(respName, qname.getNamespace());
        responses.put(qname, respQName);
    }
    handler.setResponseQName(respQName);
}
Also used : QName(org.dom4j.QName) AdminDocumentHandler(com.zimbra.cs.service.admin.AdminDocumentHandler)

Example 5 with AdminDocumentHandler

use of com.zimbra.cs.service.admin.AdminDocumentHandler 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

AdminDocumentHandler (com.zimbra.cs.service.admin.AdminDocumentHandler)8 SoapFaultException (com.zimbra.common.soap.SoapFaultException)7 AdminRight (com.zimbra.cs.account.accesscontrol.AdminRight)6 ArrayList (java.util.ArrayList)6 Test (org.junit.Test)6 Attr (com.zimbra.soap.admin.type.Attr)4 Mailbox (com.zimbra.cs.mailbox.Mailbox)2 LockoutMailbox (com.zimbra.cs.service.admin.LockoutMailbox)2 ModifyAccount (com.zimbra.cs.service.admin.ModifyAccount)2 ModifyCalendarResource (com.zimbra.cs.service.admin.ModifyCalendarResource)2 LockoutMailboxRequest (com.zimbra.soap.admin.message.LockoutMailboxRequest)2 ModifyAccountRequest (com.zimbra.soap.admin.message.ModifyAccountRequest)2 ModifyCalendarResourceRequest (com.zimbra.soap.admin.message.ModifyCalendarResourceRequest)2 ServiceException (com.zimbra.common.service.ServiceException)1 Element (com.zimbra.common.soap.Element)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