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¶
- No access check is performed (BR-06).
- Initialize
myStruc.Response = Success,myStruc.Message = String.Empty. - In a
Tryblock, call H2GetUserPrincipalwith the caller-suppliedinExternalDomain. - If the principal is
Nothing, setResponse = UserDoesNotExist. - Otherwise, get the underlying
DirectoryEntryand compose the 64-bit FILETIME aslastLogonTimestamp(0).HighPart * 4294967296 + lastLogonTimestamp(0).lowpartinto aDecimal, via late-bound COM property access (BR-30). - 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 theInfoNotAvailablecode is returned.) - Otherwise, divide by
60 * 10000000to obtain minutes and setMessage = DateAdd(DateInterval.Minute, lastLogon, #1/1/1601#).ToString(BR-30). Catch: setResponse = Failure,Message = ex.Message.Finally: releaseuserPrinandde.- Return the
ADServiceResponsesentinel.
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).
Related documentation¶
- Service index
- Overview
- Architecture
- Activation and hosting
- Operations
- Operations and processes
- Business rules
- Authentication and authorization
- Configuration
- Dependencies
- Faults
- Operational runbook
- 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)