769 lines
22 KiB
C
769 lines
22 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991-92 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
logonapi.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the Netlogon API RPC client stubs.
|
|||
|
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Cliff Van Dyke (CliffV) 27-Jun-1991
|
|||
|
|
|||
|
[Environment:]
|
|||
|
|
|||
|
User Mode - Win32
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
27-Jun-1991 CliffV
|
|||
|
Created
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
//
|
|||
|
// INCLUDES
|
|||
|
//
|
|||
|
|
|||
|
#include <nt.h>
|
|||
|
#include <ntrtl.h>
|
|||
|
|
|||
|
#include <rpc.h>
|
|||
|
#include <ntrpcp.h> // needed by rpcasync.h
|
|||
|
#include <rpcasync.h> // I_RpcExceptionFilter
|
|||
|
#include <logon_c.h>// includes lmcons.h, lmaccess.h, netlogon.h, ssi.h, windef.h
|
|||
|
|
|||
|
#include <crypt.h> // Encryption routines.
|
|||
|
#include <debuglib.h> // IF_DEBUG()
|
|||
|
#include <lmerr.h> // NERR_ and ERROR_ equates.
|
|||
|
#include <netdebug.h> // NetpKdPrint
|
|||
|
|
|||
|
|
|||
|
NET_API_STATUS NET_API_FUNCTION
|
|||
|
I_NetLogonUasLogon (
|
|||
|
IN LPWSTR UserName,
|
|||
|
IN LPWSTR Workstation,
|
|||
|
OUT PNETLOGON_VALIDATION_UAS_INFO *ValidationInformation
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function is called by the XACT server when processing a
|
|||
|
I_NetWkstaUserLogon XACT SMB. This feature allows a UAS client to
|
|||
|
logon to a SAM domain controller.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
UserName -- Account name of the user logging on.
|
|||
|
|
|||
|
Workstation -- The workstation from which the user is logging on.
|
|||
|
|
|||
|
ValidationInformation -- Returns the requested validation
|
|||
|
information.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
NERR_SUCCESS if there was no error. Otherwise, the error code is
|
|||
|
returned.
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NET_API_STATUS NetStatus;
|
|||
|
LPWSTR ServerName = NULL; // Not supported remotely
|
|||
|
|
|||
|
//
|
|||
|
// Do the RPC call with an exception handler since RPC will raise an
|
|||
|
// exception if anything fails. It is up to us to figure out what
|
|||
|
// to do once the exception is raised.
|
|||
|
//
|
|||
|
|
|||
|
RpcTryExcept {
|
|||
|
|
|||
|
*ValidationInformation = NULL; // Force RPC to allocate
|
|||
|
//
|
|||
|
// Call RPC version of the API.
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NetrLogonUasLogon(
|
|||
|
(LPWSTR) ServerName,
|
|||
|
UserName,
|
|||
|
Workstation,
|
|||
|
ValidationInformation );
|
|||
|
|
|||
|
} RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
|
|||
|
|
|||
|
NetStatus = RpcExceptionCode();
|
|||
|
|
|||
|
} RpcEndExcept;
|
|||
|
|
|||
|
IF_DEBUG( LOGON ) {
|
|||
|
NetpKdPrint(("NetrLogonUasLogon rc = %lu 0x%lx\n",
|
|||
|
NetStatus, NetStatus));
|
|||
|
}
|
|||
|
|
|||
|
return NetStatus;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NET_API_STATUS
|
|||
|
I_NetLogonUasLogoff (
|
|||
|
IN LPWSTR UserName,
|
|||
|
IN LPWSTR Workstation,
|
|||
|
OUT PNETLOGON_LOGOFF_UAS_INFO LogoffInformation
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function is called by the XACT server when processing a
|
|||
|
I_NetWkstaUserLogoff XACT SMB. This feature allows a UAS client to
|
|||
|
logoff from a SAM domain controller. The request is authenticated,
|
|||
|
the entry is removed for this user from the logon session table
|
|||
|
maintained by the Netlogon service for NetLogonEnum, and logoff
|
|||
|
information is returned to the caller.
|
|||
|
|
|||
|
The server portion of I_NetLogonUasLogoff (in the Netlogon service)
|
|||
|
compares the user name and workstation name specified in the
|
|||
|
LogonInformation with the user name and workstation name from the
|
|||
|
impersonation token. If they don't match, I_NetLogonUasLogoff fails
|
|||
|
indicating the access is denied.
|
|||
|
|
|||
|
Group SECURITY_LOCAL is refused access to this function. Membership
|
|||
|
in SECURITY_LOCAL implies that this call was made locally and not
|
|||
|
through the XACT server.
|
|||
|
|
|||
|
The Netlogon service cannot be sure that this function was called by
|
|||
|
the XACT server. Therefore, the Netlogon service will not simply
|
|||
|
delete the entry from the logon session table. Rather, the logon
|
|||
|
session table entry will be marked invisible outside of the Netlogon
|
|||
|
service (i.e., it will not be returned by NetLogonEnum) until a valid
|
|||
|
LOGON_WKSTINFO_RESPONSE is received for the entry. The Netlogon
|
|||
|
service will immediately interrogate the client (as described above
|
|||
|
for LOGON_WKSTINFO_RESPONSE) and temporarily increase the
|
|||
|
interrogation frequency to at least once a minute. The logon session
|
|||
|
table entry will reappear as soon as a function of interrogation if
|
|||
|
this isn't a true logoff request.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
UserName -- Account name of the user logging off.
|
|||
|
|
|||
|
Workstation -- The workstation from which the user is logging
|
|||
|
off.
|
|||
|
|
|||
|
LogoffInformation -- Returns the requested logoff information.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The Net status code.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NET_API_STATUS NetStatus;
|
|||
|
LPWSTR ServerName = NULL; // Not supported remotely
|
|||
|
|
|||
|
//
|
|||
|
// Do the RPC call with an exception handler since RPC will raise an
|
|||
|
// exception if anything fails. It is up to us to figure out what
|
|||
|
// to do once the exception is raised.
|
|||
|
//
|
|||
|
|
|||
|
RpcTryExcept {
|
|||
|
|
|||
|
//
|
|||
|
// Call RPC version of the API.
|
|||
|
//
|
|||
|
|
|||
|
NetStatus = NetrLogonUasLogoff(
|
|||
|
(LPWSTR) ServerName,
|
|||
|
UserName,
|
|||
|
Workstation,
|
|||
|
LogoffInformation );
|
|||
|
|
|||
|
} RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
|
|||
|
|
|||
|
NetStatus = RpcExceptionCode();
|
|||
|
|
|||
|
} RpcEndExcept;
|
|||
|
|
|||
|
IF_DEBUG( LOGON ) {
|
|||
|
NetpKdPrint(("NetrLogonUasLogoff rc = %lu 0x%lx\n",
|
|||
|
NetStatus, NetStatus));
|
|||
|
}
|
|||
|
|
|||
|
return NetStatus;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
I_NetLogonSamLogon (
|
|||
|
IN LPWSTR LogonServer OPTIONAL,
|
|||
|
IN LPWSTR ComputerName OPTIONAL,
|
|||
|
IN PNETLOGON_AUTHENTICATOR Authenticator OPTIONAL,
|
|||
|
OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator OPTIONAL,
|
|||
|
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
|
|||
|
IN LPBYTE LogonInformation,
|
|||
|
IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
|
|||
|
OUT LPBYTE * ValidationInformation,
|
|||
|
OUT PBOOLEAN Authoritative
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function is called by an NT client to process an interactive or
|
|||
|
network logon. This function passes a domain name, user name and
|
|||
|
credentials to the Netlogon service and returns information needed to
|
|||
|
build a token. It is called in three instances:
|
|||
|
|
|||
|
* It is called by the LSA's MSV1_0 authentication package for any
|
|||
|
NT system that has LanMan installed. The MSV1_0 authentication
|
|||
|
package calls SAM directly if LanMan is not installed. In this
|
|||
|
case, this function is a local function and requires the caller
|
|||
|
to have SE_TCB privilege. The local Netlogon service will
|
|||
|
either handle this request directly (validating the request with
|
|||
|
the local SAM database) or will forward this request to the
|
|||
|
appropriate domain controller as documented in sections 2.4 and
|
|||
|
2.5.
|
|||
|
|
|||
|
* It is called by a Netlogon service on a workstation to a DC in
|
|||
|
the Primary Domain of the workstation as documented in section
|
|||
|
2.4. In this case, this function uses a secure channel set up
|
|||
|
between the two Netlogon services.
|
|||
|
|
|||
|
* It is called by a Netlogon service on a DC to a DC in a trusted
|
|||
|
domain as documented in section 2.5. In this case, this
|
|||
|
function uses a secure channel set up between the two Netlogon
|
|||
|
services.
|
|||
|
|
|||
|
The Netlogon service validates the specified credentials. If they
|
|||
|
are valid, adds an entry for this LogonId, UserName, and Workstation
|
|||
|
into the logon session table. The entry is added to the logon
|
|||
|
session table only in the domain defining the specified user's
|
|||
|
account.
|
|||
|
|
|||
|
This service is also used to process a re-logon request.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
LogonServer -- Supplies the name of the logon server to process
|
|||
|
this logon request. This field should be null to indicate
|
|||
|
this is a call from the MSV1_0 authentication package to the
|
|||
|
local Netlogon service.
|
|||
|
|
|||
|
ComputerName -- Name of the machine making the call. This field
|
|||
|
should be null to indicate this is a call from the MSV1_0
|
|||
|
authentication package to the local Netlogon service.
|
|||
|
|
|||
|
Authenticator -- supplied by the client. This field should be
|
|||
|
null to indicate this is a call from the MSV1_0
|
|||
|
authentication package to the local Netlogon service.
|
|||
|
|
|||
|
ReturnAuthenticator -- Receives an authenticator returned by the
|
|||
|
server. This field should be null to indicate this is a call
|
|||
|
from the MSV1_0 authentication package to the local Netlogon
|
|||
|
service.
|
|||
|
|
|||
|
LogonLevel -- Specifies the level of information given in
|
|||
|
LogonInformation.
|
|||
|
|
|||
|
LogonInformation -- Specifies the description for the user
|
|||
|
logging on.
|
|||
|
|
|||
|
ValidationLevel -- Specifies the level of information returned in
|
|||
|
ValidationInformation. Must be NetlogonValidationSamInformation.
|
|||
|
|
|||
|
ValidationInformation -- Returns the requested validation
|
|||
|
information.
|
|||
|
|
|||
|
Authoritative -- Returns whether the status returned is an
|
|||
|
authoritative status which should be returned to the original
|
|||
|
caller. If not, this logon request may be tried again on another
|
|||
|
domain controller. This parameter is returned regardless of the
|
|||
|
status code.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_SUCCESS: if there was no error.
|
|||
|
|
|||
|
STATUS_NO_LOGON_SERVERS -- Either Pass-thru authentication or
|
|||
|
Trusted Domain Authentication could not contact the requested
|
|||
|
Domain Controller.
|
|||
|
|
|||
|
STATUS_INVALID_INFO_CLASS -- Either LogonLevel or ValidationLevel is
|
|||
|
invalid.
|
|||
|
|
|||
|
STATUS_INVALID_PARAMETER -- Another Parameter is invalid.
|
|||
|
|
|||
|
STATUS_ACCESS_DENIED -- The caller does not have access to call this
|
|||
|
API.
|
|||
|
|
|||
|
STATUS_NO_SUCH_USER -- Indicates that the user specified in
|
|||
|
LogonInformation does not exist. This status should not be returned
|
|||
|
to the originally caller. It should be mapped to STATUS_LOGON_FAILURE.
|
|||
|
|
|||
|
STATUS_WRONG_PASSWORD -- Indicates that the password information in
|
|||
|
LogonInformation was incorrect. This status should not be returned
|
|||
|
to the originally caller. It should be mapped to STATUS_LOGON_FAILURE.
|
|||
|
|
|||
|
STATUS_INVALID_LOGON_HOURES -- The user is not authorized to logon
|
|||
|
at this time.
|
|||
|
|
|||
|
STATUS_INVALID_WORKSTATION -- The user is not authorized to logon
|
|||
|
from the specified workstation.
|
|||
|
|
|||
|
STATUS_PASSWORD_EXPIRED -- The password for the user has expired.
|
|||
|
|
|||
|
STATUS_ACCOUNT_DISABLED -- The user's account has been disabled.
|
|||
|
|
|||
|
.
|
|||
|
.
|
|||
|
.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
NETLOGON_LEVEL RpcLogonInformation;
|
|||
|
NETLOGON_VALIDATION RpcValidationInformation;
|
|||
|
|
|||
|
//
|
|||
|
// Do the RPC call with an exception handler since RPC will raise an
|
|||
|
// exception if anything fails. It is up to us to figure out what
|
|||
|
// to do once the exception is raised.
|
|||
|
//
|
|||
|
|
|||
|
RpcTryExcept {
|
|||
|
|
|||
|
//
|
|||
|
// Call RPC version of the API.
|
|||
|
//
|
|||
|
|
|||
|
RpcLogonInformation.LogonInteractive =
|
|||
|
(PNETLOGON_INTERACTIVE_INFO) LogonInformation;
|
|||
|
|
|||
|
RpcValidationInformation.ValidationSam = NULL;
|
|||
|
|
|||
|
Status = NetrLogonSamLogon(
|
|||
|
LogonServer,
|
|||
|
ComputerName,
|
|||
|
Authenticator,
|
|||
|
ReturnAuthenticator,
|
|||
|
LogonLevel,
|
|||
|
&RpcLogonInformation,
|
|||
|
ValidationLevel,
|
|||
|
&RpcValidationInformation,
|
|||
|
Authoritative );
|
|||
|
|
|||
|
*ValidationInformation = (LPBYTE)
|
|||
|
RpcValidationInformation.ValidationSam;
|
|||
|
|
|||
|
} RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
|
|||
|
|
|||
|
*Authoritative = TRUE;
|
|||
|
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
|||
|
|
|||
|
} RpcEndExcept;
|
|||
|
|
|||
|
IF_DEBUG( LOGON ) {
|
|||
|
NetpKdPrint(("I_NetLogonSamLogon rc = %lu 0x%lx\n", Status, Status));
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
I_NetLogonSamLogonWithFlags (
|
|||
|
IN LPWSTR LogonServer OPTIONAL,
|
|||
|
IN LPWSTR ComputerName OPTIONAL,
|
|||
|
IN PNETLOGON_AUTHENTICATOR Authenticator OPTIONAL,
|
|||
|
OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator OPTIONAL,
|
|||
|
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
|
|||
|
IN LPBYTE LogonInformation,
|
|||
|
IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
|
|||
|
OUT LPBYTE * ValidationInformation,
|
|||
|
OUT PBOOLEAN Authoritative,
|
|||
|
IN OUT PULONG ExtraFlags
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Flag version of I_NetLogonSamLogon.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Same as I_NetLogonSamLogon except:
|
|||
|
|
|||
|
* ExtraFlags - Passes and returns a DWORD. For later expansion.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Same as I_NetLogonSamLogon.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
NETLOGON_LEVEL RpcLogonInformation;
|
|||
|
NETLOGON_VALIDATION RpcValidationInformation;
|
|||
|
|
|||
|
//
|
|||
|
// Do the RPC call with an exception handler since RPC will raise an
|
|||
|
// exception if anything fails. It is up to us to figure out what
|
|||
|
// to do once the exception is raised.
|
|||
|
//
|
|||
|
|
|||
|
RpcTryExcept {
|
|||
|
|
|||
|
//
|
|||
|
// Call RPC version of the API.
|
|||
|
//
|
|||
|
|
|||
|
RpcLogonInformation.LogonInteractive =
|
|||
|
(PNETLOGON_INTERACTIVE_INFO) LogonInformation;
|
|||
|
|
|||
|
RpcValidationInformation.ValidationSam = NULL;
|
|||
|
|
|||
|
Status = NetrLogonSamLogonWithFlags(
|
|||
|
LogonServer,
|
|||
|
ComputerName,
|
|||
|
Authenticator,
|
|||
|
ReturnAuthenticator,
|
|||
|
LogonLevel,
|
|||
|
&RpcLogonInformation,
|
|||
|
ValidationLevel,
|
|||
|
&RpcValidationInformation,
|
|||
|
Authoritative,
|
|||
|
ExtraFlags );
|
|||
|
|
|||
|
*ValidationInformation = (LPBYTE)
|
|||
|
RpcValidationInformation.ValidationSam;
|
|||
|
|
|||
|
} RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
|
|||
|
|
|||
|
*Authoritative = TRUE;
|
|||
|
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
|||
|
|
|||
|
} RpcEndExcept;
|
|||
|
|
|||
|
IF_DEBUG( LOGON ) {
|
|||
|
NetpKdPrint(("I_NetLogonSamLogonWithFlags rc = %lu 0x%lx\n", Status, Status));
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
I_NetLogonSamLogonEx (
|
|||
|
IN PVOID ContextHandle,
|
|||
|
IN LPWSTR LogonServer OPTIONAL,
|
|||
|
IN LPWSTR ComputerName OPTIONAL,
|
|||
|
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
|
|||
|
IN LPBYTE LogonInformation,
|
|||
|
IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
|
|||
|
OUT LPBYTE * ValidationInformation,
|
|||
|
OUT PBOOLEAN Authoritative,
|
|||
|
IN OUT PULONG ExtraFlags,
|
|||
|
OUT PBOOLEAN RpcFailed
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Concurrent API version of I_NetLogonSamLogon.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Same as I_NetLogonSamLogon except:
|
|||
|
|
|||
|
* No authenticator parameters.
|
|||
|
|
|||
|
* Context Handle parameter
|
|||
|
|
|||
|
* ExtraFlags - Passes and returns a DWORD. For later expansion.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Same as I_NetLogonSamLogon.
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
NETLOGON_LEVEL RpcLogonInformation;
|
|||
|
NETLOGON_VALIDATION RpcValidationInformation;
|
|||
|
*RpcFailed = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Do the RPC call with an exception handler since RPC will raise an
|
|||
|
// exception if anything fails. It is up to us to figure out what
|
|||
|
// to do once the exception is raised.
|
|||
|
//
|
|||
|
|
|||
|
RpcTryExcept {
|
|||
|
|
|||
|
//
|
|||
|
// Call RPC version of the API.
|
|||
|
//
|
|||
|
|
|||
|
RpcLogonInformation.LogonInteractive =
|
|||
|
(PNETLOGON_INTERACTIVE_INFO) LogonInformation;
|
|||
|
|
|||
|
RpcValidationInformation.ValidationSam = NULL;
|
|||
|
|
|||
|
Status = NetrLogonSamLogonEx(
|
|||
|
ContextHandle,
|
|||
|
LogonServer,
|
|||
|
ComputerName,
|
|||
|
LogonLevel,
|
|||
|
&RpcLogonInformation,
|
|||
|
ValidationLevel,
|
|||
|
&RpcValidationInformation,
|
|||
|
Authoritative,
|
|||
|
ExtraFlags );
|
|||
|
|
|||
|
*ValidationInformation = (LPBYTE)
|
|||
|
RpcValidationInformation.ValidationSam;
|
|||
|
|
|||
|
} RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
|
|||
|
|
|||
|
*Authoritative = TRUE;
|
|||
|
*RpcFailed = TRUE;
|
|||
|
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
|||
|
|
|||
|
} RpcEndExcept;
|
|||
|
|
|||
|
IF_DEBUG( LOGON ) {
|
|||
|
NetpKdPrint(("I_NetLogonSamLogonEx rc = %lu 0x%lx\n", Status, Status));
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS NET_API_FUNCTION
|
|||
|
I_NetLogonSamLogoff (
|
|||
|
IN LPWSTR LogonServer OPTIONAL,
|
|||
|
IN LPWSTR ComputerName OPTIONAL,
|
|||
|
IN PNETLOGON_AUTHENTICATOR Authenticator OPTIONAL,
|
|||
|
OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator OPTIONAL,
|
|||
|
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
|
|||
|
IN LPBYTE LogonInformation
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function is called by an NT client to process an interactive
|
|||
|
logoff. It is not called for the network logoff case since the
|
|||
|
Netlogon service does not maintain any context for network logons.
|
|||
|
|
|||
|
This function does the following. It authenticates the request. It
|
|||
|
updates the logon statistics in the SAM database on whichever machine
|
|||
|
or domain defines this user account. It updates the logon session
|
|||
|
table in the primary domain of the machine making the request. And
|
|||
|
it returns logoff information to the caller.
|
|||
|
|
|||
|
This function is called in same scenarios that I_NetLogonSamLogon is
|
|||
|
called:
|
|||
|
|
|||
|
* It is called by the LSA's MSV1_0 authentication package to
|
|||
|
support LsaApLogonTerminated. In this case, this function is a
|
|||
|
local function and requires the caller to have SE_TCB privilege.
|
|||
|
The local Netlogon service will either handle this request
|
|||
|
directly (if LogonDomainName indicates this request was
|
|||
|
validated locally) or will forward this request to the
|
|||
|
appropriate domain controller as documented in sections 2.4 and
|
|||
|
2.5.
|
|||
|
|
|||
|
* It is called by a Netlogon service on a workstation to a DC in
|
|||
|
the Primary Domain of the workstation as documented in section
|
|||
|
2.4. In this case, this function uses a secure channel set up
|
|||
|
between the two Netlogon services.
|
|||
|
|
|||
|
* It is called by a Netlogon service on a DC to a DC in a trusted
|
|||
|
domain as documented in section 2.5. In this case, this
|
|||
|
function uses a secure channel set up between the two Netlogon
|
|||
|
services.
|
|||
|
|
|||
|
When this function is a remote function, it is sent to the DC over a
|
|||
|
NULL session.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
LogonServer -- Supplies the name of the logon server which logged
|
|||
|
this user on. This field should be null to indicate this is
|
|||
|
a call from the MSV1_0 authentication package to the local
|
|||
|
Netlogon service.
|
|||
|
|
|||
|
ComputerName -- Name of the machine making the call. This field
|
|||
|
should be null to indicate this is a call from the MSV1_0
|
|||
|
authentication package to the local Netlogon service.
|
|||
|
|
|||
|
Authenticator -- supplied by the client. This field should be
|
|||
|
null to indicate this is a call from the MSV1_0
|
|||
|
authentication package to the local Netlogon service.
|
|||
|
|
|||
|
ReturnAuthenticator -- Receives an authenticator returned by the
|
|||
|
server. This field should be null to indicate this is a call
|
|||
|
from the MSV1_0 authentication package to the local Netlogon
|
|||
|
service.
|
|||
|
|
|||
|
LogonLevel -- Specifies the level of information given in
|
|||
|
LogonInformation.
|
|||
|
|
|||
|
LogonInformation -- Specifies the logon domain name, logon Id,
|
|||
|
user name and workstation name of the user logging off.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
NETLOGON_LEVEL RpcLogonInformation;
|
|||
|
|
|||
|
//
|
|||
|
// Do the RPC call with an exception handler since RPC will raise an
|
|||
|
// exception if anything fails. It is up to us to figure out what
|
|||
|
// to do once the exception is raised.
|
|||
|
//
|
|||
|
|
|||
|
RpcTryExcept {
|
|||
|
|
|||
|
//
|
|||
|
// Call RPC version of the API.
|
|||
|
//
|
|||
|
|
|||
|
RpcLogonInformation.LogonInteractive =
|
|||
|
(PNETLOGON_INTERACTIVE_INFO) LogonInformation;
|
|||
|
|
|||
|
Status = NetrLogonSamLogoff(
|
|||
|
LogonServer,
|
|||
|
ComputerName,
|
|||
|
Authenticator,
|
|||
|
ReturnAuthenticator,
|
|||
|
LogonLevel,
|
|||
|
&RpcLogonInformation );
|
|||
|
|
|||
|
} RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
|
|||
|
|
|||
|
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
|||
|
|
|||
|
} RpcEndExcept;
|
|||
|
|
|||
|
IF_DEBUG( LOGON ) {
|
|||
|
NetpKdPrint(("I_NetLogonSamLogoff rc = %lu 0x%lx\n", Status, Status));
|
|||
|
}
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS NET_API_FUNCTION
|
|||
|
I_NetLogonSendToSam (
|
|||
|
IN LPWSTR PrimaryName OPTIONAL,
|
|||
|
IN LPWSTR ComputerName,
|
|||
|
IN PNETLOGON_AUTHENTICATOR Authenticator,
|
|||
|
OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator,
|
|||
|
IN LPBYTE OpaqueBuffer,
|
|||
|
IN ULONG OpaqueBufferSize
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function sends an opaque buffer from SAM on a BDC to SAM on the PDC.
|
|||
|
|
|||
|
The original use of this routine will be to allow the BDC to forward user
|
|||
|
account password changes to the PDC.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
PrimaryName -- Computer name of the PDC to remote the call to.
|
|||
|
|
|||
|
ComputerName -- Name of the machine making the call.
|
|||
|
|
|||
|
Authenticator -- supplied by the client.
|
|||
|
|
|||
|
ReturnAuthenticator -- Receives an authenticator returned by the
|
|||
|
server.
|
|||
|
|
|||
|
OpaqueBuffer - Buffer to be passed to the SAM service on the PDC.
|
|||
|
The buffer will be encrypted on the wire.
|
|||
|
|
|||
|
OpaqueBufferSize - Size (in bytes) of OpaqueBuffer.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_SUCCESS: Message successfully sent to PDC
|
|||
|
|
|||
|
STATUS_NO_MEMORY: There is not enough memory to complete the operation
|
|||
|
|
|||
|
STATUS_NO_SUCH_DOMAIN: DomainName does not correspond to a hosted domain
|
|||
|
|
|||
|
STATUS_NO_LOGON_SERVERS: PDC is not currently available
|
|||
|
|
|||
|
STATUS_NOT_SUPPORTED: PDC does not support this operation
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
//
|
|||
|
// Do the RPC call with an exception handler since RPC will raise an
|
|||
|
// exception if anything fails. It is up to us to figure out what
|
|||
|
// to do once the exception is raised.
|
|||
|
//
|
|||
|
|
|||
|
RpcTryExcept {
|
|||
|
|
|||
|
//
|
|||
|
// Call RPC version of the API.
|
|||
|
//
|
|||
|
|
|||
|
Status = NetrLogonSendToSam(
|
|||
|
PrimaryName,
|
|||
|
ComputerName,
|
|||
|
Authenticator,
|
|||
|
ReturnAuthenticator,
|
|||
|
OpaqueBuffer,
|
|||
|
OpaqueBufferSize );
|
|||
|
|
|||
|
} RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
|
|||
|
|
|||
|
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
|||
|
|
|||
|
} RpcEndExcept;
|
|||
|
|
|||
|
IF_DEBUG( LOGON ) {
|
|||
|
NetpKdPrint(("I_NetLogonSendToSam rc = %lu 0x%lx\n", Status, Status));
|
|||
|
}
|
|||
|
return Status;
|
|||
|
}
|