Archive: Calling LogonUser() API


Calling LogonUser() API
I'm trying to call the LogonUserA() API call from an installer, but can't seem to find the exact syntax.
Here's the call in C++:

***
if (LogonUser(UserName, NULL, Password,
  LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken)) {
***

And here's what I've got in NSIS:

***
!ifndef LogonUser
  !define LogonUser "AdvAPI32::LogonUserA(t, t, t, i, i, i) i"
!endif
!ifndef LOGON32_LOGON_NETWORK
  !define LOGON32_LOGON_NETWORK 1
!endif
!ifndef LOGON32_PROVIDER_DEFAULT
  !define LOGON32_PROVIDER_DEFAULT 0
!endif

!ifmacrondef DoLogonUser
  !macro DoLogonUser UserName Password
    System::Call "*(i) i (0) .r0"
    ;System::Call "${LogonUser}('${UserName}',,'${Password}', \
      ${LOGON32_LOGON_NETWORK}, ${LOGON32_PROVIDER_DEFAULT}, r0) .r1"
    System::Call "AdvAPI32::LogonUserA(t'${UserName}',n,t'${Password}', \
      i${LOGON32_LOGON_NETWORK},i${LOGON32_PROVIDER_DEFAULT},i r0)i.r1"

    DetailPrint "Return token: $0"
    DetailPrint "Call return: $1"
  !macroend
!endif
***

Apologies for any obvious syntax glitches, I'm an NSIS virgin!
Cheers,

  Mike


!define LOGON32_PROVIDER_DEFAULT 0
!define LOGON32_LOGON_NETWORK 3
StrCpy $1 "$UserName"
StrCpy $2 "."
StrCpy $3 "$UserPassword"
System::Call 'advapi32::LogonUserW(w r1, w r2, w r3, i ${LOGON32_LOGON_NETWORK}, i ${LOGON32_PROVIDER_DEFAULT}, *i R0)i .R5'
If the function succeeds $R5 is nonzero. It returns the token handle to $R0. You obviously need to define $UserName and $UserPassword :)

Also your definitions are wrong. Here are the logon types/providers
; Logon types
!define LOGON32_LOGON_INTERACTIVE 2
!define LOGON32_LOGON_NETWORK 3
!define LOGON32_LOGON_BATCH 4
!define LOGON32_LOGON_SERVICE 5
!define LOGON32_LOGON_UNLOCK 7
!define LOGON32_LOGON_NETWORK_CLEARTEXT 8
!define LOGON32_LOGON_NEW_CREDENTIALS 9

; Logon Providers
!define LOGON32_PROVIDER_DEFAULT 0
!define LOGON32_PROVIDER_WINNT35 1
!define LOGON32_PROVIDER_WINNT40 2
!define LOGON32_PROVIDER_WINNT50 3


CF

Great, thanks for that, got it working now!

In case anyone else needs it then here's what I ended up with:

***
!ifndef LogonUser
  !define LogonUser "AdvAPI32::LogonUserW(w, w, w, i, i, *i) i"
!endif
!ifndef CloseHandle
  !define CloseHandle "Kernel32::CloseHandle(i) i"
!endif
!ifndef LOGON32_LOGON_NETWORK
  !define LOGON32_LOGON_NETWORK 3
!endif
!ifndef LOGON32_PROVIDER_DEFAULT
  !define LOGON32_PROVIDER_DEFAULT 0
!endif

!define DEBUG

!ifmacrondef DoLogonUser
  ;Logs on a user, and returns their login token in $R0
  !macro DoLogonUser UserName Password
    System::Call "${LogonUser}('${UserName}', '.', '${Password}', \
      ${LOGON32_LOGON_NETWORK}, ${LOGON32_PROVIDER_DEFAULT}, .R0) .R5"

    StrCmp $R5 0 logOnErr
    goto logOnDone
  logOnErr:
    DetailPrint "Error: Logging user '${UserName}' on"
  logOnDone:
    !ifdef DEBUG
      DetailPrint "Return token: $R0"
      DetailPrint "Call return: $R5"
    !endif
  !macroend
!endif

!ifmacrondef DoLogoffUser
  ;Logs off a user token (Returned from DoLogonUser)
  !macro DoLogoffUser Token
    System::Call "${CloseHandle}(${Token}) .R5"
    StrCmp $R5 0 logOffErr
    goto logOffDone
  logOffErr:
    DetailPrint "Error: Logging user off (Token: '${Token}')"
  logOffDone:
    !ifdef DEBUG
      DetailPrint "Close return: $R5"
    !endif
  !macroend
!endif
***

Example usage:

***
; Perform user login
!insertmacro DoLogonUser "username" "password"

; Store user token
StrCpy $8 $R0

; -- stuff here --

; Logoff user
!insertmacro DoLogoffUser $8
***


Some additional notes to this method to check if User could be logged on.
This will only work with Windows XP + greater Version.
In Windows 2000 there had to be an LocalPolicy set which is called "se_tcb_name" (Act as part of the Operating System).


can i use this for detecting users logged in or not?


No.