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
|