MU_TEST(client_server, handle_invalidation)
{
    LWMsgContext* context = NULL;
    LWMsgProtocol* protocol = NULL;
    LWMsgPeer* client = NULL;
    LWMsgPeer* server = NULL;
    CounterHandle* handle = NULL;
    CounterRequest request;
    LWMsgCall* call;
    LWMsgSession* session = NULL;
    LWMsgParams in = LWMSG_PARAMS_INITIALIZER;
    LWMsgParams out = LWMSG_PARAMS_INITIALIZER;
    LWMsgHandleType locality = 0;
    struct timespec ts = {0, 50000000};

    MU_TRY(lwmsg_context_new(NULL, &context));
    MU_TRY(lwmsg_protocol_new(context, &protocol));
    MU_TRY(lwmsg_protocol_add_protocol_spec(protocol, counterprotocol_spec));

    MU_TRY(lwmsg_peer_new(context, protocol, &server));
    MU_TRY(lwmsg_peer_add_dispatch_spec(server, counter_dispatch));
    MU_TRY(lwmsg_peer_add_listen_endpoint(server, LWMSG_CONNECTION_MODE_LOCAL, TEST_ENDPOINT, 0600));
    MU_TRY(lwmsg_peer_start_listen(server));

    MU_TRY(lwmsg_peer_new(context, protocol, &client));
    MU_TRY(lwmsg_peer_add_connect_endpoint(client, LWMSG_CONNECTION_MODE_LOCAL, TEST_ENDPOINT));

    request.counter = 0;

    MU_TRY(lwmsg_peer_acquire_call(client, &call));
    session = lwmsg_call_get_session(call);

    in.tag = COUNTER_OPEN;
    in.data = &request;

    MU_TRY(lwmsg_call_dispatch(call, &in, &out, NULL, NULL));
    
    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, out.tag, COUNTER_OPEN_SUCCESS);
    lwmsg_call_release(call);

    handle = out.data;

    MU_TRY(lwmsg_peer_stop_listen(server));
    nanosleep(&ts, NULL);
    MU_TRY(lwmsg_peer_start_listen(server));

    MU_TRY(lwmsg_peer_acquire_call(client, &call));

    MU_ASSERT_EQUAL(MU_TYPE_INTEGER, lwmsg_session_get_handle_location(session, handle, &locality), LWMSG_STATUS_INVALID_HANDLE);
    
    MU_TRY(lwmsg_session_release_handle(session, handle));

    MU_TRY(lwmsg_peer_disconnect(client));
    lwmsg_peer_delete(client);

    MU_TRY(lwmsg_peer_stop_listen(server));
    lwmsg_peer_delete(server);
}
示例#2
0
static LWMsgStatus
fserv_close_srv(
    LWMsgCall* call,
    const LWMsgParams* in,
    LWMsgParams* out,
    void* data
    )
{
    LWMsgStatus status = LWMSG_STATUS_SUCCESS;
    LWMsgSession* session = lwmsg_call_get_session(call);
    FileHandle* handle = NULL;
    StatusReply* sreply = NULL;

    LOG("fserv_close() on fd %i for session %p\n", handle->fd, session);

    /* Get our internal handle from the lwmsg handle */
    status = lwmsg_session_get_handle_data(
        session,
        (LWMsgHandle*) in->data,
        (void**)(void*) &handle);
    if (status)
    {
        goto error;
    }

    /* Unregister the handle no matter what */
    status = lwmsg_session_unregister_handle(session, (LWMsgHandle*) in->data);
    if (status)
    {
        goto error;
    }
    
    if (close(handle->fd) == -1)
    {
        sreply = malloc(sizeof(*sreply));
        
        if (!sreply)
        {
            status = LWMSG_STATUS_MEMORY;
            goto error;
        }

        sreply->err = errno;
        out->tag = FSERV_ERROR_RES;
        out->data = sreply;
    }
    else
    {
        out->tag = FSERV_VOID_RES;
        out->data = NULL;
    }

error:

    return status;
}
示例#3
0
static LWMsgStatus
fserv_write_srv(
    LWMsgCall* call,
    const LWMsgParams* in,
    LWMsgParams* out,
    void* data
    )
{
    LWMsgStatus status = LWMSG_STATUS_SUCCESS;
    WriteRequest* req = (WriteRequest*) in->data;
    StatusReply* sreply = NULL;
    FileHandle* handle = NULL;
    int fd = -1;
    LWMsgSession* session = lwmsg_call_get_session(call);
    
    /* Get our internal handle from the lwmsg handle */
    status = lwmsg_session_get_handle_data(
        session,
        req->handle,
        (void**)(void*) &handle);
    if (status)
    {
        goto error;
    }

    fd = handle->fd;

    LOG("fserv_write() of %lu bytes to fd %i on session %p\n",
        (unsigned long) req->size, fd, session);

    if (write(fd, req->data, req->size) == -1)
    {
        sreply = malloc(sizeof(*sreply));
        
        if (!sreply)
        {
            status = LWMSG_STATUS_MEMORY;
            goto error;
        }

        sreply->err = errno;
        out->tag = FSERV_ERROR_RES;
        out->data = sreply;
    }
    else
    {
        out->tag = FSERV_VOID_RES;
        out->data = NULL;
    }

    out->data = (void*) sreply;

error:
    
    return status;
}
示例#4
0
static
HANDLE
RegSrvIpcGetSessionData(
    LWMsgCall* pCall
    )
{
    LWMsgSession* pSession = lwmsg_call_get_session(pCall);

    return lwmsg_session_get_data(pSession);
}
示例#5
0
static
VOID
RegSrvIpcRetainHandle(
    LWMsgCall* pCall,
    LWMsgHandle* pHandle
    )
{
    LWMsgSession* pSession = lwmsg_call_get_session(pCall);

    lwmsg_session_retain_handle(pSession, pHandle);
}
示例#6
0
static
NTSTATUS
RegSrvIpcGetHandleData(
    LWMsgCall* pCall,
    LWMsgHandle* pHandle,
    HKEY* phKey
    )
{
    LWMsgSession* pSession = lwmsg_call_get_session(pCall);
    return MAP_LWMSG_ERROR(lwmsg_session_get_handle_data(pSession, pHandle, OUT_PPVOID(phKey)));
}
示例#7
0
static
NTSTATUS
RegSrvIpcUnregisterHandle(
    LWMsgCall* pCall,
    PVOID pHandle
    )
{
	NTSTATUS status = 0;
    LWMsgSession* pSession = lwmsg_call_get_session(pCall);

    status = MAP_LWMSG_ERROR(lwmsg_session_unregister_handle(pSession, pHandle));
    BAIL_ON_NT_STATUS(status);

error:

    return status;
}
示例#8
0
static
NTSTATUS
RegSrvIpcRegisterHandle(
    LWMsgCall* pCall,
    PCSTR pszHandleType,
    PVOID pData,
    LWMsgHandleCleanupFunction pfnCleanup,
    LWMsgHandle** ppHandle
    )
{
	NTSTATUS status = 0;
    LWMsgSession* pSession = lwmsg_call_get_session(pCall);

    status = MAP_LWMSG_ERROR(lwmsg_session_register_handle(pSession, pszHandleType, pData, pfnCleanup, ppHandle));
    BAIL_ON_NT_STATUS(status);

error:

    return status;
}
示例#9
0
static
NTSTATUS
RegSrvIpcGetHandleData(
    LWMsgCall* pCall,
    LWMsgHandle* pHandle,
    HKEY* phKey
    )
{
    LWMsgSession* pSession = lwmsg_call_get_session(pCall);
    LWMsgStatus status = lwmsg_session_get_handle_data(pSession, pHandle, OUT_PPVOID(phKey));

    if (status == LWMSG_STATUS_INVALID_HANDLE)
    {
        return STATUS_INVALID_HANDLE;
    }
    else
    {
        return MAP_LWMSG_ERROR(status);
    }
}
static LWMsgStatus
counter_srv_close(LWMsgCall* call, const LWMsgParams* request_msg, LWMsgParams* reply_msg, void* data)
{
    LWMsgStatus status = LWMSG_STATUS_SUCCESS;
    CounterHandle* handle = request_msg->data;
    CounterReply* reply = malloc(sizeof(*reply));
    LWMsgSession* session = lwmsg_call_get_session(call);

    pthread_mutex_lock(&handle->lock);
    reply->counter = handle->counter;
    pthread_mutex_unlock(&handle->lock);
    
    pthread_mutex_destroy(&handle->lock);
    lwmsg_session_unregister_handle(session, handle);

    reply_msg->tag = COUNTER_CLOSE_SUCCESS;
    reply_msg->data = reply;

    return status;
}
static LWMsgStatus
counter_srv_open(LWMsgCall* call, const LWMsgParams* request_msg, LWMsgParams* reply_msg, void* data)
{
    LWMsgStatus status = LWMSG_STATUS_SUCCESS;
    CounterHandle* handle = malloc(sizeof(*handle));
    CounterRequest* request = request_msg->data;
    LWMsgSession* session = lwmsg_call_get_session(call);

    pthread_mutex_init(&handle->lock, NULL);

    handle->counter = request->counter;

    MU_TRY(lwmsg_session_register_handle(session, "CounterHandle", handle, free));

    reply_msg->tag = COUNTER_OPEN_SUCCESS;
    reply_msg->data = handle;

    MU_TRY(lwmsg_session_retain_handle(session, handle));

    return status;
}
示例#12
0
static LWMsgStatus
fserv_read_srv(
    LWMsgCall* call,
    const LWMsgParams* in,
    LWMsgParams* out,
    void* data
    )
{
    LWMsgStatus status = LWMSG_STATUS_SUCCESS;
    ReadRequest* req = (ReadRequest*) in->data;
    StatusReply* sreply = NULL;
    ReadReply* rreply = NULL;
    FileHandle* handle = NULL;
    int fd = -1;
    int ret = 0;
    LWMsgSession* session = lwmsg_call_get_session(call);
    
    /* Get our internal handle from the lwmsg handle */
    status = lwmsg_session_get_handle_data(
        session,
        req->handle,
        (void**)(void*) &handle);
    if (status)
    {
        goto error;
    }

    fd = handle->fd;

    LOG("fserv_read() of %lu bytes from fd %i on session %p\n",
        (unsigned long) req->size, fd, session);

    rreply = malloc(sizeof(*rreply));

    if (!rreply)
    {
        status = LWMSG_STATUS_MEMORY;
        goto error;
    }

    rreply->data = malloc(req->size);
    
    if (!rreply->data)
    {
        status = LWMSG_STATUS_MEMORY;
        goto error;
    }

    ret = read(fd, rreply->data, req->size);

    if (ret == -1)
    {
        int err = errno;

        free(rreply->data);
        free(rreply);

        sreply = malloc(sizeof(*sreply));

        if (!sreply)
        {
            status = LWMSG_STATUS_MEMORY;
            goto error;
        }

        sreply->err = err;
        out->tag = FSERV_ERROR_RES;
        out->data = (void*) sreply;
    }
    else if (ret == 0)
    {
        free(rreply->data);
        rreply->data = NULL;
        rreply->size = 0;
        out->tag = FSERV_READ_RES;
        out->data = (void*) rreply;
    }
    else
    {
        rreply->size = ret;
        out->tag = FSERV_READ_RES;
        out->data = (void*) rreply;
    }

error:
    
    return status;
}
示例#13
0
/* Implementation of fserv_open() */
static LWMsgStatus
fserv_open_srv(
    LWMsgCall* call,
    const LWMsgParams* in,
    LWMsgParams* out,
    void* data
    )
{
    LWMsgStatus status = LWMSG_STATUS_SUCCESS;
    OpenRequest* req = (OpenRequest*) in->data;
    FileHandle* handle = NULL;
    StatusReply* sreply = NULL;
    LWMsgSession* session = lwmsg_call_get_session(call);
    int flags = 0;
    int fd = -1;
    int ret;
    LWMsgHandle* lwmsg_handle = NULL;
    
    LOG("fserv_open() of %s on session %p\n", req->path, session);

    /* Check permissions */
    ret = fserv_check_permissions(session, req->path, req->mode);

    if (ret)
    {
        /* Allocate status reply */
        sreply = malloc(sizeof(*sreply));
        
        /* Bail out on allocation failure */
        if (!handle)
        {
            status = LWMSG_STATUS_MEMORY;
            goto error;
        }

        /* Set output parameters */
        sreply->err = ret;   
        out->tag = FSERV_ERROR_RES;
        out->data = (void*) sreply;
    }
    else
    {
        if ((req->mode & OPEN_MODE_READ) && !(req->mode & OPEN_MODE_WRITE))
        {
            flags |= O_RDONLY;
        }
        
        if ((req->mode & OPEN_MODE_WRITE) && !(req->mode & OPEN_MODE_READ))
        {
            flags |= O_WRONLY;
        }
        
        if ((req->mode & OPEN_MODE_WRITE) && (req->mode & OPEN_MODE_READ))
        {
            flags |= O_RDWR;
        }
        
        if ((req->mode & OPEN_MODE_APPEND))
        {
            flags |= O_APPEND;
        }
        
        /* Open file */
        fd = open(req->path, flags);
        
        if (fd >= 0)
        {
            /* Create handle structure */
            handle = malloc(sizeof(*handle));
            
            if (!handle)
            {
                status = LWMSG_STATUS_MEMORY;
                goto error;
            }
            
            /* Fill in handle */
            handle->fd = fd;
            handle->mode = req->mode;
            
            /* Register handle */
            status = lwmsg_session_register_handle(
                session,
                "FileHandle",
                handle,
                fserv_free_handle,
                &lwmsg_handle);
            if (status)
            {
                goto error;
            }
            
            /* Set output parameters */
            out->tag = FSERV_OPEN_RES;
            out->data = lwmsg_handle;
            handle = NULL;

            /* Retain handle */
            lwmsg_session_retain_handle(session, lwmsg_handle);

            LOG("Successfully opened %s as fd %i for session %p\n",
                req->path, fd, session);
        }
        else
        {
            sreply = malloc(sizeof(*sreply));
            
            if (!handle)
            {
                status = LWMSG_STATUS_MEMORY;
                goto error;
            }
            
            sreply->err = errno;
            out->tag = FSERV_ERROR_RES;
            out->data = (void*) sreply;
        }
    }

error:

    if (handle)
    {
        fserv_free_handle(handle);
    }

    return status;
}
示例#14
0
static
DWORD
LwmEvtSrvGetConnection(
    IN LWMsgCall* pCall,
    OUT PLWMSG_LW_EVENTLOG_CONNECTION* ppConn
)
{
    DWORD dwError = 0;
    LWMsgSession* pSession = NULL;
    PLWMSG_LW_EVENTLOG_CONNECTION pConn = NULL;
    NTSTATUS status = 0;
    PLW_MAP_SECURITY_CONTEXT pContext = NULL;

    if (pCall == NULL)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_EVT_ERROR(dwError);
    }

    pSession = lwmsg_call_get_session(pCall);
    if (pSession == NULL)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_EVT_ERROR(dwError);
    }

    pConn = (PLWMSG_LW_EVENTLOG_CONNECTION)lwmsg_session_get_data(pSession);
    if (pConn == NULL)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_EVT_ERROR(dwError);
    }

    if (!pConn->pUserToken)
    {
        status = LwMapSecurityCreateContext(&pContext);
        BAIL_ON_EVT_ERROR(status);

        status = LwMapSecurityCreateAccessTokenFromUidGid(
                     pContext,
                     &pConn->pUserToken,
                     pConn->Uid,
                     pConn->Gid);
        BAIL_ON_EVT_ERROR(status);

        dwError = EVTCheckAllowed(
                      pConn->pUserToken,
                      EVENTLOG_READ_RECORD,
                      &pConn->ReadAllowed);
        BAIL_ON_EVT_ERROR(dwError);

        dwError = EVTCheckAllowed(
                      pConn->pUserToken,
                      EVENTLOG_WRITE_RECORD,
                      &pConn->WriteAllowed);
        BAIL_ON_EVT_ERROR(dwError);

        dwError = EVTCheckAllowed(
                      pConn->pUserToken,
                      EVENTLOG_DELETE_RECORD,
                      &pConn->DeleteAllowed);
        BAIL_ON_EVT_ERROR(dwError);

        if (!pConn->ReadAllowed &&
                !pConn->WriteAllowed &&
                !pConn->DeleteAllowed)
        {
            dwError = ERROR_ACCESS_DENIED;
            BAIL_ON_EVT_ERROR(dwError);
        }
    }

    *ppConn = pConn;

cleanup:
    if (pContext)
    {
        LwMapSecurityFreeContext(&pContext);
    }
    if (dwError == 0 && status)
    {
        dwError = LwNtStatusToWin32Error(status);
    }
    return dwError;

error:
    *ppConn = NULL;
    goto cleanup;
}