clsADUserServices
clsADUserServices is the sole service class hosted by this repository. It provisions, modifies, unlocks, and deletes Active Directory user accounts; manages group membership; reads directory attributes (email, fax, printer, last logon, group/resource membership); and implements the service's own IP-allow-list access-control primitive (CheckAccess). All directory access is concentrated in three private helpers (GetContext, GetUserPrincipal, GetGroupPrincipal) shared by every operation. No consumer of this service is identifiable from the repository.
Field
Value
Service class
ADUserServices.clsADUserServices
Marker file
clsADUserServices.asmx
Codebehind
src\ADUserServices\clsADUserServices.asmx.vb
SOAP namespace
http://tempuri.org/
WSI conformance
WsiProfiles.BasicProfile1_1
Base class
System.Web.Services.WebService
ScriptService
Commented out (not active)
Constructor work
None - no class constructor exists in the codebehind
Shared state
None process-wide; four Private instance fields live for one request only: m_CredUserId, m_CredPass (never assigned or read anywhere - dead), m_FoundUser (written/read only by dead code), m_LastMessage (written by the three directory helpers on exception, never read or returned by any operation)
Class-level authorization
None in code - every check is per-operation
Operations
19
Also hosted in
- (single host)
HelloWorld
Returns a constant greeting string; a connectivity/scaffolding check with no directory interaction.
Field
Value
Operation name
HelloWorld
Message name
HelloWorld
SOAP action
http://tempuri.org/HelloWorld
Implementing member
clsADUserServices.HelloWorld (src\ADUserServices\clsADUserServices.asmx.vb:86-89)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/hello-world.md
No input parts - the request message is empty.
HelloWorld - Output message
Field
Value
Return type
String
Response element
HelloWorldResult
Meaning
A constant greeting string, "Hello World", left over from Visual Studio ASMX project scaffolding
Empty-result behavior
Never empty - the literal is hard-coded and always returned
HelloWorld - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
-
Never
Cannot fail - no branching, no directory call
No
HelloWorld - Authorization
None in code. See Authentication and authorization .
HelloWorld - Side effects
Aspect
Finding
Records written
None
Downstream calls
None
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Identical result on every call
HelloWorld - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<HelloWorld xmlns= "http://tempuri.org/" />
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<HelloWorldResponse xmlns= "http://tempuri.org/" >
<HelloWorldResult> Hello World</HelloWorldResult>
</HelloWorldResponse>
</soap:Body>
</soap:Envelope>
AddUser
Creates an Active Directory user account in the external domain and sets its attributes.
Field
Value
Operation name
AddUser
Message name
AddUser
SOAP action
http://tempuri.org/AddUser
Implementing member
clsADUserServices.AddUser (src\ADUserServices\clsADUserServices.asmx.vb:91-197)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
Access-checked - If (Not CheckAccess().HasAccess) Then Return AccessDenied() (BR-01 )
Process
operations/add-user.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inPassword
String
Yes
-
Initial password; empty string substitutes a hard-coded default password literal (never reproduced here - see tech-debt.md SEC-05)
inName
String
Yes
-
Directory Name attribute*
inGivenName
String
Yes
-
GivenName*
inSurName
String
Yes
-
Surname*
inDescription
String
Yes
-
Description*
inPhoneNum
String
Yes
-
telephoneNumber (written only when non-empty)*
inMailAddr
String
Yes
-
mail (written only when non-empty)*
inTitle
String
Yes
-
title (written only when non-empty)*
inInfo
String
Yes
-
info (written only when non-empty)*
inCompany
String
Yes
-
company (written only when non-empty)*
inFAXNum
String
Yes
-
facsimileTelephoneNumber (written only when non-empty)*
inDivision
String
Yes
-
division (written only when non-empty)*
AddUser - Output message
Field
Value
Return type
ADServiceResponse
Response element
AddUserResult
Meaning
Outcome of the account-creation attempt
Empty-result behavior
Not applicable - the structure is always populated
Member
Type
Nullable
Purpose
Message
String
Yes
"" on success; "Access Denied" on denial; ex.Message on a caught save/commit failure
Response
EResponse
No
Success, or Failure (denial, existing user TD-17 , or a caught save/commit exception)
AddUser - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Access denied
CheckAccess().HasAccess is False
ADServiceResponse{Response=Failure, Message="Access Denied"}
No - handled, no fault
Existing user
H2 finds an existing principal for inUserId
ADServiceResponse{Response=Failure} - UserExists is set then immediately overwritten (TD-17 , unreachable on the wire)
No - handled, no fault
userPrin.Save() failure
AD rejects the new principal (policy, duplicate, connectivity)
ADServiceResponse{Response=Failure, Message=ex.Message} - execution continues into attribute writes on the unsaved principal (TD-18 , HIGH )
Yes - ex.Message copied into Message
dirEntry.CommitChanges() failure
Attribute commit fails after a successful save
ADServiceResponse{Response=Failure, Message=ex.Message}
Yes - ex.Message copied into Message
Directory/context construction failure
Failure in GetContext/New UserPrincipal/property assignment, outside both Try blocks
SoapException produced by ASP.NET
Yes
AddUser - Authorization
Access-checked: the operation's first statement is If (Not CheckAccess().HasAccess) Then Return AccessDenied() (BR-01 ). See Authentication and authorization .
AddUser - Side effects
Aspect
Finding
Records written
None (no database) - writes a new UserPrincipal/DirectoryEntry object under CN=Users, + the external container in Active Directory
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement and System.DirectoryServices
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
A second call with the same inUserId returns Response=Failure (the UserExists code is unreachable - TD-17 ); the account is not modified
AddUser - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<AddUser xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inPassword><value></inPassword>
<inName><value></inName>
<inGivenName><value></inGivenName>
<inSurName><value></inSurName>
<inDescription><value></inDescription>
<inPhoneNum><value></inPhoneNum>
<inMailAddr><value></inMailAddr>
<inTitle><value></inTitle>
<inInfo><value></inInfo>
<inCompany><value></inCompany>
<inFAXNum><value></inFAXNum>
<inDivision><value></inDivision>
</AddUser>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<AddUserResponse xmlns= "http://tempuri.org/" >
<AddUserResult>
<Message></Message>
<Response> Success</Response>
</AddUserResult>
</AddUserResponse>
</soap:Body>
</soap:Envelope>
UnlockAccount
Unlocks an Active Directory account in the external domain if it is currently locked out.
Field
Value
Operation name
UnlockAccount
Message name
UnlockAccount
SOAP action
http://tempuri.org/UnlockAccount
Implementing member
clsADUserServices.UnlockAccount (src\ADUserServices\clsADUserServices.asmx.vb:200-226)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
Access-checked (BR-01 )
Process
operations/unlock-account.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
UnlockAccount - Output message
Field
Value
Return type
ADServiceResponse
Response element
UnlockAccountResult
Meaning
Outcome of the unlock attempt
Empty-result behavior
Not applicable
Member
Type
Nullable
Purpose
Message
String
Yes
Free-text wording distinguishing "unlocked", "was not locked", and "not unlocked" - this distinction is not carried in Response
Response
EResponse
No
UserDoesNotExist, Success (covers unlocked, already-unlocked, and unlock-did-not-take-effect), or Failure + ex.Message
UnlockAccount - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Access denied
CheckAccess().HasAccess is False
Sentinel Failure/"Access Denied"
No
User not found
H2 returns Nothing
Sentinel UserDoesNotExist
No
Any other exception
The whole body is wrapped in Try/Catch ex As Exception
Sentinel Failure + ex.Message
Yes - ex.Message copied into Message
Never faults* - the entire operation body is inside a single Try/Catch.
UnlockAccount - Authorization
Access-checked (BR-01 ). See Authentication and authorization .
UnlockAccount - Side effects
Aspect
Finding
Records written
None (no database) - clears the AD lockout flag on the target principal when locked
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
A second call on an already-unlocked account returns Success with "was not locked" wording
UnlockAccount - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<UnlockAccount xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
</UnlockAccount>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<UnlockAccountResponse xmlns= "http://tempuri.org/" >
<UnlockAccountResult>
<Message></Message>
<Response> Success</Response>
</UnlockAccountResult>
</UnlockAccountResponse>
</soap:Body>
</soap:Envelope>
AddUserToGroup
Adds a user to a group in the external domain.
Field
Value
Operation name
AddUserToGroup
Message name
AddUserToGroup
SOAP action
http://tempuri.org/AddUserToGroup
Implementing member
clsADUserServices.AddUserToGroup (src\ADUserServices\clsADUserServices.asmx.vb:228-267)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
Access-checked (BR-01 )
Process
operations/add-user-to-group.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inGroupName
String
Yes
-
Target group's SamAccountName*
AddUserToGroup - Output message
Field
Value
Return type
ADServiceResponse
Response element
AddUserToGroupResult
Meaning
Outcome of the membership-add attempt
Empty-result behavior
Not applicable
Member
Type
Nullable
Purpose
Message
String
Yes
ex.Message on a generic failure; otherwise empty
Response
EResponse
No
UserDoesNotExist, GroupDoesNotExist, UserAlreadyInGroup (detected via ex.Message.Contains("already exists")), Success, or Failure
AddUserToGroup - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Access denied
CheckAccess().HasAccess is False
Sentinel Failure/"Access Denied"
No
User not found
H2 returns Nothing
Sentinel UserDoesNotExist
No
Group not found
H3 returns Nothing
Sentinel GroupDoesNotExist
No
Already a member
groupPrin.Members.Add/.Save() throws an exception whose message contains "already exists"
Sentinel UserAlreadyInGroup - locale- and provider-fragile*
No
Any other exception
groupPrin.Members.Add/.Save() fails for another reason
Sentinel Failure + ex.Message
Yes - via Message
Never faults.
AddUserToGroup - Authorization
Access-checked (BR-01 ). See Authentication and authorization .
AddUserToGroup - Side effects
Aspect
Finding
Records written
None (no database) - adds the user to the AD group's membership list
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
A second call returns UserAlreadyInGroup (subject to the English-substring detection caveat above)
AddUserToGroup - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<AddUserToGroup xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inGroupName><value></inGroupName>
</AddUserToGroup>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<AddUserToGroupResponse xmlns= "http://tempuri.org/" >
<AddUserToGroupResult>
<Message></Message>
<Response> Success</Response>
</AddUserToGroupResult>
</AddUserToGroupResponse>
</soap:Body>
</soap:Envelope>
DeleteUser
Deletes an Active Directory user account in the external domain.
Field
Value
Operation name
DeleteUser
Message name
DeleteUser
SOAP action
http://tempuri.org/DeleteUser
Implementing member
clsADUserServices.DeleteUser (src\ADUserServices\clsADUserServices.asmx.vb:270-295)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
Access-checked (BR-01 )
Process
operations/delete-user.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
DeleteUser - Output message
Field
Value
Return type
ADServiceResponse
Response element
DeleteUserResult
Meaning
Outcome of the deletion attempt
Empty-result behavior
A missing user returns Success - the delete is a silent no-op, indistinguishable from a directory-lookup failure inside GetUserPrincipal (tech-debt.md )
Member
Type
Nullable
Purpose
Message
String
Yes
ex.Message on a caught delete failure; otherwise empty
Response
EResponse
No
Success (deleted, or user absent/lookup failed) or Failure + ex.Message
DeleteUser - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Access denied
CheckAccess().HasAccess is False
Sentinel Failure/"Access Denied"
No
userPrin.Delete() failure
Directory rejects the delete
Sentinel Failure + ex.Message
Yes - via Message
User not found / lookup failure
H2 returns Nothing
Sentinel Success (no-op) - the two cases are indistinguishable
No
Never faults.
DeleteUser - Authorization
Access-checked (BR-01 ). See Authentication and authorization .
DeleteUser - Side effects
Aspect
Finding
Records written
None (no database) - removes the AD user object
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
A second call returns Success (no-op) regardless of whether the first call deleted the account
DeleteUser - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<DeleteUser xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
</DeleteUser>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<DeleteUserResponse xmlns= "http://tempuri.org/" >
<DeleteUserResult>
<Message></Message>
<Response> Success</Response>
</DeleteUserResult>
</DeleteUserResponse>
</soap:Body>
</soap:Envelope>
DeleteUserFromGroup
Removes a user from a group in the external domain.
Field
Value
Operation name
DeleteUserFromGroup
Message name
DeleteUserFromGroup
SOAP action
http://tempuri.org/DeleteUserFromGroup
Implementing member
clsADUserServices.DeleteUserFromGroup (src\ADUserServices\clsADUserServices.asmx.vb:297-340)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
Access-checked (BR-01 )
Process
operations/delete-user-from-group.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inGroupName
String
Yes
-
Target group's SamAccountName*
DeleteUserFromGroup - Output message
Field
Value
Return type
ADServiceResponse
Response element
DeleteUserFromGroupResult
Meaning
Outcome of the membership-removal attempt
Empty-result behavior
Success is returned for a genuine removal, for "user was not a member", and for a genuine directory failure - the three are indistinguishable (tech-debt.md TD-20, HIGH )
Member
Type
Nullable
Purpose
Message
String
Yes
Always empty on this path - the Catch block is an explicit swallow
Response
EResponse
No
GroupDoesNotExist or Success
DeleteUserFromGroup - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Access denied
CheckAccess().HasAccess is False
Sentinel Failure/"Access Denied"
No
Group not found
H3 returns Nothing
Sentinel GroupDoesNotExist
No
Any directory failure (including a genuine removal failure)
deGroup.Invoke("Remove", New Object() {deUser.Path})/CommitChanges() throws
Caught and swallowed - Catch block contains the authored comment 'gobble - user is pribably not in the group; returns Success
No - the failure is never surfaced to the caller in any form
Never faults. This is the most consequential fault-handling finding on this operation - see tech-debt.md TD-20 and faults.md .
DeleteUserFromGroup - Authorization
Access-checked (BR-01 ). See Authentication and authorization .
DeleteUserFromGroup - Side effects
Aspect
Finding
Records written
None (no database) - removes the user from the AD group's membership list via a DirectoryEntry.Invoke("Remove", New Object() {deUser.Path}) call (dropped to DirectoryEntry deliberately because the GroupPrincipal.Remove method fails on large groups, per an authored comment)
Downstream calls
Active Directory via System.DirectoryServices
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
A second call returns Success regardless of whether the user was ever a member
DeleteUserFromGroup - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<DeleteUserFromGroup xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inGroupName><value></inGroupName>
</DeleteUserFromGroup>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<DeleteUserFromGroupResponse xmlns= "http://tempuri.org/" >
<DeleteUserFromGroupResult>
<Message></Message>
<Response> Success</Response>
</DeleteUserFromGroupResult>
</DeleteUserFromGroupResponse>
</soap:Body>
</soap:Envelope>
DoesUserExist
Reports whether a user account exists in the requested domain.
Field
Value
Operation name
DoesUserExist
Message name
DoesUserExist
SOAP action
http://tempuri.org/DoesUserExist
Implementing member
clsADUserServices.DoesUserExist (src\ADUserServices\clsADUserServices.asmx.vb:342-353)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/does-user-exist.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inExternalDomain
Boolean
Yes
-
Selects external.saif.com (True) vs corp.saif.com (False)
DoesUserExist - Output message
Field
Value
Return type
Boolean
Response element
DoesUserExistResult
Meaning
Whether a matching principal was found
Empty-result behavior
Returns False both when the user is genuinely absent and when the directory lookup failed - the exception is swallowed inside GetUserPrincipal into the unread m_LastMessage field (tech-debt.md TD-22)
DoesUserExist - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
User absent or directory failure
H2 returns Nothing for either reason
False
No - the two cases are indistinguishable to the caller
Never faults.
DoesUserExist - Authorization
None in code. See Authentication and authorization .
DoesUserExist - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement (read-only)
Files or messages produced
None
Shared state touched
m_LastMessage - written on failure, never read by any caller-visible path
Repeat-call behavior
Identical result for the same input
DoesUserExist - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<DoesUserExist xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inExternalDomain><value></inExternalDomain>
</DoesUserExist>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<DoesUserExistResponse xmlns= "http://tempuri.org/" >
<DoesUserExistResult> true</DoesUserExistResult>
</DoesUserExistResponse>
</soap:Body>
</soap:Envelope>
DoesUserHaveResource
Reports whether a user's authorization groups include a group named inResourceName.
Field
Value
Operation name
DoesUserHaveResource
Message name
DoesUserHaveResource
SOAP action
http://tempuri.org/DoesUserHaveResource
Implementing member
clsADUserServices.DoesUserHaveResource (src\ADUserServices\clsADUserServices.asmx.vb:355-386)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/does-user-have-resource.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inResourceName
String
Yes
-
Group name to match by equality against userPrin.GetAuthorizationGroups()*
inExternalDomain
Boolean
Yes
-
Selects the domain
DoesUserHaveResource - Output message
Field
Value
Return type
ADServiceResponse
Response element
DoesUserHaveResourceResult
Meaning
Whether the named group was found among the user's authorization groups
Empty-result behavior
Not applicable - Message always carries the literal "True" or "False"
Member
Type
Nullable
Purpose
Message
String
No
Literal "True"/"False" - the answer travels in Message, not Response
Response
EResponse
No
Success (answer computed) or UserDoesNotExist
DoesUserHaveResource - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
User not found
H2 returns Nothing
Sentinel UserDoesNotExist
No
Directory failure inside GetAuthorizationGroups
No Try/Catch wraps the iteration
SoapException produced by ASP.NET
Yes
DoesUserHaveResource - Authorization
None in code. See Authentication and authorization .
DoesUserHaveResource - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement (read-only); an unused GetGroupPrincipal (H3) call is also made and its result discarded (tech-debt.md TD-23)
Files or messages produced
None
Shared state touched
m_FoundUser reset to False, never read afterward on this path
Repeat-call behavior
Identical result for the same input
DoesUserHaveResource - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<DoesUserHaveResource xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inResourceName><value></inResourceName>
<inExternalDomain><value></inExternalDomain>
</DoesUserHaveResource>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<DoesUserHaveResourceResponse xmlns= "http://tempuri.org/" >
<DoesUserHaveResourceResult>
<Message> True</Message>
<Response> Success</Response>
</DoesUserHaveResourceResult>
</DoesUserHaveResourceResponse>
</soap:Body>
</soap:Envelope>
ChangeUserAccount
Updates directory attributes on an existing user account (either domain, selected internally by the operation).
Field
Value
Operation name
ChangeUserAccount
Message name
ChangeUserAccount
SOAP action
http://tempuri.org/ChangeUserAccount
Implementing member
clsADUserServices.ChangeUserAccount (src\ADUserServices\clsADUserServices.asmx.vb:388-469)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
Access-checked (BR-01 )
Process
operations/change-user-account.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inGivenName
String
Yes
-
GivenName (written only when non-empty)*
inSurName
String
Yes
-
Surname (written only when non-empty)*
inDescription
String
Yes
-
Description (written only when non-empty)*
inPhoneNum
String
Yes
-
telephoneNumber (written only when non-empty)*
inMailAddr
String
Yes
-
mail (written only when non-empty)*
inTitle
String
Yes
-
title (written only when non-empty)*
inInfo
String
Yes
-
info (written only when non-empty; does not set the modified flag - tech-debt.md TD-19)*
inCompany
String
Yes
-
company (written only when non-empty; does not set the modified flag - TD-19)*
inFAXNum
String
Yes
-
facsimileTelephoneNumber (written only when non-empty)*
ChangeUserAccount - Output message
Field
Value
Return type
ADServiceResponse
Response element
ChangeUserAccountResult
Meaning
Outcome of the attribute-update attempt
Empty-result behavior
A request that changes only inCompany and/or inInfo returns Success having committed nothing to the directory, because those two writes never set the modified flag that gates de.CommitChanges() (tech-debt.md TD-19, HIGH )
Member
Type
Nullable
Purpose
Message
String
Yes
ex.Message on a caught failure; otherwise empty
Response
EResponse
No
UserDoesNotExist, Success, or Failure + ex.Message
ChangeUserAccount - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Access denied
CheckAccess().HasAccess is False
Sentinel Failure/"Access Denied"
No
User not found
UserPrincipal.FindByIdentity returns Nothing (called directly, not through H2)
Sentinel UserDoesNotExist
No
Any exception inside the Try
userPrin.Save()/de.CommitChanges()/property assignment fails
Sentinel Failure + ex.Message
Yes - via Message
Never faults. Unlike the other lookups this operation calls FindByIdentity directly rather than through H2, so a Nothing context (a directory failure, not just "user absent") would surface differently than in operations using H2.
ChangeUserAccount - Authorization
Access-checked (BR-01 ). See Authentication and authorization .
ChangeUserAccount - Side effects
Aspect
Finding
Records written
None (no database) - writes selected attributes on the AD user object
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement and System.DirectoryServices
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Idempotent for the fields that do set modified; a repeat call touching only inCompany/inInfo never commits (TD-19 )
ChangeUserAccount - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<ChangeUserAccount xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inGivenName><value></inGivenName>
<inSurName><value></inSurName>
<inDescription><value></inDescription>
<inPhoneNum><value></inPhoneNum>
<inMailAddr><value></inMailAddr>
<inTitle><value></inTitle>
<inInfo><value></inInfo>
<inCompany><value></inCompany>
<inFAXNum><value></inFAXNum>
</ChangeUserAccount>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<ChangeUserAccountResponse xmlns= "http://tempuri.org/" >
<ChangeUserAccountResult>
<Message></Message>
<Response> Success</Response>
</ChangeUserAccountResult>
</ChangeUserAccountResponse>
</soap:Body>
</soap:Envelope>
ChangeUserPassword
Sets a new password for a user, swallowing any failure into the sentinel response.
Field
Value
Operation name
ChangeUserPassword
Message name
ChangeUserPassword
SOAP action
http://tempuri.org/ChangeUserPassword
Implementing member
clsADUserServices.ChangeUserPassword (src\ADUserServices\clsADUserServices.asmx.vb:471-491)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
Access-checked (BR-01 )
Process
operations/change-user-password.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inNewPassword
String
Yes
-
New password value - never reproduce a real value in examples
ChangeUserPassword - Output message
Field
Value
Return type
ADServiceResponse
Response element
ChangeUserPasswordResult
Meaning
Outcome of the password-change attempt
Empty-result behavior
Not applicable
Member
Type
Nullable
Purpose
Message
String
Yes
ex.Message on any caught failure (policy, complexity, history, connectivity) - flattened into free text
Response
EResponse
No
Success, UserDoesNotExist, or Failure
ChangeUserPassword - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Access denied
CheckAccess().HasAccess is False
Sentinel Failure/"Access Denied"
No
Any exception from the private ChangePassword helper (H6)
Password rejected, user not found, or directory error
Sentinel Failure + ex.Message
Yes - via Message, raw .NET exception text
Never faults.
ChangeUserPassword - Authorization
Access-checked (BR-01 ). See Authentication and authorization .
ChangeUserPassword - Side effects
Aspect
Finding
Records written
None (no database) - sets the AD password via DirectoryEntry.Invoke("SetPassword", oPassword) and CommitChanges()
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement and System.DirectoryServices
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Each call sets the password again; no history-of-calls tracking
ChangeUserPassword - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<ChangeUserPassword xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inNewPassword><value></inNewPassword>
</ChangeUserPassword>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<ChangeUserPasswordResponse xmlns= "http://tempuri.org/" >
<ChangeUserPasswordResult>
<Message></Message>
<Response> Success</Response>
</ChangeUserPasswordResult>
</ChangeUserPasswordResponse>
</soap:Body>
</soap:Envelope>
ChangeUserPasswordOrGetException
Sets a new password for a user; the deliberately faulting counterpart of ChangeUserPassword - no exception handling.
Field
Value
Operation name
ChangeUserPasswordOrGetException
Message name
ChangeUserPasswordOrGetException
SOAP action
http://tempuri.org/ChangeUserPasswordOrGetException
Implementing member
clsADUserServices.ChangeUserPasswordOrGetException (src\ADUserServices\clsADUserServices.asmx.vb:493-501)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
Access-checked (BR-01 )
Process
operations/change-user-password-or-get-exception.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inNewPassword
String
Yes
-
New password value - never reproduce a real value in examples
ChangeUserPasswordOrGetException - Output message
Field
Value
Return type
ADServiceResponse
Response element
ChangeUserPasswordOrGetExceptionResult
Meaning
Outcome of the password-change attempt
Empty-result behavior
Not applicable
Member
Type
Nullable
Purpose
Message
String
No
String.Empty on success; not populated on failure - failure instead escapes as a fault
Response
EResponse
No
Success or UserDoesNotExist on the non-faulting paths
ChangeUserPasswordOrGetException - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Access denied
CheckAccess().HasAccess is False
Sentinel Failure/"Access Denied"
No
Any exception from the private ChangePassword helper (H6)
Password rejected, user not found, or directory error - no Try/Catch
SoapException produced by ASP.NET, carrying the .NET exception
Yes
This operation is a deliberately faulting variant of ChangeUserPassword; the two are near-duplicates differing only in error strategy, and the naming does not make that difference discoverable from the WSDL (tech-debt.md TD-24).
ChangeUserPasswordOrGetException - Authorization
Access-checked (BR-01 ). See Authentication and authorization .
ChangeUserPasswordOrGetException - Side effects
Aspect
Finding
Records written
None (no database) - sets the AD password via DirectoryEntry.Invoke("SetPassword", oPassword) and CommitChanges()
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement and System.DirectoryServices
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Each call sets the password again
ChangeUserPasswordOrGetException - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<ChangeUserPasswordOrGetException xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inNewPassword><value></inNewPassword>
</ChangeUserPasswordOrGetException>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<ChangeUserPasswordOrGetExceptionResponse xmlns= "http://tempuri.org/" >
<ChangeUserPasswordOrGetExceptionResult>
<Message></Message>
<Response> Success</Response>
</ChangeUserPasswordOrGetExceptionResult>
</ChangeUserPasswordOrGetExceptionResponse>
</soap:Body>
</soap:Envelope>
GetUserEmail
Reads the mail attribute for a user.
Field
Value
Operation name
GetUserEmail
Message name
GetUserEmail
SOAP action
http://tempuri.org/GetUserEmail
Implementing member
clsADUserServices.GetUserEmail (src\ADUserServices\clsADUserServices.asmx.vb:526-554)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/get-user-email.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inExternalDomain
Boolean
Yes
-
Selects the domain
GetUserEmail - Output message
Field
Value
Return type
ADServiceResponse
Response element
GetUserEmailResult
Meaning
The AD mail value for the user
Empty-result behavior
An unset mail attribute surfaces as Failure + a .NET null-reference/cast message rather than as a distinct response code*
Member
Type
Nullable
Purpose
Message
String
Yes
The mail attribute value, or ex.Message on failure
Response
EResponse
No
Success, UserDoesNotExist, or Failure
GetUserEmail - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
User not found
H2 returns Nothing
Sentinel UserDoesNotExist
No
Any exception (including unset mail)
Late-bound de.Properties.Item("mail").Value assignment fails, or any directory error
Sentinel Failure + ex.Message
Yes - via Message
Never faults.
GetUserEmail - Authorization
None in code. See Authentication and authorization .
GetUserEmail - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement and System.DirectoryServices (read-only)
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Identical result for the same input
GetUserEmail - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserEmail xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inExternalDomain><value></inExternalDomain>
</GetUserEmail>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserEmailResponse xmlns= "http://tempuri.org/" >
<GetUserEmailResult>
<Message><value></Message>
<Response> Success</Response>
</GetUserEmailResult>
</GetUserEmailResponse>
</soap:Body>
</soap:Envelope>
GetUserGroups
Lists the names of a user's authorization groups.
Field
Value
Operation name
GetUserGroups
Message name
GetUserGroups
SOAP action
http://tempuri.org/GetUserGroups
Implementing member
clsADUserServices.GetUserGroups (src\ADUserServices\clsADUserServices.asmx.vb:556-580)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/get-user-groups.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inExternalDomain
Boolean
Yes
-
Selects the domain
GetUserGroups - Output message
Field
Value
Return type
ArrayList - untyped on the wire, serializes as unconstrained xsd:anyType (tech-debt.md TD-05, MEDIUM ); the implementation only ever adds String (grp.Name)
Response element
GetUserGroupsResult
Meaning
Group names the user belongs to, per GetAuthorizationGroups()
Empty-result behavior
An empty list means "no groups", "no such user", or "directory failure" - the empty Catch block (tech-debt.md TD-21, HIGH ) makes all three indistinguishable
GetUserGroups - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Any failure (user not found, directory error)
H2 fails, or GetAuthorizationGroups() throws
Caught and swallowed by an empty Catch block - returns the (possibly still-empty) ArrayList
No
Never faults.
GetUserGroups - Authorization
None in code. See Authentication and authorization .
GetUserGroups - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement (read-only)
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Identical result for the same input
GetUserGroups - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserGroups xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inExternalDomain><value></inExternalDomain>
</GetUserGroups>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserGroupsResponse xmlns= "http://tempuri.org/" >
<GetUserGroupsResult>
<anyType xsi:type= "xsd:string" ><value></anyType>
</GetUserGroupsResult>
</GetUserGroupsResponse>
</soap:Body>
</soap:Envelope>
GetUserResources
Lists a subset of a user's authorization groups whose name marks them as a "resource", filtered by environment.
Field
Value
Operation name
GetUserResources
Message name
GetUserResources
SOAP action
http://tempuri.org/GetUserResources
Implementing member
clsADUserServices.GetUserResources (src\ADUserServices\clsADUserServices.asmx.vb:582-617)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/get-user-resources.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inProdEnvironment
Boolean
Yes
-
Selects the production-vs-test resource-name branch
inExternalDomain
Boolean
Yes
-
Selects the domain
GetUserResources - Output message
Field
Value
Return type
ArrayList - untyped on the wire (tech-debt.md TD-05, MEDIUM ); the implementation only ever adds String (grp.Name)
Response element
GetUserResourcesResult
Meaning
Names of groups matching "Resource", filtered by "TestResource" and inProdEnvironment
Empty-result behavior
An empty list means "no matching groups", "no such user", or "directory failure" - same empty-Catch swallow as GetUserGroups (tech-debt.md TD-21, HIGH ). Also note: when inProdEnvironment is True, a TestResource group is silently skipped by an empty branch body
GetUserResources - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Any failure (user not found, directory error)
H2 fails, or GetAuthorizationGroups() throws
Caught and swallowed by an empty Catch block
No
Never faults.
GetUserResources - Authorization
None in code. See Authentication and authorization .
GetUserResources - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement (read-only)
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Identical result for the same input
GetUserResources - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserResources xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inProdEnvironment><value></inProdEnvironment>
<inExternalDomain><value></inExternalDomain>
</GetUserResources>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserResourcesResponse xmlns= "http://tempuri.org/" >
<GetUserResourcesResult>
<anyType xsi:type= "xsd:string" ><value></anyType>
</GetUserResourcesResult>
</GetUserResourcesResponse>
</soap:Body>
</soap:Envelope>
GetUserFAX
Reads the facsimileTelephoneNumber attribute for a user.
Field
Value
Operation name
GetUserFAX
Message name
GetUserFAX
SOAP action
http://tempuri.org/GetUserFAX
Implementing member
clsADUserServices.GetUserFAX (src\ADUserServices\clsADUserServices.asmx.vb:619-647)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/get-user-fax.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inExternalDomain
Boolean
Yes
-
Selects the domain
GetUserFAX - Output message
Field
Value
Return type
ADServiceResponse
Response element
GetUserFAXResult
Meaning
The AD facsimileTelephoneNumber value for the user
Empty-result behavior
An unset attribute surfaces as Failure + a .NET exception message rather than as a distinct response code*
Member
Type
Nullable
Purpose
Message
String
Yes
The facsimileTelephoneNumber value, or ex.Message on failure
Response
EResponse
No
Success, UserDoesNotExist, or Failure
GetUserFAX - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
User not found
H2 returns Nothing
Sentinel UserDoesNotExist
No
Any exception
Late-bound property read fails, or any directory error
Sentinel Failure + ex.Message
Yes - via Message
Never faults.
GetUserFAX - Authorization
None in code. See Authentication and authorization .
GetUserFAX - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement and System.DirectoryServices (read-only)
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Identical result for the same input
GetUserFAX - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserFAX xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inExternalDomain><value></inExternalDomain>
</GetUserFAX>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserFAXResponse xmlns= "http://tempuri.org/" >
<GetUserFAXResult>
<Message><value></Message>
<Response> Success</Response>
</GetUserFAXResult>
</GetUserFAXResponse>
</soap:Body>
</soap:Envelope>
GetUserLastLogon
Computes and reports a user's last-logon timestamp from lastLogonTimestamp.
Field
Value
Operation name
GetUserLastLogon
Message name
GetUserLastLogon
SOAP action
http://tempuri.org/GetUserLastLogon
Implementing member
clsADUserServices.GetUserLastLogon (src\ADUserServices\clsADUserServices.asmx.vb:649-685)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/get-user-last-logon.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inExternalDomain
Boolean
Yes
-
Selects the domain
GetUserLastLogon - Output message
Field
Value
Return type
ADServiceResponse
Response element
GetUserLastLogonResult
Meaning
A DateTime.ToString() rendering of the last logon, derived from the lastLogonTimestamp FILETIME value
Empty-result behavior
A user with no lastLogonTimestamp attribute yields Failure + a .NET exception message rather than InfoNotAvailable. The rendered timestamp string format depends on the server's current culture and time zone
Member
Type
Nullable
Purpose
Message
String
Yes
The computed last-logon DateTime.ToString(), or ex.Message on failure; empty for InfoNotAvailable
Response
EResponse
No
Success, UserDoesNotExist, InfoNotAvailable (computed value < 1), or Failure
GetUserLastLogon - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
User not found
H2 returns Nothing
Sentinel UserDoesNotExist
No
Computed value < 1
The composed FILETIME value is less than 1
Sentinel InfoNotAvailable (the authored comment references defaulting to Jan 1, 2000, but no such date is actually applied)
No
Any other exception
Late-bound COM property access (HighPart/lowpart) fails, or any directory error
Sentinel Failure + ex.Message
Yes - via Message
Never faults.
GetUserLastLogon - Authorization
None in code. See Authentication and authorization .
GetUserLastLogon - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement and System.DirectoryServices (read-only)
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Result changes only as the underlying lastLogonTimestamp changes
GetUserLastLogon - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserLastLogon xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inExternalDomain><value></inExternalDomain>
</GetUserLastLogon>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserLastLogonResponse xmlns= "http://tempuri.org/" >
<GetUserLastLogonResult>
<Message><value></Message>
<Response> Success</Response>
</GetUserLastLogonResult>
</GetUserLastLogonResponse>
</soap:Body>
</soap:Envelope>
GetUserPrinter
Reads the extensionAttribute2 attribute for a user in the internal domain only.
Field
Value
Operation name
GetUserPrinter
Message name
GetUserPrinter
SOAP action
http://tempuri.org/GetUserPrinter
Implementing member
clsADUserServices.GetUserPrinter (src\ADUserServices\clsADUserServices.asmx.vb:687-713)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/get-user-printer.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName* - no domain parameter is offered; the operation is hard-wired to the internal domain (authored comment 'Assume internal domain)
GetUserPrinter - Output message
Field
Value
Return type
ADServiceResponse
Response element
GetUserPrinterResult
Meaning
The AD extensionAttribute2 value for the user
Empty-result behavior
An unset attribute surfaces as Failure + a .NET exception message rather than as a distinct response code*
Member
Type
Nullable
Purpose
Message
String
Yes
The extensionAttribute2 value, or ex.Message on failure
Response
EResponse
No
Success, UserDoesNotExist, or Failure
GetUserPrinter - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
User not found
H2 (internal domain, inExternalDomain = False) returns Nothing
Sentinel UserDoesNotExist
No
Any exception
Late-bound property read fails, or any directory error
Sentinel Failure + ex.Message
Yes - via Message
Never faults.
GetUserPrinter - Authorization
None in code. See Authentication and authorization .
GetUserPrinter - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory (internal domain only) via System.DirectoryServices.AccountManagement and System.DirectoryServices (read-only)
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Identical result for the same input
GetUserPrinter - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserPrinter xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
</GetUserPrinter>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<GetUserPrinterResponse xmlns= "http://tempuri.org/" >
<GetUserPrinterResult>
<Message><value></Message>
<Response> Success</Response>
</GetUserPrinterResult>
</GetUserPrinterResponse>
</soap:Body>
</soap:Envelope>
IsUserInGroup
Reports direct (non-nested) membership of a user in a group.
Field
Value
Operation name
IsUserInGroup
Message name
IsUserInGroup
SOAP action
http://tempuri.org/IsUserInGroup
Implementing member
clsADUserServices.IsUserInGroup (src\ADUserServices\clsADUserServices.asmx.vb:715-750)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code
Process
operations/is-user-in-group.md
Part
Type
Required
Default
Purpose
inUserId
String
Yes
-
Target sAMAccountName*
inGroupName
String
Yes
-
Target group's SamAccountName*
inExternalDomain
Boolean
Yes
-
Selects the domain
IsUserInGroup - Output message
Field
Value
Return type
ADServiceResponse
Response element
IsUserInGroupResult
Meaning
Whether groupPrin.Members.Contains(userPrin) is true - direct membership only , via GroupPrincipal.Members.Contains, unlike GetUserGroups/GetUserResources/DoesUserHaveResource, which walk GetAuthorizationGroups() and therefore include nested groups
Empty-result behavior
Not applicable - Message always carries the literal "True" or "False" on the success path
Member
Type
Nullable
Purpose
Message
String
Yes
Literal "True"/"False", or ex.Message on failure
Response
EResponse
No
Success, UserDoesNotExist, GroupDoesNotExist, or Failure
IsUserInGroup - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
User not found
H2 returns Nothing
Sentinel UserDoesNotExist
No
Group not found
H3 returns Nothing
Sentinel GroupDoesNotExist
No
Any other exception
Membership check throws, or any directory error
Sentinel Failure + ex.Message
Yes - via Message
Never faults. Nested-group membership answers "False" even when the user is a member transitively, because GetAuthorizationGroups() is not used here.
IsUserInGroup - Authorization
None in code. See Authentication and authorization .
IsUserInGroup - Side effects
Aspect
Finding
Records written
None
Downstream calls
Active Directory via System.DirectoryServices.AccountManagement (read-only)
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Identical result for the same input
IsUserInGroup - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<IsUserInGroup xmlns= "http://tempuri.org/" >
<inUserId><value></inUserId>
<inGroupName><value></inGroupName>
<inExternalDomain><value></inExternalDomain>
</IsUserInGroup>
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<IsUserInGroupResponse xmlns= "http://tempuri.org/" >
<IsUserInGroupResult>
<Message> True</Message>
<Response> Success</Response>
</IsUserInGroupResult>
</IsUserInGroupResponse>
</soap:Body>
</soap:Envelope>
CheckAccess
The service's own access-control primitive: reports whether the caller's observed remote address is local or on the configured IP allow-list.
Field
Value
Operation name
CheckAccess
Message name
CheckAccess
SOAP action
http://tempuri.org/CheckAccess
Implementing member
clsADUserServices.CheckAccess (src\ADUserServices\clsADUserServices.asmx.vb:752-776)
Member kind
Function - method with a return value
Attributes
<WebMethod()>
Authorization
None in code - this operation is itself the access-control primitive consumed by the other eight operations, and it is published and unauthenticated
Process
operations/check-access.md
No input parts - the request message is empty.
CheckAccess - Output message
Field
Value
Return type
HasAccessResponse
Response element
CheckAccessResult
Meaning
The access decision and its basis
Empty-result behavior
Not applicable - always populated when no fault occurs
Member
Type
Nullable
Purpose
HasAccess
Boolean
No
Overall decision - True if local or allow-listed
Local
Boolean
No
True when HttpContext.Current.Request.IsLocal
EnvironmentApi
Boolean
No
True when the incoming IP matched an allow-list entry
RemoteAddress
String
No
The caller's observed remote address (HTTP_X_FORWARDED_FOR, falling back to REMOTE_ADDR) - discloses the origin-check basis to any caller
CheckAccess - Faults
Failure
Raised when
Surfaced as
Detail crosses the boundary
Environment-service failure
GetAllowedIPs (constructing WebEnvironmentService or its .Split(",") call) throws - no Try/Catch
SoapException produced by ASP.NET
Yes
This is also the failure path that causes the eight gated operations to fault instead of returning the Access Denied sentinel - see tech-debt.md TD-12.
CheckAccess - Authorization
None in code. CheckAccess publishes the caller's observed remote address and the allow-list decision to any unauthenticated caller, functioning as an allow-list probing oracle. See Authentication and authorization .
CheckAccess - Side effects
Aspect
Finding
Records written
None
Downstream calls
WebEnvironmentService (SAIF.Framework.Security) to read the aduserservices.allowedips setting
Files or messages produced
None
Shared state touched
None
Repeat-call behavior
Identical result for the same caller address and allow-list configuration; re-reads the incoming IP on every allow-list comparison iteration rather than reusing the computed value (tech-debt.md TD-09)
CheckAccess - Example message
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<CheckAccess xmlns= "http://tempuri.org/" />
</soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" >
<soap:Body>
<CheckAccessResponse xmlns= "http://tempuri.org/" >
<CheckAccessResult>
<HasAccess> true</HasAccess>
<Local> false</Local>
<EnvironmentApi> true</EnvironmentApi>
<RemoteAddress><value></RemoteAddress>
</CheckAccessResult>
</CheckAccessResponse>
</soap:Body>
</soap:Envelope>
Coverage checklist
Member
<WebMethod()>
Documented section
String HelloWorld()
Yes
HelloWorld
ADServiceResponse AddUser(inUserId, inPassword, inName, inGivenName, inSurName, inDescription, inPhoneNum, inMailAddr, inTitle, inInfo, inCompany, inFAXNum, inDivision)
Yes
AddUser
ADServiceResponse UnlockAccount(inUserId)
Yes
UnlockAccount
ADServiceResponse AddUserToGroup(inUserId, inGroupName)
Yes
AddUserToGroup
ADServiceResponse DeleteUser(inUserId)
Yes
DeleteUser
ADServiceResponse DeleteUserFromGroup(inUserId, inGroupName)
Yes
DeleteUserFromGroup
Boolean DoesUserExist(inUserId, inExternalDomain)
Yes
DoesUserExist
ADServiceResponse DoesUserHaveResource(inUserId, inResourceName, inExternalDomain)
Yes
DoesUserHaveResource
ADServiceResponse ChangeUserAccount(inUserId, inGivenName, inSurName, inDescription, inPhoneNum, inMailAddr, inTitle, inInfo, inCompany, inFAXNum)
Yes
ChangeUserAccount
ADServiceResponse ChangeUserPassword(inUserId, inNewPassword)
Yes
ChangeUserPassword
ADServiceResponse ChangeUserPasswordOrGetException(inUserId, inNewPassword)
Yes
ChangeUserPasswordOrGetException
ADServiceResponse GetUserEmail(inUserId, inExternalDomain)
Yes
GetUserEmail
ArrayList GetUserGroups(inUserId, inExternalDomain)
Yes
GetUserGroups
ArrayList GetUserResources(inUserId, inProdEnvironment, inExternalDomain)
Yes
GetUserResources
ADServiceResponse GetUserFAX(inUserId, inExternalDomain)
Yes
GetUserFAX
ADServiceResponse GetUserLastLogon(inUserId, inExternalDomain)
Yes
GetUserLastLogon
ADServiceResponse GetUserPrinter(inUserId)
Yes
GetUserPrinter
ADServiceResponse IsUserInGroup(inUserId, inGroupName, inExternalDomain)
Yes
IsUserInGroup
HasAccessResponse CheckAccess()
Yes
CheckAccess
Enum EResponse
No
Not an operation - message type consumed by ADServiceResponse, not itself invocable
Structure ADServiceResponse
No
Not an operation - message type (response shape for most operations)
Structure HasAccessResponse
No
Not an operation - message type (response shape for CheckAccess)
EResponse ChangePassword(inUserId, inNewPassword) (Private)
No
Not an operation - private helper behind ChangeUserPassword/ChangeUserPasswordOrGetException
ADServiceResponse AccessDenied() (Private)
No
Not an operation - private helper that builds the Failure/"Access Denied" sentinel
List(Of String) GetAllowedIPs() (Private)
No
Not an operation - private helper reading the aduserservices.allowedips configuration setting
String GetIncomingIp() (Private)
No
Not an operation - private helper reading HTTP_X_FORWARDED_FOR/REMOTE_ADDR
String GetLocalIpAddress() (Private)
No
Not an operation - private helper, and dead code, never called
PrincipalContext GetContext(inExternalDomain, [inContainer]) (Private)
No
Not an operation - private helper building the directory context
UserPrincipal GetUserPrincipal(inUserId, inExternalDomain) (Private)
No
Not an operation - private helper resolving a user principal
GroupPrincipal GetGroupPrincipal(inGroupId, inExternalDomain) (Private)
No
Not an operation - private helper resolving a group principal
Sub FindUserInResource(ByRef inUserPrin As UserPrincipal, ByRef inGroupPrin As GroupPrincipal) (Private)
No
Not an operation - private helper, and dead code, never called
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
src\ADUserServices\clsADUserServices.asmx.vb
.saifdocgen\state\runs\20260922-101326-aduserservices\analysis\aduserservices-analysis.md
.saifdocgen\state\runs\20260922-101326-aduserservices\analysis\aduserservices-security-analysis.md