You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
6.2 KiB
218 lines
6.2 KiB
//+-----------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1991 - 1992
|
|
//
|
|
// File: restrict.cxx
|
|
//
|
|
// Contents: Logon restriction code
|
|
// This routine is called only on the KDC (not in kerberos)
|
|
//
|
|
//
|
|
// History: 4-Aug-1996 MikeSw Created from tickets.cxx
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
#include "kdcsvr.hxx"
|
|
|
|
#include "fileno.h"
|
|
#define FILENO FILENO_RESTRICT
|
|
|
|
|
|
extern SAMPR_HANDLE GlobalAccountDomainHandle;
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: KerbCheckLogonRestrictions
|
|
//
|
|
// Synopsis: Checks logon restrictions for an account
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: UserHandle - handle to a user
|
|
// Workstation - Name of client's workstation
|
|
// SecondsToLogon - Receives logon duration in seconds
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns: kerberos errors
|
|
//
|
|
// Notes:
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
KERBERR
|
|
KerbCheckLogonRestrictions(
|
|
IN OPTIONAL PVOID UserHandle,
|
|
IN PUNICODE_STRING Workstation,
|
|
IN PUSER_ALL_INFORMATION UserAll,
|
|
IN ULONG LogonRestrictionsFlags,
|
|
OUT PLARGE_INTEGER LogoffTime,
|
|
OUT PNTSTATUS RetStatus
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
KERBERR KerbErr;
|
|
LARGE_INTEGER KickoffTime;
|
|
LARGE_INTEGER CurrentTime;
|
|
PLARGE_INTEGER TempTime;
|
|
|
|
GetSystemTimeAsFileTime((PFILETIME) &CurrentTime );
|
|
|
|
//
|
|
// The Administrator can be locked out #248363
|
|
// We need to check Lockout before PW_Expired or PW_MustChange
|
|
//
|
|
|
|
if (UserAll->UserAccountControl & USER_ACCOUNT_AUTO_LOCKED)
|
|
{
|
|
BOOL LockOut = TRUE;
|
|
|
|
if (UserAll->UserId == DOMAIN_USER_RID_ADMIN)
|
|
{
|
|
PSAMPR_DOMAIN_INFO_BUFFER DomainPasswordInfo = NULL;
|
|
|
|
D_DebugLog((DEB_TRACE,"KLIN(%x) Admin reached lockout limit - check sys properties\n",
|
|
KLIN(FILENO,__LINE__)));
|
|
|
|
Status = SamrQueryInformationDomain(
|
|
GlobalAccountDomainHandle,
|
|
DomainPasswordInformation,
|
|
&DomainPasswordInfo );
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
Status = STATUS_INTERNAL_ERROR;
|
|
goto Cleanup;
|
|
}
|
|
if( ((DOMAIN_PASSWORD_INFORMATION *)DomainPasswordInfo)->PasswordProperties & DOMAIN_LOCKOUT_ADMINS)
|
|
{
|
|
|
|
D_DebugLog((DEB_TRACE,"KLIN(%x) Domain admin lockout enabled\n",
|
|
KLIN(FILENO,__LINE__)));
|
|
//
|
|
// get the safeboot mode - do not lockout Admin if in safeboot mode
|
|
//
|
|
|
|
if (KdcGlobalGlobalSafeBoot)
|
|
{
|
|
D_DebugLog((DEB_TRACE,"KLIN(%x) KDC in SafeBoot - no admin lockout\n",
|
|
KLIN(FILENO,__LINE__)));
|
|
LockOut = FALSE;
|
|
}
|
|
|
|
} else
|
|
{
|
|
D_DebugLog((DEB_TRACE,"KLIN(%x) Domain admin lockout disabled\n",
|
|
KLIN(FILENO,__LINE__)));
|
|
LockOut = FALSE;
|
|
}
|
|
SamIFree_SAMPR_DOMAIN_INFO_BUFFER( DomainPasswordInfo,
|
|
DomainPasswordInformation );
|
|
}
|
|
|
|
if (LockOut) {
|
|
Status = STATUS_ACCOUNT_LOCKED_OUT;
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check the restrictions SAM doesn't:
|
|
//
|
|
|
|
TempTime = (PLARGE_INTEGER) &UserAll->AccountExpires;
|
|
if ((TempTime->QuadPart != 0) &&
|
|
(TempTime->QuadPart < CurrentTime.QuadPart))
|
|
{
|
|
Status = STATUS_ACCOUNT_EXPIRED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// For user accounts, check if the password has expired.
|
|
//
|
|
|
|
if (((LogonRestrictionsFlags & KDC_RESTRICT_IGNORE_PW_EXPIRATION) == 0) &&
|
|
((UserAll->UserAccountControl & USER_NORMAL_ACCOUNT) != 0))
|
|
{
|
|
TempTime = (PLARGE_INTEGER) &UserAll->PasswordMustChange;
|
|
|
|
if (TempTime->QuadPart < CurrentTime.QuadPart)
|
|
{
|
|
if (TempTime->QuadPart == 0)
|
|
{
|
|
Status = STATUS_PASSWORD_MUST_CHANGE;
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_PASSWORD_EXPIRED;
|
|
}
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
if ((UserAll->UserAccountControl & USER_ACCOUNT_DISABLED))
|
|
{
|
|
Status = STATUS_ACCOUNT_DISABLED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ((UserAll->UserAccountControl & USER_SMARTCARD_REQUIRED) &&
|
|
((LogonRestrictionsFlags & KDC_RESTRICT_PKINIT_USED) == 0))
|
|
{
|
|
Status = STATUS_SMARTCARD_LOGON_REQUIRED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ((LogonRestrictionsFlags & KDC_RESTRICT_SAM_CHECKS) == 0)
|
|
{
|
|
|
|
DsysAssert(UserHandle); // don't need this unless we're doing SAM checks.
|
|
|
|
Status = SamIAccountRestrictions(
|
|
UserHandle,
|
|
Workstation,
|
|
&UserAll->WorkStations,
|
|
&UserAll->LogonHours,
|
|
LogoffTime,
|
|
&KickoffTime
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
*RetStatus = Status;
|
|
switch(Status)
|
|
{
|
|
case STATUS_SUCCESS:
|
|
KerbErr = KDC_ERR_NONE;
|
|
break;
|
|
case STATUS_ACCOUNT_EXPIRED: // See bug #23456
|
|
case STATUS_ACCOUNT_LOCKED_OUT:
|
|
case STATUS_ACCOUNT_DISABLED:
|
|
case STATUS_INVALID_LOGON_HOURS:
|
|
case STATUS_LOGIN_TIME_RESTRICTION:
|
|
case STATUS_LOGIN_WKSTA_RESTRICTION:
|
|
KerbErr = KDC_ERR_CLIENT_REVOKED;
|
|
break;
|
|
case STATUS_PASSWORD_EXPIRED:
|
|
case STATUS_PASSWORD_MUST_CHANGE:
|
|
KerbErr = KDC_ERR_KEY_EXPIRED;
|
|
break;
|
|
default:
|
|
KerbErr = KDC_ERR_POLICY;
|
|
}
|
|
return(KerbErr);
|
|
}
|
|
|
|
|
|
|