FIX: LogonUserW() Fails If lpszDomain Is NULL (245683)



The information in this article applies to:

  • Microsoft Win32 Application Programming Interface (API), when used with:
    • the operating system: Microsoft Windows NT 4.0

This article was previously published under Q245683

SYMPTOMS

When you are performing a logon operation by using the LogonUser() API, it is sometimes desirable to pass NULL for the name of the domain or server whose account database should be accessed. In this case, the system first attempts to validate the specified user account by using the computer's local account database. If the user does not exist in the local database, an attempt is then made to validate the user by searching the account databases of the computer's trusted domains until a match is found.

The ANSI version of this API, LogonUserA(), works as expected. However on Windows NT 4.0, the Unicode version, LogonUserW(), causes an access violation within NTDLL.dll if the lpszDomain parameter is passed as NULL.

CAUSE

When NULL is passed for the domain name, LogonUserW() makes the incorrect assumption that the domain was passed as part of an initialized UNICODE_STRING structure. An attempt is made to access other members of this structure, which results in an access violation.

RESOLUTION

The easiest way to work around this problem is to explicitly call LogonUserA(), expressing the user name and password as ANSI strings.

It is also possible to work around this problem by coercing the NULL value for the domain name into a UNICODE_STRING structure and passing it to LogonUserW(). The following sample code demonstrates how to do this.

NOTE: The following approach should only be used on Windows NT 4.0. Furthermore, it should only be used when it is necessary to call LogonUserW() with NULL for the domain name. If an actual string is to be passed for the domain name, there is no need to put it into a UNICODE_STRING structure.
#define UNICODE
#define _UNICODE

#include <windows.h>
#include <ntsecapi.h>
#include <lmcons.h>
#include <stdio.h>

#define USERNAME L"Tristan"
#define PASSWORD L"Password"

void wmain() {

   WCHAR  szDomain[1] = {NULL};
   WCHAR  szUser[UNLEN+1];
   WCHAR  szPw[PWLEN+1];
   HANDLE hToken;

   UNICODE_STRING Domain;

   Domain.Buffer = (PWSTR) &szDomain;
   Domain.Length = 0;
   Domain.MaximumLength = 2;

   wcsncpy(szUser, USERNAME, UNLEN);
   wcsncpy(szPw, PASSWORD, PWLEN);

   if (!LogonUserW(szUser, Domain.Buffer, szPw, LOGON32_LOGON_NETWORK,
         LOGON32_PROVIDER_DEFAULT, &hToken)) {
      wprintf(L"LogonUser() failed with error %d\n", GetLastError());
      return;
   }

   CloseHandle(hToken);
}
				

STATUS

Microsoft has confirmed that this is a bug in Windows NT 4.0.

This bug was corrected in Windows 2000.

Modification Type:MinorLast Reviewed:11/15/2003
Keywords:kbACL kbAPI kbbug kbfix kbKernBase kbSecurity KB245683