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.
917 lines
24 KiB
917 lines
24 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
austub.c
|
|
|
|
Abstract:
|
|
|
|
Local Security Authority AUTHENTICATION service client stubs.
|
|
|
|
Author:
|
|
|
|
Jim Kelly (JimK) 20-Feb-1991
|
|
|
|
Environment: Kernel or User Modes
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "lsadllp.h"
|
|
#include <string.h>
|
|
#include <zwapi.h>
|
|
|
|
#ifdef _NTSYSTEM_
|
|
//
|
|
// Unfortunately the security header files are just not at all constructed
|
|
// in a manner compatible with kernelmode. For some reason they are totally
|
|
// reliant on usermode header definitions. Just assume the text and const
|
|
// pragma's will work. If they don't work on an architecture, they can be
|
|
// fixed.
|
|
//
|
|
#pragma alloc_text(PAGE,LsaFreeReturnBuffer)
|
|
#pragma alloc_text(PAGE,LsaRegisterLogonProcess)
|
|
#pragma alloc_text(PAGE,LsaConnectUntrusted)
|
|
#pragma alloc_text(PAGE,LsaLookupAuthenticationPackage)
|
|
#pragma alloc_text(PAGE,LsaLogonUser)
|
|
#pragma alloc_text(PAGE,LsaCallAuthenticationPackage)
|
|
#pragma alloc_text(PAGE,LsaDeregisterLogonProcess)
|
|
//#pragma const_seg("PAGECONST")
|
|
#endif //_NTSYSTEM_
|
|
|
|
const WCHAR LsapEvent[] = L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED";
|
|
const WCHAR LsapPort[] = L"\\LsaAuthenticationPort";
|
|
|
|
|
|
NTSTATUS
|
|
LsaFreeReturnBuffer (
|
|
IN PVOID Buffer
|
|
)
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Some of the LSA authentication services allocate memory buffers to
|
|
hold returned information. This service is used to free those buffers
|
|
when no longer needed.
|
|
|
|
Arguments:
|
|
|
|
Buffer - Supplies a pointer to the return buffer to be freed.
|
|
|
|
Return Status:
|
|
|
|
STATUS_SUCCESS - Indicates the service completed successfully.
|
|
|
|
Others - returned by NtFreeVirtualMemory().
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
ULONG_PTR Length;
|
|
|
|
Length = 0;
|
|
Status = ZwFreeVirtualMemory(
|
|
NtCurrentProcess(),
|
|
&Buffer,
|
|
&Length,
|
|
MEM_RELEASE
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
LsaRegisterLogonProcess(
|
|
IN PSTRING LogonProcessName,
|
|
OUT PHANDLE LsaHandle,
|
|
OUT PLSA_OPERATIONAL_MODE SecurityMode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This service connects to the LSA server and verifies that the caller
|
|
is a legitimate logon process. this is done by ensuring the caller has
|
|
the SeTcbPrivilege privilege. It also opens the caller's process for
|
|
PROCESS_DUP_HANDLE access in anticipation of future LSA authentication
|
|
calls.
|
|
|
|
Arguments:
|
|
|
|
LogonProcessName - Provides a name string that identifies the logon
|
|
process. This should be a printable name suitable for display to
|
|
administrators. For example, "User32LogonProces" might be used
|
|
for the windows logon process name. No check is made to determine
|
|
whether the name is already in use. This name must NOT be longer
|
|
than 127 bytes long.
|
|
|
|
LsaHandle - Receives a handle which must be provided in future
|
|
authenticaiton services.
|
|
|
|
SecurityMode - The security mode the system is running under. This
|
|
value typically influences the logon user interface. For example,
|
|
a system running with password control will prompt for username
|
|
and passwords before bringing up the UI shell. One running without
|
|
password control would typically automatically bring up the UI shell
|
|
at system initialization.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The call completed successfully.
|
|
|
|
STATUS_PRIVILEGE_NOT_HELD - Indicates the caller does not have the
|
|
privilege necessary to act as a logon process. The SeTcbPrivilege
|
|
privilege is needed.
|
|
|
|
|
|
STATUS_NAME_TOO_LONG - The logon process name provided is too long.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status, IgnoreStatus;
|
|
UNICODE_STRING PortName, EventName;
|
|
LSAP_AU_REGISTER_CONNECT_INFO ConnectInfo;
|
|
ULONG ConnectInfoLength;
|
|
SECURITY_QUALITY_OF_SERVICE DynamicQos;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE EventHandle;
|
|
|
|
|
|
//
|
|
// Validate input parameters
|
|
//
|
|
|
|
if (LogonProcessName->Length > LSAP_MAX_LOGON_PROC_NAME_LENGTH) {
|
|
return STATUS_NAME_TOO_LONG;
|
|
}
|
|
|
|
|
|
//
|
|
// Wait for LSA to initialize...
|
|
//
|
|
|
|
|
|
RtlInitUnicodeString( &EventName, LsapEvent );
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&EventName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
Status = NtOpenEvent( &EventHandle, SYNCHRONIZE, &ObjectAttributes );
|
|
if (!NT_SUCCESS(Status)) {
|
|
return(Status);
|
|
}
|
|
|
|
Status = NtWaitForSingleObject( EventHandle, TRUE, NULL);
|
|
IgnoreStatus = NtClose( EventHandle );
|
|
if (!NT_SUCCESS(Status)) {
|
|
return(Status);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Set up the security quality of service parameters to use over the
|
|
// port. Use the most efficient (least overhead) - which is dynamic
|
|
// rather than static tracking.
|
|
//
|
|
|
|
DynamicQos.Length = sizeof( DynamicQos );
|
|
DynamicQos.ImpersonationLevel = SecurityImpersonation;
|
|
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
|
DynamicQos.EffectiveOnly = TRUE;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Set up the connection information to contain the logon process
|
|
// name.
|
|
//
|
|
|
|
ConnectInfoLength = sizeof(LSAP_AU_REGISTER_CONNECT_INFO);
|
|
strncpy(
|
|
ConnectInfo.LogonProcessName,
|
|
LogonProcessName->Buffer,
|
|
LogonProcessName->Length
|
|
);
|
|
ConnectInfo.LogonProcessNameLength = LogonProcessName->Length;
|
|
ConnectInfo.LogonProcessName[ConnectInfo.LogonProcessNameLength] = '\0';
|
|
|
|
|
|
//
|
|
// Connect to the LSA server
|
|
//
|
|
|
|
*LsaHandle = NULL;
|
|
RtlInitUnicodeString(&PortName,LsapPort);
|
|
Status = ZwConnectPort(
|
|
LsaHandle,
|
|
&PortName,
|
|
&DynamicQos,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ConnectInfo,
|
|
&ConnectInfoLength
|
|
);
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
//DbgPrint("LSA AU: Logon Process Register failed %lx\n",Status);
|
|
return Status;
|
|
}
|
|
|
|
if ( !NT_SUCCESS(ConnectInfo.CompletionStatus) ) {
|
|
//DbgPrint("LSA AU: Logon Process Register rejected %lx\n",ConnectInfo.CompletionStatus);
|
|
if ( LsaHandle && *LsaHandle != NULL ) {
|
|
ZwClose( *LsaHandle );
|
|
*LsaHandle = NULL;
|
|
}
|
|
}
|
|
|
|
(*SecurityMode) = ConnectInfo.SecurityMode;
|
|
|
|
return ConnectInfo.CompletionStatus;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
LsaConnectUntrusted(
|
|
OUT PHANDLE LsaHandle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This service connects to the LSA server and sets up an untrusted
|
|
connection. It does not check anything about the caller.
|
|
|
|
Arguments:
|
|
|
|
|
|
LsaHandle - Receives a handle which must be provided in future
|
|
authenticaiton services.
|
|
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - The call completed successfully.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status, IgnoreStatus;
|
|
UNICODE_STRING PortName, EventName;
|
|
LSAP_AU_REGISTER_CONNECT_INFO ConnectInfo;
|
|
ULONG ConnectInfoLength;
|
|
SECURITY_QUALITY_OF_SERVICE DynamicQos;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE EventHandle;
|
|
|
|
|
|
|
|
//
|
|
// Wait for LSA to initialize...
|
|
//
|
|
|
|
|
|
RtlInitUnicodeString( &EventName, LsapEvent );
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&EventName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
Status = NtOpenEvent( &EventHandle, SYNCHRONIZE, &ObjectAttributes );
|
|
if (!NT_SUCCESS(Status)) {
|
|
return(Status);
|
|
}
|
|
|
|
Status = NtWaitForSingleObject( EventHandle, TRUE, NULL);
|
|
IgnoreStatus = NtClose( EventHandle );
|
|
if (!NT_SUCCESS(Status)) {
|
|
return(Status);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Set up the security quality of service parameters to use over the
|
|
// port. Use the most efficient (least overhead) - which is dynamic
|
|
// rather than static tracking.
|
|
//
|
|
|
|
DynamicQos.ImpersonationLevel = SecurityImpersonation;
|
|
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
|
DynamicQos.EffectiveOnly = TRUE;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Set up the connection information to contain the logon process
|
|
// name.
|
|
//
|
|
|
|
ConnectInfoLength = sizeof(LSAP_AU_REGISTER_CONNECT_INFO);
|
|
RtlZeroMemory(
|
|
&ConnectInfo,
|
|
ConnectInfoLength
|
|
);
|
|
|
|
|
|
//
|
|
// Connect to the LSA server
|
|
//
|
|
|
|
RtlInitUnicodeString(&PortName,LsapPort);
|
|
Status = ZwConnectPort(
|
|
LsaHandle,
|
|
&PortName,
|
|
&DynamicQos,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ConnectInfo,
|
|
&ConnectInfoLength
|
|
);
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
//DbgPrint("LSA AU: Logon Process Register failed %lx\n",Status);
|
|
return Status;
|
|
}
|
|
|
|
if ( !NT_SUCCESS(ConnectInfo.CompletionStatus) ) {
|
|
//DbgPrint("LSA AU: Logon Process Register rejected %lx\n",ConnectInfo.CompletionStatus);
|
|
;
|
|
}
|
|
|
|
return ConnectInfo.CompletionStatus;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
LsaLookupAuthenticationPackage (
|
|
IN HANDLE LsaHandle,
|
|
IN PSTRING PackageName,
|
|
OUT PULONG AuthenticationPackage
|
|
)
|
|
|
|
/*++
|
|
|
|
Arguments:
|
|
|
|
LsaHandle - Supplies a handle obtained in a previous call to
|
|
LsaRegisterLogonProcess.
|
|
|
|
PackageName - Supplies a string which identifies the
|
|
Authentication Package. "MSV1.0" is the standard NT
|
|
authentication package name. The package name must not
|
|
exceed 127 bytes in length.
|
|
|
|
AuthenticationPackage - Receives an ID used to reference the
|
|
authentication package in subsequent authentication services.
|
|
|
|
Return Status:
|
|
|
|
STATUS_SUCCESS - Indicates the service completed successfully.
|
|
|
|
STATUS_NO_SUCH_PACKAGE - The specified authentication package is
|
|
unknown to the LSA.
|
|
|
|
STATUS_NAME_TOO_LONG - The authentication package name provided is too
|
|
long.
|
|
|
|
|
|
|
|
Routine Description:
|
|
|
|
This service is used to obtain the ID of an authentication package.
|
|
This ID may then be used in subsequent authentication services.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
LSAP_AU_API_MESSAGE Message = {0};
|
|
PLSAP_LOOKUP_PACKAGE_ARGS Arguments;
|
|
|
|
//
|
|
// Validate input parameters
|
|
//
|
|
|
|
if (PackageName->Length > LSAP_MAX_PACKAGE_NAME_LENGTH) {
|
|
return STATUS_NAME_TOO_LONG;
|
|
}
|
|
|
|
|
|
|
|
Arguments = &Message.Arguments.LookupPackage;
|
|
|
|
//
|
|
// Set arguments
|
|
//
|
|
|
|
strncpy(Arguments->PackageName, PackageName->Buffer, PackageName->Length);
|
|
Arguments->PackageNameLength = PackageName->Length;
|
|
Arguments->PackageName[Arguments->PackageNameLength] = '\0';
|
|
|
|
|
|
|
|
//
|
|
// Call the Local Security Authority Server.
|
|
//
|
|
|
|
Message.ApiNumber = LsapAuLookupPackageApi;
|
|
Message.PortMessage.u1.s1.DataLength = sizeof(*Arguments) + 8;
|
|
Message.PortMessage.u1.s1.TotalLength = sizeof(Message);
|
|
Message.PortMessage.u2.ZeroInit = 0L;
|
|
|
|
Status = ZwRequestWaitReplyPort(
|
|
LsaHandle,
|
|
(PPORT_MESSAGE) &Message,
|
|
(PPORT_MESSAGE) &Message
|
|
);
|
|
|
|
//
|
|
// Return the authentication package ID.
|
|
// If the call failed for any reason, this will be garbage,
|
|
// but who cares.
|
|
//
|
|
|
|
(*AuthenticationPackage) = Arguments->AuthenticationPackage;
|
|
|
|
|
|
if ( NT_SUCCESS(Status) ) {
|
|
Status = Message.ReturnedStatus;
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
//DbgPrint("LSA AU: Package Lookup Failed %lx\n",Status);
|
|
;
|
|
}
|
|
} else {
|
|
#if DBG
|
|
DbgPrint("LSA AU: Package Lookup NtRequestWaitReply Failed %lx\n",Status);
|
|
#else
|
|
;
|
|
#endif
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
LsaLogonUser (
|
|
IN HANDLE LsaHandle,
|
|
IN PSTRING OriginName,
|
|
IN SECURITY_LOGON_TYPE LogonType,
|
|
IN ULONG AuthenticationPackage,
|
|
IN PVOID AuthenticationInformation,
|
|
IN ULONG AuthenticationInformationLength,
|
|
IN PTOKEN_GROUPS LocalGroups OPTIONAL,
|
|
IN PTOKEN_SOURCE SourceContext,
|
|
OUT PVOID *ProfileBuffer,
|
|
OUT PULONG ProfileBufferLength,
|
|
OUT PLUID LogonId,
|
|
OUT PHANDLE Token,
|
|
OUT PQUOTA_LIMITS Quotas,
|
|
OUT PNTSTATUS SubStatus
|
|
)
|
|
|
|
/*++
|
|
|
|
Arguments:
|
|
|
|
LsaHandle - Supplies a handle obtained in a previous call to
|
|
LsaRegisterLogonProcess.
|
|
|
|
OriginName - Supplies a string which identifies the origin of the
|
|
logon attempt. For example, "TTY1" specify terminal 1, or
|
|
"LAN Manager - remote node JAZZ" might indicate a network
|
|
logon attempt via LAN Manager from a remote node called
|
|
"JAZZ".
|
|
|
|
LogonType - Identifies the type of logon being attempted. If the
|
|
type is Interactive or Batch then a PrimaryToken will be
|
|
generated to represent this new user. If the type is Network
|
|
then an impersonation token will be generated.
|
|
|
|
AuthenticationPackage - Supplies the ID of the authentication
|
|
package to use for the logon attempt. The standard
|
|
authentication package name for NT is called "MSV1.0".
|
|
|
|
AuthenticationInformation - Supplies the authentication
|
|
information specific to the authentication package. It is
|
|
expected to include identification and authentication
|
|
information such as user name and password.
|
|
|
|
AuthenticationInformationLength - Indicates the length of the
|
|
authentication information buffer.
|
|
|
|
LocalGroups - Optionally supplies a list of additional group
|
|
identifiers to add to the authenticated user's token. The
|
|
WORLD group will always be included in the token. A group
|
|
identifying the logon type (INTERACTIVE, NETWORK, BATCH) will
|
|
also automatically be included in the token.
|
|
|
|
SourceContext - Supplies information identifying the source
|
|
component (e.g., session manager) and context that may be
|
|
useful to that component. This information will be included
|
|
in the token and may later be retrieved.
|
|
|
|
ProfileBuffer - Receives a pointer to any returned profile and
|
|
accounting information about the logged on user's account.
|
|
This information is authentication package specific and
|
|
provides such information as the logon shell, home directory
|
|
and so forth. For an authentication package value of
|
|
"MSV1.0", a MSV1_0_PROFILE_DATA data structure is returned.
|
|
|
|
This buffer is allocated by this service and must be freed
|
|
using LsaFreeReturnBuffer() when no longer needed.
|
|
|
|
ProfileBufferLength - Receives the length (in bytes) of the
|
|
returned profile buffer.
|
|
|
|
LogonId - Points to a buffer which receives a LUID that uniquely
|
|
identifies this logon session. This LUID was assigned by the
|
|
domain controller which authenticated the logon information.
|
|
|
|
Token - Receives a handle to the new token created for this
|
|
authentication.
|
|
|
|
Quotas - When a primary token is returned, this parameter will be
|
|
filled in with process quota limits that are to be assigned
|
|
to the newly logged on user's initial process.
|
|
|
|
SubStatus - If the logon failed due to account restrictions, this
|
|
out parameter will receive an indication as to why the logon
|
|
failed. This value will only be set to a meaningful value if
|
|
the user has a legitimate account, but may not currently
|
|
logon for some reason. The substatus values for
|
|
authentication package "MSV1.0" are:
|
|
|
|
STATUS_INVALID_LOGON_HOURS
|
|
|
|
STATUS_INVALID_WORKSTATION
|
|
|
|
STATUS_PASSWORD_EXPIRED
|
|
|
|
STATUS_ACCOUNT_DISABLED
|
|
|
|
Return Status:
|
|
|
|
STATUS_SUCCESS - Indicates the service completed successfully.
|
|
|
|
STATUS_QUOTA_EXCEEDED - Indicates the caller does not have
|
|
enough quota to allocate the profile data being returned by
|
|
the authentication package.
|
|
|
|
STATUS_NO_LOGON_SERVERS - Indicates that no domain controllers
|
|
are currently able to service the authentication request.
|
|
|
|
STATUS_LOGON_FAILURE - Indicates the logon attempt failed. No
|
|
indication as to the reason for failure is given, but typical
|
|
reasons include mispelled usernames, mispelled passwords.
|
|
|
|
STATUS_ACCOUNT_RESTRICTION - Indicates the user account and
|
|
password were legitimate, but that the user account has some
|
|
restriction preventing successful logon at this time.
|
|
|
|
STATUS_NO_SUCH_PACKAGE - The specified authentication package is
|
|
unknown to the LSA.
|
|
|
|
STATUS_BAD_VALIDATION_CLASS - The authentication information
|
|
provided is not a validation class known to the specified
|
|
authentication package.
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to authenticate a user logon attempt. This is
|
|
used only for user's initial logon, necessary to gain access to NT
|
|
OS/2. Subsequent (supplementary) authentication requests must be done
|
|
using LsaCallAuthenticationPackage(). This service will cause a logon
|
|
session to be created to represent the new logon. It will also return
|
|
a token representing the newly logged on user.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
LSAP_AU_API_MESSAGE Message = {0};
|
|
PLSAP_LOGON_USER_ARGS Arguments;
|
|
|
|
Arguments = &Message.Arguments.LogonUser;
|
|
|
|
//
|
|
// Set arguments
|
|
//
|
|
|
|
Arguments->AuthenticationPackage = AuthenticationPackage;
|
|
Arguments->AuthenticationInformation = AuthenticationInformation;
|
|
Arguments->AuthenticationInformationLength = AuthenticationInformationLength;
|
|
Arguments->OriginName = (*OriginName);
|
|
Arguments->LogonType = LogonType;
|
|
Arguments->SourceContext = (*SourceContext);
|
|
|
|
Arguments->LocalGroups = LocalGroups;
|
|
if ( ARGUMENT_PRESENT(LocalGroups) ) {
|
|
Arguments->LocalGroupsCount = LocalGroups->GroupCount;
|
|
} else {
|
|
Arguments->LocalGroupsCount = 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Call the Local Security Authority Server.
|
|
//
|
|
|
|
Message.ApiNumber = LsapAuLogonUserApi;
|
|
Message.PortMessage.u1.s1.DataLength = sizeof(*Arguments) + 8;
|
|
Message.PortMessage.u1.s1.TotalLength = sizeof(Message);
|
|
Message.PortMessage.u2.ZeroInit = 0L;
|
|
|
|
Status = ZwRequestWaitReplyPort(
|
|
LsaHandle,
|
|
(PPORT_MESSAGE) &Message,
|
|
(PPORT_MESSAGE) &Message
|
|
);
|
|
|
|
//
|
|
// We may be returning bogus return values here, but it doesn't
|
|
// matter. They will just be ignored if an error occured.
|
|
//
|
|
|
|
(*SubStatus) = Arguments->SubStatus;
|
|
|
|
if ( NT_SUCCESS( Status ) )
|
|
{
|
|
Status = Message.ReturnedStatus ;
|
|
|
|
// Don't not clear the ProfileBuffer even in case of error, cause
|
|
// subauth packages need the ProfileBuffer.
|
|
*ProfileBuffer = Arguments->ProfileBuffer ;
|
|
*ProfileBufferLength = Arguments->ProfileBufferLength ;
|
|
|
|
if ( NT_SUCCESS( Status ) )
|
|
{
|
|
*LogonId = Arguments->LogonId ;
|
|
*Token = Arguments->Token ;
|
|
*Quotas = Arguments->Quotas ;
|
|
} else {
|
|
*Token = NULL;
|
|
}
|
|
|
|
} else {
|
|
|
|
*ProfileBuffer = NULL ;
|
|
*Token = NULL ;
|
|
}
|
|
|
|
return Status;
|
|
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
LsaCallAuthenticationPackage (
|
|
IN HANDLE LsaHandle,
|
|
IN ULONG AuthenticationPackage,
|
|
IN PVOID ProtocolSubmitBuffer,
|
|
IN ULONG SubmitBufferLength,
|
|
OUT PVOID *ProtocolReturnBuffer OPTIONAL,
|
|
OUT PULONG ReturnBufferLength OPTIONAL,
|
|
OUT PNTSTATUS ProtocolStatus OPTIONAL
|
|
)
|
|
|
|
/*++
|
|
|
|
Arguments:
|
|
|
|
LsaHandle - Supplies a handle obtained in a previous call to
|
|
LsaRegisterLogonProcess.
|
|
|
|
AuthenticationPackage - Supplies the ID of the authentication
|
|
package to use for the logon attempt. The standard
|
|
authentication package name for NT is called "MSV1.0".
|
|
|
|
ProtocolSubmitBuffer - Supplies a protocol message specific to
|
|
the authentication package.
|
|
|
|
SubmitBufferLength - Indicates the length of the submitted
|
|
protocol message buffer.
|
|
|
|
ProtocolReturnBuffer - Receives a pointer to a returned protocol
|
|
message whose format and semantics are specific to the
|
|
authentication package.
|
|
|
|
This buffer is allocated by this service and must be freed
|
|
using LsaFreeReturnBuffer() when no longer needed.
|
|
|
|
ReturnBufferLength - Receives the length (in bytes) of the
|
|
returned profile buffer.
|
|
|
|
ProtocolStatus - Assuming the services completion is
|
|
STATUS_SUCCESS, this parameter will receive completion status
|
|
returned by the specified authentication package. The list
|
|
of status values that may be returned are authentication
|
|
package specific.
|
|
|
|
Return Status:
|
|
|
|
STATUS_SUCCESS - The call was made to the authentication package.
|
|
The ProtocolStatus parameter must be checked to see what the
|
|
completion status from the authentication package is.
|
|
|
|
STATUS_QUOTA_EXCEEDED - This error indicates that the call could
|
|
not be completed because the client does not have sufficient
|
|
quota to allocate the return buffer.
|
|
|
|
STATUS_NO_SUCH_PACKAGE - The specified authentication package is
|
|
unknown to the LSA.
|
|
|
|
Routine Description:
|
|
|
|
This routine is used when a logon process needs to communicate with an
|
|
authentication package. There are several reasons why a logon process
|
|
may want to do this. Some examples are:
|
|
|
|
o To implement multi-message authentication protocols (such as
|
|
the LAN Manager Challenge-response protocol.
|
|
|
|
o To notify the authentication package of interesting state
|
|
change information, such as LAN Manager notifying the MSV1.0
|
|
package that a previously unreachable domain controller is
|
|
now reachable. In this example, the authentication package
|
|
would re-logon any users logged on to that domain controller.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
LSAP_AU_API_MESSAGE Message = {0};
|
|
PLSAP_CALL_PACKAGE_ARGS Arguments;
|
|
|
|
|
|
|
|
Arguments = &Message.Arguments.CallPackage;
|
|
|
|
//
|
|
// Set arguments
|
|
//
|
|
|
|
Arguments->AuthenticationPackage = AuthenticationPackage;
|
|
Arguments->ProtocolSubmitBuffer = ProtocolSubmitBuffer;
|
|
Arguments->SubmitBufferLength = SubmitBufferLength;
|
|
|
|
|
|
|
|
//
|
|
// Call the Local Security Authority Server.
|
|
//
|
|
|
|
Message.ApiNumber = LsapAuCallPackageApi;
|
|
Message.PortMessage.u1.s1.DataLength = sizeof(*Arguments) + 8;
|
|
Message.PortMessage.u1.s1.TotalLength = sizeof(Message);
|
|
Message.PortMessage.u2.ZeroInit = 0L;
|
|
|
|
Status = ZwRequestWaitReplyPort(
|
|
LsaHandle,
|
|
(PPORT_MESSAGE) &Message,
|
|
(PPORT_MESSAGE) &Message
|
|
);
|
|
|
|
//
|
|
// We may be returning bogus return values here, but it doesn't
|
|
// matter. They will just be ignored if an error occured.
|
|
//
|
|
|
|
if ( ProtocolReturnBuffer )
|
|
{
|
|
(*ProtocolReturnBuffer) = Arguments->ProtocolReturnBuffer;
|
|
}
|
|
|
|
if ( ReturnBufferLength )
|
|
{
|
|
(*ReturnBufferLength) = Arguments->ReturnBufferLength;
|
|
}
|
|
|
|
if ( ProtocolStatus )
|
|
{
|
|
(*ProtocolStatus) = Arguments->ProtocolStatus;
|
|
}
|
|
|
|
|
|
if ( NT_SUCCESS(Status) ) {
|
|
Status = Message.ReturnedStatus;
|
|
#if DBG
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
DbgPrint("LSA AU: Call Package Failed %lx\n",Status);
|
|
}
|
|
} else {
|
|
DbgPrint("LSA AU: Call Package Failed %lx\n",Status);
|
|
#endif //DBG
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
LsaDeregisterLogonProcess (
|
|
IN HANDLE LsaHandle
|
|
)
|
|
|
|
/*++
|
|
|
|
This function deletes the caller's logon process context.
|
|
|
|
|
|
--- WARNING ---
|
|
|
|
Logon Processes are part of the Trusted Computer Base, and,
|
|
as such, are expected to be debugged to a high degree. If
|
|
a logon process deregisters, we will believe it. This
|
|
allows us to re-use the old Logon Process context value.
|
|
If the Logon process accidently uses its context value
|
|
after freeing it, strange things may happen. LIkewise,
|
|
if a client calls to release a context that has already
|
|
been released, then LSA may grind to a halt.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
LsaHandle - Supplies a handle obtained in a previous call to
|
|
LsaRegisterLogonProcess.
|
|
|
|
|
|
Return Status:
|
|
|
|
STATUS_SUCCESS - Indicates the service completed successfully.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
LSAP_AU_API_MESSAGE Message = {0};
|
|
NTSTATUS TempStatus;
|
|
|
|
//
|
|
// Call the Local Security Authority Server.
|
|
//
|
|
|
|
Message.ApiNumber = LsapAuDeregisterLogonProcessApi;
|
|
Message.PortMessage.u1.s1.DataLength = 8;
|
|
Message.PortMessage.u1.s1.TotalLength = sizeof(Message);
|
|
Message.PortMessage.u2.ZeroInit = 0L;
|
|
|
|
Status = ZwRequestWaitReplyPort(
|
|
LsaHandle,
|
|
(PPORT_MESSAGE) &Message,
|
|
(PPORT_MESSAGE) &Message
|
|
);
|
|
|
|
TempStatus = ZwClose(LsaHandle);
|
|
ASSERT(NT_SUCCESS(TempStatus));
|
|
|
|
if ( NT_SUCCESS(Status) ) {
|
|
Status = Message.ReturnedStatus;
|
|
#if DBG
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
DbgPrint("LSA AU: DeRregisterLogonProcess Failed 0x%lx\n",Status);
|
|
}
|
|
} else {
|
|
DbgPrint("LSA AU: Package Lookup NtRequestWaitReply Failed 0x%lx\n",Status);
|
|
#endif
|
|
}
|
|
|
|
return Status;
|
|
}
|