Skip to content

GetUserLastLogon (OP-16)

Request and response

Part Type Description
inUserId String The SamAccountName to look up.
inExternalDomain Boolean Selects external.saif.com when True, corp.saif.com when False (BR-07).
Part Type Description
<return> ADServiceResponse Response (EResponse code) and Message (the rendered last-logon date-time string on success).

WebMethod attributes

<WebMethod()> — bare, no arguments supplied.

Steps

  1. No access check is performed (BR-06).
  2. Initialize myStruc.Response = Success, myStruc.Message = String.Empty.
  3. In a Try block, call H2 GetUserPrincipal with the caller-supplied inExternalDomain.
  4. If the principal is Nothing, set Response = UserDoesNotExist.
  5. Otherwise, get the underlying DirectoryEntry and compose the 64-bit FILETIME as lastLogonTimestamp(0).HighPart * 4294967296 + lastLogonTimestamp(0).lowpart into a Decimal, via late-bound COM property access (BR-30).
  6. If the composed value is less than 1, set Response = InfoNotAvailable. (An authored comment reads "let's assume they logged in Jan 1, 2000", but no such date is actually applied — only the InfoNotAvailable code is returned.)
  7. Otherwise, divide by 60 * 10000000 to obtain minutes and set Message = DateAdd(DateInterval.Minute, lastLogon, #1/1/1601#).ToString (BR-30).
  8. Catch: set Response = Failure, Message = ex.Message.
  9. Finally: release userPrin and de.
  10. Return the ADServiceResponse sentinel.

A user with no lastLogonTimestamp attribute yields Failure with a .NET exception message rather than InfoNotAvailable. The rendered timestamp uses the server's current culture and time zone, which is environment-dependent.

Process flow

flowchart TD
    A["Call GetUserLastLogon"] --> B["GetUserPrincipal<br>caller-selected domain"]
    B -->|"Nothing"| C["Response = UserDoesNotExist"]
    B -->|"Found"| D["Compose FILETIME<br>HighPart * 4294967296 + lowPart"]
    D --> E{"Value < 1?"}
    E -->|"Yes"| F["Response = InfoNotAvailable"]
    E -->|"No"| G["Divide by 60 * 10000000<br>DateAdd from 1/1/1601"]
    G --> H["Message = rendered timestamp<br>Response = Success"]
    D -->|"Exception"| I["Response = Failure<br>Message = ex.Message"]
    C --> J["Return ADServiceResponse"]
    F --> J
    H --> J
    I --> J

Shared state effects

None — this operation touches no process-wide state; all locals are per-request.

Error handling

This operation never faults: every failure path — an unresolved user, an unset lastLogonTimestamp attribute, or any other directory exception — is caught and mapped to Response = Failure with ex.Message in Message. See Faults for the service-wide fault model.

Authorization

None in code. This is one of the eleven ungated operations that disclose directory data to any caller who can reach the endpoint (see Authentication and authorization and Tech debt).

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • src\ADUserServices\clsADUserServices.asmx.vb (lines 649-685)