Пример #1
0
NET_API_STATUS
RxpConvertAuditArray(
    IN LPVOID InputArray,
    IN DWORD InputByteCount,
    OUT LPBYTE * OutputArrayPtr, // will be alloc'ed (free w/ NetApiBufferFree).
    OUT LPDWORD OutputByteCountPtr
    )
{
    DWORD EntryType;
    const LPBYTE InputArrayEndPtr
            = (LPVOID) ( ((LPBYTE)InputArray) + InputByteCount );
    LPBYTE InputBytePtr;
    DWORD InputDataOffset;
    DWORD InputTotalEntrySize;
    LPBYTE InputFixedPtr;
    LPBYTE InputVariablePtr;
    DWORD InputVariableSize;
    LPVOID OutputArray;
    DWORD OutputArraySize;
    DWORD OutputBytesUsed = 0;
    DWORD OutputEntrySizeSoFar;
    LPAUDIT_ENTRY OutputFixedPtr;
    DWORD OutputVariableSize;
    LPBYTE OutputVariablePtr;
    NET_API_STATUS Status;

    //
    // Error check caller's parameters.
    // Set output parameters to make error handling easier below.
    // (Also check for memory faults while we're at it.)
    //
    if (OutputArrayPtr != NULL) {
        *OutputArrayPtr = NULL;
    }
    if (OutputByteCountPtr != NULL) {
        *OutputByteCountPtr = 0;
    }
    if ( (OutputArrayPtr == NULL) || (OutputByteCountPtr == NULL) ) {
        return (ERROR_INVALID_PARAMETER);
    }
    if ( (InputArray == NULL) || (InputByteCount == 0) ) {
        return (ERROR_INVALID_PARAMETER);
    }

    //
    // Compute size needed for output buffer, taking into account:
    //    per field expansion,
    //    per entry expansion,
    //    and alignment.
    //

    Status = RxpEstimateLogSize(
            DOWNLEVEL_AUDIT_FIXED_ENTRY_SIZE,
            InputByteCount,     // input (downlevel) array size in bytes.
            FALSE,              // no, we're not doing error log
            & OutputArraySize); // set estimated array size in bytes.
    if (Status != NO_ERROR) {
        return (Status);        // (output vars are already set.)
    }

    NetpAssert( OutputArraySize > 0 );
    NetpAssert( OutputArraySize > InputByteCount );

    *OutputByteCountPtr = OutputArraySize;

    //
    // Allocate oversize area for output; we'll realloc it to shrink it.
    //
    Status = NetApiBufferAllocate(
            OutputArraySize,
            (LPVOID *) & OutputArray );
    if (Status != NERR_Success) {
        return (Status);        // (output vars are already set.)
    }
    NetpAssert( OutputArray != NULL );
    NetpAssert( POINTER_IS_ALIGNED( OutputArray, ALIGN_WORST ) );

    //
    // Loop for each entry in the input area.
    //
    OutputFixedPtr = OutputArray;
    for (InputBytePtr = InputArray; InputBytePtr < InputArrayEndPtr; ) {

        InputFixedPtr = InputBytePtr;

        NetpAssert( POINTER_IS_ALIGNED( OutputFixedPtr, ALIGN_WORST ) );

        IF_DEBUG(AUDIT) {
            NetpKdPrint(( PREFIX_NETLIB
                    "RxpConvertAuditArray: doing input entry at "
                    FORMAT_LPVOID ", out entry at " FORMAT_LPVOID ".\n",
                    (LPVOID) InputFixedPtr, (LPVOID) OutputFixedPtr ));
        }

        //
        // Process each field in input fixed entry.
        //

        InputTotalEntrySize = (DWORD) SmbGetUshort( (LPWORD) InputBytePtr );
        if (InputTotalEntrySize < MIN_DOWNLEVEL_ENTRY_SIZE) {
            goto FileCorrupt;
        }

        {
            LPBYTE EndPos = InputBytePtr + InputTotalEntrySize;
            if (EndPos > InputArrayEndPtr) {
                goto FileCorrupt;
            }
            EndPos -= sizeof(WORD);     // the last ae_len2
            if (SmbGetUshort( (LPWORD) EndPos ) != InputTotalEntrySize) {
                goto FileCorrupt;
            }
        }
        InputBytePtr += sizeof(WORD);    // skip ae_len.

        OutputFixedPtr->ae_reserved =
                (DWORD) SmbGetUshort( (LPWORD) InputBytePtr );
        InputBytePtr += sizeof(WORD);   //  skip ae_reserved

        {
            DWORD LocalTime = (DWORD) SmbGetUlong( (LPDWORD) InputBytePtr );
            DWORD GmtTime;
            NetpLocalTimeToGmtTime( LocalTime, & GmtTime );
            OutputFixedPtr->ae_time = GmtTime;
            InputBytePtr += sizeof(DWORD);
        }

        EntryType = (DWORD) SmbGetUshort( (LPWORD) InputBytePtr );
        OutputFixedPtr->ae_type = EntryType;
        InputBytePtr += sizeof(WORD);

        InputDataOffset = (DWORD) SmbGetUshort( (LPWORD) InputBytePtr );
        NetpAssert( InputDataOffset >= DOWNLEVEL_AUDIT_FIXED_ENTRY_SIZE );
        InputBytePtr += sizeof(WORD);

        OutputEntrySizeSoFar = sizeof(AUDIT_ENTRY);


        //
        // Process variable portion (if any):
        //

        InputVariablePtr = (LPVOID)
                ( ((LPBYTE) InputFixedPtr) + InputDataOffset );
        InputVariableSize =
                (InputTotalEntrySize - InputDataOffset)
                - sizeof(WORD);  // don't include ae_len2.

        OutputVariablePtr = (LPVOID)
                ( ((LPBYTE) OutputFixedPtr) + sizeof(AUDIT_ENTRY) );

        // Align variable part.
        OutputVariablePtr = ROUND_UP_POINTER( OutputVariablePtr, ALIGN_WORST );
        OutputEntrySizeSoFar =
                ROUND_UP_COUNT( OutputEntrySizeSoFar, ALIGN_WORST );

        OutputFixedPtr->ae_data_offset = OutputEntrySizeSoFar;

        // Copy and convert the variable part.
        RxpConvertAuditEntryVariableData(
                EntryType,
                InputVariablePtr,
                OutputVariablePtr,
                InputVariableSize,
                & OutputVariableSize);

#ifdef REVISED_AUDIT_ENTRY_STRUCT
        OutputFixedPtr->ae_data_size = OutputVariableSize;
#endif

        // Account for variable area and ae_len2 in total length.
        OutputEntrySizeSoFar += (OutputVariableSize + sizeof(DWORD));

        // Round size up so next entry (if any) is worst-case aligned.
        OutputEntrySizeSoFar =
                ROUND_UP_COUNT( OutputEntrySizeSoFar, ALIGN_WORST );


#define OutputEntrySize  OutputEntrySizeSoFar


        OutputFixedPtr->ae_len = OutputEntrySize;

        {
            LPDWORD EndSizePtr = (LPVOID)
                    ( ((LPBYTE)OutputFixedPtr)
                        + OutputEntrySize - sizeof(DWORD) );
            *EndSizePtr = OutputEntrySize;   // set ae_len2.
        }

        //
        // Update for next loop iteration.
        //

        InputBytePtr = (LPVOID)
                ( ((LPBYTE) InputFixedPtr)
                    + InputTotalEntrySize);

        OutputFixedPtr = (LPVOID)
                ( ((LPBYTE) OutputFixedPtr) + OutputEntrySize );

        OutputBytesUsed += OutputEntrySize;

        NetpAssert( OutputBytesUsed <= OutputArraySize );

    }

    NetpAssert(OutputBytesUsed > 0);
    NetpAssert( OutputBytesUsed <= OutputArraySize );

    // BUGBUG: realloc OutputArray to OutputBytesUsed


    *OutputArrayPtr = OutputArray;
    *OutputByteCountPtr = OutputBytesUsed;

    return (NERR_Success);

FileCorrupt:

    NetpKdPrint(( PREFIX_NETAPI
            "RxpConvertAuditArray: corrupt audit log!\n" ));

    if (OutputArray != NULL) {
        (VOID) NetApiBufferFree( OutputArray );
    }
    if (OutputArrayPtr != NULL) {
        *OutputArrayPtr = NULL;
    }
    if (OutputByteCountPtr != NULL) {
        *OutputByteCountPtr = 0;
    }
    return (NERR_LogFileCorrupt);

}
Пример #2
0
NTSTATUS
RdrMapSmbError (
    IN PSMB_HEADER Smb,
    IN PSERVERLISTENTRY Sle OPTIONAL
)

/*++

Routine Description:

    This routine takes an SMB, grabs the error from it, and maps it to an NT
    error.

Arguments:

    IN PSMB_HEADER Smb - Supplies the SMB buffer to check.
    IN PSERVERLISTENTRY Sle OPTIONAL - Supplies the server name for the Smb.

Return Value:

    NTSTATUS - Status of resulting operation.

--*/

{
    NTSTATUS Status;
    USHORT Error;
    USHORT i;
    UCHAR ErrorClass;

    DISCARDABLE_CODE(RdrVCDiscardableSection);

    //
    //  If this SMB contains an NT status for the operation, return
    //  that, otherwise map the resulting error.
    //

    if (SmbGetUshort(&Smb->Flags2) & SMB_FLAGS2_NT_STATUS) {

        PNT_SMB_HEADER NtSmb = (PNT_SMB_HEADER)Smb;

        return(SmbGetUlong(&NtSmb->Status.NtStatus));
    } else {

        if ((ErrorClass = Smb->ErrorClass) == SMB_ERR_SUCCESS) {
            return STATUS_SUCCESS;
        }

    }

    Error = SmbGetUshort(&Smb->Error);
    if (Error == SMB_ERR_SUCCESS) {
        Status = STATUS_UNEXPECTED_NETWORK_ERROR;
        goto ReturnStatus;
    }

    switch (ErrorClass) {
    case SMB_ERR_CLASS_DOS:
    case SMB_ERR_CLASS_HARDWARE:
        for (i=0; i<RdrOs2ErrorMapLength; i++) {
            if (RdrOs2ErrorMap[i].ErrorCode==Error) {
                Status = RdrOs2ErrorMap[i].ResultingStatus;
                goto ReturnStatus;
            }
        }
        Status = BASE_DOS_ERROR + SmbGetUshort(&Smb->Error);
        break;

    case SMB_ERR_CLASS_SERVER:
        for (i=0; i<RdrSmbErrorMapLength; i++) {
            if (RdrSmbErrorMap[i].ErrorCode==Error) {
                Status = RdrSmbErrorMap[i].ResultingStatus;
                goto ReturnStatus;
            }
        }
        Status = STATUS_UNEXPECTED_NETWORK_ERROR;
        break;

    default:
        dprintf(DPRT_SMB|DPRT_ERROR, ("Unknown error SMB error class %x", ErrorClass));
        Status = STATUS_NOT_IMPLEMENTED;
        break;
    }

ReturnStatus:
    if ( Status == STATUS_UNEXPECTED_NETWORK_ERROR ) {
        RdrStatistics.NetworkErrors += 1;

        RdrWriteErrorLogEntry(
            Sle,
            IO_ERR_LAYERED_FAILURE,
            EVENT_RDR_UNEXPECTED_ERROR,
            Status,
            Smb,
            sizeof(SMB_HEADER)
        );
    }
    return Status;
}
Пример #3
0
NTSTATUS
BowserHandleIpxDomainAnnouncement(
    IN PTRANSPORT Transport,
    IN PSMB_IPX_NAME_PACKET NamePacket,
    IN PBROWSE_ANNOUNCE_PACKET_1 DomainAnnouncement,
    IN DWORD RequestLength,
    IN ULONG ReceiveFlags
    )

/*++

Routine Description:

    This routine will process receive datagram indication messages, and
    process them as appropriate.

Arguments:

    IN PTRANSPORT Transport     - The transport provider for this request.
    IN PSMB_IPX_NAME_PACKET NamePacket    - The name packet for this request.

Return Value:

    NTSTATUS - Status of operation.

--*/
{
    PVIEW_BUFFER ViewBuffer;

    DISCARDABLE_CODE(BowserDiscardableCodeSection);

    ExInterlockedAddLargeStatistic(&BowserStatistics.NumberOfDomainAnnouncements, 1);

    ViewBuffer = BowserAllocateViewBuffer();

    //
    //  If we are unable to allocate a view buffer, ditch this datagram on
    //  the floor.
    //

    if (ViewBuffer == NULL) {
        return STATUS_REQUEST_NOT_ACCEPTED;
    }

    BowserCopyOemComputerName(ViewBuffer->ServerName, NamePacket->Name, SMB_IPX_NAME_LENGTH, ReceiveFlags);

    BowserCopyOemComputerName(ViewBuffer->ServerComment, NamePacket->SourceName, SMB_IPX_NAME_LENGTH, ReceiveFlags);

    if ( DomainAnnouncement->Type & SV_TYPE_NT ) {
        ViewBuffer->ServerType = SV_TYPE_DOMAIN_ENUM | SV_TYPE_NT;
    } else {
        ViewBuffer->ServerType = SV_TYPE_DOMAIN_ENUM;
    }

    ASSERT (Transport->MasterBrowser != NULL);

    ViewBuffer->TransportName = Transport->MasterBrowser;

    ViewBuffer->ServerVersionMajor = DomainAnnouncement->VersionMajor;

    ViewBuffer->ServerVersionMinor = DomainAnnouncement->VersionMinor;

    ViewBuffer->ServerPeriodicity = (USHORT)((SmbGetUlong(&DomainAnnouncement->Periodicity) + 999) / 1000);

    BowserReferenceTransportName(Transport->MasterBrowser);
    BowserReferenceTransport( Transport );

    ExInitializeWorkItem(&ViewBuffer->Overlay.WorkHeader, BowserProcessDomainAnnouncement, ViewBuffer);

    ExQueueWorkItem(&ViewBuffer->Overlay.WorkHeader, DelayedWorkQueue);

    return STATUS_SUCCESS;
}