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.
402 lines
14 KiB
402 lines
14 KiB
/*++ BUILD Version: 0009 // Increment this if a change has global effects
|
|
Copyright (c) 1987-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sessetup.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the Session setup related routines
|
|
|
|
Author:
|
|
|
|
Balan Sethu Raman (SethuR) 06-Mar-95 Created
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include <exsessup.h>
|
|
#include "ntlsapi.h"
|
|
#include "mrxsec.h"
|
|
|
|
NTSTATUS
|
|
BuildSessionSetupSecurityInformation(
|
|
PSMB_EXCHANGE pExchange,
|
|
PBYTE pSmbBuffer,
|
|
PULONG pSmbBufferSize)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine builds the security related information for the session setup SMB
|
|
|
|
Arguments:
|
|
|
|
pServer - the server instance
|
|
|
|
pSmbBuffer - the SMB buffer
|
|
|
|
pSmbBufferSize - the size of the buffer on input ( modified to size remaining on
|
|
output)
|
|
|
|
Return Value:
|
|
|
|
RXSTATUS - The return status for the operation
|
|
|
|
Notes:
|
|
|
|
Eventhough the genral structure of the code tries to isolate dialect specific issues
|
|
as much as possible this routine takes the opposite approach. This is because of the
|
|
preamble and prologue to security interaction which far outweigh the dialect specific
|
|
work required to be done. Therefore in the interests of a smaller footprint this approach
|
|
has been adopted.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS Status;
|
|
BOOLEAN fProcessAttached = FALSE;
|
|
|
|
UNICODE_STRING UserName;
|
|
UNICODE_STRING DomainName;
|
|
|
|
STRING CaseSensitiveResponse;
|
|
STRING CaseInsensitiveResponse;
|
|
|
|
PVOID pSecurityBlob;
|
|
USHORT SecurityBlobSize;
|
|
|
|
PSMBCE_SERVER pServer = &pExchange->SmbCeContext.pServerEntry->Server;
|
|
PSMBCE_SESSION pSession = &pExchange->SmbCeContext.pSessionEntry->Session;
|
|
|
|
SECURITY_RESPONSE_CONTEXT ResponseContext;
|
|
|
|
PAGED_CODE();
|
|
RxDbgTrace( +1, Dbg, ("BuildSessionSetupSecurityInformation -- Entry\n"));
|
|
|
|
// Attach to the redirector's FSP to allow us to call into the security impl.
|
|
if (PsGetCurrentProcess() != RxGetRDBSSProcess()) {
|
|
KeAttachProcess(RxGetRDBSSProcess());
|
|
|
|
fProcessAttached = TRUE;
|
|
}
|
|
|
|
if (pServer->DialectFlags & DF_EXTENDED_SECURITY) {
|
|
Status = BuildExtendedSessionSetupResponsePrologue(
|
|
pExchange,
|
|
&pSecurityBlob,
|
|
&SecurityBlobSize,
|
|
&ResponseContext);
|
|
} else {
|
|
Status = BuildNtLanmanResponsePrologue(
|
|
pExchange,
|
|
&UserName,
|
|
&DomainName,
|
|
&CaseSensitiveResponse,
|
|
&CaseInsensitiveResponse,
|
|
&ResponseContext);
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
PBYTE pBuffer = pSmbBuffer;
|
|
ULONG BufferSize = *pSmbBufferSize;
|
|
|
|
if ((pServer->Dialect == NTLANMAN_DIALECT) &&
|
|
(BooleanFlagOn(pServer->DialectFlags,DF_EXTENDED_SECURITY))) {
|
|
PREQ_NT_EXTENDED_SESSION_SETUP_ANDX pExtendedNtSessionSetupReq;
|
|
|
|
// Position the buffer for copying the security blob
|
|
pBuffer += FIELD_OFFSET(REQ_NT_EXTENDED_SESSION_SETUP_ANDX,Buffer);
|
|
BufferSize -= FIELD_OFFSET(REQ_NT_EXTENDED_SESSION_SETUP_ANDX,Buffer);
|
|
|
|
pExtendedNtSessionSetupReq = (PREQ_NT_EXTENDED_SESSION_SETUP_ANDX)pSmbBuffer;
|
|
|
|
SmbPutUshort(
|
|
&pExtendedNtSessionSetupReq->SecurityBlobLength,
|
|
SecurityBlobSize);
|
|
|
|
if (BufferSize >= SecurityBlobSize) {
|
|
RtlCopyMemory(
|
|
pBuffer,
|
|
pSecurityBlob,
|
|
SecurityBlobSize);
|
|
BufferSize -= SecurityBlobSize;
|
|
} else {
|
|
Status = STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
} else if (pServer->Dialect == NTLANMAN_DIALECT) {
|
|
PREQ_NT_SESSION_SETUP_ANDX pNtSessionSetupReq = (PREQ_NT_SESSION_SETUP_ANDX)pSmbBuffer;
|
|
|
|
// It it is a NT server both the case insensitive and case sensitive passwords
|
|
// need to be copied. for share-level, just copy a token 1-byte NULL password
|
|
|
|
// Position the buffer for copying the password.
|
|
pBuffer += FIELD_OFFSET(REQ_NT_SESSION_SETUP_ANDX,Buffer);
|
|
BufferSize -= FIELD_OFFSET(REQ_NT_SESSION_SETUP_ANDX,Buffer);
|
|
|
|
if (pServer->SecurityMode == SECURITY_MODE_USER_LEVEL){
|
|
|
|
RxDbgTrace( 0, Dbg, ("BuildSessionSetupSecurityInformation -- NtUserPasswords\n"));
|
|
|
|
SmbPutUshort(
|
|
&pNtSessionSetupReq->CaseInsensitivePasswordLength,
|
|
CaseInsensitiveResponse.Length);
|
|
|
|
SmbPutUshort(
|
|
&pNtSessionSetupReq->CaseSensitivePasswordLength,
|
|
CaseSensitiveResponse.Length);
|
|
|
|
Status = SmbPutString(
|
|
&pBuffer,
|
|
&CaseInsensitiveResponse,
|
|
&BufferSize);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
Status = SmbPutString(
|
|
&pBuffer,
|
|
&CaseSensitiveResponse,
|
|
&BufferSize);
|
|
}
|
|
} else {
|
|
|
|
RxDbgTrace( 0, Dbg, ("BuildSessionSetupSecurityInformation -- NtSharePasswords\n"));
|
|
|
|
SmbPutUshort(&pNtSessionSetupReq->CaseInsensitivePasswordLength, 1);
|
|
SmbPutUshort(&pNtSessionSetupReq->CaseSensitivePasswordLength, 1);
|
|
*pBuffer = 0;
|
|
*(pBuffer+1) = 0;
|
|
pBuffer += 2;
|
|
BufferSize -= 2;
|
|
}
|
|
} else {
|
|
PREQ_SESSION_SETUP_ANDX pSessionSetupReq = (PREQ_SESSION_SETUP_ANDX)pSmbBuffer;
|
|
|
|
// Position the buffer for copying the password.
|
|
pBuffer += FIELD_OFFSET(REQ_SESSION_SETUP_ANDX,Buffer);
|
|
BufferSize -= FIELD_OFFSET(REQ_SESSION_SETUP_ANDX,Buffer);
|
|
|
|
if (pServer->SecurityMode == SECURITY_MODE_USER_LEVEL) {
|
|
// For othe lanman servers only the case sensitive password is required.
|
|
SmbPutUshort(
|
|
&pSessionSetupReq->PasswordLength,
|
|
CaseSensitiveResponse.Length);
|
|
|
|
// Copy the password
|
|
Status = SmbPutString(
|
|
&pBuffer,
|
|
&CaseSensitiveResponse,
|
|
&BufferSize);
|
|
} else {
|
|
// Share level security. Send a null string for the password
|
|
SmbPutUshort(&pSessionSetupReq->PasswordLength,1);
|
|
*pBuffer++ = '\0';
|
|
BufferSize -= sizeof(CHAR);
|
|
}
|
|
}
|
|
|
|
// The User name and the domain name strings can be either copied from
|
|
// the information returned in the request response or the information
|
|
// that is already present in the session entry.
|
|
if (NT_SUCCESS(Status) &&
|
|
!BooleanFlagOn(pServer->DialectFlags,DF_EXTENDED_SECURITY)) {
|
|
if ((pServer->Dialect == NTLANMAN_DIALECT) &&
|
|
(pServer->NtServer.NtCapabilities & CAP_UNICODE)) {
|
|
// Copy the account/domain names as UNICODE strings
|
|
PBYTE pTempBuffer = pBuffer;
|
|
|
|
RxDbgTrace( 0, Dbg, ("BuildSessionSetupSecurityInformation -- account/domain as unicode\n"));
|
|
pBuffer = ALIGN_SMB_WSTR(pBuffer);
|
|
BufferSize -= (pBuffer - pTempBuffer);
|
|
|
|
Status = SmbPutUnicodeString(
|
|
&pBuffer,
|
|
&UserName,
|
|
&BufferSize);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
Status = SmbPutUnicodeString(
|
|
&pBuffer,
|
|
&DomainName,
|
|
&BufferSize);
|
|
|
|
}
|
|
} else {
|
|
// Copy the account/domain names as ASCII strings.
|
|
RxDbgTrace( 0, Dbg, ("BuildSessionSetupSecurityInformation -- account/domain as ascii\n"));
|
|
Status = SmbPutUnicodeStringAsOemString(
|
|
&pBuffer,
|
|
&UserName,
|
|
&BufferSize);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
Status = SmbPutUnicodeStringAsOemString(
|
|
&pBuffer,
|
|
&DomainName,
|
|
&BufferSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
*pSmbBufferSize = BufferSize;
|
|
}
|
|
}
|
|
|
|
// Free the buffer allocated by the security package.
|
|
if (pServer->DialectFlags & DF_EXTENDED_SECURITY) {
|
|
BuildExtendedSessionSetupResponseEpilogue(&ResponseContext);
|
|
} else {
|
|
BuildNtLanmanResponseEpilogue(&ResponseContext);
|
|
}
|
|
|
|
// Detach from the rdr process.
|
|
if (fProcessAttached) {
|
|
KeDetachProcess();
|
|
}
|
|
|
|
RxDbgTrace( -1, Dbg, ("BuildSessionSetupSecurityInformation -- Exit, status=%08lx\n",Status));
|
|
return Status;
|
|
}
|
|
NTSTATUS
|
|
BuildTreeConnectSecurityInformation(
|
|
PSMB_EXCHANGE pExchange,
|
|
PBYTE pBuffer,
|
|
PBYTE pPasswordLength,
|
|
PULONG pSmbBufferSize)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine builds the security related information for the session setup SMB
|
|
|
|
Arguments:
|
|
|
|
pServer - the server instance
|
|
|
|
pLogonId - the logon id. for which the session is being setup
|
|
|
|
pPassword - the user supplied password if any
|
|
|
|
pBuffer - the password buffer
|
|
|
|
pPasswordLength - where the password length is to be stored
|
|
|
|
pSmbBufferSize - the size of the buffer on input ( modified to size remaining on
|
|
output)
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - The return status for the operation
|
|
|
|
Notes:
|
|
|
|
Eventhough the genral structure of the code tries to isolate dialect specific issues
|
|
as much as possible this routine takes the opposite approach. This is because of the
|
|
preamble and prologue to security interaction which far outweigh the dialect specific
|
|
work required to be done. Therefore in the interests of a smaller footprint this approach
|
|
has been adopted.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS FinalStatus,Status;
|
|
BOOLEAN fProcessAttached = FALSE;
|
|
|
|
UNICODE_STRING UserName,DomainName;
|
|
STRING CaseSensitiveChallengeResponse,CaseInsensitiveChallengeResponse;
|
|
|
|
SECURITY_RESPONSE_CONTEXT ResponseContext;
|
|
|
|
ULONG PasswordLength = 0;
|
|
|
|
PSMBCE_SERVER pServer = &pExchange->SmbCeContext.pServerEntry->Server;
|
|
PSMBCE_SESSION pSession = &pExchange->SmbCeContext.pSessionEntry->Session;
|
|
|
|
PAGED_CODE();
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
if (pServer->EncryptPasswords) {
|
|
// Attach to the redirector's FSP to allow us to call into the securiy impl.
|
|
if (PsGetCurrentProcess() != RxGetRDBSSProcess()) {
|
|
KeAttachProcess(RxGetRDBSSProcess());
|
|
fProcessAttached = TRUE;
|
|
}
|
|
|
|
Status = BuildNtLanmanResponsePrologue(
|
|
pExchange,
|
|
&UserName,
|
|
&DomainName,
|
|
&CaseSensitiveChallengeResponse,
|
|
&CaseInsensitiveChallengeResponse,
|
|
&ResponseContext);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
if (FlagOn(pServer->DialectFlags,DF_MIXEDCASEPW)) {
|
|
RxDbgTrace( 0, Dbg, ("BuildTreeConnectSecurityInformation -- case sensitive password\n"));
|
|
// Copy the password length onto the SMB buffer
|
|
PasswordLength = CaseSensitiveChallengeResponse.Length;
|
|
|
|
// Copy the password
|
|
Status = SmbPutString(
|
|
&pBuffer,
|
|
&CaseSensitiveChallengeResponse,
|
|
pSmbBufferSize);
|
|
} else {
|
|
RxDbgTrace( 0, Dbg, ("BuildTreeConnectSecurityInformation -- case insensitive password\n"));
|
|
// Copy the password length onto the SMB buffer
|
|
PasswordLength = CaseInsensitiveChallengeResponse.Length;
|
|
|
|
// Copy the password
|
|
Status = SmbPutString(
|
|
&pBuffer,
|
|
&CaseInsensitiveChallengeResponse,
|
|
pSmbBufferSize);
|
|
}
|
|
|
|
BuildNtLanmanResponseEpilogue(&ResponseContext);
|
|
}
|
|
|
|
if (fProcessAttached) {
|
|
KeDetachProcess();
|
|
}
|
|
} else {
|
|
if (pSession->pPassword == NULL) {
|
|
// The logon password cannot be sent as plain text. Send a single blank as password.
|
|
|
|
PasswordLength = 2;
|
|
if (*pSmbBufferSize >= 2) {
|
|
*((PCHAR)pBuffer) = ' ';
|
|
pBuffer += sizeof(CHAR);
|
|
*((PCHAR)pBuffer) = '\0';
|
|
pBuffer += sizeof(CHAR);
|
|
Status = STATUS_SUCCESS;
|
|
} else {
|
|
Status = STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
} else {
|
|
OEM_STRING OemString;
|
|
|
|
OemString.Length = OemString.MaximumLength = (USHORT)(*pSmbBufferSize - sizeof(CHAR));
|
|
OemString.Buffer = pBuffer;
|
|
Status = RtlUnicodeStringToOemString(
|
|
&OemString,
|
|
pSession->pPassword,
|
|
FALSE);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
PasswordLength = OemString.Length+1;
|
|
}
|
|
}
|
|
|
|
// reduce the byte count
|
|
*pSmbBufferSize -= PasswordLength;
|
|
}
|
|
|
|
SmbPutUshort(pPasswordLength,(USHORT)PasswordLength);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|