PSS ID Number: 151082
Article Last Modified on 11/8/2003
HKEY_LOCAL_MACHINE\
SYSTEM\
CurrentControlSet\
Control\
Lsa\
Notification Packages (value of type REG_MULTI_SZ)
Description Examples
English Upper Case Letters A, B, C, ... Z
English Lower Case Letters a, b, c, ... z
Westernized Arabic Numerals 0, 1, 2, ... 9
Non-alphanumeric ("Special characters") E.g., punctuation symbols.
/*++
Copyright (c) 1995, 1996 Microsoft Corporation
Module Name:
pswdntfy.c
Abstract:
This module illustrates how to implement password change
notification and password filtering in Windows NT 4.0.
Password change notification is useful for synchronization of
non-Windows NT account databases.
Password change filtering is useful for enforcing quality or
strength of passwords in an Windows NT account database.
This sample illustrates one approach to enforcing additional
password quality.
Author:
Scott Field (sfield) 14-May-96
--*/
#include <windows.h>
#include "ntsecapi.h" // \mstools\samples\win32\winnt\security\include\
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif
NTSTATUS
NTAPI
PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING Password
)
/*++
Routine Description:
This (optional) routine is notified of a password change.
Arguments:
UserName - Name of user whose password changed
RelativeId - RID of the user whose password changed
Password - Cleartext new password for the user
Return Value:
STATUS_SUCCESS only - errors from packages are ignored.
--*/
{
#ifdef DEBUG
LPWSTR String;
String = HeapAlloc(GetProcessHeap(), 0,
Password->Length + UserName->Length + (256*sizeof(WCHAR)));
swprintf(String,
L"Password for account %.*ls (rid 0x%x) changed to %.*ls\n",
UserName->Length / sizeof(WCHAR),
UserName->Buffer,
RelativeId,
Password->Length / sizeof(WCHAR),
Password->Buffer
);
OutputDebugStringW( String );
ZeroMemory(String,
Password->Length + UserName->Length + (256*sizeof(WCHAR)));
HeapFree(GetProcessHeap(), 0, String);
#endif
return STATUS_SUCCESS;
}
BOOL
NTAPI
PasswordFilter(
PUNICODE_STRING UserName,
PUNICODE_STRING FullName,
PUNICODE_STRING Password,
BOOL SetOperation
)
/*++
Routine Description:
This (optional) routine is notified of a password change.
Arguments:
UserName - Name of user whose password changed
FullName - Full name of the user whose password changed
NewPassword - Cleartext new password for the user
SetOperation - TRUE if the password was SET rather than CHANGED
Return Value:
TRUE if the specified Password is suitable (complex, long, etc).
The system will continue to evaluate the password update request
through any other installed password change packages.
FALSE if the specified Password is unsuitable. The password change
on the specified account will fail.
--*/
{
BOOL bComplex = FALSE; // assume the password in not complex enough
DWORD cchPassword;
PWORD CharType;
DWORD i;
DWORD dwNum = 0;
DWORD dwUpper = 0;
DWORD dwLower = 0;
//
// check if the password is complex enough for our liking by
// checking that at least two of the four character types are
// present.
//
CharType = HeapAlloc(GetProcessHeap(), 0, Password->Length);
if(CharType == NULL) return FALSE;
cchPassword = Password->Length / sizeof(WCHAR);
if(GetStringTypeW(
CT_CTYPE1,
Password->Buffer,
cchPassword,
CharType
)) {
for(i = 0 ; i < cchPassword ; i++) {
//
// keep track of what type of characters we have encountered
//
if(CharType[i] & C1_DIGIT) {
dwNum = 1;
continue;
}
if(CharType[i] & C1_UPPER) {
dwUpper = 1;
continue;
}
if(CharType[i] & C1_LOWER) {
dwLower = 1;
continue;
}
if(!(CharType[i] & (C1_ALPHA | C1_DIGIT) )) {
//
// any other character types make the password complex
//
dwNum = 2;
break;
}
} // for
//
// Indicate whether we encountered enough password complexity
//
if( (dwNum + dwUpper + dwLower) >= 2 )
bComplex = TRUE;
ZeroMemory( CharType, Password->Length );
} // if
HeapFree(GetProcessHeap(), 0, CharType);
return bComplex;
}
BOOL
NTAPI
InitializeChangeNotify(
void
)
/*++
Routine Description:
This (optional) routine is called when the password change package
is loaded.
Arguments:
Return Value:
TRUE if initialization succeeded.
FALSE if initialization failed. This DLL will be unloaded by the
system.
--*/
{
#ifdef DEBUG
OutputDebugString( TEXT("Initialize Change Notify called!\n") );
#endif
//
// initialize any critical sections associated with password change
// events, etc.
//
return TRUE;
}
/********
pswdntfy.def
------------
LIBRARY pswdntfy
EXPORTS
InitializeChangeNotify
PasswordChangeNotify
PasswordFilter
********/
Additional query words: 4.00 password notification authenticate sync
Keywords: kbAPI kbcode kbFAQ kbhowto kbKernBase KB151082
Technology: kbAudDeveloper kbOSWin2000 kbOSWinNT400 kbOSWinNTSearch kbOSWinSearch kbOSWinXP kbOSWinXPSearch kbSDKSearch kbWin32SDK400 kbWin32SDKSearch kbWin32sSearch