mirror of https://github.com/tongzx/nt5src
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.
1110 lines
28 KiB
1110 lines
28 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ApiLogon.c
|
|
|
|
Abstract:
|
|
|
|
This module contains individual API handlers for the NetLogon APIs.
|
|
|
|
SUPPORTED : NetGetDCName, NetLogonEnum, NetServerAuthenticate,
|
|
NetServerPasswordSet, NetServerReqChallenge,
|
|
NetWkstaUserLogoff, NetWkstaUserLogon.
|
|
|
|
SEE ALSO : NetAccountDeltas, NetAccountSync - in ApiAcct.c.
|
|
|
|
Author:
|
|
|
|
Shanku Niyogi (w-shanku) 04-Apr-1991
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
//
|
|
// Logon APIs are Unicode only.
|
|
//
|
|
|
|
#ifndef UNICODE
|
|
#define UNICODE
|
|
#endif
|
|
|
|
#include "xactsrvp.h"
|
|
#include <netlibnt.h>
|
|
|
|
#include <crypt.h> // must be included before <logonmsv.h>
|
|
#include <ntsam.h> // must be included before <logonmsv.h>
|
|
#include <logonmsv.h> // must be included before <ssi.h>
|
|
#include <ssi.h> // I_NetAccountDeltas and I_NetAccountSync prototypes
|
|
|
|
//
|
|
// Declaration of descriptor strings.
|
|
//
|
|
|
|
STATIC const LPDESC Desc16_user_logon_info_0 = REM16_user_logon_info_0;
|
|
STATIC const LPDESC Desc32_user_logon_info_0 = REM32_user_logon_info_0;
|
|
STATIC const LPDESC Desc16_user_logon_info_1 = REM16_user_logon_info_1;
|
|
STATIC const LPDESC Desc32_user_logon_info_1 = REM32_user_logon_info_1;
|
|
STATIC const LPDESC Desc16_user_logon_info_2 = REM16_user_logon_info_2;
|
|
STATIC const LPDESC Desc32_user_logon_info_2 = REM32_user_logon_info_2;
|
|
STATIC const LPDESC Desc16_user_logoff_info_1 = REM16_user_logoff_info_1;
|
|
STATIC const LPDESC Desc32_user_logoff_info_1 = REM32_user_logoff_info_1;
|
|
|
|
|
|
NTSTATUS
|
|
XsNetGetDCName (
|
|
API_HANDLER_PARAMETERS
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine handles a call to NetGetDCName.
|
|
|
|
Arguments:
|
|
|
|
API_HANDLER_PARAMETERS - Information about the API call. See
|
|
XsTypes.h for details.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
PXS_NET_GET_DC_NAME parameters = Parameters;
|
|
LPTSTR nativeDomain = NULL; // Native parameters
|
|
LPTSTR dcName = NULL;
|
|
|
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|
|
|
try {
|
|
//
|
|
// Translate parameters, check for errors.
|
|
//
|
|
|
|
XsConvertTextParameter(
|
|
nativeDomain,
|
|
(LPSTR)XsSmbGetPointer( ¶meters->Domain )
|
|
);
|
|
|
|
//
|
|
// Make the local call.
|
|
//
|
|
|
|
status = NetGetDCName(
|
|
NULL,
|
|
nativeDomain,
|
|
(LPBYTE *)&dcName
|
|
);
|
|
|
|
if ( !XsApiSuccess( status )) {
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetGetDCName: NetGetDCName failed: %X\n",
|
|
status ));
|
|
}
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Put string into buffer. Convert from Unicode if necessary.
|
|
//
|
|
|
|
if ( (DWORD)SmbGetUshort( ¶meters->BufLen ) <= NetpUnicodeToDBCSLen( dcName )) {
|
|
|
|
status = NERR_BufTooSmall;
|
|
|
|
} else {
|
|
|
|
NetpCopyWStrToStrDBCS( (LPSTR)XsSmbGetPointer( ¶meters->Buffer ), dcName );
|
|
|
|
}
|
|
|
|
|
|
IF_DEBUG(LOGON) {
|
|
NetpKdPrint(( "Name is %ws\n", dcName ));
|
|
}
|
|
|
|
cleanup:
|
|
;
|
|
} except ( EXCEPTION_EXECUTE_HANDLER ) {
|
|
status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|
}
|
|
|
|
|
|
//
|
|
// Set return data count.
|
|
//
|
|
|
|
if ( status == NERR_Success ) {
|
|
SmbPutUshort( ¶meters->BufLen, (USHORT)( STRLEN( dcName ) + 1 ));
|
|
} else {
|
|
SmbPutUshort( ¶meters->BufLen, 0 );
|
|
}
|
|
|
|
|
|
Header->Status = (WORD)status;
|
|
NetpMemoryFree( nativeDomain );
|
|
NetApiBufferFree( dcName );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // XsNetGetDCName
|
|
|
|
|
|
NTSTATUS
|
|
XsNetLogonEnum (
|
|
API_HANDLER_PARAMETERS
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine handles a call to NetLogonEnum.
|
|
|
|
Arguments:
|
|
|
|
API_HANDLER_PARAMETERS - Information about the API call. See
|
|
XsTypes.h for details.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
PXS_NET_LOGON_ENUM parameters = Parameters;
|
|
LPVOID outBuffer= NULL;
|
|
DWORD entriesRead = 0;
|
|
DWORD totalEntries = 0;
|
|
|
|
DWORD entriesFilled = 0;
|
|
DWORD bytesRequired = 0;
|
|
LPDESC nativeStructureDesc;
|
|
|
|
API_HANDLER_PARAMETERS_REFERENCE;
|
|
|
|
IF_DEBUG(LOGON) {
|
|
NetpKdPrint(( "XsNetLogonEnum: header at %lx, params at %lx, "
|
|
"level %ld, buf size %ld\n",
|
|
Header, parameters, SmbGetUshort( ¶meters->Level ),
|
|
SmbGetUshort( ¶meters->BufLen )));
|
|
}
|
|
|
|
try {
|
|
//
|
|
// Check for errors.
|
|
//
|
|
|
|
if (( SmbGetUshort( ¶meters->Level ) != 0 )
|
|
&& ( SmbGetUshort( ¶meters->Level ) != 2 )) {
|
|
|
|
Header->Status = ERROR_INVALID_LEVEL;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Make the local call.
|
|
//
|
|
|
|
#ifdef LOGON_ENUM_SUPPORTED
|
|
status = NetLogonEnum(
|
|
NULL,
|
|
(DWORD)SmbGetUshort( ¶meters->Level ),
|
|
(LPBYTE *)&outBuffer,
|
|
XsNativeBufferSize( SmbGetUshort( ¶meters->BufLen )),
|
|
&entriesRead,
|
|
&totalEntries,
|
|
NULL
|
|
);
|
|
#else // LOGON_ENUM_SUPPORTED
|
|
status = NERR_InvalidAPI;
|
|
#endif // LOGON_ENUM_SUPPORTED
|
|
|
|
if ( !XsApiSuccess( status )) {
|
|
IF_DEBUG(API_ERRORS) {
|
|
NetpKdPrint(( "XsNetLogonEnum: NetLogonEnum failed: "
|
|
"%X\n", status ));
|
|
}
|
|
Header->Status = (WORD)status;
|
|
goto cleanup;
|
|
}
|
|
|
|
IF_DEBUG(LOGON) {
|
|
NetpKdPrint(( "XsNetLogonEnum: received %ld entries at %lx\n",
|
|
entriesRead, outBuffer ));
|
|
}
|
|
|
|
//
|
|
// Use the requested level to determine the format of the
|
|
// data structure.
|
|
//
|
|
|
|
switch ( SmbGetUshort( ¶meters->Level ) ) {
|
|
|
|
case 0:
|
|
|
|
nativeStructureDesc = Desc32_user_logon_info_0;
|
|
StructureDesc = Desc16_user_logon_info_0;
|
|
break;
|
|
|
|
case 2:
|
|
|
|
nativeStructureDesc = Desc32_user_logon_info_2;
|
|
StructureDesc = Desc16_user_logon_info_2;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Do the actual conversion from the 32-bit structures to 16-bit
|
|
// structures.
|
|
//
|
|
|
|
XsFillEnumBuffer(
|
|
outBuffer,
|
|
entriesRead,
|
|
nativeStructureDesc,
|
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|
SmbGetUshort( ¶meters->BufLen ),
|
|
StructureDesc,
|
|
NULL, // verify function
|
|
&bytesRequired,
|
|
&entriesFilled,
|
|
NULL
|
|
);
|
|
|
|
IF_DEBUG(LOGON) {
|
|
NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR,"
|
|
" Entries %ld of %ld\n",
|
|
outBuffer, SmbGetUlong( ¶meters->Buffer ),
|
|
bytesRequired, entriesFilled, totalEntries ));
|
|
}
|
|
|
|
//
|
|
// If all the entries could not be filled, return ERROR_MORE_DATA,
|
|
// and return the buffer as is. Otherwise, the data needs to be
|
|
// packed so that we don't send too much useless data.
|
|
//
|
|
|
|
if ( entriesFilled < totalEntries ) {
|
|
|
|
Header->Status = ERROR_MORE_DATA;
|
|
|
|
} else {
|
|
|
|
Header->Converter = XsPackReturnData(
|
|
(LPVOID)XsSmbGetPointer( ¶meters->Buffer ),
|
|
SmbGetUshort( ¶meters->BufLen ),
|
|
StructureDesc,
|
|
entriesFilled
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// Set up the response parameters.
|
|
//
|
|
|
|
SmbPutUshort( ¶meters->EntriesRead, (WORD)entriesFilled );
|
|
SmbPutUshort( ¶meters->TotalAvail, (WORD)totalEntries );
|
|
|
|
cleanup:
|
|
;
|
|
} except ( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|
}
|
|
|
|
NetApiBufferFree( outBuffer );
|
|
|
|
//
|
|
// Determine return buffer size.
|
|
//
|
|
|
|
XsSetDataCount(
|
|
¶meters->BufLen,
|
|
StructureDesc,
|
|
Header->Converter,
|
|
entriesFilled,
|
|
Header->Status
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // XsNetLogonEnum
|
|
|
|
|
|
NTSTATUS
|
|
XsNetServerAuthenticate (
|
|
API_HANDLER_PARAMETERS
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine handles a call to NetServerAuthenticate.
|
|
|
|
Arguments:
|
|
|
|
API_HANDLER_PARAMETERS - Information about the API call. See
|
|
XsTypes.h for details.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
PXS_NET_SERVER_AUTHENTICATE parameters = Parameters;
|
|
NET_API_STATUS status; // Native parameters
|
|
LPTSTR nativeRequestor = NULL;
|
|
NETLOGON_CREDENTIAL inCredential = {0};
|
|
NETLOGON_CREDENTIAL outCredential = {0};
|
|
WCHAR AccountName[MAX_PATH+1];
|
|
|
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|
|
|
try {
|
|
//
|
|
// Translate parameters, check for errors.
|
|
//
|
|
|
|
XsConvertTextParameter(
|
|
nativeRequestor,
|
|
(LPSTR)XsSmbGetPointer( ¶meters->Requestor )
|
|
);
|
|
|
|
//
|
|
// Copy the source credential, and zero out the destination
|
|
// credential.
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
&inCredential,
|
|
(PVOID)XsSmbGetPointer( ¶meters->Caller ),
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
|
|
RtlZeroMemory(
|
|
&outCredential,
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
|
|
//
|
|
// Build the account name.
|
|
//
|
|
|
|
NetpNCopyTStrToWStr( AccountName, nativeRequestor, MAX_PATH );
|
|
|
|
//
|
|
// Make the local call.
|
|
//
|
|
|
|
status = NetpNtStatusToApiStatus(
|
|
I_NetServerAuthenticate(
|
|
NULL,
|
|
AccountName,
|
|
UasServerSecureChannel,
|
|
nativeRequestor,
|
|
&inCredential,
|
|
&outCredential
|
|
));
|
|
|
|
if ( !XsApiSuccess( status )) {
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetServerAuthenticate: I_NetServerAuthenticate "
|
|
"failed: %X\n", status ));
|
|
}
|
|
Header->Status = (WORD)status;
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
|
|
//
|
|
// Set the return credential.
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
parameters->Primary,
|
|
&outCredential,
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
|
|
} except ( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|
}
|
|
|
|
NetpMemoryFree( nativeRequestor );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // XsNetServerAuthenticate
|
|
|
|
|
|
NTSTATUS
|
|
XsNetServerPasswordSet (
|
|
API_HANDLER_PARAMETERS
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine handles a call to NetGetDCName.
|
|
|
|
Arguments:
|
|
|
|
API_HANDLER_PARAMETERS - Information about the API call. See
|
|
XsTypes.h for details.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
PXS_NET_SERVER_PASSWORD_SET parameters = Parameters;
|
|
NET_API_STATUS status; // Native parameters
|
|
LPTSTR nativeRequestor = NULL;
|
|
NETLOGON_AUTHENTICATOR authIn = {0};
|
|
NETLOGON_AUTHENTICATOR authOut = {0};
|
|
ENCRYPTED_LM_OWF_PASSWORD password;
|
|
WCHAR AccountName[MAX_PATH+1];
|
|
|
|
LPBYTE structure = NULL; // Conversion variables
|
|
|
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|
|
|
try {
|
|
//
|
|
// Translate parameters, check for errors.
|
|
//
|
|
|
|
XsConvertTextParameter(
|
|
nativeRequestor,
|
|
(LPSTR)XsSmbGetPointer( ¶meters->Requestor )
|
|
);
|
|
|
|
//
|
|
// Copy the source authenticator and password, and zero out the
|
|
// destination authenticator.
|
|
//
|
|
|
|
structure = (LPBYTE)XsSmbGetPointer( ¶meters->Authenticator );
|
|
RtlCopyMemory(
|
|
&authIn.Credential,
|
|
structure,
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
structure += sizeof(NETLOGON_CREDENTIAL);
|
|
authIn.timestamp = SmbGetUlong( structure );
|
|
|
|
RtlCopyMemory(
|
|
&password,
|
|
parameters->Password,
|
|
sizeof(ENCRYPTED_LM_OWF_PASSWORD)
|
|
);
|
|
|
|
RtlZeroMemory(
|
|
&authOut,
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
|
|
|
|
//
|
|
// Build the account name.
|
|
//
|
|
if( STRLEN( nativeRequestor ) >= MAX_PATH )
|
|
{
|
|
Header->Status = NERR_PasswordTooShort;
|
|
goto cleanup;
|
|
}
|
|
|
|
// Make sure its NULL terminated
|
|
AccountName[MAX_PATH] = L'\0';
|
|
NetpNCopyTStrToWStr( AccountName, nativeRequestor, MAX_PATH );
|
|
|
|
//
|
|
// Make the local call.
|
|
//
|
|
|
|
status = NetpNtStatusToApiStatus(
|
|
I_NetServerPasswordSet(
|
|
NULL,
|
|
AccountName,
|
|
UasServerSecureChannel,
|
|
nativeRequestor,
|
|
&authIn,
|
|
&authOut,
|
|
&password
|
|
));
|
|
|
|
if ( !XsApiSuccess( status )) {
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetServerPasswordSet: "
|
|
"I_NetServerPasswordSet failed: %X\n",
|
|
status ));
|
|
}
|
|
|
|
//
|
|
// !!! When protocol level is available in the header information,
|
|
// we can check it. Right now, we ignore this code.
|
|
//
|
|
// For clients older than LanMan 2.1, return a different error code.
|
|
// LANMAN 2.1 Protocol Level is 6.
|
|
//
|
|
|
|
#if 0
|
|
if ( status == NERR_TimeDiffAtDC && Header->ProtocolLevel < 6 ) {
|
|
status = NERR_SyncRequired;
|
|
}
|
|
#endif
|
|
|
|
Header->Status = (WORD)status;
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
|
|
//
|
|
// Fill in 16 bit return structures.
|
|
//
|
|
|
|
structure = parameters->RetAuth;
|
|
RtlCopyMemory(
|
|
structure,
|
|
&authOut.Credential,
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
structure += sizeof(NETLOGON_CREDENTIAL);
|
|
SmbPutUlong( (LPDWORD)structure, authOut.timestamp );
|
|
|
|
} except ( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|
}
|
|
|
|
NetpMemoryFree( nativeRequestor );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // XsNetServerPasswordSet
|
|
|
|
|
|
NTSTATUS
|
|
XsNetServerReqChallenge (
|
|
API_HANDLER_PARAMETERS
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine handles a call to NetGetDCName.
|
|
|
|
Arguments:
|
|
|
|
API_HANDLER_PARAMETERS - Information about the API call. See
|
|
XsTypes.h for details.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
PXS_NET_SERVER_REQ_CHALLENGE parameters = Parameters;
|
|
NET_API_STATUS status; // Native parameters
|
|
LPTSTR nativeRequestor = NULL;
|
|
NETLOGON_CREDENTIAL inChallenge = {0};
|
|
NETLOGON_CREDENTIAL outChallenge = {0};
|
|
|
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|
|
|
try {
|
|
//
|
|
// Translate parameters, check for errors.
|
|
//
|
|
|
|
XsConvertTextParameter(
|
|
nativeRequestor,
|
|
(LPSTR)XsSmbGetPointer( ¶meters->Requestor )
|
|
);
|
|
|
|
//
|
|
// Copy the source challenge, and zero out the destination
|
|
// challenge.
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
&inChallenge,
|
|
(PVOID)XsSmbGetPointer( ¶meters->Caller ),
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
|
|
RtlZeroMemory(
|
|
&outChallenge,
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
|
|
|
|
//
|
|
// Make the local call.
|
|
//
|
|
|
|
status = NetpNtStatusToApiStatus(
|
|
I_NetServerReqChallenge(
|
|
NULL,
|
|
nativeRequestor,
|
|
&inChallenge,
|
|
&outChallenge
|
|
));
|
|
|
|
if ( !XsApiSuccess( status )) {
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetServerReqChallenge: "
|
|
"I_NetServerReqChallenge failed: %X\n",
|
|
status ));
|
|
}
|
|
Header->Status = (WORD)status;
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
|
|
//
|
|
// Set the return credential.
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
parameters->Primary,
|
|
&outChallenge,
|
|
sizeof(NETLOGON_CREDENTIAL)
|
|
);
|
|
} except ( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|
}
|
|
|
|
NetpMemoryFree( nativeRequestor );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // XsNetServerReqChallenge
|
|
|
|
|
|
NTSTATUS
|
|
XsNetWkstaUserLogoff (
|
|
API_HANDLER_PARAMETERS
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This temporary routine just returns STATUS_NOT_IMPLEMENTED.
|
|
|
|
Arguments:
|
|
|
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|
XsTypes.h for details.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
PXS_NET_WKSTA_USER_LOGOFF parameters = Parameters;
|
|
LPWSTR machineName = NULL; // Native parameters
|
|
LPWSTR userName = NULL;
|
|
NETLOGON_LOGOFF_UAS_INFORMATION buffer;
|
|
|
|
LPBYTE stringLocation = NULL; // Conversion variables
|
|
DWORD bytesRequired = 0;
|
|
PWKSTA_16_USER_LOGOFF_REQUEST_1 usrLogoffReq =
|
|
(PWKSTA_16_USER_LOGOFF_REQUEST_1)parameters->InBuf;
|
|
PUSER_16_LOGOFF_INFO_1 logoffInfo;
|
|
|
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|
|
|
try {
|
|
//
|
|
// Translate parameters, check for errors.
|
|
//
|
|
|
|
XsConvertUnicodeTextParameter(
|
|
userName,
|
|
(LPSTR)( usrLogoffReq->wlreq1_name )
|
|
);
|
|
|
|
XsConvertUnicodeTextParameter(
|
|
machineName,
|
|
(LPSTR)( usrLogoffReq->wlreq1_workstation )
|
|
);
|
|
|
|
if ( SmbGetUshort( ¶meters->Level ) != 1 ) {
|
|
|
|
Header->Status = ERROR_INVALID_LEVEL;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Make sure the workstation name in the logon request is the
|
|
// name of the workstation from which the request came.
|
|
//
|
|
|
|
if ( wcscmp( machineName, Header->ClientMachineName ) ) {
|
|
|
|
Header->Status = (WORD)ERROR_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Make the local call.
|
|
//
|
|
|
|
status = I_NetLogonUasLogoff(
|
|
userName,
|
|
machineName,
|
|
&buffer
|
|
);
|
|
|
|
if ( !XsApiSuccess(status)) {
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetWkstaUserLogoff: I_NetLogonUasLogoff "
|
|
"failed: %X\n", status ));
|
|
}
|
|
Header->Status = (WORD)status;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Convert the structure returned by the 32-bit call to a 16-bit
|
|
// structure. The last possible location for variable data is
|
|
// calculated from buffer location and length.
|
|
//
|
|
|
|
stringLocation = (LPBYTE)( XsSmbGetPointer( ¶meters->OutBuf )
|
|
+ SmbGetUshort( ¶meters->OutBufLen ) );
|
|
|
|
status = RapConvertSingleEntry(
|
|
(LPBYTE)&buffer,
|
|
Desc32_user_logoff_info_1,
|
|
FALSE,
|
|
(LPBYTE)XsSmbGetPointer( ¶meters->OutBuf ),
|
|
(LPBYTE)XsSmbGetPointer( ¶meters->OutBuf ),
|
|
Desc16_user_logoff_info_1,
|
|
TRUE,
|
|
&stringLocation,
|
|
&bytesRequired,
|
|
Response,
|
|
NativeToRap
|
|
);
|
|
|
|
if ( status != NERR_Success ) {
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetWkstaUserLogoff: RapConvertSingleEntry "
|
|
"failed: %X\n", status ));
|
|
}
|
|
|
|
Header->Status = NERR_InternalError;
|
|
goto cleanup;
|
|
}
|
|
|
|
IF_DEBUG(LOGON) {
|
|
NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR\n",
|
|
&buffer, SmbGetUlong( ¶meters->OutBuf ),
|
|
bytesRequired ));
|
|
}
|
|
|
|
//
|
|
// Determine return code based on the size of the buffer.
|
|
// The user_logoff_info_1 structure has no variable data to pack,
|
|
// but we do need to fill in the code field of the return structure.
|
|
//
|
|
|
|
if ( !XsCheckBufferSize(
|
|
SmbGetUshort( ¶meters->OutBufLen ),
|
|
Desc16_user_logoff_info_1,
|
|
FALSE // not in native format
|
|
)) {
|
|
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetWkstaUserLogoff: Buffer too small.\n" ));
|
|
}
|
|
Header->Status = NERR_BufTooSmall;
|
|
|
|
} else if ( bytesRequired > (DWORD)SmbGetUshort( ¶meters->OutBufLen )) {
|
|
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetWkstaUserLogoff: More data available.\n" ));
|
|
}
|
|
Header->Status = ERROR_MORE_DATA;
|
|
}
|
|
|
|
if ( SmbGetUshort( ¶meters->OutBufLen ) > sizeof(WORD)) {
|
|
|
|
logoffInfo = (PUSER_16_LOGOFF_INFO_1)XsSmbGetPointer(
|
|
¶meters->OutBuf );
|
|
SmbPutUshort( &logoffInfo->usrlogf1_code, VALID_LOGOFF );
|
|
}
|
|
|
|
//
|
|
// Set up the response parameters.
|
|
//
|
|
|
|
SmbPutUshort( ¶meters->TotalAvail, (WORD)bytesRequired );
|
|
|
|
cleanup:
|
|
;
|
|
} except ( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|
}
|
|
|
|
|
|
NetpMemoryFree( userName );
|
|
NetpMemoryFree( machineName );
|
|
|
|
//
|
|
// Determine return buffer size.
|
|
//
|
|
|
|
XsSetDataCount(
|
|
¶meters->OutBufLen,
|
|
Desc16_user_logoff_info_1,
|
|
Header->Converter,
|
|
1,
|
|
Header->Status
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // XsNetWkstaUserLogoff
|
|
|
|
|
|
NTSTATUS
|
|
XsNetWkstaUserLogon (
|
|
API_HANDLER_PARAMETERS
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine handles a call to NetWkstaUserLogon.
|
|
|
|
Arguments:
|
|
|
|
API_HANDLER_PARAMETERS - information about the API call. See
|
|
XsTypes.h for details.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - STATUS_SUCCESS or reason for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
NET_API_STATUS status;
|
|
PXS_NET_WKSTA_USER_LOGON parameters = Parameters;
|
|
LPWSTR machineName = NULL; // Native parameters
|
|
LPWSTR userName = NULL;
|
|
PNETLOGON_VALIDATION_UAS_INFO buffer = NULL;
|
|
|
|
LPBYTE stringLocation = NULL; // Conversion variables
|
|
DWORD bytesRequired = 0;
|
|
PWKSTA_16_USER_LOGON_REQUEST_1 usrLogonReq =
|
|
(PWKSTA_16_USER_LOGON_REQUEST_1)parameters->InBuf;
|
|
PUSER_16_LOGON_INFO_1 logonInfo;
|
|
|
|
|
|
API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
|
|
|
|
try {
|
|
//
|
|
// Translate parameters, check for errors.
|
|
//
|
|
|
|
XsConvertUnicodeTextParameter(
|
|
userName,
|
|
(LPSTR)( usrLogonReq->wlreq1_name )
|
|
);
|
|
|
|
XsConvertUnicodeTextParameter(
|
|
machineName,
|
|
(LPSTR)( usrLogonReq->wlreq1_workstation )
|
|
);
|
|
|
|
if ( SmbGetUshort( ¶meters->Level ) != 1 ) {
|
|
|
|
Header->Status = ERROR_INVALID_LEVEL;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Make sure the workstation name in the logon request is the
|
|
// name of the workstation from which the request came.
|
|
//
|
|
|
|
if ( wcscmp( machineName, Header->ClientMachineName ) ) {
|
|
|
|
Header->Status = (WORD)ERROR_ACCESS_DENIED;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Make the local call.
|
|
//
|
|
|
|
status = I_NetLogonUasLogon(
|
|
userName,
|
|
machineName,
|
|
&buffer
|
|
);
|
|
|
|
if ( !XsApiSuccess ( status )) {
|
|
|
|
IF_DEBUG(API_ERRORS) {
|
|
NetpKdPrint(( "XsNetWkstaUserLogon: I_NetLogonUasLogon failed: "
|
|
"%X\n", status));
|
|
}
|
|
Header->Status = (WORD) status;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Convert the structure returned by the 32-bit call to a 16-bit
|
|
// structure. The last possible location for variable data is
|
|
// calculated from buffer location and length.
|
|
//
|
|
|
|
stringLocation = (LPBYTE)( XsSmbGetPointer( ¶meters->OutBuf )
|
|
+ SmbGetUshort( ¶meters->OutBufLen ) );
|
|
|
|
status = RapConvertSingleEntry(
|
|
(LPBYTE)buffer,
|
|
Desc32_user_logon_info_1,
|
|
FALSE,
|
|
(LPBYTE)XsSmbGetPointer( ¶meters->OutBuf ),
|
|
(LPBYTE)XsSmbGetPointer( ¶meters->OutBuf ),
|
|
Desc16_user_logon_info_1,
|
|
TRUE,
|
|
&stringLocation,
|
|
&bytesRequired,
|
|
Response,
|
|
NativeToRap
|
|
);
|
|
|
|
if ( status != NERR_Success ) {
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetWkstaUserLogon: RapConvertSingleEntry "
|
|
"failed: %X\n", status ));
|
|
}
|
|
|
|
Header->Status = NERR_InternalError;
|
|
goto cleanup;
|
|
}
|
|
|
|
IF_DEBUG(LOGON) {
|
|
NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR\n",
|
|
buffer, SmbGetUlong( ¶meters->OutBuf ),
|
|
bytesRequired ));
|
|
}
|
|
|
|
//
|
|
// Determine return code based on the size of the buffer.
|
|
// The user_logoff_info_1 structure has no variable data to pack,
|
|
// but we do need to fill in the code field of the return structure.
|
|
//
|
|
|
|
if ( !XsCheckBufferSize(
|
|
SmbGetUshort( ¶meters->OutBufLen ),
|
|
Desc16_user_logon_info_1,
|
|
FALSE // not in native format
|
|
)) {
|
|
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetWkstaUserLogon: Buffer too small.\n" ));
|
|
}
|
|
Header->Status = NERR_BufTooSmall;
|
|
|
|
} else if ( bytesRequired > (DWORD)SmbGetUshort( ¶meters->OutBufLen )) {
|
|
|
|
IF_DEBUG(ERRORS) {
|
|
NetpKdPrint(( "XsNetWkstaUserLogoff: More data available.\n" ));
|
|
}
|
|
Header->Status = ERROR_MORE_DATA;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Pack the response data.
|
|
//
|
|
|
|
Header->Converter = XsPackReturnData(
|
|
(LPVOID)XsSmbGetPointer( ¶meters->OutBuf ),
|
|
SmbGetUshort( ¶meters->OutBufLen ),
|
|
Desc16_user_logon_info_1,
|
|
1
|
|
);
|
|
}
|
|
|
|
if ( SmbGetUshort( ¶meters->OutBufLen ) > sizeof(WORD)) {
|
|
|
|
logonInfo = (PUSER_16_LOGON_INFO_1)XsSmbGetPointer(
|
|
¶meters->OutBuf );
|
|
SmbPutUshort( &logonInfo->usrlog1_code, VALIDATED_LOGON );
|
|
}
|
|
|
|
//
|
|
// Set up the response parameters.
|
|
//
|
|
|
|
SmbPutUshort( ¶meters->TotalAvail, (WORD)bytesRequired );
|
|
|
|
cleanup:
|
|
;
|
|
} except ( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
|
|
}
|
|
|
|
|
|
NetpMemoryFree( userName );
|
|
NetpMemoryFree( machineName );
|
|
if ( buffer != NULL ) {
|
|
NetApiBufferFree( buffer );
|
|
}
|
|
|
|
//
|
|
// Determine return buffer size.
|
|
//
|
|
|
|
XsSetDataCount(
|
|
¶meters->OutBufLen,
|
|
Desc16_user_logon_info_1,
|
|
Header->Converter,
|
|
1,
|
|
Header->Status
|
|
);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
} // XsNetWkstaUserLogon
|