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); }
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; }
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; }
static HANDLE RegSrvIpcGetSessionData( LWMsgCall* pCall ) { LWMsgSession* pSession = lwmsg_call_get_session(pCall); return lwmsg_session_get_data(pSession); }
static VOID RegSrvIpcRetainHandle( LWMsgCall* pCall, LWMsgHandle* pHandle ) { LWMsgSession* pSession = lwmsg_call_get_session(pCall); lwmsg_session_retain_handle(pSession, pHandle); }
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))); }
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; }
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; }
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; }
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; }
/* 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; }
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; }