|
|
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1991 - 1992
//
// File: ctxtapi.c
//
// Contents: Context APIs to the SPMgr.
// - LsaInitContext
// - LsaAcceptContext
// - LsaFinalizeContext
// - LsaMapContext
//
// And WLsa functions
//
// History: 20 May 92 RichardW Commented existing code
//
//------------------------------------------------------------------------
#include <lsapch.hxx>
//+---------------------------------------------------------------------------
//
// Function: WLsaInitContext
//
// Synopsis: Worker that maps the call to the appropriate package
//
// Effects:
//
// Arguments: [phCredential] --
// [phContext] --
// [pTarget] --
// [fContextReq] --
// [dwReserved1] --
// [TargetDataRep] --
// [pInput] --
// [dwReserved2] --
// [phNewContext] --
// [pOutput] --
// [pfContextAttr] --
// [ptsExpiry] --
// [MappedContext] --
// [ContextData] --
//
// Requires:
//
// Returns:
//
// History: 9-24-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
NTSTATUS WLsaInitContext( PCredHandle phCredential, PCtxtHandle phContext, PSECURITY_STRING pTarget, DWORD fContextReq, DWORD dwReserved1, DWORD TargetDataRep, PSecBufferDesc pInput, DWORD dwReserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, DWORD * pfContextAttr, PTimeStamp ptsExpiry, PBOOLEAN MappedContext, PSecBuffer ContextData ) { NTSTATUS scRet; PLSAP_SECURITY_PACKAGE pspPackage; PSession pSession = GetCurrentSession(); PLSA_CALL_INFO CallInfo = LsapGetCurrentCall(); PVOID ContextKey = NULL ; PVOID CredKey = NULL ;
DebugLog((DEB_TRACE_WAPI, "[%x] WLsaInitContext(%p : %p, %p : %p, %ws)\n", pSession->dwProcessID, phCredential->dwUpper, phCredential->dwLower, phContext->dwUpper, phContext->dwLower, pTarget->Buffer));
#if DBG
if ( pInput && pInput->cBuffers ) { DsysAssert( (ULONG_PTR) pInput->pBuffers > PORT_MAXIMUM_MESSAGE_LENGTH ); } if ( pOutput && pOutput->cBuffers ) { DsysAssert( (ULONG_PTR) pOutput->pBuffers > PORT_MAXIMUM_MESSAGE_LENGTH );
} #endif
//
// Reset the new handle to a known, invalid state
//
phNewContext->dwLower = SPMGR_ID; phNewContext->dwUpper = 0;
//
// Check handles against the session to make sure they're valid. If the
// context handle is valid, we use that, otherwise the credential.
//
scRet = ValidateContextHandle( pSession, phContext, &ContextKey );
if ( NT_SUCCESS( scRet ) ) { pspPackage = SpmpValidRequest( phContext->dwLower, SP_ORDINAL_INITLSAMODECTXT );
//
// Tricky stuff: if the context handle is valid, but does not
// come from the same package as the credential, null out the cred
// handle:
//
if ( phCredential->dwLower != phContext->dwLower ) { phCredential->dwLower = 0; phCredential->dwUpper = 0; }
LsapLogCallInfo( CallInfo, pSession, *phContext );
} else {
LsapLogCallInfo( CallInfo, pSession, *phCredential );
scRet = ValidateCredHandle( pSession, phCredential, &CredKey );
if ( NT_SUCCESS( scRet ) ) { pspPackage = SpmpValidRequest( phCredential->dwLower, SP_ORDINAL_INITLSAMODECTXT ); } else { DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
return( SEC_E_INVALID_HANDLE ); } }
if ( !pspPackage ) { if ( ContextKey ) { DerefContextHandle( pSession, NULL, ContextKey ); }
if ( CredKey ) { DerefCredHandle( pSession, NULL, CredKey ); }
return( SEC_E_INVALID_HANDLE ); }
SetCurrentPackageId( pspPackage->dwPackageID );
StartCallToPackage( pspPackage );
DebugLog((DEB_TRACE_VERB, "\tContext Req = 0x%08x\n", fContextReq));
DebugLog((DEB_TRACE_VERB, "\tPackage = %ws\n", pspPackage->Name.Buffer));
__try {
scRet = pspPackage->FunctionTable.InitLsaModeContext( phCredential->dwUpper, phContext->dwUpper, pTarget, fContextReq, TargetDataRep, pInput, &phNewContext->dwUpper, pOutput, pfContextAttr, ptsExpiry, MappedContext, ContextData ); } __except (SP_EXCEPTION) { scRet = GetExceptionCode(); scRet = SPException(scRet, pspPackage->dwPackageID); }
EndCallToPackage( pspPackage );
DebugLog((DEB_TRACE_WAPI, "InitResult = %x\n", scRet)); DebugLog((DEB_TRACE_VERB, "\tFlags = %08x\n", *pfContextAttr));
//
// Only add a new context if the old one didn't exist.
// Otherwise copy the old context over the new context.
//
if ( NT_SUCCESS( scRet ) ) { if ( (phNewContext->dwUpper != 0) && (phNewContext->dwUpper != phContext->dwUpper) ) { //
// If the package ID is unchanged, set it to the current package
// id. This is so that if package changes the ID through
// LsapChangeHandle, we can catch it.
//
if ( phNewContext->dwLower == SPMGR_ID ) { phNewContext->dwLower = pspPackage->dwPackageID ;
if(!AddContextHandle( pSession, phNewContext, 0 )) { DebugLog(( DEB_ERROR, "Failed adding context handle %p:%p to session %p\n", phNewContext->dwUpper, phNewContext->dwLower, pSession ));
pspPackage = SpmpValidRequest( phNewContext->dwLower, SP_ORDINAL_DELETECTXT );
if( pspPackage ) { //
// remove the handle from the underlying package.
//
StartCallToPackage( pspPackage );
__try { pspPackage->FunctionTable.DeleteContext( phNewContext->dwUpper ); } __except (SP_EXCEPTION) { NOTHING; }
EndCallToPackage( pspPackage ); }
phNewContext->dwLower = 0; phNewContext->dwUpper = 0;
scRet = SEC_E_INSUFFICIENT_MEMORY; } }
} else { *phNewContext = *phContext; } } else { *phNewContext = *phContext ; }
DebugLog(( DEB_TRACE_WAPI, "Init New Context = %p : %p to session %p\n", phNewContext->dwUpper , phNewContext->dwLower, pSession ));
SetCurrentPackageId( SPMGR_ID );
if ( ContextKey ) { DerefContextHandle( pSession, NULL, ContextKey ); }
if ( CredKey ) { DerefCredHandle( pSession, NULL, CredKey ); }
return(scRet);
}
//+-------------------------------------------------------------------------
//
// Function: WLsaAcceptContext()
//
// Synopsis: Worker function for AcceptSecurityContext()
//
// Effects: Creates a server-side security context
//
// Arguments: See LsaAcceptContext()
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
NTSTATUS WLsaAcceptContext( PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, DWORD fContextReq, DWORD TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, DWORD * pfContextAttr, PTimeStamp ptsExpiry, PBOOLEAN MappedContext, PSecBuffer ContextData) { NTSTATUS scRet; PLSAP_SECURITY_PACKAGE pspPackage; PSession pSession; PVOID ContextKey = NULL ; PVOID CredKey = NULL ; PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
//
// Clear out the handle
//
phNewContext->dwLower = SPMGR_ID; phNewContext->dwUpper = 0;
#if DBG
if ( pInput && pInput->cBuffers ) { DsysAssert( (ULONG_PTR) pInput->pBuffers > PORT_MAXIMUM_MESSAGE_LENGTH ); } if ( pOutput && pOutput->cBuffers ) { DsysAssert( (ULONG_PTR) pOutput->pBuffers > PORT_MAXIMUM_MESSAGE_LENGTH );
} #endif
//
// Get our session
//
pSession = GetCurrentSession();
DebugLog((DEB_TRACE_WAPI, "[%x] WLsaAcceptContext(%p : %p)\n", pSession->dwProcessID, phCredential->dwUpper, phCredential->dwLower));
//
// Check handles against the session to make sure they're valid. If the
// context handle is valid, we use that, otherwise the credential.
//
scRet = ValidateContextHandle( pSession, phContext, &ContextKey );
if ( NT_SUCCESS( scRet ) ) { pspPackage = SpmpValidRequest( phContext->dwLower, SP_ORDINAL_ACCEPTLSAMODECTXT );
//
// Tricky stuff: if the context handle is valid, but does not
// come from the same package as the credential, null out the cred
// handle:
//
if ( phCredential->dwLower != phContext->dwLower ) { phCredential->dwLower = 0; phCredential->dwUpper = 0; }
LsapLogCallInfo( CallInfo, pSession, *phContext );
} else {
LsapLogCallInfo( CallInfo, pSession, *phCredential );
scRet = ValidateCredHandle( pSession, phCredential, &CredKey );
if ( NT_SUCCESS( scRet ) ) { pspPackage = SpmpValidRequest( phCredential->dwLower, SP_ORDINAL_ACCEPTLSAMODECTXT ); } else { DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
return( SEC_E_INVALID_HANDLE ); } }
if ( !pspPackage ) { DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
if ( ContextKey ) { DerefContextHandle( pSession, NULL, ContextKey ); }
if ( CredKey ) { DerefCredHandle( pSession, NULL, CredKey ); }
return( SEC_E_INVALID_HANDLE ); }
SetCurrentPackageId( pspPackage->dwPackageID );
StartCallToPackage( pspPackage );
__try { scRet = pspPackage->FunctionTable.AcceptLsaModeContext( phCredential->dwUpper, phContext->dwUpper, pInput, fContextReq, TargetDataRep, &phNewContext->dwUpper, pOutput, pfContextAttr, ptsExpiry, MappedContext, ContextData ); } __except (SP_EXCEPTION) { scRet = GetExceptionCode(); scRet = SPException(scRet, pspPackage->dwPackageID); }
EndCallToPackage( pspPackage );
DebugLog((DEB_TRACE_WAPI, "[%x] Result = %x\n", pSession->dwProcessID, scRet));
//
// Only add a new context if the old one didn't exist.
// Otherwise copy the old context over the new context.
//
if ( NT_SUCCESS( scRet ) || ( scRet == SEC_E_INCOMPLETE_MESSAGE ) ) { if ( (phNewContext->dwUpper != 0) && (phNewContext->dwUpper != phContext->dwUpper) ) { //
// If the package ID is unchanged, set it to the current package
// id. This is so that if package changes the ID through
//
if ( phNewContext->dwLower == SPMGR_ID ) { phNewContext->dwLower = pspPackage->dwPackageID ;
if(!AddContextHandle( pSession, phNewContext, 0 )) { DebugLog(( DEB_ERROR, "Failed adding context handle %p:%p to session %p\n", phNewContext->dwUpper, phNewContext->dwLower, pSession ));
pspPackage = SpmpValidRequest( phNewContext->dwLower, SP_ORDINAL_DELETECTXT );
if( pspPackage ) { //
// remove the handle from the underlying package.
//
StartCallToPackage( pspPackage );
__try { pspPackage->FunctionTable.DeleteContext( phNewContext->dwUpper ); } __except (SP_EXCEPTION) { NOTHING; }
EndCallToPackage( pspPackage ); }
phNewContext->dwLower = 0; phNewContext->dwUpper = 0;
scRet = SEC_E_INSUFFICIENT_MEMORY; } }
} else { *phNewContext = *phContext; } } else { *phNewContext = *phContext ; }
DebugLog(( DEB_TRACE_WAPI, "Accept new context = %p : %p \n", phNewContext->dwUpper, phNewContext->dwLower ));
SetCurrentPackageId( SPMGR_ID );
if ( ContextKey ) { DerefContextHandle( pSession, NULL, ContextKey ); }
if ( CredKey ) { DerefCredHandle( pSession, NULL, CredKey ); }
return(scRet);
}
//+-------------------------------------------------------------------------
//
// Function: WLsaDeleteContext
//
// Synopsis: Worker function for deleting a context
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
NTSTATUS WLsaDeleteContext( PCtxtHandle phContext) { NTSTATUS scRet; PSession pSession = GetCurrentSession(); PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
DebugLog((DEB_TRACE_WAPI, "[%x] WDeleteContext(%p : %p)\n", pSession->dwProcessID, phContext->dwUpper, phContext->dwLower));
scRet = ValidateAndDerefContextHandle( pSession, phContext );
if ( (CallInfo->Flags & CALL_FLAG_NO_HANDLE_CHK) == 0 ) { if ( !NT_SUCCESS( scRet ) ) { DebugLog((DEB_ERROR,"[%x] Invalid handle passed to DeleteContext: %p:%p\n", pSession->dwProcessID, phContext->dwUpper,phContext->dwLower));
/// DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
} }
LsapLogCallInfo( CallInfo, pSession, *phContext );
if (SUCCEEDED(scRet)) { phContext->dwUpper = phContext->dwLower = 0xFFFFFFFF; }
return(scRet);
}
//+-------------------------------------------------------------------------
//
// Function: WLsaApplyControlToken
//
// Synopsis: Worker function for applying a control token
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
NTSTATUS WLsaApplyControlToken( PCtxtHandle phContext, PSecBufferDesc pInput) { NTSTATUS scRet; PLSAP_SECURITY_PACKAGE pspPackage; PSession pSession = GetCurrentSession(); PLSA_CALL_INFO CallInfo = LsapGetCurrentCall(); PVOID ContextKey ;
DebugLog((DEB_TRACE_WAPI, "[%x] WApplyControlToken(%p : %p)\n", pSession->dwProcessID, phContext->dwUpper, phContext->dwLower));
LsapLogCallInfo( CallInfo, pSession, *phContext );
scRet = ValidateContextHandle( pSession, phContext, &ContextKey );
if ( !NT_SUCCESS( scRet ) ) { DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
return( scRet );
}
pspPackage = SpmpValidRequest( phContext->dwLower, SP_ORDINAL_APPLYCONTROLTOKEN);
if ( !pspPackage ) { return SEC_E_INVALID_HANDLE ; }
SetCurrentPackageId(phContext->dwLower);
StartCallToPackage( pspPackage );
__try { scRet = pspPackage->FunctionTable.ApplyControlToken( phContext->dwUpper, pInput); } __except (SP_EXCEPTION) { scRet = GetExceptionCode(); scRet = SPException(scRet, pspPackage->dwPackageID); }
EndCallToPackage( pspPackage );
SetCurrentPackageId( SPMGR_ID );
DerefContextHandle( pSession, NULL, ContextKey );
return(scRet);
}
NTSTATUS WLsaQueryContextAttributes( PCtxtHandle phContext, ULONG ulAttribute, PVOID pvBuffer ) { NTSTATUS scRet; PLSAP_SECURITY_PACKAGE pspPackage = NULL ; PSession pSession = GetCurrentSession(); PLSA_CALL_INFO CallInfo = LsapGetCurrentCall(); PVOID ContextKey ;
DebugLog((DEB_TRACE_WAPI, "[%x] WLsaQueryContextAttributes(%p : %p)\n", pSession->dwProcessID, phContext->dwUpper, phContext->dwLower));
LsapLogCallInfo( CallInfo, pSession, *phContext );
scRet = ValidateContextHandle( pSession, phContext, &ContextKey );
if ( NT_SUCCESS( scRet ) ) { pspPackage = SpmpValidRequest( phContext->dwLower, SP_ORDINAL_QUERYCONTEXTATTRIBUTES); } if (( !pspPackage ) || !NT_SUCCESS( scRet ) ) { DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
return(SEC_E_INVALID_HANDLE); }
StartCallToPackage( pspPackage );
SetCurrentPackageId(phContext->dwLower);
__try { scRet = pspPackage->FunctionTable.QueryContextAttributes( phContext->dwUpper, ulAttribute, pvBuffer ); } __except (SP_EXCEPTION) { scRet = GetExceptionCode(); scRet = SPException(scRet, pspPackage->dwPackageID); }
EndCallToPackage( pspPackage );
SetCurrentPackageId( SPMGR_ID );
DerefContextHandle( pSession, NULL, ContextKey );
return(scRet);
}
NTSTATUS WLsaSetContextAttributes( PCtxtHandle phContext, ULONG ulAttribute, PVOID pvBuffer, ULONG cbBuffer ) { NTSTATUS scRet; PLSAP_SECURITY_PACKAGE pspPackage = NULL ; PSession pSession = GetCurrentSession(); PLSA_CALL_INFO CallInfo = LsapGetCurrentCall(); PVOID ContextKey ;
DebugLog((DEB_TRACE_WAPI, "[%x] WLsaSetContextAttributes(%p : %p)\n", pSession->dwProcessID, phContext->dwUpper, phContext->dwLower));
LsapLogCallInfo( CallInfo, pSession, *phContext );
scRet = ValidateContextHandle( pSession, phContext, &ContextKey );
if ( NT_SUCCESS( scRet ) ) { pspPackage = SpmpValidRequest( phContext->dwLower, SP_ORDINAL_SETCONTEXTATTRIBUTES); } if (( !pspPackage ) || !NT_SUCCESS( scRet ) ) { DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
return(SEC_E_INVALID_HANDLE); }
StartCallToPackage( pspPackage );
SetCurrentPackageId(phContext->dwLower);
__try { scRet = pspPackage->FunctionTable.SetContextAttributes( phContext->dwUpper, ulAttribute, pvBuffer, cbBuffer ); } __except (SP_EXCEPTION) { scRet = GetExceptionCode(); scRet = SPException(scRet, pspPackage->dwPackageID); }
EndCallToPackage( pspPackage );
SetCurrentPackageId( SPMGR_ID );
DerefContextHandle( pSession, NULL, ContextKey );
return(scRet);
}
|