public class LdapAccount extends LdapEntry implements Account
This class extends LdapEntry
to provide functionality specific to account entries in an LDAP directory which have passwords, group membership and other characteristics of account objects.
Modifier and Type | Field and Description |
---|---|
static java.lang.String |
EXPIRES_NEVER
For attributes that represent an expiration date, this value is returned to indicate that the target will never expire.
|
Constructor and Description |
---|
LdapAccount(LdapSecurityProvider provider,
java.lang.String distinguishedName)
Construct an LdapAccount object for the purpose of performing account related operations.
|
Modifier and Type | Method and Description |
---|---|
void |
changePassword(char[] curpassword,
char[] newpassword)
Change the password of this account to the supplied value but only if the supplied current password is correct.
|
boolean |
isMemberOf(java.lang.String group)
Return true only if this account is a member of the named group.
|
void |
setPassword(char[] password)
Set the password on this account to the supplied value.
|
clear, containsKey, containsValue, create, create, delete, entrySet, equals, get, get, getProperty, hashCode, isEmpty, keySet, put, putAll, remove, size, update, update, values
decodeObject, encodeObject, getEncryptedProperty, getFilteredProperties, getFilteredProperties, getProperty, getPropertyAsBoolean, getPropertyAsLong, setEncryptedProperty, setProperty
clone, compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, remove, replace, replace, replaceAll
finalize, getClass, notify, notifyAll, wait, wait, wait
create, create, delete, getProperty, getProperty, setProperty, update, update
public static java.lang.String EXPIRES_NEVER
For attributes that represent an expiration date, this value is returned to indicate that the target will never expire. Consider the following example:
Account acct = provider.getAccount(acctname, attrs); if (acct.getProperty("accountExpires", null) == LdapAccount.EXPIRES_NEVER) { System.out.println("The account is not set to expire"); }
Currently this implementation only returns EXPIRES_NEVER when the Active Directory specific accountExpires attribute value is equal to "9223372036854775807" (which is 0x7fffffffffffffffL in hexadecimal). The literal value of this constant is "<never>".
public LdapAccount(LdapSecurityProvider provider, java.lang.String distinguishedName) throws SecurityProviderException
LdapSecurityProvider.getAccount(java.lang.String, java.lang.String[])
.
However, when creating a new account in the provider authority with LdapEntry.create(java.lang.String[])
, this constructor must be used.
Consider the following code fragment which constructs and LdapAccount for the purpose of creating a new account entry in Active Directory and setting it's password:
// See http://support.microsoft.com/kb/305144 // regarding userAccountControl values int ACCOUNTDISABLE = 0x00000002; int PASSWD_NOTREQD = 0x00000020; int NORMAL_ACCOUNT = 0x00000200; int PASSWORD_EXPIRED = 0x00800000; LdapSecurityProvider lsp = new LdapSecurityProvider(props); try { LdapAccount acct = new LdapAccount(lsp, "CN=Chris Davis"); acct.put("objectClass", "user"); acct.put("sAMAccountName", "cdavis"); acct.put("userPrincipalName", "cdavis@busicorp.local"); acct.put("mail", "chris.davis@busicorp.com"); // If this is just a test, use ACCOUNTDISABLE acct.put("userAccountControl", Integer.toString(ACCOUNTDISABLE | PASSWD_NOTREQD | NORMAL_ACCOUNT | PASSWORD_EXPIRED)); acct.create(); acct.setPassword("moonbike69".toCharArray()); } finally { lsp.dispose(); }
provider
- the LdapSecurityProvider representing the authority for this accountdistinguishedName
- the DN that uniquely identifies this account (or RDN relative to the base in the provider bindstr)SecurityProviderException
- if the distinguishedName is not valid or if certain properties cannot be retrieved from the providerpublic boolean isMemberOf(java.lang.String group) throws SecurityProviderException
The following table shows some example group DNs and RDNs:
Example Group DN or RDN | Notes |
---|---|
CN=Wiki Users,OU=Students,DC=openbook,DC=edu
|
|
CN=Wiki Users
|
To use an RDN, a bindstr with a base like ldap://openbook.edu/OU=Students,DC=openbook,DC=edu must be used. More specifically, if the suffix of the supplied group name does not match the base, it will be appended to compose a full DN.
|
If the ldap.disposition begins with "RFC" (as opposed to the default of "ADS"), RFC2307 behavior is assumed. Currently this method does not support RFC-based servers other than those which use the posixGroup, memberUid, gidNumber and other related attributes defined in RFC2307.
If the named group cannot be found, this method will return false and may result in a noticable delay.
If an exception is thrown, it may be an instance of LdapException to indicate that an LDAP protocol error has occured.
isMemberOf
in interface Account
group
- the full DN or RDN relative to the bindstr baseSecurityProviderException
- if a catostrophic error occurs trying to retrieve group and / or account informationpublic void setPassword(char[] password) throws SecurityProviderException
The behavior of this method depends greatly on the ldap.disposition and ldap.password.encoding properties of the underlying LdapSecurityProvider.
If the ldap.disposition starts with "ADS" (the default value does), the unicodePwd attribute will be set using the Active Directory specific UTF-16LE representation of the password in quotes.
flags.confidentiality = false
.
Consider the following example:
LdapSecurityProvider lsp = new LdapSecurityProvider(props); try { Account acct = lsp.getAccount(acctname, new String[0]); acct.setPassword(password.toCharArray()); } finally { lsp.dispose(); }
Otherwise, if the account authority is not Active Directory, this implementation will attempt to set the userPassword attribute of the account using one of the following encodings specified with the ldap.password.encoding property (the default is SSHA):
ldap.password.encoding Property Value | Description |
---|---|
SSHA512 | Salted 512 bit SHA |
SSHA384 | Salted 384 bit SHA hash |
SSHA256 | Salted 256 bit SHA hash |
SSHA | Salted 128 bit SHA hash (default encoding) |
SMD5 | Salted 128 bit MD5 hash |
SHA512 | 512 bit SHA hash |
SHA384 | 384 bit SHA hash |
SHA256 | 256 bit SHA hash |
SHA | 128 bit SHA hash |
MD5 | 128 bit MD5 hash |
CLEAR | Unhashed "clear" password |
Consider the following example SSHA256 encoded userPassword value:
{SSHA256}51qgGes9FqSTj6jFOZdVAVJ4Xx7IBbbWsP6Foy1JaNhW1ywLW5HxCg==
The above example is the 256 bit SHA hash of the password and random salt concatonated with the salt, base 64 encoded and prefixed with the encoding name in curly brackets. This is the standard form LDAP servers expect for the userPassword attribute. Salt sizes are currently fixed at 8 bytes.
setPassword
in interface Account
password
- the password to setSecurityProviderException
- if a catostrophic error occurspublic void changePassword(char[] curpassword, char[] newpassword) throws SecurityProviderException
The behavior of this method depends greatly on the ldap.disposition and ldap.password.encoding properties of the underlying LdapSecurityProvider.
If the ldap.disposition starts with "ADS" (the default value does) the underlying LdapSecurityProvider does not need to be bound using domain administrator credentials.
If the ldap.disposition starts with "ADS", an LDAP modify call will be submitted to remove and add the unicodePwd attribute in the Active Directory specific UTF-16LE representation of the password in quotes.
flags.confidentiality = false
.
Consider the following example:
LdapSecurityProvider lsp = new LdapSecurityProvider(props); try { Account acct = lsp.getAccount(acctname, new String[0]); acct.changePassword(curpassword.toCharArray(), newpassword.toCharArray()); } finally { lsp.dispose(); }
Otherwise, if the account authority is not Active Directory (as indicated by the ldap.disposition property) such as OpenLDAP or another RFC-based implementation, this method will simply validate the current password and call setPassword(char[])
.
The underlying LdapSecurityProvider will likely need to bind with privileged credentials.
The encoding of the password is specified with the ldap.password.encoding property as per the setPassword method description.
If the current password is incorrect (and the caller is not an Active Directory domain administrator), a SecurityProviderException will be thrown with an error code of SecurityProviderException.STATUS_INVALID_CREDENTIALS.
If the account identified by this object cannot be found, a SecurityProviderException will be thrown with an error code of SecurityProviderException.STATUS_ACCOUNT_NOT_FOUND.
The exception thrown may be an instance of LdapException to indicate that an LDAP protocol error has occurred.
changePassword
in interface Account
curpassword
- the current password of this accountnewpassword
- the new password to set on this accountSecurityProviderException
- if this account cannot be found, if the current password is incorrect or if a catostrophic error occurs.