mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
667 lines
16 KiB
667 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
admin.c
|
|
|
|
Abstract:
|
|
|
|
Make and Verify routines for Admin class SMBs.
|
|
|
|
Author:
|
|
|
|
David Treadwell (davidtr) 20-Nov-1989
|
|
Chuck Lenzmeier (chuckl)
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define INCLUDE_SMB_ADMIN
|
|
|
|
#include "usrv.h"
|
|
|
|
#include "protocol.h"
|
|
|
|
//
|
|
// Statics
|
|
//
|
|
|
|
STRING NativeOS = { 16, 16, "NT SMB test 1.0" };
|
|
STRING NativeLanManager = { 11, 11, "NT SMB 0.2" };
|
|
STRING PrimaryDomain = { 6, 6, "NtLan" };
|
|
|
|
typedef struct _TEST_DIALECT {
|
|
PSZ String;
|
|
SMB_DIALECT Dialect;
|
|
} TEST_DIALECT;
|
|
|
|
TEST_DIALECT TestDialects[] = {
|
|
{NTLANMAN, SmbDialectNtLanMan}, // NT SMB protocol
|
|
//{NTLM20, SmbDialectLanMan30}, // OS/2 1.2 LanMan 2.0, NT client
|
|
{LANMAN12, SmbDialectLanMan20}, // OS/2 1.2 LanMan 2.0
|
|
{DOSLANMAN12, SmbDialectDosLanMan20}, // DOS LanMan 2.0
|
|
{LANMAN10, SmbDialectLanMan10}, // 1st ver. of full LanMan extensions
|
|
{MSNET30, SmbDialectMsNet30}, // Larger subset of LanMan extensions
|
|
{MSNET103, SmbDialectMsNet103}, // Limited subset of LanMan extensions
|
|
{PCLAN1, SmbDialectPcLan10}, // Alternate original protocol
|
|
{PCNET1, SmbDialectPcNet10}, // Original protocol
|
|
{"ILLEGAL", SmbDialectIllegal}
|
|
};
|
|
|
|
|
|
NTSTATUS
|
|
MakeNegotiateSmb(
|
|
IN OUT PDESCRIPTOR Redir,
|
|
IN OUT PVOID Buffer,
|
|
IN OUT PVOID ForcedParams OPTIONAL,
|
|
IN UCHAR AndXCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN PID_VALUES IdValues,
|
|
OUT PULONG SmbSize
|
|
)
|
|
|
|
{
|
|
PSMB_HEADER Header;
|
|
PREQ_NEGOTIATE Params;
|
|
NTSTATUS status;
|
|
UCHAR i;
|
|
USHORT totalSize;
|
|
UCHAR useDialect = DefaultDialect;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_NEGOTIATE)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_NEGOTIATE,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_NEGOTIATE)(ForcedParams);
|
|
|
|
}
|
|
|
|
if ( Redir->argc > 1 &&
|
|
*Redir->argv[1] == '-' && *(Redir->argv[1]+1) == 'l' ) {
|
|
useDialect = (UCHAR)atol( Redir->argv[1]+2 );
|
|
}
|
|
|
|
//
|
|
// Build buffer containing dialect strings separated by 0x02.
|
|
//
|
|
|
|
totalSize = 0;
|
|
|
|
for( i = 0; i < sizeof(TestDialects) / sizeof(TEST_DIALECT); i++ ) {
|
|
|
|
*(Params->Buffer + totalSize++) = 0x02;
|
|
|
|
RtlMoveMemory(
|
|
Params->Buffer + totalSize,
|
|
TestDialects[i].String,
|
|
strlen( TestDialects[i].String ) + 1
|
|
);
|
|
|
|
if ( useDialect != 0 && i != useDialect ) {
|
|
*(Params->Buffer + totalSize) = '~';
|
|
}
|
|
|
|
totalSize += strlen( TestDialects[i].String ) + 1;
|
|
}
|
|
|
|
Params->WordCount = 0;
|
|
SmbPutUshort( &Params->ByteCount, totalSize );
|
|
*SmbSize = sizeof(SMB_HEADER) + SIZEOF_SMB_PARAMS(REQ_NEGOTIATE,totalSize);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // MakeNegotiateSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyNegotiate(
|
|
IN OUT PDESCRIPTOR Redir,
|
|
IN PVOID ForcedParams OPTIONAL,
|
|
IN UCHAR AndXCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN OUT PID_VALUES IdValues,
|
|
OUT PULONG SmbSize,
|
|
IN PVOID Buffer
|
|
)
|
|
|
|
{
|
|
PSMB_HEADER Header;
|
|
PRESP_NEGOTIATE Params;
|
|
PRESP_NT_NEGOTIATE NtParams;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand, SmbSize; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_NEGOTIATE)(Header + 1);
|
|
NtParams = (PRESP_NT_NEGOTIATE)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_NEGOTIATE
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_NEGOTIATE)ForcedParams;
|
|
NtParams = (PRESP_NT_NEGOTIATE)ForcedParams;
|
|
|
|
}
|
|
|
|
if ( SmbGetUshort( &Params->DialectIndex ) == 255 ) {
|
|
printf( "USRV: No dialects were acceptable to the server.\n" );
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
Redir->Dialect = TestDialects[SmbGetUshort( &Params->DialectIndex )].Dialect;
|
|
|
|
if ( Redir->Dialect == SmbDialectNtLanMan ) {
|
|
if ( SmbGetUshort( &Params->MaxBufferSize ) < Redir->MaxBufferSize ) {
|
|
Redir->MaxBufferSize = SmbGetUlong( &NtParams->MaxBufferSize );
|
|
}
|
|
IF_DEBUG(2) printf( "MaxBufferSize: %ld\n", Redir->MaxBufferSize );
|
|
|
|
Redir->ServerCapabilities = SmbGetUlong( &NtParams->Capabilities );
|
|
|
|
IF_DEBUG(2) printf( "Server Capabilities:\n");
|
|
if ( Redir->ServerCapabilities == 0 ) {
|
|
IF_DEBUG(2) printf( "\tNo NT capabilities\n" );
|
|
}
|
|
if ( Redir->ServerCapabilities & CAP_RAW_MODE ) {
|
|
IF_DEBUG(2) printf( "\tRaw SMBs\n" );
|
|
}
|
|
if ( Redir->ServerCapabilities & CAP_MPX_MODE ) {
|
|
IF_DEBUG(2) printf( "\tMulitplex SMBs\n" );
|
|
}
|
|
if ( Redir->ServerCapabilities & CAP_UNICODE ) {
|
|
IF_DEBUG(2) printf( "\tUnicode\n" );
|
|
}
|
|
if ( Redir->ServerCapabilities & CAP_LARGE_FILES ) {
|
|
IF_DEBUG(2) printf( "\tLarge file (64 bit offsets)\n" );
|
|
}
|
|
if ( Redir->ServerCapabilities & CAP_NT_SMBS ) {
|
|
IF_DEBUG(2) printf( "\tNT SMBs\n" );
|
|
}
|
|
if ( Redir->ServerCapabilities & CAP_RPC_REMOTE_APIS ) {
|
|
IF_DEBUG(2) printf( "\tRPC remote APIs\n" );
|
|
}
|
|
|
|
} else if ( Redir->Dialect <= SmbDialectLanMan10 ) {
|
|
if ( SmbGetUshort( &Params->MaxBufferSize ) < Redir->MaxBufferSize ) {
|
|
Redir->MaxBufferSize = SmbGetUshort( &Params->MaxBufferSize );
|
|
}
|
|
IF_DEBUG(2) printf( "MaxBufferSize: %ld\n", Redir->MaxBufferSize );
|
|
}
|
|
|
|
if ( Redir->Dialect > SmbDialectNtLanMan ) {
|
|
UCHAR i;
|
|
|
|
for( i = 0; i < sizeof(TestDialects) / sizeof(TEST_DIALECT); i++ ) {
|
|
if ( TestDialects[i].Dialect == Redir->Dialect ) {
|
|
printf( "Negotiated level %ld, %s\n", i, TestDialects[i].String );
|
|
}
|
|
}
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyNegotiate
|
|
|
|
|
|
NTSTATUS
|
|
MakeSessionSetupAndXSmb(
|
|
IN OUT PDESCRIPTOR Redir,
|
|
IN OUT PVOID Buffer,
|
|
IN OUT PVOID ForcedParams OPTIONAL,
|
|
IN UCHAR AndXCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN PID_VALUES IdValues,
|
|
OUT PULONG SmbSize
|
|
)
|
|
|
|
{
|
|
PSMB_HEADER Header;
|
|
PREQ_SESSION_SETUP_ANDX Params;
|
|
PREQ_NT_SESSION_SETUP_ANDX NtParams;
|
|
NTSTATUS status;
|
|
PCH smbBuffer;
|
|
USHORT byteCount;
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_SESSION_SETUP_ANDX)(Header + 1);
|
|
NtParams = (PREQ_NT_SESSION_SETUP_ANDX)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_SESSION_SETUP_ANDX,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_SESSION_SETUP_ANDX)(ForcedParams);
|
|
NtParams = (PREQ_NT_SESSION_SETUP_ANDX)(ForcedParams);
|
|
|
|
}
|
|
|
|
//
|
|
// Fill in common part of SMB
|
|
//
|
|
|
|
Params->AndXCommand = AndXCommand;
|
|
Params->AndXReserved = 0;
|
|
SmbPutUshort( &Params->MaxBufferSize, (USHORT)Redir->MaxBufferSize );
|
|
SmbPutUshort( &Params->MaxMpxCount, 1 );
|
|
SmbPutUshort( &Params->VcNumber, 0 );
|
|
SmbPutUlong( &Params->SessionKey, 0 );
|
|
SmbPutUshort(
|
|
&Params->PasswordLength,
|
|
(USHORT)(strlen( SessionSetupStrings[IdSelections->Uid].Buffer ) + 1)
|
|
);
|
|
SmbPutUlong( &Params->Reserved, 0 );
|
|
|
|
//
|
|
// Fill in protocol dependent part of SMB.
|
|
//
|
|
|
|
if ( Redir->Dialect == SmbDialectNtLanMan ) {
|
|
NtParams->WordCount = 12;
|
|
NtParams->Capabilities = CAP_NT_STATUS | CAP_LEVEL_II_OPLOCKS | CAP_LARGE_FILES | CAP_NT_SMBS;
|
|
|
|
byteCount = SessionSetupStrings[IdSelections->Uid].Length +
|
|
NativeOS.Length +
|
|
NativeLanManager.Length +
|
|
PrimaryDomain.Length;
|
|
|
|
SmbPutUshort(
|
|
&NtParams->ByteCount,
|
|
byteCount
|
|
);
|
|
|
|
smbBuffer = NtParams->Buffer;
|
|
|
|
RtlMoveMemory(
|
|
smbBuffer,
|
|
SessionSetupStrings[IdSelections->Uid].Buffer,
|
|
SessionSetupStrings[IdSelections->Uid].Length
|
|
);
|
|
|
|
smbBuffer += SessionSetupStrings[IdSelections->Uid].Length;
|
|
|
|
RtlMoveMemory(
|
|
smbBuffer,
|
|
NativeOS.Buffer,
|
|
NativeOS.Length
|
|
);
|
|
|
|
smbBuffer += NativeOS.Length;
|
|
|
|
RtlMoveMemory(
|
|
smbBuffer,
|
|
NativeLanManager.Buffer,
|
|
NativeLanManager.Length
|
|
);
|
|
|
|
smbBuffer += NativeLanManager.Length;
|
|
|
|
RtlMoveMemory(
|
|
smbBuffer,
|
|
PrimaryDomain.Buffer,
|
|
PrimaryDomain.Length
|
|
);
|
|
|
|
SmbPutUshort( &Params->AndXOffset, GET_ANDX_OFFSET(
|
|
Header,
|
|
NtParams,
|
|
REQ_NT_SESSION_SETUP_ANDX,
|
|
byteCount
|
|
) );
|
|
|
|
} else {
|
|
Params->WordCount = 10;
|
|
SmbPutUshort(
|
|
&Params->ByteCount,
|
|
SessionSetupStrings[IdSelections->Uid].Length
|
|
);
|
|
|
|
|
|
smbBuffer = Params->Buffer;
|
|
SmbPutUshort( &Params->AndXOffset, GET_ANDX_OFFSET(
|
|
Header,
|
|
Params,
|
|
REQ_SESSION_SETUP_ANDX,
|
|
SmbGetUshort( &Params->ByteCount )
|
|
) );
|
|
|
|
RtlMoveMemory(
|
|
smbBuffer,
|
|
SessionSetupStrings[IdSelections->Uid].Buffer,
|
|
(ULONG)SmbGetUshort( &Params->ByteCount )
|
|
);
|
|
}
|
|
|
|
|
|
|
|
*SmbSize = SmbGetUshort( &Params->AndXOffset );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // MakeSessionSetupAndXSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifySessionSetupAndX(
|
|
IN OUT PDESCRIPTOR Redir,
|
|
IN PVOID ForcedParams OPTIONAL,
|
|
IN UCHAR AndXCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN OUT PID_VALUES IdValues,
|
|
OUT PULONG SmbSize,
|
|
IN PVOID Buffer
|
|
)
|
|
|
|
{
|
|
PSMB_HEADER Header;
|
|
PRESP_SESSION_SETUP_ANDX Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_SESSION_SETUP_ANDX)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_SESSION_SETUP_ANDX
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_SESSION_SETUP_ANDX)ForcedParams;
|
|
|
|
}
|
|
|
|
IF_DEBUG(2) printf( "Redir UID: %lx\n", SmbGetUshort( &Header->Uid ) );
|
|
|
|
IdValues->Uid[IdSelections->Uid] = SmbGetUshort( &Header->Uid );
|
|
|
|
if ( Redir->Dialect == SmbDialectNtLanMan ) {
|
|
|
|
IF_DEBUG(2) {
|
|
|
|
PCHAR ptr;
|
|
|
|
ptr = Params->Buffer;
|
|
|
|
printf("Server OS = %s\n", ptr );
|
|
ptr += strlen( ptr ) + 1;
|
|
|
|
printf("Server LM type = %s\n", ptr );
|
|
ptr += strlen( ptr ) + 1;
|
|
|
|
printf("Server domain %s\n", ptr );
|
|
}
|
|
|
|
}
|
|
|
|
*SmbSize = SmbGetUshort( &Params->AndXOffset );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifySessionSetupAndX
|
|
|
|
|
|
NTSTATUS
|
|
MakeLogoffAndXSmb(
|
|
IN OUT PDESCRIPTOR Redir,
|
|
IN OUT PVOID Buffer,
|
|
IN OUT PVOID ForcedParams OPTIONAL,
|
|
IN UCHAR AndXCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN PID_VALUES IdValues,
|
|
OUT PULONG SmbSize
|
|
)
|
|
|
|
{
|
|
PSMB_HEADER Header;
|
|
PREQ_LOGOFF_ANDX Params;
|
|
NTSTATUS status;
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_LOGOFF_ANDX)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_LOGOFF_ANDX,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_LOGOFF_ANDX)ForcedParams;
|
|
|
|
}
|
|
|
|
Params->WordCount = 2;
|
|
Params->AndXCommand = AndXCommand;
|
|
Params->AndXReserved = 0;
|
|
SmbPutUshort(
|
|
&Params->AndXOffset,
|
|
GET_ANDX_OFFSET(Header,Params,RESP_LOGOFF_ANDX,0)
|
|
);
|
|
SmbPutUshort( &Params->ByteCount, 0 );
|
|
|
|
*SmbSize = SmbGetUshort( &Params->AndXOffset );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // MakeLogoffAndXSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyLogoffAndX(
|
|
IN OUT PDESCRIPTOR Redir,
|
|
IN PVOID ForcedParams OPTIONAL,
|
|
IN UCHAR AndXCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN OUT PID_VALUES IdValues,
|
|
OUT PULONG SmbSize,
|
|
IN PVOID Buffer
|
|
)
|
|
|
|
{
|
|
PSMB_HEADER Header;
|
|
PRESP_LOGOFF_ANDX Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_LOGOFF_ANDX)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_LOGOFF_ANDX
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_LOGOFF_ANDX)ForcedParams;
|
|
|
|
}
|
|
|
|
*SmbSize = SmbGetUshort( &Params->AndXOffset );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyLogoffAndX
|
|
|
|
|
|
NTSTATUS
|
|
MakeProcessExitSmb(
|
|
IN OUT PDESCRIPTOR Redir,
|
|
IN OUT PVOID Buffer,
|
|
IN OUT PVOID ForcedParams OPTIONAL,
|
|
IN UCHAR AndXCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN PID_VALUES IdValues,
|
|
OUT PULONG SmbSize
|
|
)
|
|
|
|
{
|
|
PSMB_HEADER Header;
|
|
PREQ_PROCESS_EXIT Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_PROCESS_EXIT)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_PROCESS_EXIT,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_PROCESS_EXIT)(ForcedParams);
|
|
|
|
}
|
|
|
|
Params->WordCount = 0;
|
|
SmbPutUshort( &Params->ByteCount, 0 );
|
|
|
|
*SmbSize = GET_ANDX_OFFSET(
|
|
Header,
|
|
Params,
|
|
REQ_PROCESS_EXIT,
|
|
SmbGetUshort( &Params->ByteCount )
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // MakeProcessExitSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyProcessExit(
|
|
IN OUT PDESCRIPTOR Redir,
|
|
IN PVOID ForcedParams OPTIONAL,
|
|
IN UCHAR AndXCommand,
|
|
IN PID_SELECTIONS IdSelections,
|
|
IN OUT PID_VALUES IdValues,
|
|
OUT PULONG SmbSize,
|
|
IN PVOID Buffer
|
|
)
|
|
|
|
{
|
|
PSMB_HEADER Header;
|
|
PRESP_PROCESS_EXIT Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand, SmbSize; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_PROCESS_EXIT)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_PROCESS_EXIT
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_PROCESS_EXIT)ForcedParams;
|
|
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyProcessExit
|
|
|