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.
517 lines
12 KiB
517 lines
12 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
tree.c
|
|
|
|
Abstract:
|
|
|
|
Make and Verify routines for Tree class SMBs.
|
|
|
|
Author:
|
|
|
|
David Treadwell (davidtr) 20-Nov-1989
|
|
Chuck Lenzmeier (chuckl)
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define INCLUDE_SMB_TREE
|
|
|
|
#include "usrv.h"
|
|
|
|
|
|
NTSTATUS
|
|
MakeTreeConnectSmb(
|
|
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_TREE_CONNECT Params;
|
|
NTSTATUS status;
|
|
PSZ pBuffer;
|
|
PSZ shareName;
|
|
int bufferSize;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_TREE_CONNECT)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_TREE_CONNECT,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_TREE_CONNECT)ForcedParams;
|
|
|
|
}
|
|
|
|
Params->WordCount = 0;
|
|
|
|
if ( IdSelections->Tid != 0xF ) {
|
|
|
|
SmbPutUshort(
|
|
&Params->ByteCount,
|
|
TreeConnectStrings[IdSelections->Tid].Length
|
|
);
|
|
RtlMoveMemory(
|
|
Params->Buffer,
|
|
TreeConnectStrings[IdSelections->Tid].Buffer,
|
|
(ULONG)SmbGetUshort( &Params->ByteCount )
|
|
);
|
|
|
|
} else {
|
|
|
|
if ( Redir->argc < 4 || strcmp( Redir->argv[1], "use" ) != 0 ) {
|
|
printf( "Usage: net use X: sharename\n" );
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
pBuffer = Params->Buffer;
|
|
|
|
*pBuffer++ = '\004';
|
|
|
|
//
|
|
// Upcase path.
|
|
//
|
|
|
|
{
|
|
PCHAR s;
|
|
|
|
for ( s = Redir->argv[3]; *s != '\0'; s++ ) {
|
|
if ( *s >= 'a' && *s <= 'z' ) {
|
|
*s -= 'a' - 'A';
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Copy path with NUL terminator into SMB buffer
|
|
//
|
|
|
|
bufferSize = strlen( Redir->argv[3] ) + 1;
|
|
RtlMoveMemory(
|
|
pBuffer,
|
|
Redir->argv[3],
|
|
bufferSize
|
|
);
|
|
pBuffer += bufferSize;
|
|
|
|
*pBuffer++ = '\004';
|
|
|
|
//
|
|
// Copy password with NUL terminator into SMB buffer
|
|
//
|
|
|
|
|
|
bufferSize = (Redir->argc == 4 ?
|
|
strlen( "password" ) : strlen( Redir->argv[4] )) + 1;
|
|
RtlMoveMemory(
|
|
pBuffer,
|
|
Redir->argc == 4 ? "password" : Redir->argv[4],
|
|
bufferSize
|
|
);
|
|
pBuffer += bufferSize;
|
|
|
|
*pBuffer++ = '\004';
|
|
|
|
//
|
|
// For now, if share name begins with comq, assume this is a
|
|
// comm share. Share is of form "\\server\share". (Just
|
|
// "share" is also allowed.)
|
|
//
|
|
|
|
shareName = Redir->argv[3];
|
|
if ( *shareName == '\\' ) {
|
|
if ( *(shareName+1) != '\\' ) {
|
|
shareName = NULL;
|
|
} else {
|
|
shareName = strchr (Redir->argv[3] + 2, '\\');
|
|
if ( shareName != NULL ) {
|
|
shareName++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( shareName != NULL ) {
|
|
|
|
if ( strncmp( shareName, "COMQ", 4 ) == 0 ) {
|
|
RtlMoveMemory( pBuffer, "COMM", 4 );
|
|
pBuffer += 4;
|
|
} else if ( strncmp( shareName, "IPC$", 4 ) == 0 ) {
|
|
RtlMoveMemory( pBuffer, "IPC", 3 );
|
|
pBuffer += 3;
|
|
} else { // assume disk share
|
|
RtlMoveMemory( pBuffer, "A:", 2 );
|
|
pBuffer += 2;
|
|
}
|
|
|
|
} else {
|
|
|
|
printf ("Invalid share name\n");
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
*pBuffer++ = '\0';
|
|
|
|
SmbPutUshort(
|
|
&Params->ByteCount,
|
|
(USHORT)(pBuffer - Params->Buffer)
|
|
);
|
|
|
|
}
|
|
|
|
*SmbSize = sizeof(SMB_HEADER) + SIZEOF_SMB_PARAMS(
|
|
REQ_TREE_CONNECT,
|
|
SmbGetUshort( &Params->ByteCount)
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // MakeTreeConnectSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyTreeConnect(
|
|
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_TREE_CONNECT Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand, SmbSize; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_TREE_CONNECT)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_TREE_CONNECT
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_TREE_CONNECT)ForcedParams;
|
|
|
|
}
|
|
|
|
if ( IdSelections->Tid != 0xF ) {
|
|
IdValues->Tid[IdSelections->Tid] = SmbGetUshort( &Params->Tid );
|
|
} else {
|
|
IdValues->Tid[GetTreeConnectIndex( Redir->argv[2] )] =
|
|
SmbGetUshort( &Params->Tid );
|
|
}
|
|
|
|
IdValues->Uid[0] = SmbGetUshort( &Header->Uid );
|
|
|
|
if ( Redir->Dialect > SmbDialectLanMan10 ) {
|
|
if ( SmbGetUshort( &Params->MaxBufferSize ) < Redir->MaxBufferSize ) {
|
|
Redir->MaxBufferSize = SmbGetUshort( &Params->MaxBufferSize );
|
|
}
|
|
IF_DEBUG(2) printf( "MaxBufferSize: %ld\n", Redir->MaxBufferSize );
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyTreeConnect
|
|
|
|
|
|
NTSTATUS
|
|
MakeTreeConnectAndXSmb(
|
|
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_TREE_CONNECT_ANDX Params;
|
|
NTSTATUS status;
|
|
PSZ TreeConnectString;
|
|
PSZ shareName, password, shareType;
|
|
CLONG shareNameLength, passwordLength, shareTypeLength;
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_TREE_CONNECT_ANDX)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_TREE_CONNECT_ANDX,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_TREE_CONNECT_ANDX)ForcedParams;
|
|
|
|
}
|
|
|
|
TreeConnectString = TreeConnectStrings[IdSelections->Tid].Buffer;
|
|
shareName = TreeConnectString + 1;
|
|
shareNameLength = strlen(shareName) + 1;
|
|
password = shareName + shareNameLength + 1;
|
|
passwordLength = strlen(password) + 1;
|
|
shareType = password + passwordLength + 1;
|
|
shareTypeLength = strlen(shareType) + 1;
|
|
|
|
Params->WordCount = 4;
|
|
Params->AndXCommand = AndXCommand;
|
|
Params->AndXReserved = 0;
|
|
SmbPutUshort( &Params->Flags, 1 );
|
|
SmbPutUshort( &Params->PasswordLength, (USHORT)passwordLength );
|
|
SmbPutUshort(
|
|
&Params->ByteCount,
|
|
(USHORT)(passwordLength + shareNameLength + shareTypeLength)
|
|
);
|
|
RtlMoveMemory(
|
|
Params->Buffer,
|
|
password,
|
|
passwordLength
|
|
);
|
|
RtlMoveMemory(
|
|
Params->Buffer + passwordLength,
|
|
shareName,
|
|
shareNameLength
|
|
);
|
|
RtlMoveMemory(
|
|
Params->Buffer + passwordLength + shareNameLength,
|
|
shareType,
|
|
shareTypeLength
|
|
);
|
|
|
|
SmbPutUshort( &Params->AndXOffset, GET_ANDX_OFFSET(
|
|
Header,
|
|
Params,
|
|
REQ_TREE_CONNECT_ANDX,
|
|
SmbGetUshort( &Params->ByteCount )
|
|
) );
|
|
|
|
*SmbSize = SmbGetUshort( &Params->AndXOffset );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // MakeTreeConnectAndXSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyTreeConnectAndX(
|
|
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_TREE_CONNECT_ANDX Params;
|
|
PRESP_21_TREE_CONNECT_ANDX Params21;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_TREE_CONNECT_ANDX)(Header + 1);
|
|
Params21 = (PRESP_21_TREE_CONNECT_ANDX)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_TREE_CONNECT_ANDX
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_TREE_CONNECT_ANDX)ForcedParams;
|
|
Params21 = (PRESP_21_TREE_CONNECT_ANDX)ForcedParams;
|
|
|
|
}
|
|
|
|
IdValues->Tid[IdSelections->Tid] = SmbGetUshort( &Header->Tid );
|
|
|
|
if ( Redir->Dialect == SmbDialectNtLanMan ) {
|
|
|
|
IF_DEBUG(2) {
|
|
|
|
PCHAR ptr;
|
|
|
|
printf ("Server %s search bits",
|
|
Params21->OptionalSupport & SMB_SUPPORT_SEARCH_BITS ?
|
|
"supports" : "doesn't support" );
|
|
|
|
ptr = Params21->Buffer;
|
|
printf ("File system service: %s\n", ptr );
|
|
|
|
ptr += strlen( ptr ) + 1;
|
|
printf ("File system for tree: %s\n", ptr );
|
|
|
|
}
|
|
}
|
|
|
|
*SmbSize = SmbGetUshort( &Params->AndXOffset );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyTreeConnectAndX
|
|
|
|
|
|
NTSTATUS
|
|
MakeTreeDisconnectSmb(
|
|
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_TREE_DISCONNECT Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)Buffer;
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PREQ_TREE_DISCONNECT)(Header + 1);
|
|
|
|
status = MakeSmbHeader(
|
|
Redir,
|
|
Header,
|
|
SMB_COM_TREE_DISCONNECT,
|
|
IdSelections,
|
|
IdValues
|
|
);
|
|
|
|
if ( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PREQ_TREE_DISCONNECT)ForcedParams;
|
|
|
|
}
|
|
|
|
Params->WordCount = 0;
|
|
SmbPutUshort( &Params->ByteCount, 0 );
|
|
|
|
*SmbSize = sizeof(SMB_HEADER) +
|
|
SIZEOF_SMB_PARAMS(REQ_TREE_DISCONNECT,0);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // MakeTreeDisconnectSmb
|
|
|
|
|
|
NTSTATUS
|
|
VerifyTreeDisconnect(
|
|
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_TREE_DISCONNECT Params;
|
|
NTSTATUS status;
|
|
|
|
AndXCommand, SmbSize; // prevent compiler warnings
|
|
|
|
Header = (PSMB_HEADER)(Buffer);
|
|
|
|
if ( ForcedParams == NULL ) {
|
|
|
|
Params = (PRESP_TREE_DISCONNECT)(Header + 1);
|
|
|
|
status = VerifySmbHeader(
|
|
Redir,
|
|
IdSelections,
|
|
IdValues,
|
|
Header,
|
|
SMB_COM_TREE_DISCONNECT
|
|
);
|
|
if( !NT_SUCCESS(status) ) {
|
|
return status;
|
|
}
|
|
|
|
} else {
|
|
|
|
Params = (PRESP_TREE_DISCONNECT)ForcedParams;
|
|
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // VerifyTreeDisconnect
|