I am setting up openLDAP for one of my Java applications. Usernames and passwords are stored in openLDAP and users are able to update their passwords via the application (using the javax.naming.directory API'). I imported our users from our existing Sun Directory Server into openLDAP. Import was successfull and passwords were encrypted in SSHA format. I noticed that when i update a password from the application, it stores it in 'Plain Text' format. I can unhide the password when i view it via Apache Directory Studio. A lot of googling later, i tried setting the "password-hash {SSHA}" in the slapd.conf file and that didn't help me either. I am on a windows environment. I am passing the password to openLDAP in plain text format. There is no encryption going on in the code. I know i can encrypt it in the application but i would prefer openLDAP to do it for me. Please let me know if i can do anything on the openLDAP side.
This is the JAVA code i use today to modify passwords. This has been working fine in our existing environment for the past 7 years.
ModificationItem[] newAttribs = new ModificationItem[1];
Attribute passwordAttrib = new BasicAttribute(DirectoryConstants.USER_PASSWORD, password);
ModificationItem passwordItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, passwordAttrib);
newAttribs[0] = passwordItem;
.....
DirContext ctx = this.getContext();
ctx.modifyAttributes( DirectoryConstants.USER_UID + "=" + userId + "," + ou, newAttribs);
So, the default password hash format in openldap is SSHA, which is nice.
Unfortunately, the default password policy in openldap is 'do not enforce password hashing'.
You will want to add an overlay to the database you're storing users in.
In the cn=config version, this looks like, approximately:
dn: olcOverlay={X}ppolicy,olcDatabase={Y}bdb,cn=config
objectClass: olcPPolicyConfig
olcOverlay: {X}ppolicy
olcPPolicyHashCleartext: TRUE
(where Y is your database number in cn=config, X is the overlay number you want it to be)
The slapd.conf version is similar, you need an:
overlay ppolicy
ppolicy_hash_cleartext
entry, inside the relevant database definition (you don't need to provide a value for ppolicy_hash_cleartext, presence indicates TRUE).
Related
When attempting an ldapmodify to set the unicode password (with the correct encoding) over SSL(636), the operation fails and Active Directory returns the following error code:
0000052D: SvcErr: DSID-031A1248, problem 5003 (WILL_NOT_PERFORM), data
0
I found countless threads and answers on resolving WILL_NOT_PERFORM but I am hoping someone knows the meaning of the exact codes above.
Every other solution points to password complexity, min pw age before the modify, SSL requirement, encoding requirement, and some others.
We have set the min pw age to 0, ensured we met the pw complexity requirements, encoded in UTF16LE=>base64, submitted the operation over SSL with 256 bit encryption and trusted/verified certificates, and we still receive this message.
The ldapadds/modifies are being performed by an automated tool which has successfully worked on other AD 2008 R2 instances so we know the password reqs, encodings, and SSL requirements are satisfied by the tool. We also tested with manual ldapmodify via LDIF and receive the same message.
Can anyone shed some light on any other possible permission, bug, UAC related setting, or way to decrypt the exact error code above?
Any help would be greatly appreciated! :)
I could only guess about your environment setup, but try to perform these steps:
Check if this password really could be setup through AD interface on server
Ensure you wrap you password with double quotes before encoding (i.e. it should be "password", not password
Check if you use unicodePwd attribute to set the password
So my ldapmodify entry to set password to StrongPassword! looks like:
dn: CN=User,CN=Users,DC=corp,DC=example,DC=org
changetype: modify
replace: unicodePwd
unicodePwd:: IgBTAHQAcgBvAG4AZwBQAGEAcwBzAHcAbwByAGQAIQAiAA==
Note unicodePwd has two colons
In Gforge, when a new user tries to log in; the user is automatically registered by fetching data from LDAP. It works fine for other users but one particular user is not able to log in and gets the error LDAP Authentication failed: Invalid Credentials . I don't understand what could be the issue? Could you please help?
This is the search function I am using.
ldap_bind($ldap, $dn, $pw)
$dn = ldap_get_dn($ldap, $entry);
$entry = ldap_first_entry($ldap,$res);
$res=ldap_search($ldap, $sys_ldap_base,$sys_ldap_id_attribute . '=' . $id,
array());
If it works for some users but not for one specific user, then it's something to do with the LDAP configuration, or with the characters in that user's ID or pwd.
Is the failing user in a different org/OU? Do they have accent characters in their username or password? These things can cause compatibility issues between GForge and the LDAP server.
Does this user have a much longer user name than other users? There is a GForge config setting called "usernameregex" that governs the complexity and length of allowed user names. Even though LDAP logins result in automatic account creation, the validation of the user's unix name might fail due to the regex in place. The error noted above could certainly be the catch-all message when this happens.
The default setting is "^[a-z0-9_.-]{3,15}$". You can change the upper length limit by changing the 15 to something else. The unix_name field in the GForge database is TEXT, so it can be extremely long (1GB?).
In GForge 6.3.x and earlier, you can find that setting in /etc/gforge/gforge.conf. Change the value and then update the system using:
cd /opt/gforge/bin && php create_config_cache.php
In GForge 6.4 and later, you can use the gf-config utility to set the value. It will take effect right away:
/opt/gforge/bin/gf-config set "usernameregex" "new regex value"
I setup an ApacheDS with default password-policy enabled. For testing proposes I locked a simple User (objectClass=Person extended with some custom User-objectClass) by entering the wrong credentials a number of times. As I expected the user was locked (error msg: user was permanently locked).
The question now is: How to unlock the user again? Is there a better way then just deleting and adding again?
I tried the same with an extended user (objectClass=pwdPolicy) but no pwd* attributes were added when the user was locked.
More recently, I encountered the same problem at work. But, it seems that there is no answer on Internet. Finally,I found the answer by viewing this document:
Password Policy for LDAP Directories draft-behera-ldap-password-policy
At section 5.3.3: pwdAccountLockedTime
This attribute holds the time that the user's account was locked. A
locked account means that the password may no longer be used to
authenticate. A 000001010000Z value means that the account has been
locked permanently, and that only a password administrator can unlock
the account.
At section 5.2.12: pwdLockoutDuration
This attribute holds the number of seconds that the password cannot
be used to authenticate due to too many failed bind attempts. If
this attribute is not present, or if the value is 0 the password
cannot be used to authenticate until reset by a password
administrator.
Through above two section, we can assume that we should connect to ApacheDS server with administrator(by default: uid=admin,ou=system, password=secret ), and delete the user's userPassword attribute. By this way,the permanently locked user can be unlock.
I practiced this sulotion and it works well.
I suggest you should set value for pwdLockoutDuration attribute, in this case the user can not been permanently locked.
For more infomation:
ApacheDS password Policy
Use ApacheDS Studio and log in as admin, find the user, right-click and choose "Fetch->Fetch operational attributes". Now pwdAccountLockedTime is visible and you can delete it to unlocks the user
The answer by Mister's is perfect to unlock an account and if you want to set the pwdLockoutDuration for a single user (assuming the user has implemnted the objectClass pwdPolicy.
There is also a global config file found in:
ou=config
* ads-directoryServiceId=<default>
* ou=interceptors
* ads-interceptorId=authenticationInterceptor
* ou=passwordPolicies
Here we can set the default password policy:
As mine is just a test-server, I have completely disabled lockout via setting the ads-pwdlockout to FALSE. For more on configuring password policy read the official docs.
For reference, this is how you enable this on the server via java:
AuthenticationInterceptor authenticationInterceptor = new AuthenticationInterceptor();
PasswordPolicyConfiguration config = new PasswordPolicyConfiguration();
config.setPwdLockout(true);
authenticationInterceptor.setPwdPolicies(config);
Client methods can then be written, to enable/disable specific accounts, similar to:
public void disableUser(String dn) throws LdapException, UnsupportedEncodingException
{
Modification disablePassword = new DefaultModification(
ModificationOperation.REPLACE_ATTRIBUTE, "pwdAccountLockedTime","000001010000Z" );
connection.modify(dn,disablePassword);
}
public void enableUser(String dn) throws LdapException, UnsupportedEncodingException
{
Modification disablePassword = new DefaultModification(ModificationOperation.REMOVE_ATTRIBUTE, "pwdAccountLockedTime");
connection.modify(dn,disablePassword);
}
I am trying to find a solution which will allow me to change a user's password from our Central User Administration (CUA) system where the user's access and password is on the child system.
I tried to use BAPI_USER_CHANGE with destination call but it doest suit in my case.
(we locked change password function in child systems). This is my code with destination call
CALL FUNCTION 'BAPI_USER_CHANGE'
DESTINATION 'CLNT_500'
EXPORTING
username = p_bname
password = wa_password
passwordx = wa_passwordx
TABLES
return = it_return.
Any suggestions welcome.
We tried to do something similar a while ago, and we ended up doing it in two steps:
BAPI_USER_CHANGE sets an initial password for the user
SUSR_USER_CHANGE_PASSWORD_RFC sets a productive password. It needs the old password as a parameter, that's why we needed to call BAPI_USER_CHANGE first.
Using Apache mod_auth_basic and mod_authn_dbd you can authenticate a user by looking up that user's password in the database. I see that working if the password is held in clear, but what if we use a random string as a salt (also stored in the database) then store the hash of the concatenation?
mod_authn_dbd requires you to specify a query to select that password not to decide if the user is authenticated of not. So you cannot use that query to concatenate the user provided password with the salt then compare with the stored hash.
AuthDBDUserRealmQuery "SELECT password FROM authn WHERE user = %s AND realm = %s"
Is there a way to make this work?
Looking at the Password Formats for Basic Auth it seemed that I could make this work if the hash is done using the apr_md5_encode function.
Found another question that relates to this and links to a Java implementation. I used that implementation with a small change to calculate the database hash inside my website normal user-creation flow. After this i could use mod_authn_dbd with this query:
AuthDBDUserRealmQuery "SELECT CONCAT('$apr1$',password_salt,'$',password_hash) FROM users WHERE user = %s AND realm = %s"