Esempio n. 1
0
NTSTATUS
LsaAllocateSids(
    OUT PSID                    *pOut,
    IN OUT PDWORD                pdwOffset,
    IN OUT PDWORD                pdwSpaceLeft,
    IN PLSA_ACCOUNT_ENUM_BUFFER  pIn,
    IN OUT PDWORD                pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PVOID pBuffer = pOut;
    DWORD iSid = 0;

    BAIL_ON_INVALID_PTR(pdwOffset, ntStatus);
    BAIL_ON_INVALID_PTR(pIn, ntStatus);
    BAIL_ON_INVALID_PTR(pdwSize, ntStatus);

    for (iSid = 0; iSid < pIn->NumAccounts; iSid++)
    {
        LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);
        LWBUF_ALLOC_PSID(pBuffer, pIn->pAccount[iSid].pSid);
    }

cleanup:
    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    goto cleanup;
}
Esempio n. 2
0
static
NTSTATUS
NetrAllocateSamInfo3(
    OUT NetrSamInfo3    *pOut,
    IN OUT PDWORD        pdwOffset,
    IN OUT PDWORD        pdwSpaceLeft,
    IN  NetrSamInfo3    *pIn,
    IN OUT PDWORD        pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PVOID pBuffer = pOut;
    PVOID pCursor = NULL;
    UINT32 iSid = 0;
    DWORD dwSidsOffset = 0;
    DWORD dwSidsSize = 0;
    DWORD dwSidsSpaceLeft = 0;
    PVOID pSids = NULL;
    NetrSidAttr **ppSids = NULL;

    BAIL_ON_INVALID_PTR(pdwOffset, ntStatus);
    BAIL_ON_INVALID_PTR(pIn, ntStatus);
    BAIL_ON_INVALID_PTR(pdwSize, ntStatus);

    ntStatus = NetrInitSamBaseInfo((NetrSamBaseInfo*)pBuffer,
                                   pdwOffset,
                                   pdwSpaceLeft,
                                   &pIn->base,
                                   pdwSize);
    BAIL_ON_NT_STATUS(ntStatus);

    LWBUF_ALLOC_DWORD(pBuffer, pIn->sidcount);
    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    if (pIn->sidcount)
    {
        for (iSid = 0; iSid < pIn->sidcount; iSid++)
        {
            ntStatus = NetrAllocateSidAttr(NULL,
                                           &dwSidsOffset,
                                           NULL,
                                           &(pIn->sids[iSid]),
                                           &dwSidsSize);
            BAIL_ON_NT_STATUS(ntStatus);
        }
    }

    if (pBuffer && pdwSpaceLeft)
    {
        BAIL_IF_NOT_ENOUGH_SPACE(dwSidsSize, pdwSpaceLeft, dwError);
        pCursor = pBuffer + (*pdwOffset);

        if (pIn->sids)
        {
            pSids = LWBUF_TARGET_PTR(pBuffer, dwSidsSize, pdwSpaceLeft);

            /* sanity check - the sids pointer and current buffer cursor
               must not overlap */
            BAIL_IF_PTR_OVERLAP(NetrSidAttr*, pSids, dwError);

            dwSidsSpaceLeft = dwSidsSize;
            dwSidsOffset    = 0;

            /* Allocate the sid entries */
            for (iSid = 0; iSid < pIn->sidcount; iSid++)
            {
                PVOID pSidCursor = pSids + (iSid * sizeof(pIn->sids[0]));

                ntStatus = NetrAllocateSidAttr(pSidCursor,
                                               &dwSidsOffset,
                                               &dwSidsSpaceLeft,
                                               &(pIn->sids[iSid]),
                                               pdwSize);
                BAIL_ON_NT_STATUS(ntStatus);

                dwSidsOffset = 0;
            }
        }

        ppSids           = (NetrSidAttr**)pCursor;
        *ppSids          = (NetrSidAttr*)pSids;
        (*pdwSpaceLeft) -= (pSids) ? LWBUF_ALIGN_SIZE(dwSidsSize) : 0;

        /* recalculate space after setting the pointer */
        (*pdwSpaceLeft)  -= sizeof(NetrSidAttr*);
    }
    else
    {
        (*pdwSize) += LWBUF_ALIGN_SIZE(dwSidsSize);
    }

    /* include size of the pointer */
    (*pdwOffset) += sizeof(NetrSidAttr*);
    (*pdwSize)   += sizeof(NetrSidAttr*);

cleanup:
    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    goto cleanup;
}
Esempio n. 3
0
static
NTSTATUS
NetrAllocateRidWithAttributeArray(
    OUT PVOID                      *pOut,
    IN OUT PDWORD                   pdwOffset,
    IN OUT PDWORD                   pdwSpaceLeft,
    IN  PRID_WITH_ATTRIBUTE_ARRAY   pIn,
    IN OUT PDWORD                   pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PVOID pBuffer = pOut;
    PVOID pCursor = NULL;
    DWORD dwRidsSize = 0;
    DWORD dwRidsSpaceLeft = 0;
    DWORD dwRidsOffset = 0;
    DWORD iRid = 0;
    PVOID pRids = NULL;
    PRID_WITH_ATTRIBUTE *ppRids = NULL;
    
    BAIL_ON_INVALID_PTR(pdwOffset, ntStatus);
    BAIL_ON_INVALID_PTR(pIn, ntStatus);
    BAIL_ON_INVALID_PTR(pdwSize, ntStatus);

    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    LWBUF_ALLOC_DWORD(pBuffer, pIn->dwCount);
    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    if (pIn->dwCount)
    {
        dwRidsSize = sizeof(pIn->pRids[0]) * pIn->dwCount;
    }

    if (pBuffer && pdwSpaceLeft)
    {
        BAIL_IF_NOT_ENOUGH_SPACE(dwRidsSize, pdwSpaceLeft, dwError);
        pCursor = pBuffer + (*pdwOffset);

        if (pIn->pRids)
        {
            pRids = LWBUF_TARGET_PTR(pBuffer, dwRidsSize, pdwSpaceLeft);

            /* sanity check - the rids pointer and current buffer cursor
               must not overlap */
            BAIL_IF_PTR_OVERLAP(PRID_WITH_ATTRIBUTE, pRids, dwError);

            dwRidsSpaceLeft = dwRidsSize;
            dwRidsOffset    = 0;

            /* Allocate the rid entries */
            for (iRid = 0; iRid < pIn->dwCount; iRid++)
            {
                PVOID pRidCursor = pRids + (iRid * sizeof(pIn->pRids[0]));

                ntStatus = NetrAllocateRidWithAttribute(pRidCursor,
                                                        &dwRidsOffset,
                                                        &dwRidsSpaceLeft,
                                                        &(pIn->pRids[iRid]),
                                                        pdwSize);
                BAIL_ON_NT_STATUS(ntStatus);

                dwRidsOffset = 0;
            }
        }

        ppRids           = (PRID_WITH_ATTRIBUTE*)pCursor;
        *ppRids          = (PRID_WITH_ATTRIBUTE)pRids;
        (*pdwSpaceLeft) -= (pRids) ? LWBUF_ALIGN_SIZE(dwRidsSize) : 0;

        /* recalculate space after setting the pointer */
        (*pdwSpaceLeft)  -= sizeof(PRID_WITH_ATTRIBUTE);
    }
    else
    {
        (*pdwSize) += LWBUF_ALIGN_SIZE(dwRidsSize);
    }

    /* include size of the pointer */
    (*pdwOffset) += sizeof(PRID_WITH_ATTRIBUTE);
    (*pdwSize)   += sizeof(PRID_WITH_ATTRIBUTE);

cleanup:
    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    goto cleanup;
}
Esempio n. 4
0
static
NTSTATUS
NetrInitSamBaseInfo(
    OUT NetrSamBaseInfo *pOut,
    IN OUT PDWORD        pdwOffset,
    IN OUT PDWORD        pdwSpaceLeft,
    IN  NetrSamBaseInfo *pIn,
    IN OUT PDWORD        pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PVOID pBuffer = pOut;

    BAIL_ON_INVALID_PTR(pdwOffset, ntStatus);
    BAIL_ON_INVALID_PTR(pIn, ntStatus);
    BAIL_ON_INVALID_PTR(pdwSize, ntStatus);

    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    LWBUF_ALLOC_WINNTTIME(pBuffer, pIn->last_logon);
    LWBUF_ALLOC_WINNTTIME(pBuffer, pIn->last_logoff);
    LWBUF_ALLOC_WINNTTIME(pBuffer, pIn->acct_expiry);
    LWBUF_ALLOC_WINNTTIME(pBuffer, pIn->last_password_change);
    LWBUF_ALLOC_WINNTTIME(pBuffer, pIn->allow_password_change);
    LWBUF_ALLOC_WINNTTIME(pBuffer, pIn->force_password_change);
    LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->account_name);
    LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->full_name);
    LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->logon_script);
    LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->profile_path);
    LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->home_directory);
    LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->home_drive);
    LWBUF_ALLOC_WORD(pBuffer, pIn->logon_count);
    LWBUF_ALLOC_WORD(pBuffer, pIn->bad_password_count);
    LWBUF_ALLOC_DWORD(pBuffer, pIn->rid);
    LWBUF_ALLOC_DWORD(pBuffer, pIn->primary_gid);

    ntStatus = NetrAllocateRidWithAttributeArray(pBuffer,
                                                 pdwOffset,
                                                 pdwSpaceLeft,
                                                 &pIn->groups,
                                                 pdwSize);
    BAIL_ON_NT_STATUS(ntStatus);

    LWBUF_ALLOC_DWORD(pBuffer, pIn->user_flags);
    LWBUF_ALLOC_SESSION_KEY(pBuffer, &pIn->key);
    LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->logon_server);
    LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->domain);
    LWBUF_ALLOC_PSID(pBuffer, pIn->domain_sid);
    LWBUF_ALLOC_SESSION_KEY(pBuffer, &pIn->lmkey);
    LWBUF_ALLOC_DWORD(pBuffer, pIn->acct_flags);
    LWBUF_ALLOC_BLOB(pBuffer, sizeof(pIn->unknown), pIn->unknown);

cleanup:
    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    goto cleanup;
}
Esempio n. 5
0
static
NTSTATUS
NetrAllocateChallengeResponse(
    OUT PVOID         pOut,
    IN OUT PDWORD     pdwOffset,
    IN OUT PDWORD     pdwSpaceLeft,
    IN  PBYTE         pResponse,
    IN  DWORD         dwResponseLen,
    IN OUT PDWORD     pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PVOID pBuffer = pOut;
    PVOID pCursor = NULL;
    PVOID pRespData = NULL;
    PBYTE *ppRespData = NULL;
    DWORD dwResponseSize = dwResponseLen;
    DWORD dwResponseSpaceLeft = 0;
    DWORD dwResponseOffset = 0;

    BAIL_ON_INVALID_PTR(pdwOffset, ntStatus);
    BAIL_ON_INVALID_PTR(pdwSize, ntStatus);

    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    LWBUF_ALLOC_WORD(pBuffer, dwResponseLen);
    LWBUF_ALLOC_WORD(pBuffer, dwResponseLen);
    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    if (pBuffer && pdwSpaceLeft)
    {
        BAIL_IF_NOT_ENOUGH_SPACE(dwResponseSize, pdwSpaceLeft, dwError);
        pCursor = pBuffer + (*pdwOffset);

        if (pResponse)
        {
            pRespData = LWBUF_TARGET_PTR(pBuffer, dwResponseSize, pdwSpaceLeft);

            /* sanity check - the data pointer and current buffer cursor
               must not overlap */
            BAIL_IF_PTR_OVERLAP(PBYTE, pRespData, dwError);

            dwResponseSpaceLeft = dwResponseSize;
            dwResponseOffset    = 0;

            dwError = LwBufferAllocFixedBlob(pRespData,
                                             &dwResponseOffset,
                                             &dwResponseSpaceLeft,
                                             pResponse,
                                             dwResponseSize,
                                             pdwSize);
            BAIL_ON_WIN_ERROR(dwError);
        }

        ppRespData       = (PBYTE*)pCursor;
        *ppRespData      = pRespData;
        (*pdwSpaceLeft) -= (pRespData) ? LWBUF_ALIGN_SIZE(dwResponseSize) : 0;

        /* recalculate space after setting the pointer */
        (*pdwSpaceLeft)  -= sizeof(PBYTE);
    }
    else
    {
        (*pdwSize) += LWBUF_ALIGN_SIZE(dwResponseSize);
    }

    /* include size of the pointer */
    (*pdwOffset) += sizeof(PBYTE);
    (*pdwSize)   += sizeof(PBYTE);

cleanup:
    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    goto cleanup;
}
Esempio n. 6
0
static
NTSTATUS
NetrAllocateDomainInfo1(
    OUT NetrDomainInfo1  *pOut,
    IN OUT PDWORD         pdwOffset,
    IN OUT PDWORD         pdwSpaceLeft,
    IN  NetrDomainInfo1  *pIn,
    IN OUT PDWORD         pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PVOID pBuffer = pOut;
    PVOID pCursor = NULL;
    DWORD iTrust = 0;
    DWORD dwTrustsSize = 0;
    DWORD dwTrustsOffset = 0;
    DWORD dwTrustsSpaceLeft = 0;
    PVOID pTrusts = NULL;
    NetrDomainTrustInfo **ppTrusts = NULL;

    BAIL_ON_INVALID_PTR(pdwOffset, ntStatus);
    BAIL_ON_INVALID_PTR(pIn, ntStatus);
    BAIL_ON_INVALID_PTR(pdwSize, ntStatus);

    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    ntStatus = NetrAllocateDomainTrustInfo(pBuffer,
                                           pdwOffset,
                                           pdwSpaceLeft,
                                           &pIn->domain_info,
                                           pdwSize);
    BAIL_ON_NT_STATUS(ntStatus);

    LWBUF_ALLOC_DWORD(pBuffer, pIn->num_trusts);
    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    if (pIn->num_trusts)
    {
        for (iTrust = 0; iTrust < pIn->num_trusts; iTrust++)
        {
            ntStatus = NetrAllocateDomainTrustInfo(NULL,
                                                   &dwTrustsOffset,
                                                   NULL,
                                                   &(pIn->trusts[iTrust]),
                                                   &dwTrustsSize);
            BAIL_ON_NT_STATUS(ntStatus);
        }
    }

    if (pBuffer && pdwSpaceLeft)
    {
        BAIL_IF_NOT_ENOUGH_SPACE(dwTrustsSize, pdwSpaceLeft, dwError);
        pCursor = pBuffer + (*pdwOffset);

        if (pIn->trusts)
        {
            pTrusts = LWBUF_TARGET_PTR(pBuffer, dwTrustsSize, pdwSpaceLeft);

            /* sanity check - the rids pointer and current buffer cursor
               must not overlap */
            BAIL_IF_PTR_OVERLAP(NetrDomainTrustInfo*, pTrusts, dwError);

            dwTrustsSpaceLeft = dwTrustsSize;
            dwTrustsOffset    = 0;

            /* Allocate the trust entries */
            for (iTrust = 0; iTrust < pIn->num_trusts; iTrust++)
            {
                PVOID pTrustCursor = pTrusts +
                                     (iTrust * sizeof(NetrDomainTrustInfo));

                ntStatus = NetrAllocateDomainTrustInfo(pTrustCursor,
                                                       &dwTrustsOffset,
                                                       &dwTrustsSpaceLeft,
                                                       &(pIn->trusts[iTrust]),
                                                       pdwSize);
                BAIL_ON_NT_STATUS(ntStatus);

                dwTrustsOffset = 0;
            }
        }

        ppTrusts         = (NetrDomainTrustInfo**)pCursor;
        *ppTrusts        = (NetrDomainTrustInfo*)pTrusts;
        (*pdwSpaceLeft) -= (pTrusts) ? LWBUF_ALIGN_SIZE(dwTrustsSize) : 0;

        /* recalculate space after setting the pointer */
        (*pdwSpaceLeft)  -= sizeof(NetrDomainTrustInfo*);
    }
    else
    {
        (*pdwSize) += LWBUF_ALIGN_SIZE(dwTrustsSize);
    }

    /* include size of the pointer */
    (*pdwOffset) += sizeof(NetrDomainTrustInfo*);
    (*pdwSize)   += sizeof(NetrDomainTrustInfo*);

cleanup:
    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    goto cleanup;
}
Esempio n. 7
0
NTSTATUS
NetrAllocateDomainInfo(
    OUT NetrDomainInfo  *pOut,
    IN OUT PDWORD        pdwOffset,
    IN OUT PDWORD        pdwSpaceLeft,
    IN  WORD             swLevel,
    IN  NetrDomainInfo  *pIn,
    IN OUT PDWORD        pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PVOID pBuffer = pOut;
    PVOID pCursor = NULL;
    DWORD dwInfoSize = 0;
    DWORD dwInfoOffset = 0;
    DWORD dwInfoSpaceLeft = 0;
    PVOID pInfo = NULL;
    NetrDomainInfo1 **ppInfo = NULL;

    BAIL_ON_INVALID_PTR(pdwOffset, ntStatus);
    BAIL_ON_INVALID_PTR(pIn, ntStatus);
    BAIL_ON_INVALID_PTR(pdwSize, ntStatus);

    LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);

    if (pIn->info1)
    {
        switch (swLevel)
        {
        case 1:
            ntStatus = NetrAllocateDomainInfo1(NULL,
                                               &dwInfoOffset,
                                               NULL,
                                               pIn->info1,
                                               &dwInfoSize);
            break;

        case 2:
            ntStatus = NetrAllocateDomainInfo1(NULL,
                                               &dwInfoOffset,
                                               NULL,
                                               pIn->info2,
                                               &dwInfoSize);
            break;

        default:
            ntStatus = STATUS_INVALID_LEVEL;
        }
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (pBuffer && pdwSpaceLeft)
    {
        BAIL_IF_NOT_ENOUGH_SPACE(dwInfoSize, pdwSpaceLeft, dwError);
        pCursor = pBuffer + (*pdwOffset);

        if (pIn->info1)
        {
            pInfo = LWBUF_TARGET_PTR(pBuffer, dwInfoSize, pdwSpaceLeft);

            /* sanity check - the rids pointer and current buffer cursor
               must not overlap */
            BAIL_IF_PTR_OVERLAP(NetrDomainInfo1*, pInfo, dwError);

            dwInfoSpaceLeft = dwInfoSize;
            dwInfoOffset    = 0;

            switch (swLevel)
            {
            case 1:
                ntStatus = NetrAllocateDomainInfo1(pBuffer,
                                                   &dwInfoOffset,
                                                   &dwInfoSpaceLeft,
                                                   pIn->info1,
                                                   pdwSize);
                break;

            case 2:
                ntStatus = NetrAllocateDomainInfo1(pBuffer,
                                                   &dwInfoOffset,
                                                   &dwInfoSpaceLeft,
                                                   pIn->info2,
                                                   pdwSize);
                break;

            default:
                ntStatus = STATUS_INVALID_LEVEL;
            }
            BAIL_ON_NT_STATUS(ntStatus);
        }

        ppInfo           = (NetrDomainInfo1**)pCursor;
        *ppInfo          = (NetrDomainInfo1*)pInfo;
        (*pdwSpaceLeft) -= (pInfo) ? LWBUF_ALIGN_SIZE(dwInfoSize) : 0;

        /* recalculate space after setting the pointer */
        (*pdwSpaceLeft)  -= sizeof(NetrDomainInfo1*);
    }
    else
    {
        (*pdwSize) += LWBUF_ALIGN_SIZE(dwInfoSize);
    }

    /* include size of the pointer */
    (*pdwOffset) += sizeof(NetrDomainInfo1*);
    (*pdwSize)   += sizeof(NetrDomainInfo1*);

cleanup:
    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    goto cleanup;
}
Esempio n. 8
0
NTSTATUS
LsaAllocatePolicyInformation(
    OUT LsaPolicyInformation *pOut,
    IN OUT PDWORD             pdwOffset,
    IN OUT PDWORD             pdwSpaceLeft,
    IN  WORD                  swLevel,
    IN  LsaPolicyInformation *pIn,
    IN OUT PDWORD             pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    PVOID pBuffer = pOut;

    BAIL_ON_INVALID_PTR(pdwOffset, ntStatus);
    BAIL_ON_INVALID_PTR(pIn, ntStatus);
    BAIL_ON_INVALID_PTR(pdwSize, ntStatus);

    switch (swLevel)
    {
    case LSA_POLICY_INFO_AUDIT_LOG:
        LWBUF_ALLOC_DWORD(pBuffer, pIn->audit_log.percent_full);
        LWBUF_ALLOC_DWORD(pBuffer, pIn->audit_log.log_size);
        LWBUF_ALLOC_NTTIME(pBuffer, pIn->audit_log.retention_time);
        LWBUF_ALLOC_BYTE(pBuffer, pIn->audit_log.shutdown_in_progress);
        LWBUF_ALLOC_NTTIME(pBuffer, pIn->audit_log.time_to_shutdown);
        LWBUF_ALLOC_DWORD(pBuffer, pIn->audit_log.next_audit_record);
        LWBUF_ALLOC_DWORD(pBuffer, pIn->audit_log.unknown);
        break;

    case LSA_POLICY_INFO_AUDIT_EVENTS:
        ntStatus = LsaAllocateAuditEventsInfo(pBuffer,
                                              pdwOffset,
                                              pdwSpaceLeft,
                                              &pIn->audit_events,
                                              pdwSize);
        break;

    case LSA_POLICY_INFO_DOMAIN:
        ntStatus = LsaAllocateDomainInfo(pBuffer,
                                         pdwOffset,
                                         pdwSpaceLeft,
                                         &pIn->domain,
                                         pdwSize);
        break;

    case LSA_POLICY_INFO_PD:
        LWBUF_ALLOC_UNICODE_STRING(pBuffer, (PUNICODE_STRING)&pIn->pd.name);
        break;

    case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
        ntStatus = LsaAllocateDomainInfo(pBuffer,
                                         pdwOffset,
                                         pdwSpaceLeft,
                                         &pIn->account_domain,
                                         pdwSize);
        break;

    case LSA_POLICY_INFO_ROLE:
        LWBUF_ALLOC_WORD(pBuffer, pIn->role.unknown);
        LWBUF_ALLOC_WORD(pBuffer, pIn->role.role);
        break;

    case LSA_POLICY_INFO_REPLICA:
        LWBUF_ALLOC_UNICODE_STRING(pBuffer,
                                   (PUNICODE_STRING)&pIn->replica.source);
        LWBUF_ALLOC_UNICODE_STRING(pBuffer,
                                   (PUNICODE_STRING)&pIn->replica.account);
        break;

    case LSA_POLICY_INFO_QUOTA:
        LWBUF_ALLOC_DWORD(pBuffer, pIn->quota.paged_pool);
        LWBUF_ALLOC_DWORD(pBuffer, pIn->quota.non_paged_pool);
        LWBUF_ALLOC_DWORD(pBuffer, pIn->quota.min_wss);
        LWBUF_ALLOC_DWORD(pBuffer, pIn->quota.max_wss);
        LWBUF_ALLOC_DWORD(pBuffer, pIn->quota.pagefile);
        LWBUF_ALLOC_ULONG64(pBuffer, pIn->quota.unknown);
        break;

    case LSA_POLICY_INFO_DB:
        LWBUF_ALLOC_ULONG64(pBuffer, pIn->db.modified_id);
        LWBUF_ALLOC_NTTIME(pBuffer, pIn->db.db_create_time);
        break;

    case LSA_POLICY_INFO_AUDIT_FULL_SET:
        LWBUF_ALLOC_BYTE(pBuffer, pIn->audit_set.shutdown_on_full);
        break;

    case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
        LWBUF_ALLOC_WORD(pBuffer, pIn->audit_query.unknown);
        LWBUF_ALLOC_BYTE(pBuffer, pIn->audit_query.shutdown_on_full);
        LWBUF_ALLOC_BYTE(pBuffer, pIn->audit_query.log_is_full);
        break;

    case LSA_POLICY_INFO_DNS:
        LWBUF_ALLOC_UNICODE_STRING(pBuffer,
                                   (PUNICODE_STRING)&pIn->dns.name);
        LWBUF_ALLOC_UNICODE_STRING(pBuffer,
                                   (PUNICODE_STRING)&pIn->dns.dns_domain);
        LWBUF_ALLOC_UNICODE_STRING(pBuffer,
                                   (PUNICODE_STRING)&pIn->dns.dns_forest);
        LWBUF_ALIGN(pdwOffset, pdwSize, pdwSpaceLeft);
        LWBUF_ALLOC_BLOB(pBuffer,
                         sizeof(pIn->dns.domain_guid),
                         (PBYTE)&(pIn->dns.domain_guid));
        LWBUF_ALLOC_PSID(pBuffer, pIn->dns.sid);
        break;

    default:
        ntStatus = STATUS_INVALID_LEVEL;
        BAIL_ON_NT_STATUS(ntStatus);
    }

cleanup:
    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    return ntStatus;

error:
    goto cleanup;
}