static
NTSTATUS
ExpandCommands(
    PKQUEUE_COMMANDS pCommands
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG ulNewCapacity = 0;
    struct kevent* pNewCommands = NULL;

    if (pCommands->ulCommandMax + COMMANDS_PER_FD > pCommands->ulCommandCapacity)
    {
        ulNewCapacity = pCommands->ulCommandCapacity;

        if (ulNewCapacity == 0)
        {
            ulNewCapacity = 8;
        }

        while (pCommands->ulCommandMax > ulNewCapacity)
        {
            ulNewCapacity *= 2;
        }

        pNewCommands = LwRtlMemoryRealloc(
            pCommands->pCommands,
            sizeof(*pNewCommands) * ulNewCapacity);
        if (!pNewCommands)
        {
            status = STATUS_INSUFFICIENT_RESOURCES;
            GOTO_ERROR_ON_STATUS(status);
        }

        pCommands->ulCommandCapacity = ulNewCapacity;
        pCommands->pCommands = pNewCommands;
    }

    pCommands->ulCommandMax += COMMANDS_PER_FD;

error:

    return status;
}
Esempio n. 2
0
LW_NTSTATUS
LwIoReallocMemory(
    LW_PVOID pMemory,
    size_t Size,
    LW_PVOID * ppNewMemory
    )
{
    PVOID pNewMemory = LwRtlMemoryRealloc(pMemory, Size);

    if (!pNewMemory)
    {
        *ppNewMemory = NULL;
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        *ppNewMemory = pNewMemory;
        return STATUS_SUCCESS;
    }
}
Esempio n. 3
0
static DWORD
LWNetNbResolveNameUdp(
    PSTR pszHostName,
    PSTR winsServer,
    UINT8 queryType,
    OUT struct in_addr **retAddrs,
    OUT PDWORD retAddrsLen)
{
    DWORD dwError = 0;
    UINT16 transactionId = 0;
    UINT8 *NetBiosQuery = NULL;
    DWORD NetBiosQueryLen = 0;
    struct sockaddr_in dgAddr;
    struct timespec cvTimeout = {0};
    struct timeval  tp = {0};
    struct in_addr *resAddrs = NULL;
    struct in_addr *tmpResAddrs = NULL;
    int sts = 0;
    DWORD i = 0;
    DWORD resAddrsLen = 0;
    DWORD resAddrsAllocLen = 128;
    DWORD commType = 0;
    BOOLEAN bLocked = FALSE;

    dwError = LWNetAllocateMemory(
                  LWNB_NETBIOS_UDP_MAX,
                  (PVOID*) &NetBiosQuery);
    BAIL_ON_LWNET_ERROR(dwError);

    memset(&dgAddr, 0, sizeof(dgAddr));
    dgAddr.sin_family = AF_INET;
    dgAddr.sin_port = htons(137);

    if (winsServer && *winsServer)
    {
        sts = inet_aton(winsServer, &dgAddr.sin_addr);
        if (sts == -1)
        {
            dwError = LwErrnoToWin32Error(ERROR_INCORRECT_ADDRESS);
            BAIL_ON_LWNET_ERROR(dwError);
        }

        commType = LWNB_QUERY_WINS;
        dwError = LWNetNbConstructNameQuery(
                      pszHostName,
                      commType,
                      queryType,
                      &transactionId,
                      NetBiosQuery,
                      &NetBiosQueryLen);
        BAIL_ON_LWNET_ERROR(dwError);
    }
    else
    {
        dgAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
        commType = LWNB_QUERY_BROADCAST;
        dwError = LWNetNbConstructNameQuery(
                      pszHostName,
                      commType,
                      queryType,
                      &transactionId,
                      NetBiosQuery,
                      &NetBiosQueryLen);
        BAIL_ON_LWNET_ERROR(dwError);
    }


    // If this is not enough memory, realloc below fixes that
    dwError = LWNetAllocateMemory(
                  resAddrsAllocLen * sizeof(struct in_addr),
                  (PVOID*) &resAddrs);
    BAIL_ON_LWNET_ERROR(dwError);

    pthread_mutex_lock(&gpNbCtx->mutex);
    bLocked = TRUE;
    sts = sendto(gpNbCtx->sock,
                 NetBiosQuery,
                 NetBiosQueryLen,
                 0,  /* flags */
                 (struct sockaddr *) &dgAddr,
                 sizeof(dgAddr));
    if (sts == -1)
    {
        dwError = ERROR_NET_WRITE_FAULT;
        BAIL_ON_LWNET_ERROR(dwError);
    }
    do
    {
        gettimeofday(&tp, NULL);
        cvTimeout.tv_sec = tp.tv_sec + gpNbCtx->udpTimeout;
        cvTimeout.tv_nsec = tp.tv_usec * 1000;
        do {
            sts = pthread_cond_timedwait(
                      &gpNbCtx->cv,
                      &gpNbCtx->mutex,
                      &cvTimeout);
        } while (!gpNbCtx->bNbRepsponse && sts != ETIMEDOUT);

        if (sts == 0 && gpNbCtx->transactionId == transactionId)
        {
            gpNbCtx->bNbRepsponse = FALSE;


            if ((commType == LWNB_QUERY_WINS && gpNbCtx->respError == 0) ||
                (commType == LWNB_QUERY_BROADCAST))
            {
                if ((gpNbCtx->addrsLen + resAddrsLen) > resAddrsAllocLen)
                {
                    resAddrsAllocLen = resAddrsAllocLen * 2 + gpNbCtx->addrsLen;
                    tmpResAddrs = LwRtlMemoryRealloc(
                                      resAddrs,
                                      resAddrsAllocLen);
                    if (!tmpResAddrs)
                    {
                        dwError = ERROR_NOT_ENOUGH_MEMORY;
                        BAIL_ON_LWNET_ERROR(dwError);
                    }
                    resAddrs = tmpResAddrs;
                    tmpResAddrs = NULL;
                }
                for (i=0; i<gpNbCtx->addrsLen; i++)
                {
                    memcpy(&resAddrs[resAddrsLen++],
                           &gpNbCtx->addrs[i],
                           sizeof(struct in_addr));
                }
            }
            pthread_mutex_lock(&gpNbCtx->mutexAck);
            gpNbCtx->bAck = TRUE;
            pthread_mutex_unlock(&gpNbCtx->mutexAck);
            pthread_cond_signal(&gpNbCtx->cvAck);

            if (commType == LWNB_QUERY_WINS && gpNbCtx->respError)
            {
                // Bail when WINS query fails to resolve the hostname
                dwError = gpNbCtx->respError;
                BAIL_ON_LWNET_ERROR(dwError);
            }
        }
    } while (commType == LWNB_QUERY_BROADCAST && sts != ETIMEDOUT);
    bLocked = FALSE;
    pthread_mutex_unlock(&gpNbCtx->mutex);

    if (resAddrsLen == 0)
    {
        dwError = ERROR_BAD_NET_NAME;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    *retAddrs = resAddrs;
    *retAddrsLen = resAddrsLen;

cleanup:
    if (bLocked)
    {
        pthread_mutex_unlock(&gpNbCtx->mutex);
    }
    LWNET_SAFE_FREE_MEMORY(NetBiosQuery);
    return dwError;

error:
    LWNET_SAFE_FREE_MEMORY(resAddrs);
    goto cleanup;
}
Esempio n. 4
0
LW_NTSTATUS
LwIoGetPeerAccessToken(
    IO_FILE_HANDLE File,
    PACCESS_TOKEN* ppToken
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    IO_STATUS_BLOCK IoStatus;
    ULONG ulLength = ACCESS_TOKEN_LENGTH;
    PBYTE pBuffer = NULL;
    PBYTE pNewBuffer = NULL;

    Status = RTL_ALLOCATE(&pBuffer, BYTE, ulLength);
    BAIL_ON_NT_STATUS(Status);

    do
    {
        Status =
            LwNtFsControlFile(
                File,
                NULL,
                &IoStatus,
                IO_FSCTL_SMB_GET_PEER_ACCESS_TOKEN,
                NULL,
                0,
                pBuffer,
                ulLength);

        if (Status == STATUS_BUFFER_TOO_SMALL)
        {
            ulLength *= 2;
            pNewBuffer = LwRtlMemoryRealloc(pBuffer, ulLength);
            if (!pNewBuffer)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                BAIL_ON_NT_STATUS(Status);
            }
            pBuffer = pNewBuffer;
        }
    } while (Status == STATUS_BUFFER_TOO_SMALL);

    BAIL_ON_NT_STATUS(Status);

    if (IoStatus.BytesTransferred > 0)
    {
        Status = RtlSelfRelativeAccessTokenToAccessToken(
            (PACCESS_TOKEN_SELF_RELATIVE) pBuffer,
            IoStatus.BytesTransferred,
            ppToken);
        BAIL_ON_NT_STATUS(Status);
    }
    else
    {
        *ppToken = NULL;
    }

cleanup:

    RTL_FREE(&pBuffer);

    return Status;

error:

    *ppToken = NULL;

    goto cleanup;
}
Esempio n. 5
0
LW_NTSTATUS
LwIoRdrGetPhysicalPath(
    IO_FILE_HANDLE File,
    LW_PWSTR* ppResolved
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    IO_STATUS_BLOCK ioStatus;
    ULONG length = RESOLVED_PATH_LENGTH;
    PBYTE pBuffer = NULL;
    PBYTE pNewBuffer = NULL;
    PWSTR pResolved = NULL;

    status = RTL_ALLOCATE(&pBuffer, BYTE, length);
    GOTO_CLEANUP_ON_STATUS(status);

    do
    {
        status =
            LwNtDeviceIoControlFile(
                File,
                NULL,
                &ioStatus,
                RDR_DEVCTL_GET_PHYSICAL_PATH,
                NULL,
                0,
                pBuffer,
                length);

        if (status == STATUS_BUFFER_TOO_SMALL)
        {
            length *= 2;
            pNewBuffer = LwRtlMemoryRealloc(pBuffer, length);
            if (!pNewBuffer)
            {
                status = STATUS_INSUFFICIENT_RESOURCES;
                GOTO_CLEANUP_ON_STATUS(status);
            }
            pBuffer = pNewBuffer;
        }
    } while (status == STATUS_BUFFER_TOO_SMALL);

    GOTO_CLEANUP_ON_STATUS(status);

    if (ioStatus.BytesTransferred > 0)
    {
        status = LW_RTL_ALLOCATE(
            &pResolved,
            WCHAR,
            ioStatus.BytesTransferred + sizeof(WCHAR));
        GOTO_CLEANUP_ON_STATUS(status);

#ifdef WORDS_BIGENDIAN
        swab(pBuffer, pResolved, ioStatus.BytesTransferred);
#else
        memcpy(pResolved, pBuffer, ioStatus.BytesTransferred);
#endif
    }

cleanup:

    *ppResolved = pResolved;

    RTL_FREE(&pBuffer);

    return status;
}