Java Q&A
by Elisabeth Strunk 

Listing One
LPTSTR lpszUsername // string that specifies the user name
LPTSTR lpszDomain   // string that specifies the domain or server
LPTSTR lpszPassword // string that specifies the password
DWORD dwLogonType   // specifies type of logon operation
    Values include:
    LOGON32_LOGON_INTERACTIVE   //returns impersonation token with user's
             // credentials. the token can then be used to run other processes
             //as that user.
    LOGON32_LOGON_NETWORK   //fastest, but does not return credentials
DWORD dwLogonProvider   // specifies the logon provider
   Values include:
    LOGON32_PROVIDER_DEFAULT
    LOGON32_PROVIDER_WINNT40
PHANDLE phToken         //pointer variable to receive impersonation token
handle. Remember to allocate space for this--LogonUserA does not it for you.


Listing Two
// You will want to check to ensure you have deallocated memory through
// every error path. I have left some of this out for readability.

#include "logon_JavaNTLogon.h"  // Header file output by the RMI registry
#include <windows.h>
#include <iostream.h>
#include <string.h>

//tells the compiler the function signature to expect.
typedef BOOL (CALLBACK* LPFNDLLFUNC1)(LPTSTR, LPTSTR, LPTSTR, DWORD,
                                                         DWORD, PHANDLE);
JNIEXPORT jboolean JNICALL Java_logon_JavaNTLogon_logonUserA
    (JNIEnv * env, jclass obj, jstring userName, jstring userPass)
{
  //declare all these variables we need
  jboolean successful=0;

  HINSTANCE hDLL;         // Handle to DLL
  LPFNDLLFUNC1 f1;        // Function pointer
  BOOL ReturnVal;
  LPTSTR lpszUsername = new char[12];
  LPTSTR lpszDomain = "BFUSA";
  LPTSTR lpszPassword = new char[30];
  DWORD dwLogonType = LOGON32_LOGON_INTERACTIVE;
  DWORD dwLogonProvider = LOGON32_PROVIDER_DEFAULT;
  PHANDLE phToken = (PHANDLE)malloc(sizeof(HANDLE));

  //convert the java strings to UTF-8 strings so
  // the dll can deal with them
  const char * Username = env->GetStringUTFChars(userName, 0);
  const char * Userpass = env->GetStringUTFChars(userPass, 0);

  //copy them into non-constant arrays for the function call
  strcpy(lpszUsername, Username);
  strcpy(lpszPassword, Userpass);

  hDLL = LoadLibrary("Advapi32.dll");
  if (hDLL != NULL)
  {
   f1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, "LogonUserA");
   if (!f1)
   {
        // handle the error
    jclass newExcCls = env->FindClass("java/lang/Exception");
    if (newExcCls == 0) {
          return 0;
       }
        env->ThrowNew(newExcCls,
             "couldn't find the Windows LogonUserA function");
   }
   else
   {  // try to call the function
      ReturnVal = f1(lpszUsername, lpszDomain, lpszPassword, dwLogonType,
         dwLogonProvider, phToken);
      successful = (jboolean)ReturnVal;
   }
  }
  else
  {
    jclass newExcCls = env->FindClass("java/lang/Exception");
       if (newExcCls == 0)
       {
          return 0;
       }
       env->ThrowNew(newExcCls, "couldn't load Advapi32.dll in native code");
  }
  FreeLibrary(hDLL);
  free(lpszUsername);
  free(lpszPassword);
  free(phToken);
  env->ReleaseStringUTFChars(userName, Username);
  env->ReleaseStringUTFChars(userPass, Userpass);
  return successful;
}


Listing Three
public static boolean logonUser(String userName, String password)
throws RemoteException
{
    boolean isValid = false;
    // There must be a security manager for certain classes to be
    // served through RMI.  If you are getting security exceptions, you
    // may have to define your own security manager.
    if (System.getSecurityManager() == null) {
        System.setSecurityManager(new java.rmi.RMISecurityManager());
    }
    try {
        // Specify the name of the server the remote logon object is on,
        // the port that the remote RMI registry is listening on, and the
        // name of the remote object we want to access.  Format is just
        // like a URL.  1099 is the default port for RMI.
        String remoteServer = "//myServer:1099/LogonUser";

        // Get a handle on the remote logon object by doing an RMI lookup.
        LogonUser user = (LogonUser) java.rmi.Naming.lookup(remoteServer);

        // Call the NT authentication method on the remote object. True means
        // the username and password was successfully authenticated, False
        // means it wasn't.
        isValid = user.validateUser(userName, password);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return isValid;
}





3


