windows-nt/Source/XPSP1/NT/net/ias/providers/ntuser/auth/acctinfo.cpp
2020-09-26 16:20:57 +08:00

166 lines
3.6 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998, Microsoft Corp. All rights reserved.
//
// FILE
//
// acctinfo.cpp
//
// SYNOPSIS
//
// Defines the class AccountInfo.
//
// MODIFICATION HISTORY
//
// 10/21/1998 Original version.
//
///////////////////////////////////////////////////////////////////////////////
#include <ias.h>
#include <lm.h>
#include <acctinfo.h>
#include <lockkey.h>
#include <new>
// Registry value names.
const WCHAR VALUE_NAME_DENIALS[] = L"Denials";
// Delimeter used for account names (registry won't allow backslash).
const WCHAR ACCOUNT_NAME_DELIMETER = L':';
// The shared LockoutKey.
LockoutKey AccountInfo::root;
AccountInfo* AccountInfo::open(PCWSTR domain, PCWSTR username) throw ()
{
// If account lockout is disabled or the input parameters are invalid,
// we return NULL.
if (root.getMaxDenials() == 0 || domain == NULL || username == NULL)
{
return NULL;
}
// Calculate the memory needed.
size_t nbyte = sizeof(AccountInfo) +
sizeof(WCHAR) * (wcslen(domain) + wcslen(username));
// Allocate a chunk.
PVOID p = malloc(nbyte);
// Construct the object in place.
return p ? new (p) AccountInfo(domain, username) : NULL;
}
// Close an AccountInfo object; 'info' may be NULL.
void AccountInfo::close(AccountInfo* info) throw ()
{
if (info)
{
// Invoke the destructor.
info->~AccountInfo();
// Free the memory.
free(info);
}
}
bool AccountInfo::isLockedOut() const throw ()
{
DWORD maxDenials = root.getMaxDenials();
return maxDenials && maxDenials <= denials;
}
void AccountInfo::initialize() throw ()
{
root.initialize();
}
void AccountInfo::finalize() throw ()
{
root.finalize();
}
AccountInfo::AccountInfo(PCWSTR domain, PCWSTR username) throw ()
: denials(0)
{
// Copy in the domain.
size_t len = wcslen(domain);
memcpy(identity, domain, len * sizeof(WCHAR));
// Set the delimiter.
delim = identity + len;
*delim = ACCOUNT_NAME_DELIMETER;
// Copy in the username.
wcscpy(delim + 1, username);
// Open the registry entry.
hKey = root.openEntry(identity);
// Reset the delimeter for the getDomain and getUserName accessors.
*delim = L'\0';
if (hKey)
{
// The key exists, so read the denials.
DWORD type, data, cb = sizeof(DWORD);
LONG result = RegQueryValueExW(
hKey,
VALUE_NAME_DENIALS,
NULL,
&type,
(LPBYTE)&data,
&cb
);
if (result == NO_ERROR && type == REG_DWORD && cb == sizeof(DWORD))
{
denials = data;
}
// If the denials are zero, persist will delete the key.
if (denials == 0) { persist(); }
}
}
AccountInfo::~AccountInfo() throw ()
{
if (hKey) { RegCloseKey(hKey); }
}
void AccountInfo::persist() throw ()
{
if (denials > 0)
{
// Make sure we have a key to write to.
if (!hKey)
{
*delim = ACCOUNT_NAME_DELIMETER;
hKey = root.createEntry(identity);
*delim = L'\0';
}
// Update the value.
RegSetValueExW(
hKey,
VALUE_NAME_DENIALS,
0,
REG_DWORD,
(CONST BYTE*)&denials,
sizeof(DWORD)
);
}
else if (hKey)
{
// We never store zero denials, so close the key ...
RegCloseKey(hKey);
hKey = NULL;
// ... and delete.
*delim = ACCOUNT_NAME_DELIMETER;
root.deleteEntry(identity);
*delim = L'\0';
}
}