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