Leaked source code of windows server 2003
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

//+-----------------------------------------------------------------------
//
// 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);
}