887 lines
25 KiB
C++
887 lines
25 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1996 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
kerberos.cpp
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Routines to read/write/configure kerberos policy settings
|
|||
|
|
|||
|
The following modules have links to kerberos policy
|
|||
|
scejet.c <SceJetAddSection>
|
|||
|
inftojet.c <SceConvertpInfKeyValue>
|
|||
|
pfget.c <ScepGetKerberosPolicy>
|
|||
|
config.c <ScepConfigureKerberosPolicy>
|
|||
|
analyze.c <ScepAnalyzeKerberosPolicy>
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Jin Huang (jinhuang) 17-Dec-1997
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
jinhuang 28-Jan-1998 splitted to client-server
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "headers.h"
|
|||
|
#include "serverp.h"
|
|||
|
#include "kerberos.h"
|
|||
|
#include "kerbcon.h"
|
|||
|
#include "pfp.h"
|
|||
|
|
|||
|
#define MAXDWORD 0xffffffff
|
|||
|
|
|||
|
static PWSTR KerbItems[] = {
|
|||
|
{(PWSTR)TEXT("MaxTicketAge")},
|
|||
|
{(PWSTR)TEXT("MaxRenewAge")},
|
|||
|
{(PWSTR)TEXT("MaxServiceAge")},
|
|||
|
{(PWSTR)TEXT("MaxClockSkew")},
|
|||
|
{(PWSTR)TEXT("TicketValidateClient")}
|
|||
|
};
|
|||
|
|
|||
|
#define MAX_KERB_ITEMS 5
|
|||
|
|
|||
|
#define IDX_KERB_MAX 0
|
|||
|
#define IDX_KERB_RENEW 1
|
|||
|
#define IDX_KERB_SERVICE 2
|
|||
|
#define IDX_KERB_CLOCK 3
|
|||
|
#define IDX_KERB_VALIDATE 4
|
|||
|
|
|||
|
|
|||
|
SCESTATUS
|
|||
|
ScepGetKerberosPolicy(
|
|||
|
IN PSCECONTEXT hProfile,
|
|||
|
IN SCETYPE ProfileType,
|
|||
|
OUT PSCE_KERBEROS_TICKET_INFO * ppKerberosInfo,
|
|||
|
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
|||
|
)
|
|||
|
/*++
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine retrieves kerberos policy information from the Jet database
|
|||
|
and stores in the output buffer ppKerberosInfo.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hProfile - The profile handle context
|
|||
|
|
|||
|
ppKerberosInfo - the output buffer to hold kerberos settings.
|
|||
|
|
|||
|
Errlog - A buffer to hold all error codes/text encountered when
|
|||
|
parsing the INF file. If Errlog is NULL, no further error
|
|||
|
information is returned except the return DWORD
|
|||
|
|
|||
|
Return value:
|
|||
|
|
|||
|
SCESTATUS - SCESTATUS_SUCCESS
|
|||
|
SCESTATUS_NOT_ENOUGH_RESOURCE
|
|||
|
SCESTATUS_INVALID_PARAMETER
|
|||
|
SCESTATUS_BAD_FORMAT
|
|||
|
SCESTATUS_INVALID_DATA
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
SCESTATUS rc;
|
|||
|
PSCESECTION hSection=NULL;
|
|||
|
|
|||
|
SCE_KEY_LOOKUP AccessKeys[] = {
|
|||
|
{(PWSTR)TEXT("MaxTicketAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxTicketAge), 'D'},
|
|||
|
{(PWSTR)TEXT("MaxRenewAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxRenewAge), 'D'},
|
|||
|
{(PWSTR)TEXT("MaxServiceAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxServiceAge), 'D'},
|
|||
|
{(PWSTR)TEXT("MaxClockSkew"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxClockSkew), 'D'},
|
|||
|
{(PWSTR)TEXT("TicketValidateClient"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, TicketValidateClient), 'D'}
|
|||
|
};
|
|||
|
|
|||
|
DWORD cKeys = sizeof(AccessKeys) / sizeof(SCE_KEY_LOOKUP);
|
|||
|
SCE_KERBEROS_TICKET_INFO TicketInfo;
|
|||
|
|
|||
|
if ( ppKerberosInfo == NULL ) {
|
|||
|
return(SCESTATUS_INVALID_PARAMETER);
|
|||
|
}
|
|||
|
|
|||
|
rc = ScepGetFixValueSection(
|
|||
|
hProfile,
|
|||
|
szKerberosPolicy,
|
|||
|
AccessKeys,
|
|||
|
cKeys,
|
|||
|
ProfileType,
|
|||
|
(PVOID)&TicketInfo,
|
|||
|
&hSection,
|
|||
|
Errlog
|
|||
|
);
|
|||
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
//
|
|||
|
// copy the value in TicketInfo to ppKerberosInfo
|
|||
|
//
|
|||
|
if ( NULL == *ppKerberosInfo ) {
|
|||
|
*ppKerberosInfo = (PSCE_KERBEROS_TICKET_INFO)ScepAlloc(0, sizeof(SCE_KERBEROS_TICKET_INFO));
|
|||
|
}
|
|||
|
|
|||
|
if ( *ppKerberosInfo ) {
|
|||
|
|
|||
|
memcpy(*ppKerberosInfo, &TicketInfo, sizeof(SCE_KERBEROS_TICKET_INFO));
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
|||
|
}
|
|||
|
|
|||
|
SceJetCloseSection(&hSection, TRUE);
|
|||
|
|
|||
|
return(rc);
|
|||
|
}
|
|||
|
|
|||
|
#if _WIN32_WINNT>=0x0500
|
|||
|
|
|||
|
SCESTATUS
|
|||
|
ScepConfigureKerberosPolicy(
|
|||
|
IN PSCECONTEXT hProfile,
|
|||
|
IN PSCE_KERBEROS_TICKET_INFO pKerberosInfo,
|
|||
|
IN DWORD ConfigOptions
|
|||
|
)
|
|||
|
/* ++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine configure the kerberos policy settings in the area of security
|
|||
|
policy.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pKerberosInfo - The buffer which contains kerberos policy settings
|
|||
|
|
|||
|
Return value:
|
|||
|
|
|||
|
SCESTATUS_SUCCESS
|
|||
|
SCESTATUS_NOT_ENOUGH_RESOURCE
|
|||
|
SCESTATUS_INVALID_PARAMETER
|
|||
|
SCESTATUS_OTHER_ERROR
|
|||
|
|
|||
|
-- */
|
|||
|
{
|
|||
|
if ( !pKerberosInfo ) {
|
|||
|
//
|
|||
|
// if no info to configure
|
|||
|
//
|
|||
|
return SCESTATUS_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
NTSTATUS NtStatus;
|
|||
|
LSA_HANDLE lsaHandle=NULL;
|
|||
|
DWORD rc = NO_ERROR;
|
|||
|
BOOL bDefaultUsed=FALSE;
|
|||
|
BOOL bDefined=FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// open LSA policy to configure kerberos policy
|
|||
|
//
|
|||
|
NtStatus = ScepOpenLsaPolicy(
|
|||
|
MAXIMUM_ALLOWED,
|
|||
|
&lsaHandle,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
if (!NT_SUCCESS(NtStatus)) {
|
|||
|
|
|||
|
lsaHandle = NULL;
|
|||
|
rc = RtlNtStatusToDosError( NtStatus );
|
|||
|
ScepLogOutput3( 1, rc, SCEDLL_LSA_POLICY);
|
|||
|
|
|||
|
if ( ConfigOptions & SCE_RSOP_CALLBACK )
|
|||
|
|
|||
|
ScepRsopLog(SCE_RSOP_KERBEROS_INFO, rc, NULL, 0, 0);
|
|||
|
|
|||
|
return(ScepDosErrorToSceStatus(rc));
|
|||
|
}
|
|||
|
//
|
|||
|
// query current kerberos policy settings into pBuffer
|
|||
|
//
|
|||
|
PPOLICY_DOMAIN_KERBEROS_TICKET_INFO pBuffer=NULL;
|
|||
|
POLICY_DOMAIN_KERBEROS_TICKET_INFO TicketInfo;
|
|||
|
|
|||
|
NtStatus = LsaQueryDomainInformationPolicy(
|
|||
|
lsaHandle,
|
|||
|
PolicyDomainKerberosTicketInformation,
|
|||
|
(PVOID *)&pBuffer
|
|||
|
);
|
|||
|
|
|||
|
if ( NT_SUCCESS(NtStatus) && pBuffer ) {
|
|||
|
//
|
|||
|
// transfer ticket info to TicketInfo buffer
|
|||
|
//
|
|||
|
TicketInfo.AuthenticationOptions = pBuffer->AuthenticationOptions;
|
|||
|
TicketInfo.MaxTicketAge = pBuffer->MaxTicketAge;
|
|||
|
TicketInfo.MaxRenewAge = pBuffer->MaxRenewAge;
|
|||
|
TicketInfo.MaxServiceTicketAge = pBuffer->MaxServiceTicketAge;
|
|||
|
TicketInfo.MaxClockSkew = pBuffer->MaxClockSkew;
|
|||
|
|
|||
|
//
|
|||
|
// free the buffer
|
|||
|
//
|
|||
|
LsaFreeMemory((PVOID)pBuffer);
|
|||
|
|
|||
|
} else {
|
|||
|
//
|
|||
|
// no kerberos policy is configured yet because by default it's not created.
|
|||
|
// let's create it now. set a default ticket info
|
|||
|
//
|
|||
|
TicketInfo.AuthenticationOptions = POLICY_KERBEROS_VALIDATE_CLIENT;
|
|||
|
|
|||
|
TicketInfo.MaxTicketAge.QuadPart = (LONGLONG) KERBDEF_MAX_TICKET*60*60 * 10000000L;
|
|||
|
TicketInfo.MaxRenewAge.QuadPart = (LONGLONG) KERBDEF_MAX_RENEW*24*60*60 * 10000000L;
|
|||
|
TicketInfo.MaxServiceTicketAge.QuadPart = (LONGLONG) KERBDEF_MAX_SERVICE*60 * 10000000L;
|
|||
|
TicketInfo.MaxClockSkew.QuadPart = (LONGLONG) KERBDEF_MAX_CLOCK*60 * 10000000L;
|
|||
|
|
|||
|
bDefaultUsed = TRUE;
|
|||
|
}
|
|||
|
pBuffer = &TicketInfo;
|
|||
|
|
|||
|
//
|
|||
|
// process each field in pKerberosInfo
|
|||
|
//
|
|||
|
BOOL bFlagSet=FALSE;
|
|||
|
ULONG lOptions=0;
|
|||
|
ULONG lValue=0;
|
|||
|
|
|||
|
SCE_TATTOO_KEYS *pTattooKeys=NULL;
|
|||
|
DWORD cTattooKeys=0;
|
|||
|
|
|||
|
PSCESECTION hSectionDomain=NULL;
|
|||
|
PSCESECTION hSectionTattoo=NULL;
|
|||
|
|
|||
|
#define MAX_KERB_KEYS 5
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// if in policy propagation, open the policy sections
|
|||
|
// since kerberos policy is only available on DCs and kerberos policy (account policy)
|
|||
|
// can't be reset to local settings on each DC, there is no point to query/save
|
|||
|
// the tattoo values
|
|||
|
//
|
|||
|
/* do not take tattoo value for kerberos
|
|||
|
if ( (ConfigOptions & SCE_POLICY_TEMPLATE) &&
|
|||
|
hProfile ) {
|
|||
|
|
|||
|
pTattooKeys = (SCE_TATTOO_KEYS *)ScepAlloc(LPTR,MAX_KERB_KEYS*sizeof(SCE_TATTOO_KEYS));
|
|||
|
|
|||
|
if ( !pTattooKeys ) {
|
|||
|
ScepLogOutput3(1, ERROR_NOT_ENOUGH_MEMORY, SCESRV_POLICY_TATTOO_ERROR_CREATE);
|
|||
|
}
|
|||
|
}
|
|||
|
*/
|
|||
|
if ( pKerberosInfo->MaxRenewAge != SCE_NO_VALUE ) {
|
|||
|
ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
|
|||
|
(PWSTR)L"MaxRenewAge", ConfigOptions,
|
|||
|
KERBDEF_MAX_RENEW);
|
|||
|
}
|
|||
|
|
|||
|
if ( pKerberosInfo->MaxRenewAge == SCE_FOREVER_VALUE ) {
|
|||
|
|
|||
|
if ( pBuffer->MaxRenewAge.HighPart != MINLONG ||
|
|||
|
pBuffer->MaxRenewAge.LowPart != 0 ) {
|
|||
|
//
|
|||
|
// Maximum LARGE_INTEGER .ie. never
|
|||
|
//
|
|||
|
|
|||
|
pBuffer->MaxRenewAge.HighPart = MINLONG;
|
|||
|
pBuffer->MaxRenewAge.LowPart = 0;
|
|||
|
bFlagSet = TRUE;
|
|||
|
|
|||
|
}
|
|||
|
bDefined = TRUE;
|
|||
|
|
|||
|
} else if ( SCE_NO_VALUE != pKerberosInfo->MaxRenewAge ) {
|
|||
|
|
|||
|
//
|
|||
|
// ticket is renewable, the max age is stored in MaxRenewAge
|
|||
|
// using days
|
|||
|
//
|
|||
|
|
|||
|
lValue = (DWORD) (pBuffer->MaxRenewAge.QuadPart /
|
|||
|
(LONGLONG)(10000000L) );
|
|||
|
lValue /= 3600;
|
|||
|
lValue /= 24;
|
|||
|
|
|||
|
if ( lValue != pKerberosInfo->MaxRenewAge ) {
|
|||
|
|
|||
|
pBuffer->MaxRenewAge.QuadPart = (LONGLONG)pKerberosInfo->MaxRenewAge*24*3600 * 10000000L;
|
|||
|
bFlagSet = TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
bDefined = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// validate client ?
|
|||
|
//
|
|||
|
|
|||
|
if ( pKerberosInfo->TicketValidateClient != SCE_NO_VALUE ) {
|
|||
|
|
|||
|
if ( pKerberosInfo->TicketValidateClient ) {
|
|||
|
lOptions |= POLICY_KERBEROS_VALIDATE_CLIENT;
|
|||
|
}
|
|||
|
|
|||
|
ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
|
|||
|
(PWSTR)L"TicketValidateClient", ConfigOptions,
|
|||
|
KERBDEF_VALIDATE);
|
|||
|
|
|||
|
if ( ( pBuffer->AuthenticationOptions & POLICY_KERBEROS_VALIDATE_CLIENT ) !=
|
|||
|
( lOptions & POLICY_KERBEROS_VALIDATE_CLIENT ) ) {
|
|||
|
|
|||
|
|
|||
|
pBuffer->AuthenticationOptions = lOptions;
|
|||
|
bFlagSet = TRUE;
|
|||
|
}
|
|||
|
bDefined = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// max ticket age
|
|||
|
//
|
|||
|
if ( pKerberosInfo->MaxTicketAge != SCE_NO_VALUE ) {
|
|||
|
ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
|
|||
|
(PWSTR)L"MaxTicketAge", ConfigOptions,
|
|||
|
KERBDEF_MAX_TICKET);
|
|||
|
bDefined = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if ( pKerberosInfo->MaxTicketAge == SCE_FOREVER_VALUE ) {
|
|||
|
|
|||
|
if ( pBuffer->MaxTicketAge.HighPart != MINLONG ||
|
|||
|
pBuffer->MaxTicketAge.LowPart != 0 ) {
|
|||
|
//
|
|||
|
// Maximum LARGE_INTEGER .ie. never
|
|||
|
//
|
|||
|
|
|||
|
pBuffer->MaxTicketAge.HighPart = MINLONG;
|
|||
|
pBuffer->MaxTicketAge.LowPart = 0;
|
|||
|
bFlagSet = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
bDefined = TRUE;
|
|||
|
|
|||
|
} else if ( pKerberosInfo->MaxTicketAge != SCE_NO_VALUE ) {
|
|||
|
// in hours
|
|||
|
|
|||
|
|
|||
|
lValue = (DWORD) (pBuffer->MaxTicketAge.QuadPart /
|
|||
|
(LONGLONG)(10000000L) );
|
|||
|
lValue /= 3600;
|
|||
|
|
|||
|
if ( lValue != pKerberosInfo->MaxTicketAge ) {
|
|||
|
|
|||
|
pBuffer->MaxTicketAge.QuadPart = (LONGLONG)pKerberosInfo->MaxTicketAge*60*60 * 10000000L;
|
|||
|
bFlagSet = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
bDefined = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// max service ticket age
|
|||
|
//
|
|||
|
if ( pKerberosInfo->MaxServiceAge != SCE_NO_VALUE ) {
|
|||
|
ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
|
|||
|
(PWSTR)L"MaxServiceAge", ConfigOptions,
|
|||
|
KERBDEF_MAX_SERVICE);
|
|||
|
bDefined = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if ( pKerberosInfo->MaxServiceAge == SCE_FOREVER_VALUE ) {
|
|||
|
|
|||
|
if ( pBuffer->MaxServiceTicketAge.HighPart != MINLONG ||
|
|||
|
pBuffer->MaxServiceTicketAge.LowPart != 0 ) {
|
|||
|
//
|
|||
|
// Maximum LARGE_INTEGER .ie. never
|
|||
|
//
|
|||
|
|
|||
|
pBuffer->MaxServiceTicketAge.HighPart = MINLONG;
|
|||
|
pBuffer->MaxServiceTicketAge.LowPart = 0;
|
|||
|
bFlagSet = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
bDefined = TRUE;
|
|||
|
|
|||
|
} else if ( pKerberosInfo->MaxServiceAge != SCE_NO_VALUE ) {
|
|||
|
// in minutes
|
|||
|
|
|||
|
|
|||
|
lValue = (DWORD) (pBuffer->MaxServiceTicketAge.QuadPart /
|
|||
|
(LONGLONG)(10000000L) );
|
|||
|
lValue /= 60;
|
|||
|
|
|||
|
if ( lValue != pKerberosInfo->MaxServiceAge ) {
|
|||
|
|
|||
|
pBuffer->MaxServiceTicketAge.QuadPart = (LONGLONG)pKerberosInfo->MaxServiceAge*60 * 10000000L;
|
|||
|
bFlagSet = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
bDefined = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// max clock
|
|||
|
//
|
|||
|
if ( pKerberosInfo->MaxClockSkew != SCE_NO_VALUE ) {
|
|||
|
ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
|
|||
|
(PWSTR)L"MaxClockSkew", ConfigOptions,
|
|||
|
KERBDEF_MAX_CLOCK);
|
|||
|
bDefined = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if ( pKerberosInfo->MaxClockSkew == SCE_FOREVER_VALUE ) {
|
|||
|
|
|||
|
if ( pBuffer->MaxClockSkew.HighPart != MINLONG ||
|
|||
|
pBuffer->MaxClockSkew.LowPart != 0 ) {
|
|||
|
|
|||
|
//
|
|||
|
// Maximum LARGE_INTEGER .ie. never
|
|||
|
//
|
|||
|
|
|||
|
pBuffer->MaxClockSkew.HighPart = MINLONG;
|
|||
|
pBuffer->MaxClockSkew.LowPart = 0;
|
|||
|
bFlagSet = TRUE;
|
|||
|
}
|
|||
|
bDefined = TRUE;
|
|||
|
|
|||
|
} else if ( pKerberosInfo->MaxClockSkew != SCE_NO_VALUE ) {
|
|||
|
// in minutes
|
|||
|
|
|||
|
lValue = (DWORD) (pBuffer->MaxClockSkew.QuadPart /
|
|||
|
(LONGLONG)(10000000L) );
|
|||
|
lValue /= 60;
|
|||
|
|
|||
|
if ( lValue != pKerberosInfo->MaxClockSkew ) {
|
|||
|
|
|||
|
pBuffer->MaxClockSkew.QuadPart = (LONGLONG)pKerberosInfo->MaxClockSkew*60 * 10000000L;
|
|||
|
bFlagSet = TRUE;
|
|||
|
}
|
|||
|
bDefined = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if ( bFlagSet || (bDefaultUsed && bDefined) ) {
|
|||
|
//
|
|||
|
// if anything for kerberos to configure
|
|||
|
//
|
|||
|
NtStatus = LsaSetDomainInformationPolicy(
|
|||
|
lsaHandle,
|
|||
|
PolicyDomainKerberosTicketInformation,
|
|||
|
(PVOID)pBuffer
|
|||
|
);
|
|||
|
rc = RtlNtStatusToDosError( NtStatus );
|
|||
|
|
|||
|
if ( rc != NO_ERROR ) {
|
|||
|
ScepLogOutput3(1, rc, SCEDLL_SCP_ERROR_KERBEROS);
|
|||
|
} else {
|
|||
|
ScepLogOutput3(1, 0, SCEDLL_SCP_KERBEROS);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( (ConfigOptions & SCE_POLICY_TEMPLATE) &&
|
|||
|
hProfile && pTattooKeys && cTattooKeys ) {
|
|||
|
|
|||
|
ScepTattooOpenPolicySections(
|
|||
|
hProfile,
|
|||
|
szKerberosPolicy,
|
|||
|
&hSectionDomain,
|
|||
|
&hSectionTattoo
|
|||
|
);
|
|||
|
ScepLogOutput3(3,0,SCESRV_POLICY_TATTOO_ARRAY,cTattooKeys);
|
|||
|
//
|
|||
|
// some policy is different than the system setting
|
|||
|
// check if we should save the existing setting as the tattoo value
|
|||
|
// also remove reset'ed tattoo policy
|
|||
|
//
|
|||
|
ScepTattooManageValues(hSectionDomain, hSectionTattoo, pTattooKeys, cTattooKeys, rc);
|
|||
|
|
|||
|
if ( hSectionDomain ) SceJetCloseSection(&hSectionDomain,TRUE);
|
|||
|
if ( hSectionTattoo ) SceJetCloseSection(&hSectionTattoo,TRUE);
|
|||
|
}
|
|||
|
|
|||
|
if ( pTattooKeys ) ScepFree(pTattooKeys);
|
|||
|
|
|||
|
if ( ConfigOptions & SCE_RSOP_CALLBACK )
|
|||
|
|
|||
|
ScepRsopLog(SCE_RSOP_KERBEROS_INFO, rc, NULL, 0, 0);
|
|||
|
|
|||
|
//
|
|||
|
// close LSA policy
|
|||
|
//
|
|||
|
LsaClose( lsaHandle );
|
|||
|
|
|||
|
return(ScepDosErrorToSceStatus(rc));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
SCESTATUS
|
|||
|
ScepAnalyzeKerberosPolicy(
|
|||
|
IN PSCECONTEXT hProfile OPTIONAL,
|
|||
|
IN PSCE_KERBEROS_TICKET_INFO pKerInfo,
|
|||
|
IN DWORD Options
|
|||
|
)
|
|||
|
/* ++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine queries the system kerberos policy settings and compare them
|
|||
|
with the template settings.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
hProfile - the profile context
|
|||
|
|
|||
|
pKerInfo - The buffer which contains kerberos settings to compare with or
|
|||
|
the buffer to query system settings into
|
|||
|
|
|||
|
Options - the option(s) for the analysis, e.g., SCE_SYSTEM_SETTINGS
|
|||
|
|
|||
|
Return value:
|
|||
|
|
|||
|
|
|||
|
-- */
|
|||
|
{
|
|||
|
NTSTATUS NtStatus;
|
|||
|
LSA_HANDLE lsaHandle=NULL;
|
|||
|
DWORD rc32 = NO_ERROR;
|
|||
|
SCESTATUS rc=SCESTATUS_SUCCESS;
|
|||
|
PPOLICY_DOMAIN_KERBEROS_TICKET_INFO pBuffer=NULL;
|
|||
|
DWORD dValue;
|
|||
|
PSCESECTION hSection=NULL;
|
|||
|
POLICY_DOMAIN_KERBEROS_TICKET_INFO KerbTicketInfo;
|
|||
|
|
|||
|
if ( !pKerInfo ) {
|
|||
|
//
|
|||
|
// if no template info, do not analyze
|
|||
|
//
|
|||
|
if ( Options & SCE_SYSTEM_SETTINGS ) {
|
|||
|
return SCESTATUS_INVALID_PARAMETER;
|
|||
|
} else {
|
|||
|
return SCESTATUS_SUCCESS;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// open LSA policy to configure kerberos policy
|
|||
|
//
|
|||
|
NtStatus = ScepOpenLsaPolicy(
|
|||
|
MAXIMUM_ALLOWED,
|
|||
|
&lsaHandle,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
if (!NT_SUCCESS(NtStatus)) {
|
|||
|
|
|||
|
lsaHandle = NULL;
|
|||
|
rc32 = RtlNtStatusToDosError( NtStatus );
|
|||
|
ScepLogOutput3( 1, rc32, SCEDLL_LSA_POLICY);
|
|||
|
|
|||
|
return(ScepDosErrorToSceStatus(rc32));
|
|||
|
}
|
|||
|
|
|||
|
if ( !(Options & SCE_SYSTEM_SETTINGS) ) {
|
|||
|
|
|||
|
//
|
|||
|
// Prepare kerberos section
|
|||
|
//
|
|||
|
rc = ScepStartANewSection(
|
|||
|
hProfile,
|
|||
|
&hSection,
|
|||
|
(Options & SCE_GENERATE_ROLLBACK) ? SCEJET_TABLE_SMP : SCEJET_TABLE_SAP,
|
|||
|
szKerberosPolicy
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
if ( rc != SCESTATUS_SUCCESS ) {
|
|||
|
ScepLogOutput3(1, ScepSceStatusToDosError(rc),
|
|||
|
SCEDLL_SAP_START_SECTION, (PWSTR)szKerberosPolicy);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
DWORD KerbValues[MAX_KERB_ITEMS];
|
|||
|
|
|||
|
for ( dValue=0; dValue<MAX_KERB_ITEMS; dValue++ ) {
|
|||
|
KerbValues[dValue] = SCE_ERROR_VALUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// query current kerberos policy settings into pBuffer
|
|||
|
//
|
|||
|
NtStatus = LsaQueryDomainInformationPolicy(
|
|||
|
lsaHandle,
|
|||
|
PolicyDomainKerberosTicketInformation,
|
|||
|
(PVOID *)&pBuffer
|
|||
|
);
|
|||
|
|
|||
|
if ( STATUS_NOT_FOUND == NtStatus ) {
|
|||
|
|
|||
|
//
|
|||
|
// there is no Kerberos policy
|
|||
|
//
|
|||
|
KerbTicketInfo.AuthenticationOptions = POLICY_KERBEROS_VALIDATE_CLIENT;
|
|||
|
|
|||
|
KerbTicketInfo.MaxTicketAge.QuadPart = (LONGLONG) KERBDEF_MAX_TICKET*60*60 * 10000000L;
|
|||
|
KerbTicketInfo.MaxRenewAge.QuadPart = (LONGLONG) KERBDEF_MAX_RENEW*24*60*60 * 10000000L;
|
|||
|
KerbTicketInfo.MaxServiceTicketAge.QuadPart = (LONGLONG) KERBDEF_MAX_SERVICE*60 * 10000000L;
|
|||
|
KerbTicketInfo.MaxClockSkew.QuadPart = (LONGLONG) KERBDEF_MAX_CLOCK*60 * 10000000L;
|
|||
|
|
|||
|
pBuffer = &KerbTicketInfo;
|
|||
|
NtStatus = STATUS_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
rc = ScepDosErrorToSceStatus(
|
|||
|
RtlNtStatusToDosError( NtStatus ));
|
|||
|
|
|||
|
if ( NT_SUCCESS(NtStatus) && pBuffer ) {
|
|||
|
|
|||
|
//
|
|||
|
// analyze kerberos values
|
|||
|
// max ticket age
|
|||
|
//
|
|||
|
if ( pBuffer->MaxTicketAge.HighPart == MINLONG &&
|
|||
|
pBuffer->MaxTicketAge.LowPart == 0 ) {
|
|||
|
//
|
|||
|
// Maximum password age value is MINLONG,0
|
|||
|
//
|
|||
|
dValue = SCE_FOREVER_VALUE;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
dValue = (DWORD) ( pBuffer->MaxTicketAge.QuadPart /
|
|||
|
(LONGLONG)(10000000L) );
|
|||
|
//
|
|||
|
// using hours
|
|||
|
//
|
|||
|
// dValue /= 24;
|
|||
|
|
|||
|
dValue /= 3600;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
rc = SCESTATUS_SUCCESS;
|
|||
|
|
|||
|
if ( Options & SCE_SYSTEM_SETTINGS ) {
|
|||
|
|
|||
|
pKerInfo->MaxTicketAge = dValue;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
rc = ScepCompareAndSaveIntValue(
|
|||
|
hSection,
|
|||
|
L"MaxTicketAge",
|
|||
|
(Options & SCE_GENERATE_ROLLBACK),
|
|||
|
pKerInfo->MaxTicketAge,
|
|||
|
dValue);
|
|||
|
}
|
|||
|
|
|||
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|||
|
|
|||
|
KerbValues[IDX_KERB_MAX] = 1;
|
|||
|
|
|||
|
|
|||
|
if ( pBuffer->MaxRenewAge.HighPart == MINLONG &&
|
|||
|
pBuffer->MaxRenewAge.LowPart == 0 ) {
|
|||
|
//
|
|||
|
// Maximum age value is MINLONG,0
|
|||
|
//
|
|||
|
dValue = SCE_FOREVER_VALUE;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
dValue = (DWORD) ( pBuffer->MaxRenewAge.QuadPart /
|
|||
|
(LONGLONG)(10000000L) );
|
|||
|
//
|
|||
|
// using days
|
|||
|
//
|
|||
|
dValue /= 3600;
|
|||
|
dValue /= 24;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( Options & SCE_SYSTEM_SETTINGS ) {
|
|||
|
|
|||
|
pKerInfo->MaxRenewAge = dValue;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
rc = ScepCompareAndSaveIntValue(
|
|||
|
hSection,
|
|||
|
L"MaxRenewAge",
|
|||
|
(Options & SCE_GENERATE_ROLLBACK),
|
|||
|
pKerInfo->MaxRenewAge,
|
|||
|
dValue);
|
|||
|
}
|
|||
|
|
|||
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|||
|
|
|||
|
KerbValues[IDX_KERB_RENEW] = 1;
|
|||
|
|
|||
|
if ( pBuffer->MaxServiceTicketAge.HighPart == MINLONG &&
|
|||
|
pBuffer->MaxServiceTicketAge.LowPart == 0 ) {
|
|||
|
//
|
|||
|
// Maximum age value is MINLONG,0
|
|||
|
//
|
|||
|
dValue = SCE_FOREVER_VALUE;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
dValue = (DWORD) ( pBuffer->MaxServiceTicketAge.QuadPart /
|
|||
|
(LONGLONG)(10000000L) );
|
|||
|
//
|
|||
|
// using minutes
|
|||
|
//
|
|||
|
dValue /= 60;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( Options & SCE_SYSTEM_SETTINGS ) {
|
|||
|
|
|||
|
pKerInfo->MaxServiceAge = dValue;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
rc = ScepCompareAndSaveIntValue(
|
|||
|
hSection,
|
|||
|
L"MaxServiceAge",
|
|||
|
(Options & SCE_GENERATE_ROLLBACK),
|
|||
|
pKerInfo->MaxServiceAge,
|
|||
|
dValue);
|
|||
|
}
|
|||
|
|
|||
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|||
|
|
|||
|
KerbValues[IDX_KERB_SERVICE] = 1;
|
|||
|
|
|||
|
if ( pBuffer->MaxClockSkew.HighPart == MINLONG &&
|
|||
|
pBuffer->MaxClockSkew.LowPart == 0 ) {
|
|||
|
//
|
|||
|
// Maximum age value is MINLONG,0
|
|||
|
//
|
|||
|
dValue = SCE_FOREVER_VALUE;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
dValue = (DWORD) ( pBuffer->MaxClockSkew.QuadPart /
|
|||
|
(LONGLONG)(10000000L) );
|
|||
|
//
|
|||
|
// using minutes
|
|||
|
//
|
|||
|
dValue /= 60;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( Options & SCE_SYSTEM_SETTINGS ) {
|
|||
|
|
|||
|
pKerInfo->MaxClockSkew = dValue;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
rc = ScepCompareAndSaveIntValue(
|
|||
|
hSection,
|
|||
|
L"MaxClockSkew",
|
|||
|
(Options & SCE_GENERATE_ROLLBACK),
|
|||
|
pKerInfo->MaxClockSkew,
|
|||
|
dValue);
|
|||
|
}
|
|||
|
|
|||
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|||
|
|
|||
|
KerbValues[IDX_KERB_CLOCK] = 1;
|
|||
|
|
|||
|
//
|
|||
|
// validate client
|
|||
|
//
|
|||
|
dValue = ( pBuffer->AuthenticationOptions & POLICY_KERBEROS_VALIDATE_CLIENT ) ? 1 : 0;
|
|||
|
|
|||
|
if ( Options & SCE_SYSTEM_SETTINGS ) {
|
|||
|
|
|||
|
pKerInfo->TicketValidateClient = dValue;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
rc = ScepCompareAndSaveIntValue(
|
|||
|
hSection,
|
|||
|
L"TicketValidateClient",
|
|||
|
(Options & SCE_GENERATE_ROLLBACK),
|
|||
|
pKerInfo->TicketValidateClient,
|
|||
|
dValue);
|
|||
|
}
|
|||
|
|
|||
|
if ( SCESTATUS_SUCCESS == rc ) {
|
|||
|
|
|||
|
KerbValues[IDX_KERB_VALIDATE] = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( !(Options & SCE_SYSTEM_SETTINGS) ) {
|
|||
|
|
|||
|
if ( rc == SCESTATUS_SUCCESS ) {
|
|||
|
|
|||
|
ScepLogOutput3( 1, 0, SCEDLL_SAP_KERBEROS);
|
|||
|
} else {
|
|||
|
ScepLogOutput3( 1, ScepSceStatusToDosError(rc),
|
|||
|
SCEDLL_SAP_ERROR_KERBEROS);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( pBuffer != &KerbTicketInfo ) {
|
|||
|
|
|||
|
//
|
|||
|
// free the buffer
|
|||
|
//
|
|||
|
LsaFreeMemory((PVOID)pBuffer);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( !(Options & SCE_SYSTEM_SETTINGS) ) {
|
|||
|
|
|||
|
if ( SCESTATUS_SUCCESS != rc &&
|
|||
|
!(Options & SCE_GENERATE_ROLLBACK) ) {
|
|||
|
|
|||
|
for ( dValue=0; dValue<MAX_KERB_ITEMS; dValue++ ) {
|
|||
|
if ( KerbValues[dValue] == SCE_ERROR_VALUE ) {
|
|||
|
|
|||
|
ScepCompareAndSaveIntValue(
|
|||
|
hSection,
|
|||
|
KerbItems[dValue],
|
|||
|
FALSE,
|
|||
|
SCE_NO_VALUE,
|
|||
|
SCE_ERROR_VALUE
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// close the section
|
|||
|
//
|
|||
|
|
|||
|
SceJetCloseSection(&hSection, TRUE);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
LsaClose( lsaHandle );
|
|||
|
|
|||
|
if ( ( rc == SCESTATUS_PROFILE_NOT_FOUND) ||
|
|||
|
( rc == SCESTATUS_RECORD_NOT_FOUND) ) {
|
|||
|
rc = SCESTATUS_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
return(rc);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
#endif
|