From b9bdb947c0d75b45107c4430db19d8b8e56c1480 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Fri, 5 Dec 2003 03:33:34 +0000 Subject: TreeConnect implemented --- src/nu_server.c | 83 ++++++++++++++++++++++++++++++++++++--------------------- src/nu_server.h | 5 ++-- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/nu_server.c b/src/nu_server.c index d79967c..1360ccb 100755 --- a/src/nu_server.c +++ b/src/nu_server.c @@ -7,7 +7,7 @@ #include #include -#include "nu_header.h" +#include "nu_server.h" static void bailout( char *reason ); static void sigint( int reason ) { bailout( "User interrupt." ); } @@ -35,7 +35,7 @@ static void netbios_read( SMB_HEADER **buf) { static void netbios_write( SMB_HEADER *buf, SMB_DATA *data, int datacount ) { - struct iovec iov[1 + 2 * SMB_MAXREQUEST] = { {buf , sizeof(SMB_HEADER) } }; + struct iovec iov[1 + 2 * SMB_MAXREQUESTS] = { {buf , sizeof(SMB_HEADER) } }; int i, sizeout = sizeof( SMB_HEADER ); for( i=0; i < datacount; ++i ) @@ -45,11 +45,11 @@ static void netbios_write( SMB_HEADER *buf, sizeout += iov[2+2*i].iov_len = 2 + data[i].bytes->ByteCount; buf->netbios_command = buf->netbios_flags = 0; - buf->netbios_size = htons( sizeout ); + buf->netbios_size = htons( sizeout - 4 ); buf->Flags = 0x88; buf->Flags2 = 0x4001; - if( writev( childsock, iov, 1 + 2 * datacount ) < sizeout + 4 ) + if( writev( childsock, iov, 1 + 2 * datacount ) < sizeout ) bailout( "Write failed." ); } @@ -58,49 +58,63 @@ static WORD SMB_COM_NEGOTIATE_params[] = { 0x0511, 0x0000, 0x0001, 0x0001, 0x0000, 0x0100, 0x0000, 0x0100, 0x0000, 0x0000, 0xC049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; -static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_DATA *data ) { +static SMB_STATUS handle_SMB_COM_NEGOTIATE( SMB_HEADER *header, SMB_DATA *data ) { struct timeval t; gettimeofday( &t, NULL ); SMB_COM_NEGOTIATE_params[8] = getpid(); SMB_COM_NEGOTIATE_params[9] = getppid(); *(QWORD*)(SMB_COM_NEGOTIATE_params+12) = getnttime( &t ); - - data->params = SMB_COM_NEGOTIATE_bytes; data->bytes = SMB_COM_NEGOTIATE_params; + data->params = (SMB_PARAMS*)SMB_COM_NEGOTIATE_params; + data->bytes = (SMB_BYTES *)SMB_COM_NEGOTIATE_bytes; return STATUS_SUCCESS; } -static const BYTE SMB_SESSION_SETUP_ANDX_bytes[] = { +static const BYTE SMB_COM_SESSION_SETUP_ANDX_bytes[] = { 19,0,'O','S',0,'g','a','t','l','i','n','g',0,'g','a','t','l','i','n','g',0}; -static BYTE SMB_SESSION_SETUP_ANDX_params[] = { 4, 0, 0, 23, 0, 1, 0, 0, 0 }; +static BYTE SMB_COM_SESSION_SETUP_ANDX_params[] = { 4, 255, 0, 0, 0, 1, 0, 0, 0 }; + +static SMB_STATUS handle_SMB_COM_SESSION_SETUP_ANDX( SMB_HEADER *header, SMB_DATA *data ) { + data->params = (SMB_PARAMS*)SMB_COM_SESSION_SETUP_ANDX_params; + data->bytes = (SMB_BYTES *)SMB_COM_SESSION_SETUP_ANDX_bytes; + return STATUS_SUCCESS; +} + +static const BYTE SMB_COM_TREE_CONNECT_ANDX_bytes[] = { 8, 0, 'I', 'P', 'C', 0, 'I', 'P', 'C', 0 }; +static BYTE SMB_COM_TREE_CONNECT_ANDX_params[] = { 3, 255, 0, 0, 0, 0, 0 }; -static SMB_STATUS handle_SMB_SESSION_SETUP_ANDX( SMB_DATA *data ) { - data->params = SMB_SESSION_SETUP_ANDX_bytes; data->bytes = SMB_SESSION_SETUP_ANDX_params; +static SMB_STATUS handle_SMB_COM_TREE_CONNECT_ANDX( SMB_HEADER *header, SMB_DATA *data ){ + data->params = (SMB_PARAMS*)SMB_COM_TREE_CONNECT_ANDX_params; + data->bytes = (SMB_BYTES *)SMB_COM_TREE_CONNECT_ANDX_bytes; return STATUS_SUCCESS; } -static‰int command_handler_match( const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; } +static int command_handler_match(const void *a, const void *b ) { return *(BYTE*)a - *(BYTE*)b; } + +/* If you add command handlers, please insert them in the right position, + this list is sorted by command, for later bsearch*/ static SMB_COMMAND_HANDLER command_handler[] = { - { { SMB_COM_NEGOTIATE, 0x00, handle_SMB_COM_NEGOTIATE }, - { SMB_COM_SESSION_SETUP_ANDX, 0x01, handle_SMB_COM_SESSION_SETUP_ANDX } - } + { SMB_COM_NEGOTIATE, 0x00, handle_SMB_COM_NEGOTIATE }, + { SMB_COM_SESSION_SETUP_ANDX, 0x01, handle_SMB_COM_SESSION_SETUP_ANDX }, + { SMB_COM_TREE_CONNECT_ANDX, 0x01, handle_SMB_COM_TREE_CONNECT_ANDX } }; static void child( ) { SMB_HEADER *inpacket = NULL; + DWORD netbios_ack = 0x00000082; /* I should spare that code... */ if( mainsock != -1 ) { close( mainsock ); mainsock = -1; } /* Try to answer first netbios packet */ netbios_read( &inpacket ); - if( inpacket->netbios_command++ != 0x81 ) + if( inpacket->netbios_command != 0x81 ) bailout( "No session request"); - write( childsock, inpacket, 4); + write( childsock, &netbios_ack, 4); while( 1 ) { SMB_COMMAND cmd; SMB_DATA requests[ 1 + SMB_MAXREQUESTS ]; SMB_STATUS status = STATUS_SUCCESS; - WORD sizeout = sizeof( SMB_HEADER ); + WORD sizeout = sizeof( SMB_HEADER ) - 4; int num_requests = 0; netbios_read( &inpacket ); @@ -114,29 +128,38 @@ static void child( ) { requests[ 0 ].params = (SMB_PARAMS*)(inpacket+1); while( (status == STATUS_SUCCESS) && (cmd != 0xff) ) { - SMB_COMMAND_HANDLER *handler = (SMB_COMMAND_HANDLER*)bsearch( cmd, command_handler, + SMB_COMMAND_HANDLER *handler = (SMB_COMMAND_HANDLER*)bsearch( &cmd, command_handler, sizeof(command_handler)/sizeof(*command_handler), sizeof(*command_handler), command_handler_match); - requests[ num_request ].bytes = 2 + *((WORD*)requests[ num_request ].params) + (BYTE*)requests[ num_request ].params; + requests[ num_requests ].bytes = + (SMB_BYTES*)(((BYTE*)requests[ num_requests ].params) + *((WORD*)(requests[ num_requests ].params)) + 2); + if( handler ) { if( handler->flags & SMB_COMMAND_FLAG_ANDX ) { - cmd = ((BYTE*)requests[ num_requests ].params)[3]; - requests[ num_requests+1 ].params = ((BYTE*)inpacket) + ((WORD*)requests[ num_requests ].params)[2]; + cmd = ((BYTE*)requests[ num_requests ].params)[1]; + requests[ num_requests+1 ].params = (SMB_PARAMS*)(((BYTE*)inpacket) + 4 + ((WORD*)requests[ num_requests ].params)[2]); } - status = handler->handler( &requests( num_requests ) ); - - if( (status == STATUS_SUCCESS) && (handler->flags & SMB_COMMAND_FLAG_ANDX) ) { + /* <---------- Calling handler here -----> */ + if( (status = handler->handler( inpacket, requests + num_requests )) != STATUS_SUCCESS ) + cmd = 0xff; + if( handler->flags & SMB_COMMAND_FLAG_ANDX ) { sizeout += 3 + 2 * requests[ num_requests ].params->WordCount + requests[ num_requests ].bytes->ByteCount; - ((WORD*)requests[ num_requests ].params)[2] = sizeout; - ((BYTE*)requests[ num_requests ].params)[3] = cmd; - } + ((BYTE*)requests[ num_requests ].params)[1] = cmd, + ((BYTE*)requests[ num_requests ].params)[3] = sizeout & 255, + ((BYTE*)requests[ num_requests ].params)[4] = sizeout >> 8; + } else + cmd = 0xff; + num_requests++; - } else + } else { + if( num_requests ) + ((BYTE*)requests[ num_requests-1 ].params)[1] = 0xff; status = 0x00400002; + } } - memcpy( inpacket->status, &status, 4 ); /* not aligned, maybe we might do a store DWORD on x86 */ + memcpy( inpacket->Status, &status, 4 ); /* not aligned, maybe we might do a store DWORD on x86 */ netbios_write( inpacket, requests, num_requests ); } /* End main loop */ } diff --git a/src/nu_server.h b/src/nu_server.h index 0a2ecc2..4d6abaa 100755 --- a/src/nu_server.h +++ b/src/nu_server.h @@ -4,6 +4,7 @@ typedef unsigned long DWORD; typedef int64_t QWORD; #include "nu_defines.h" +#define SMB_MAXREQUESTS 16 typedef struct { BYTE netbios_command; @@ -37,7 +38,7 @@ typedef struct { } SMB_DATA; typedef struct { - SMB_COMMAND cmd; + BYTE cmd; SMB_COMMAND_FLAG flags; - SMB_STATUS (*handler)(SMB_DATA *data); + SMB_STATUS (*handler)(SMB_HEADER *header, SMB_DATA *data); } SMB_COMMAND_HANDLER; -- cgit v1.2.3