summaryrefslogtreecommitdiffstats
path: root/private/net/svcdlls/ntlmssp/server/api.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/net/svcdlls/ntlmssp/server/api.c')
-rw-r--r--private/net/svcdlls/ntlmssp/server/api.c859
1 files changed, 859 insertions, 0 deletions
diff --git a/private/net/svcdlls/ntlmssp/server/api.c b/private/net/svcdlls/ntlmssp/server/api.c
new file mode 100644
index 000000000..c58706dde
--- /dev/null
+++ b/private/net/svcdlls/ntlmssp/server/api.c
@@ -0,0 +1,859 @@
+/*++
+
+Copyright (c) 1993 Microsoft Corporation
+
+Module Name:
+
+ api.c
+
+Abstract:
+
+ NtLmSsp Service API dispatch routines.
+
+Author:
+
+ Cliff Van Dyke (CliffV) 26-Jun-1993
+
+Revision History:
+
+--*/
+
+
+//
+// Common include files.
+//
+
+#include <ntlmssps.h> // Include files common to server side of service
+
+//
+// Include files specific to this .c file
+//
+
+SECURITY_STATUS
+SspApiAcquireCredentialHandle(
+ IN PSSP_CLIENT_CONNECTION ClientConnection,
+ IN OUT PSSP_API_MESSAGE Message
+ )
+
+/*++
+
+Routine Description:
+
+
+ This API allows applications to acquire a handle to pre-existing
+ credentials associated with the user on whose behalf the call is made
+ i.e. under the identity this application is running. These pre-existing
+ credentials have been established through a system logon not described
+ here. Note that this is different from "login to the network" and does
+ not imply gathering of credentials.
+
+
+ This API returns a handle to the credentials of a principal (user, client)
+ as used by a specific security package. This handle can then be used
+ in subsequent calls to the Context APIs. This API will not let a
+ process obtain a handle to credentials that are not related to the
+ process; i.e. we won't allow a process to grab the credentials of
+ another user logged into the same machine. There is no way for us
+ to determine if a process is a trojan horse or not, if it is executed
+ by the user.
+
+Arguments:
+
+ ClientConnection - Describes the client process.
+
+ Message - Message from the caller. Returns the response to be passed to
+ the caller. The message contains all of the following fields:
+
+
+ PrincipalName - Name of the principal for whose credentials the handle
+ will reference. Note, if the process requesting the handle does
+ not have access to the credentials, an error will be returned.
+ A null string indicates that the process wants a handle to the
+ credentials of the user under whose security it is executing.
+
+ PackageName - Name of the package with which these credentials will
+ be used.
+
+ CredentialUseFlags - Flags indicating the way with which these
+ credentials will be used.
+
+ #define CRED_INBOUND 0x00000001
+ #define CRED_OUTBOUND 0x00000002
+ #define CRED_BOTH 0x00000003
+
+ The credentials created with CRED_INBOUND option can only be used
+ for (validating incoming calls and can not be used for making accesses.
+
+ LogonId - Pointer to NT style Logon Id which is a LUID. (Provided for
+ file system ; processes such as network redirectors.)
+
+ CredentialHandle - Returned credential handle.
+
+ Lifetime - Time that these credentials expire. The value returned in
+ this field depends on the security package.
+
+Return Value:
+
+ STATUS_SUCCESS -- Call completed successfully
+
+ SEC_E_INSUFFICIENT_MEMORY -- Not enough memory
+ SEC_E_PRINCIPAL_UNKNOWN -- No such principal
+ SEC_E_NOT_OWNER -- caller does not own the specified credentials
+
+--*/
+
+{
+ SECURITY_STATUS SecStatus;
+ PSSP_ACQUIRE_CREDENTIAL_HANDLE_ARGS Args;
+ HANDLE ClientTokenHandle = NULL;
+ LUID LogonId;
+
+ //
+ // Simply call the worker routine.
+ //
+
+ Args = &Message->Arguments.AcquireCredentialHandleArgs;
+
+
+ SecStatus = SspLpcGetLogonId(
+ ClientConnection,
+ Message,
+ &LogonId,
+ &ClientTokenHandle
+ );
+
+ if ( !NT_SUCCESS(SecStatus) ) {
+ SspPrint(( SSP_API,
+ "SspApiAcquireCredentialHandle: "
+ "GetLogonId returns 0x%lx\n",
+ SecStatus ));
+ } else {
+
+ SecStatus = SsprAcquireCredentialHandle(
+ ClientConnection,
+ &ClientTokenHandle,
+ &LogonId,
+ Args->CredentialUseFlags,
+ &Args->CredentialHandle,
+ &Args->Lifetime,
+ Args->DomainName,
+ Args->DomainNameSize,
+ Args->UserName,
+ Args->UserNameSize,
+ Args->Password,
+ Args->PasswordSize );
+ }
+
+ if ( ClientTokenHandle != NULL) {
+ NtClose(ClientTokenHandle);
+ }
+ return SecStatus;
+
+}
+
+SECURITY_STATUS
+SspApiFreeCredentialHandle(
+ IN PSSP_CLIENT_CONNECTION ClientConnection,
+ IN OUT PSSP_API_MESSAGE Message
+ )
+
+/*++
+
+
+ This API is used to notify the security system that the credentials are
+ no longer needed and allows the application to free the handle acquired
+ in the call described above. When all references to this credential
+ set has been removed then the credentials may themselves be removed.
+
+Arguments:
+
+ ClientConnection - Describes the client process.
+
+ Message - Message from the caller. Returns the response to be passed to
+ the caller. The message contains all of the following fields:
+
+ CredentialHandle - Credential Handle obtained through
+ AcquireCredentialHandle.
+
+Return Value:
+
+ STATUS_SUCCESS -- Call completed successfully
+
+ SEC_E_INVALID_HANDLE -- Credential Handle is invalid
+
+--*/
+
+{
+ SECURITY_STATUS SecStatus;
+ PSSP_FREE_CREDENTIAL_HANDLE_ARGS Args;
+
+ //
+ // Simply call the worker routine.
+ //
+
+ Args = &Message->Arguments.FreeCredentialHandleArgs;
+
+
+ SecStatus = SsprFreeCredentialHandle(
+ ClientConnection,
+ &Args->CredentialHandle );
+
+ return SecStatus;
+}
+
+
+SECURITY_STATUS
+SspApiInitializeSecurityContext(
+ IN PSSP_CLIENT_CONNECTION ClientConnection,
+ IN OUT PSSP_API_MESSAGE Message
+ )
+
+/*++
+
+Routine Description:
+
+ This routine initiates the outbound security context from a credential
+ handle. This results in the establishment of a security context
+ between the application and a remote peer. The routine returns a token
+ which must be passed to the remote peer which in turn submits it to the
+ local security implementation via the AcceptSecurityContext() call.
+ The token generated should be considered opaque by all callers.
+
+ This function is used by a client to initialize an outbound context.
+ For a two leg security package, the calling sequence is as follows: The
+ client calls the function with OldContextHandle set to NULL and
+ InputToken set either to NULL or to a pointer to a security package
+ specific data structure. The package returns a context handle in
+ NewContextHandle and a token in OutputToken. The handle can then be
+ used for message APIs if desired.
+
+ The OutputToken returned here is sent across to target server which
+ calls AcceptSecuirtyContext() with this token as an input argument and
+ may receive a token which is returned to the initiator so it can call
+ InitializeSecurityContext() again.
+
+ For a three leg (mutual authentication) security package, the calling
+ sequence is as follows: The client calls the function as above, but the
+ package will return SEC_I_CALLBACK_NEEDED. The client then sends the
+ output token to the server and waits for the server's reply. Upon
+ receipt of the server's response, the client calls this function again,
+ with OldContextHandle set to the handle that was returned from the
+ first call. The token received from the server is supplied in the
+ InputToken parameter. If the server has successfully responded, then
+ the package will respond with success, or it will invalidate the
+ context.
+
+ Initialization of security context may require more than one call to
+ this function depending upon the underlying authentication mechanism as
+ well as the "choices" indicated via ContextReqFlags. The
+ ContextReqFlags and ContextAttributes are bit masks representing
+ various context level functions viz. delegation, mutual
+ authentication, confidentiality, replay detection and sequence
+ detection.
+
+ When ISC_REQ_PROMPT_FOR_CREDS flag is set the security package always
+ prompts the user for credentials, irrespective of whether credentials
+ are present or not. If user indicated that the supplied credentials be
+ used then they will be stashed (overwriting existing ones if any) for
+ future use. The security packages will always prompt for credentials
+ if none existed, this optimizes for the most common case before a
+ credentials database is built. But the security packages can be
+ configured to not do that. Security packages will ensure that they
+ only prompt to the interactive user, for other logon sessions, this
+ flag is ignored.
+
+ When ISC_REQ_USE_SUPPLIED_CREDS flag is set the security package always
+ uses the credentials supplied in the InitializeSecurityContext() call
+ via InputToken parameter. If the package does not have any credentials
+ available it will prompt for them and record it as indicated above.
+
+ It is an error to set both these flags simultaneously.
+
+ If the ISC_REQ_ALLOCATE_MEMORY was specified then the caller must free
+ the memory pointed to by OutputToken by calling FreeContextBuffer().
+
+ For example, the InputToken may be the challenge from a LAN Manager or
+ NT file server. In this case, the OutputToken would be the NTLM
+ encrypted response to the challenge. The caller of this API can then
+ take the appropriate response (case-sensitive v. case-insensitive) and
+ return it to the server for an authenticated connection.
+
+
+
+Arguments:
+
+ ClientConnection - Describes the client process.
+
+ Message - Message from the caller. Returns the response to be passed to
+ the caller. The message contains all of the following fields:
+
+ CredentialHandle - Handle to the credentials to be used to
+ create the context.
+
+ ContextHandle - On input, the handle to the partially formed context, if this is
+ a second call (see above) or NULL if this is the first call.
+
+ On output, new context handle. If this is a second call, this
+ can be the same as phContext.
+
+ ContextReqFlags - Requirements of the context, package specific.
+
+ #define ISC_REQ_DELEGATE 0x00000001
+ #define ISC_REQ_MUTUAL_AUTH 0x00000002
+ #define ISC_REQ_REPLAY_DETECT 0x00000004
+ #define ISC_REQ_SEQUENCE_DETECT 0x00000008
+ #define ISC_REQ_CONFIDENTIALITY 0x00000010
+ #define ISC_REQ_USE_SESSION_KEY 0x00000020
+ #define ISC_REQ_PROMT_FOR__CREDS 0x00000040
+ #define ISC_REQ_USE_SUPPLIED_CREDS 0x00000080
+ #define ISC_REQ_ALLOCATE_MEMORY 0x00000100
+ #define ISC_REQ_USE_DCE_STYLE 0x00000200
+
+ InputTokenSize - Size of the input token, in bytes.
+
+ InputToken - Pointer to the input token. In the first call this
+ token can either be NULL or may contain security package specific
+ information.
+
+ OutputTokenSize - Size of the output token, in bytes.
+
+ OutputToken - Buffer to receive the output token.
+
+ ContextAttributes -Attributes of the context established.
+
+ #define ISC_RET_DELEGATE 0x00000001
+ #define ISC_RET_MUTUAL_AUTH 0x00000002
+ #define ISC_RET_REPLAY_DETECT 0x00000004
+ #define ISC_RET_SEQUENCE_DETECT 0x00000008
+ #define ISC_REP_CONFIDENTIALITY 0x00000010
+ #define ISC_REP_USE_SESSION_KEY 0x00000020
+ #define ISC_REP_USED_COLLECTED_CREDS 0x00000040
+ #define ISC_REP_USED_SUPPLIED_CREDS 0x00000080
+ #define ISC_REP_ALLOCATED_MEMORY 0x00000100
+ #define ISC_REP_USED_DCE_STYLE 0x00000200
+
+ ExpirationTime - Expiration time of the context.
+
+ SessionKey - Session key to be used for this context.
+
+ NegotiateFlags - Flags negotiated for this context.
+
+Return Value:
+
+ STATUS_SUCCESS - Message handled
+ SEC_I_CALLBACK_NEEDED -- Caller should call again later
+
+ SEC_E_INVALID_TOKEN -- Token improperly formatted
+ SEC_E_INVALID_HANDLE -- Credential/Context Handle is invalid
+ SEC_E_BUFFER_TOO_SMALL -- Buffer for output token isn't big enough
+ SEC_E_NO_CREDENTIALS -- There are no credentials for this client
+ SEC_E_INSUFFICIENT_MEMORY -- Not enough memory
+
+--*/
+
+{
+ SECURITY_STATUS SecStatus = SEC_E_OK;
+ PSSP_INITIALIZE_SECURITY_CONTEXT_ARGS Args;
+
+ //
+ // Simply call the worker routine.
+ //
+
+ SspPrint(( SSP_API, "SspApiInitializeSecurityContext Entered\n" ));
+ Args = &Message->Arguments.InitializeSecurityContextArgs;
+
+
+ //
+ // Handle the call differently depending on whether this is the first
+ // or second call.
+ //
+
+ if ( Args->ContextHandle.dwUpper == 0 && Args->ContextHandle.dwLower == 0 ){
+ SecStatus = SsprHandleFirstCall(
+ ClientConnection,
+ &Args->CredentialHandle,
+ &Args->ContextHandle,
+ Args->ContextReqFlags,
+ Args->InputTokenSize,
+ Args->InputToken,
+ &Args->OutputTokenSize,
+ Args->OutputToken,
+ &Args->ContextAttributes,
+ &Args->ExpirationTime,
+ Args->SessionKey,
+ &Args->NegotiateFlags );
+ } else {
+
+ if (Args->ClientTokenHandle != NULL) {
+ SecStatus = SspLpcDuplicateHandle(
+ ClientConnection,
+ TRUE, // from client
+ FALSE, // don't close source
+ Args->ClientTokenHandle, // input handle
+ &Args->ClientTokenHandle // output handle
+ );
+
+ }
+ if (NT_SUCCESS(SecStatus)) {
+
+ SecStatus = SsprHandleChallengeMessage(
+ ClientConnection,
+ &Args->CredentialHandle,
+ &Args->ContextHandle,
+ Args->ClientTokenHandle,
+ &Args->LogonId,
+ Args->ContextReqFlags,
+ Args->DomainName,
+ Args->DomainNameSize,
+ Args->UserName,
+ Args->UserNameSize,
+ Args->Password,
+ Args->PasswordSize,
+ Args->InputTokenSize,
+ Args->InputToken,
+ &Args->OutputTokenSize,
+ Args->OutputToken,
+ &Args->ContextAttributes,
+ &Args->ExpirationTime,
+ Args->SessionKey,
+ &Args->NegotiateFlags,
+ Args->ContextNames );
+ }
+
+ if (Args->ClientTokenHandle != NULL) {
+ (VOID) NtClose( Args->ClientTokenHandle );
+ }
+
+ }
+
+ SspPrint(( SSP_API, "SspApiInitializeSecurityContext returns 0x%lx\n", SecStatus ));
+ return SecStatus;
+}
+
+
+SECURITY_STATUS
+SspApiAcceptSecurityContext(
+ IN PSSP_CLIENT_CONNECTION ClientConnection,
+ IN OUT PSSP_API_MESSAGE Message
+ )
+
+/*++
+
+Routine Description:
+
+ Allows a remotely initiated security context between the application
+ and a remote peer to be established. To complete the establishment of
+ context one or more reply tokens may be required from remote peer.
+
+ This function is the server counterpart to the
+ InitializeSecurityContext API. The ContextAttributes is a bit mask
+ representing various context level functions viz. delegation, mutual
+ authentication, confidentiality, replay detection and sequence
+ detection. This API is used by the server side. When a request comes
+ in, the server uses the ContextReqFlags parameter to specify what
+ it requires of the session. In this fashion, a server can specify that
+ clients must be capable of using a confidential or integrity checked
+ session, and fail clients that can't meet that demand. Alternatively,
+ a server can require nothing, and whatever the client can provide or
+ requires is returned in the pfContextAttributes parameter. For a
+ package that supports 3 leg mutual authentication, the calling sequence
+ would be: Client provides a token, server calls Accept the first time,
+ generating a reply token. The client uses this in a second call to
+ InitializeSecurityContext, and generates a final token. This token is
+ then used in the final call to Accept to complete the session. Another
+ example would be the LAN Manager/NT authentication style. The client
+ connects to negotiate a protocol. The server calls Accept to set up a
+ context and generate a challenge to the client. The client calls
+ InitializeSecurityContext and creates a response. The server then
+ calls Accept the final time to allow the package to verify the response
+ is appropriate for the challenge.
+
+Arguments:
+
+ ClientConnection - Describes the client process.
+
+ Message - Message from the caller. Returns the response to be passed to
+ the caller. The message contains all of the following fields:
+
+ CredentialHandle - Handle to the credentials to be used to
+ create the context.
+
+
+ ContextHandle - On input, the handle to the partially formed context, if this is
+ a second call (see above) or NULL if this is the first call.
+
+ On output, new context handle. If this is a second call, this
+ can be the same as phContext.
+
+ InputTokenSize - Size of the input token, in bytes.
+
+ InputToken - Pointer to the input token. In the first call this
+ token can either be NULL or may contain security package specific
+ information.
+
+ ContextReqFlags - Requirements of the context, package specific.
+
+ #define ASC_REQ_DELEGATE 0x00000001
+ #define ASC_REQ_MUTUAL_AUTH 0x00000002
+ #define ASC_REQ_REPLAY_DETECT 0x00000004
+ #define ASC_REQ_SEQUENCE_DETECT 0x00000008
+ #define ASC_REQ_CONFIDENTIALITY 0x00000010
+ #define ASC_REQ_USE_SESSION_KEY 0x00000020
+ #define ASC_REQ_ALLOCATE_MEMORY 0x00000100
+ #define ASC_REQ_USE_DCE_STYLE 0x00000200
+
+ OutputTokenSize - Size of the output token, in bytes.
+
+ OutputToken - Buffer to receive the output token.
+
+ ContextAttributes -Attributes of the context established.
+
+ #define ASC_RET_DELEGATE 0x00000001
+ #define ASC_RET_MUTUAL_AUTH 0x00000002
+ #define ASC_RET_REPLAY_DETECT 0x00000004
+ #define ASC_RET_SEQUENCE_DETECT 0x00000008
+ #define ASC_RET_CONFIDENTIALITY 0x00000010
+ #define ASC_RET_USE_SESSION_KEY 0x00000020
+ #define ASC_RET_ALLOCATED_BUFFERS 0x00000100
+ #define ASC_RET_USED_DCE_STYLE 0x00000200
+
+ ExpirationTime - Expiration time of the context.
+
+ SessionKey - Session key to be used for this context.
+
+ NegotiateFlags - Flags negotiated for this context.
+
+Return Value:
+
+ STATUS_SUCCESS - Message handled
+ SEC_I_CALLBACK_NEEDED -- Caller should call again later
+
+ SEC_E_INVALID_TOKEN -- Token improperly formatted
+ SEC_E_INVALID_HANDLE -- Credential/Context Handle is invalid
+ SEC_E_BUFFER_TOO_SMALL -- Buffer for output token isn't big enough
+ SEC_E_LOGON_DENIED -- User is no allowed to logon to this server
+ SEC_E_INSUFFICIENT_MEMORY -- Not enough memory
+
+--*/
+
+{
+ SECURITY_STATUS SecStatus;
+ PSSP_ACCEPT_SECURITY_CONTEXT_ARGS Args;
+
+ //
+ // Simply call the worker routine.
+ //
+
+ SspPrint(( SSP_API, "SspApiAcceptSecurityContext Entered\n" ));
+ Args = &Message->Arguments.AcceptSecurityContextArgs;
+
+
+ //
+ // Handle the call differently depending on whether this is the first
+ // or second call.
+ //
+
+ if ( Args->ContextHandle.dwUpper == 0 && Args->ContextHandle.dwLower == 0 ){
+ SecStatus = SsprHandleNegotiateMessage(
+ ClientConnection,
+ &Args->CredentialHandle,
+ &Args->ContextHandle,
+ Args->ContextReqFlags,
+ Args->InputTokenSize,
+ Args->InputToken,
+ &Args->OutputTokenSize,
+ Args->OutputToken,
+ &Args->ContextAttributes,
+ &Args->ExpirationTime );
+ } else {
+ SecStatus = SsprHandleAuthenticateMessage(
+ ClientConnection,
+ &Args->CredentialHandle,
+ &Args->ContextHandle,
+ Args->ContextReqFlags,
+ Args->InputTokenSize,
+ Args->InputToken,
+ &Args->OutputTokenSize,
+ Args->OutputToken,
+ &Args->ContextAttributes,
+ &Args->ExpirationTime,
+ Args->SessionKey,
+ &Args->NegotiateFlags,
+ &Args->TokenHandle,
+ &Args->SubStatus,
+ Args->ContextNames,
+ &Args->PasswordExpiry );
+
+ //
+ // If that succeeded and we have a token handle, duplicate
+ // it into the client process.
+ //
+
+ if ((SecStatus == S_OK) && (Args->TokenHandle != NULL)) {
+ SecStatus = SspLpcDuplicateHandle(
+ ClientConnection,
+ FALSE, // not from client
+ TRUE, // close source
+ Args->TokenHandle, // input handle
+ &Args->TokenHandle // output handle
+ );
+
+
+ }
+ }
+
+ SspPrint(( SSP_API, "SspApiAcceptSecurityContext returns 0x%lx\n", SecStatus ));
+ return SecStatus;
+}
+
+
+
+SECURITY_STATUS
+SspApiQueryContextAttributes(
+ IN PSSP_CLIENT_CONNECTION ClientConnection,
+ IN OUT PSSP_API_MESSAGE Message
+ )
+
+/*++
+
+Routine Description:
+
+ This API allows a customer of the security services to determine
+ certain attributes of the context. These are: sizes, names, and
+ lifespan.
+
+Arguments:
+
+ ClientConnection - Describes the client process.
+
+ Message - Message from the caller. Returns the response to be passed to
+ the caller. The message contains all of the following fields:
+
+ ContextHandle - Handle to the context to query.
+
+ Attribute - Attribute to query.
+
+ #define SECPKG_ATTR_SIZES 0
+ #define SECPKG_ATTR_NAMES 1
+ #define SECPKG_ATTR_LIFESPAN 2
+
+ Buffer - Buffer to copy the data into. The buffer must be large enough
+ to fit the queried attribute.
+
+Return Value:
+
+ STATUS_SUCCESS - Call completed successfully
+
+ SEC_E_INVALID_HANDLE -- Credential/Context Handle is invalid
+ SEC_E_UNSUPPORTED_FUNCTION -- Function code is not supported
+
+--*/
+
+{
+ SECURITY_STATUS SecStatus;
+ PSSP_QUERY_CONTEXT_ATTRIBUTES_ARGS Args;
+
+ //
+ // Simply call the worker routine.
+ //
+
+ Args = &Message->Arguments.QueryContextAttributesArgs;
+
+
+ SecStatus = SsprQueryContextAttributes(
+ ClientConnection,
+ &Args->ContextHandle,
+ Args->Attribute,
+ Args->Buffer );
+
+ return SecStatus;
+
+}
+
+
+
+SECURITY_STATUS
+SspApiDeleteSecurityContext(
+ IN PSSP_CLIENT_CONNECTION ClientConnection,
+ IN OUT PSSP_API_MESSAGE Message
+ )
+
+/*++
+
+Routine Description:
+
+ Deletes the local data structures associated with the specified
+ security context and generates a token which is passed to a remote peer
+ so it too can remove the corresponding security context.
+
+ This API terminates a context on the local machine, and optionally
+ provides a token to be sent to the other machine. The OutputToken
+ generated by this call is to be sent to the remote peer (initiator or
+ acceptor). If the context was created with the I _REQ_ALLOCATE_MEMORY
+ flag, then the package will allocate a buffer for the output token.
+ Otherwise, it is the responsibility of the caller.
+
+Arguments:
+
+ ContextHandle - Handle to the context to delete
+
+ TokenLength - Size of the output token (if any) that should be sent to
+ the process at the other end of the session.
+
+ Token - Pointer to the token to send.
+
+Return Value:
+
+ STATUS_SUCCESS - Call completed successfully
+
+ SEC_E_NO_SPM -- Security Support Provider is not running
+ SEC_E_INVALID_HANDLE -- Credential/Context Handle is invalid
+
+--*/
+
+{
+ SECURITY_STATUS SecStatus;
+ PSSP_DELETE_SECURITY_CONTEXT_ARGS Args;
+
+ //
+ // Simply call the worker routine.
+ //
+
+ Args = &Message->Arguments.DeleteSecurityContextArgs;
+
+
+ SecStatus = SsprDeleteSecurityContext(
+ ClientConnection,
+ &Args->ContextHandle );
+
+ return SecStatus;
+
+}
+
+
+SECURITY_STATUS
+SspApiNoop(
+ IN PSSP_CLIENT_CONNECTION ClientConnection,
+ IN OUT PSSP_API_MESSAGE Message
+ )
+
+/*++
+
+Routine Description:
+
+ This is a no-operation dispatch procedure. It is passed to the LPC
+ thread when no action is required.
+
+ For instance, it is used during service shutdown to awaken the LPC thread
+ so it can recognize that it should exit.
+
+
+Arguments:
+
+Return Value:
+
+ Status of the operation.
+
+--*/
+
+{
+ NTSTATUS Status;
+ SspPrint(( SSP_API, "SspApiNoop Entered\n" ));
+ Status = STATUS_SUCCESS;
+ SspPrint(( SSP_API, "SspApiNoop returns 0x%lx\n", Status ));
+ return Status;
+ UNREFERENCED_PARAMETER( Message );
+ UNREFERENCED_PARAMETER( ClientConnection );
+}
+
+SECURITY_STATUS
+SspApiNtLmSspControl(
+ IN PSSP_CLIENT_CONNECTION ClientConnection,
+ IN OUT PSSP_API_MESSAGE Message
+ )
+
+/*++
+
+Routine Description:
+
+ This is a no-operation dispatch procedure. It is passed to the LPC
+ thread when no action is required.
+
+ For instance, it is used during service shutdown to awaken the LPC thread
+ so it can recognize that it should exit.
+
+
+Arguments:
+
+Return Value:
+
+ STATUS_SUCCESS -- Call completed successfully
+
+ SEC_E_UNSUPPORTED_FUNCTION -- Function code is not supported
+
+--*/
+
+{
+#if DBG
+ SECURITY_STATUS SecStatus;
+ PSSP_NTLMSSP_CONTROL_ARGS Args;
+
+ //
+ // Initialization
+ //
+
+ SspPrint(( SSP_API, "SspApiNtLmSspControl Entered\n" ));
+ Args = &Message->Arguments.NtLmSspControlArgs;
+
+
+ //
+ // Force a breakpoint
+ //
+
+ switch ( Args->FunctionCode ) {
+ case NTLMSSP_BREAKPOINT:
+ KdPrint(( "NtLmSsp Break Point\n"));
+ DbgBreakPoint();
+ break;
+
+ //
+ // Change the debug flags
+ //
+
+ case NTLMSSP_DBFLAG:
+ SspGlobalDbflag = Args->Data;
+ SspPrint((SSP_MISC,"SspGlobalDbflag is set to %lx\n", SspGlobalDbflag ));
+ break;
+
+ //
+ // Truncate the log file
+ //
+
+ case NTLMSSP_TRUNCATE:
+
+ SspOpenDebugFile( TRUE );
+ SspPrint((SSP_MISC, "TRUNCATE_LOG function received.\n" ));
+ break;
+
+
+ //
+ // All other function codes are invalid.
+ //
+
+ default:
+ SecStatus = SEC_E_UNSUPPORTED_FUNCTION;
+ goto Cleanup;
+ }
+
+
+ SecStatus = STATUS_SUCCESS;
+
+Cleanup:
+ SspPrint(( SSP_API, "SspApiNtLmSspControl returns 0x%lx\n", SecStatus ));
+ return SecStatus;
+#else // DBG
+ return SEC_E_UNSUPPORTED_FUNCTION;
+ UNREFERENCED_PARAMETER( Message );
+#endif // DBG
+ UNREFERENCED_PARAMETER( ClientConnection );
+}