Year: 2020
Richard Jewell (2019)
GitHub – axcore/tartube: A GUI front-end for youtube-dl, partly based on youtube-dl-gui and written in Python 3 / Gtk 3
Logtop by JulienPalard
How can we get the Password attributes such as pwdMaxAge, pwdMaxFailure etc for LDAP server in Apigee ?
ou can use the below command to find out the values of Ldap attributes – pwdMaxAge, pwdMaxFailure
ldapsearch -H ldap://localhost:10389 -x -D "cn=manager,dc=apigee,dc=com" -W -b "cn=default,ou=pwpolicies,dc=apigee,dc=com"
Here’s the sample output for the above command:
# extended LDIF # # LDAPv3 # base <cn=default,ou=pwpolicies,dc=apigee,dc=com> with scope subtree # filter: (objectclass=*) # requesting: ALL # # default, pwpolicies, apigee.com dn: cn=default,ou=pwpolicies,dc=apigee,dc=com objectClass: person objectClass: pwdPolicy objectClass: top cn: default pwdAttribute: userPassword sn: dummy value pwdExpireWarning: 604800 pwdInHistory: 3 pwdLockoutDuration: 300 pwdFailureCountInterval: 300 pwdMaxFailure: 3 pwdMinLength: 8 pwdMaxAge: 0 pwdLockout: FALSE # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
Account expiration mail warning [LDAP Tool Box (LTB)]
Account expiration mail warning
Presentation
This script will browse the LDAP directory a look for entries that uses password policy. If the user’s password will expire soon, a mail is sent. It was only tested with OpenLDAP (ppolicy overlay).
This shell script must be run as a cronjob. You can run it daily.
It requires :
-
gawk (GNU awk)
-
ldapsearch
-
mailx
-
date
It was tested for GNU/Linux and SunOS 5.8.
Usage
There is no command line parameter:
sh checkLdapPwdExpiration.sh
Logs are sent through STDOUT and STDERR:
sh checkLdapPwdExpiration.sh 1>result.log 2>audit.log
Sample log files:
-
result.log
--- Statistics --- Users checked: 5 Account expired: 1 Account in warning: 1
-
audit.log
No password policy for coudot Password expired for sbahloul No password change date for tchemineau No password change date for rouazana Mail sent to user farmand (farmand@example.com)
Configuration
Edit the script to adapt configuration:
-
MY_LDAP_HOSTURI
: LDAP URI -
MY_LDAP_ROOTDN
(optional): DN to use to bind. No DN means anonymous -
MY_LDAP_ROOTPW
: Password -
MY_LDAP_DEFAULTPWDPOLICYDN
: Default password policy DN. Do not set if no default policy is used. In this case, the script will ony affect users with password policy in their entry (pwdPolicySubentry) -
MY_LDAP_SEARCHBASE
: Users search base -
MY_LDAP_SEARCHFILTER
: Users search filter -
MY_LDAP_SEARCHBIN
: Path to ldapsearch binary -
MY_MAIL_DELAY
: Time before expiration where a mail is sent. No mail sent after expiration. If no value, the script will take the pwdExpireWarning of the password policy -
MY_LDAP_NAME_ATTR
: attribute containing user’s name -
MY_LDAP_LOGIN_ATTR
: attribute containing user’s login -
MY_LDAP_MAIL_ATTR
:attribute containing user’s name -
MY_MAIL_BODY
: message body -
MY_MAIL_SUBJECT
: message subject -
MY_MAIL_BIN
: mail binary -
MY_LOG_HEADER
: log header -
MY_GAWK_BIN
: path to gawk binary
Mail content: you can edit MY_MAIL_BODY
and use the following variables:
-
name
-
login
-
expireTimeTZ
-
expireDays
-
pwdMinLength
-
pwdInHistory
Date localization: you can change the lang by modifying this line:
export LC_ALL=en_US.UTF-8
Source: Account expiration mail warning [LDAP Tool Box (LTB)]
LP – Errard piano
OpenLDAP Software 2.4 Administrator’s Guide: Overlays
12.10.2. Password Policy Configuration
Instantiate the module in the database where it will be used, after adding the new ppolicy schema and loading the ppolicy module. The following example shows the ppolicy module being added to the database that handles the naming context “dc=example,dc=com”. In this example we are also specifying the DN of a policy object to use if none other is specified in a user’s object.
database mdb suffix "dc=example,dc=com" [...additional database configuration directives go here...] overlay ppolicy ppolicy_default "cn=default,ou=policies,dc=example,dc=com"
Now we need a container for the policy objects. In our example the password policy objects are going to be placed in a section of the tree called “ou=policies,dc=example,dc=com”:
dn: ou=policies,dc=example,dc=com objectClass: organizationalUnit objectClass: top ou: policies
The default policy object that we are creating defines the following policies:
- The user is allowed to change his own password. Note that the directory ACLs for this attribute can also affect this ability (pwdAllowUserChange: TRUE).
- The name of the password attribute is “userPassword” (pwdAttribute: userPassword). Note that this is the only value that is accepted by OpenLDAP for this attribute.
- The server will check the syntax of the password. If the server is unable to check the syntax (i.e., it was hashed or otherwise encoded by the client) it will return an error refusing the password (pwdCheckQuality: 2).
- When a client includes the Password Policy Request control with a bind request, the server will respond with a password expiration warning if it is going to expire in ten minutes or less (pwdExpireWarning: 600). The warnings themselves are returned in a Password Policy Response control.
- When the password for a DN has expired, the server will allow five additional “grace” logins (pwdGraceAuthNLimit: 5).
- The server will maintain a history of the last five passwords that were used for a DN (pwdInHistory: 5).
- The server will lock the account after the maximum number of failed bind attempts has been exceeded (pwdLockout: TRUE).
- When the server has locked an account, the server will keep it locked until an administrator unlocks it (pwdLockoutDuration: 0)
- The server will reset its failed bind count after a period of 30 seconds.
- Passwords will not expire (pwdMaxAge: 0).
- Passwords can be changed as often as desired (pwdMinAge: 0).
- Passwords must be at least 5 characters in length (pwdMinLength: 5).
- The password does not need to be changed at the first bind or when the administrator has reset the password (pwdMustChange: FALSE)
- The current password does not need to be included with password change requests (pwdSafeModify: FALSE)
- The server will only allow five failed binds in a row for a particular DN (pwdMaxFailure: 5).
The actual policy would be:
dn: cn=default,ou=policies,dc=example,dc=com cn: default objectClass: pwdPolicy objectClass: person objectClass: top pwdAllowUserChange: TRUE pwdAttribute: userPassword pwdCheckQuality: 2 pwdExpireWarning: 600 pwdFailureCountInterval: 30 pwdGraceAuthNLimit: 5 pwdInHistory: 5 pwdLockout: TRUE pwdLockoutDuration: 0 pwdMaxAge: 0 pwdMaxFailure: 5 pwdMinAge: 0 pwdMinLength: 5 pwdMustChange: FALSE pwdSafeModify: FALSE sn: dummy value
You can create additional policy objects as needed.
There are two ways password policy can be applied to individual objects:
1. The pwdPolicySubentry in a user’s object – If a user’s object has a pwdPolicySubEntry attribute specifying the DN of a policy object, then the policy defined by that object is applied.
2. Default password policy – If there is no specific pwdPolicySubentry set for an object, and the password policy module was configured with the DN of a default policy object and if that object exists, then the policy defined in that object is applied.
Please see slapo-ppolicy(5) for complete explanations of features and discussion of “Password Management Issues” at http://www.symas.com/blog/?page_id=66
12.10.3. Further Information
slapo-ppolicy(5)
Source: OpenLDAP Software 2.4 Administrator’s Guide: Overlays
OpenLDAP Password Policy overlay (ppolicy)
OpenLDAP has a dynamically loadable module which can enforce password policies. It allows to define policies for the userPassword
attribute. Policies can define the maximum login attempts with the wrong password, maximum age of a password and many more.
Here is a short introduction into this module. If you want to read about it in detail, see the link collection at the end of this page.
Note: The connection parameters and DN parameters deeply depend on your setup, the examples here need to be adjusted to your setup.
Configuration of the ppolicy overlay
The basic configuration depends on your OpenLDAP version. Newer versions store their configuration in a so-called Online Configuration Database (OLC), older ones use a configuration file called slapd.conf
OpenLDAP with OLC
- Load the ppolicy schema into OLC:
ldapmodify -D "cn=root,cn=config" -W -a -f /etc/openldap/schema/ppolicy.ldif
- Load the module:
ldapmodify -D "cn=root,cn=config" -W -a -f ppolicymodule.ldif
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModuleLoad: ppolicy.la
- Configure ppolicy overlay:
ldapmodify -D "cn=root,cn=config" -W -a -f ppolicyoverlay.ldif
dn: olcOverlay=ppolicy,olcDatabase={1}bdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
olcPPolicyDefault: cn=passwordDefault,ou=Policies,dc=mydomain,dc=tld
olcPPolicyHashCleartext: FALSE
olcPPolicyUseLockout: FALSE
olcPPolicyForwardUpdates: FALSE
OpenLDAP with slapd.conf
If you have an older version of OpenLDAP, the configuration goes into slapd.conf
:
#-- Load schema
include /etc/openldap/schema/ppolicy.schema
#-- Load module
moduleload ppolicy.la
The next snippet should come somewhere after the database
definition:
#-- Load overlay
overlay ppolicy
ppolicy_default "cn=passwordDefault,ou=Policies,dc=mydomain,dc=tld"
This means the default policy is located under cn=passwordDefault,ou=Policies,dc=mydomain,dc=tld
Definition of a password policy
In the overlay configuration we specified the default policy, so we add it now using the following LDIF:
dn: ou=Policies,dc=mydomain,dc=tld
ou: Policies
objectClass: organizationalUnit
dn: cn=passwordDefault,ou=Policies,dc=mydomain,dc=tld
objectClass: pwdPolicy
objectClass: person
objectClass: top
cn: passwordDefault
sn: passwordDefault
pwdAttribute: userPassword
pwdCheckQuality: 0
pwdMinAge: 0
pwdMaxAge: 0
pwdMinLength: 8
pwdInHistory: 5
pwdMaxFailure: 3
pwdFailureCountInterval: 0
pwdLockout: TRUE
pwdLockoutDuration: 0
pwdAllowUserChange: TRUE
pwdExpireWarning: 0
pwdGraceAuthNLimit: 0
pwdMustChange: FALSE
pwdSafeModify: FALSE
All these parameters are described in detail at Chapter 6 OpenLDAP password policy overlay / pwdPolicy ObjectClass and Attributes.
This policy applies to all userPassword
attributes. If an object needs a different policy, just define the differing policy under another name and reference the policy with the pwdPolicySubentry
attribute. Example:
dn: cn=My User,ou=People,dc=mydomain,dc=tld
changetype: modify
add: pwdPolicySubentry
pwdPolicySubentry: cn=passwordSpecial,ou=Policies,dc=mydomain,dc=tld
Usage and behaviour
Query all locked accounts
If an object has the pwdAccountLockedTime
attribute: it is locked since then. Simply issue the following query:
ldapsearch <MYCONNECTIONPARAMS> -b "ou=People,dc=mydomain,dc=tld" "pwdAccountLockedTime=*" pwdAccountLockedTime
Unlock an account
There are two variants. For the first one you simply delete the pwdAccountLockedTime
attribute which unlocks the account immediately:
dn: cn=My User,ou=People,dc=mydomain,dc=tld
changetype: modify
delete: pwdAccountLockedTime
The second variant adds the attribute pwdReset
which basically means: The user can only login again after changing it’s password:
dn: cn=My User,ou=People,dc=mydomain,dc=tld
changetype: modify
add: pwdReset
pwdReset: TRUE
If the user tries other operations than changing its password, the OpenLDAP server responds with bind: Operations are restricted to bind/unbind/abandon/StartTLS/modify password
Changing an LDAP password can be done f.e. with the ldappasswd tool:
ldappasswd <MYCONNECTIONPARAMS> -D "cn=My User,ou=People,dc=mydomain,dc=tld" -W -S "cn=My User,ou=People,dc=mydomain,dc=tld"
Behaviour of some policy settings
A short overview of how some of the policies behave (not all covered here):
pwdMinAge
Result: Constraint violation (19)
Additional info: Password is too young to change
pwdMaxAge
ldap_bind: Invalid credentials (49)
in the logfile: ppolicy_bind: Entry cn=My User,ou=People,dc=mydomain,dc=tld has an expired password: 0 grace logins
pwdGraceAuthNLimit
in the log: ppolicy_bind: Entry cn=My User,ou=People,dc=mydomain,dc=tld has an expired password: 1 grace logins
pwdInHistory
Result: Constraint violation (19)
Additional info: Password is in history of old passwords
pwdAllowUserChange
Result: Insufficient access (50)
Additional info: User alteration of password is not allowed
Storage location of the policy data
Policy data (f.e. number of failed login attempts) is stored as Operational Attributes on each object. In a normal ldapsearch query operational attributes are not returned. To make them visible, add a “+” to the end of the query. Example: ldapsearch <MYCONNECTIONPARAMS> -b "ou=People,dc=mydomain,dc=tld" "+"
Considerations when using LDAP replication
If you replicate from an LDAP master to LDAP slave(s) and your users are authenticating against slaves, take into consideration that the policy data needs to be synced somehow back to the master (f.e. number of failed login attempts).
The ppolicy module already knows about it. You basically need to set the
configuration value olcPPolicyForwardUpdates
(OLC style) / ppolicy_forward_updates
(slapd.conf). Furthermore chaining must be configured, including syncrepl. This is very well documented at Linuxtopia.
Add new schema to OpenLDAP
Hello ! In this post, I will explain how to add a new schema into OpenLDAP 2.4 and higher. Why ? Because since release 2.4, the structure of the server has a little changed. I’m not an LDAP expert but I’m writing this article because I insulted my OpenLDAP and my Linux several times during one week while I try to add my own schema into OpenLDAP 2.4. I have read a lot of posts but honestly, I never find a good “how-to” which respond to the question in this post’s title.
The configuration in OpenLDAP 2.4 and next versions is now in LDIF format and it follows a pretty logical schema like this :
We can look that schemas must be placed as child of cn=schema,cn=config. Before the release 2.4, all .schema (stored under /etc/ldap/schema/) were included into slapd.conf. Since 2.4, we must “forget” the .schema file. The best way to explain how to add new schema with 2.4 (and higher) release is to start with a real and practical example. I suppose you already have a OpenLDAP server running. For your information, my OpenLDAP runs on a Ubuntu Server 12.04 LTS with a 3.5.0-48 64 bits kernel.
root@ldapserver:~# lsb_release -a && uname -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 12.04.4 LTS Release: 12.04 Codename: precise Linux ldapserver 3.5.0-48-generic #72~precise1-Ubuntu SMP Tue Mar 11 20:09:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
THE PREPARATION
For this example, we can imagine that we want to add a new schema with a custom objectClass for our business application. This new objectClass has the name of nsaEngineer and the schema nsaProject. As a reminder, a schema is a container (package) for one or many objectClass. An objectClass contains references to other objectClass and attributes. Now, the objectClass nsaEngineer has 3 customs mandatory attributes and a optional (description) which is referenced in another base schema.
- mainDoorKey (mandatory)
- safeKey (mandatory)
- nsaID (mandatory)
- description (optional)
Now, let’s go to create this schema (and objectClass and attributes). Note : for more information about LDAP structures, please consult the following link : LDAP structure
CREATION OF CLASSIC .SCHEMA
The .schema format is simple to understand and to write for the beginners. Let’s start by creating a working directory for example /tmp/ldapworkingdir.
root@ldapserver:~# mkdir /tmp/ldapworkingdir
Now, create the file nsaProject.schema which contains the definition of the new and custom attributes and the new objectClass nsaEngineer and save it in /etc/ldap/schema/. I will not explain in detail the content of nsaProject.schema because it is out of the scope for this post.
Convert and add the schema to OpenLDAP
Now it’s time to try to convert our .schema into an LDIF file and add it to OpenLDAP. To begin, create a dummy file into /tmp/ldapworkingdir called ldap.conf for example and write into it the include directive to the nsaProject.schema.
root@ldapserver:~# cd /tmp/ldapworkingdir/ root@ldapserver:/tmp/ldapworkingdir# touch ldap.conf root@ldapserver:/tmp/ldapworkingdir# echo "include /etc/ldap/schema/nsaProject.schema" > ldap.conf
Now try to convert the .schema file with this command
root@ldapserver:/tmp/ldapworkingdir# slaptest -f ldap.conf -F . config file testing succeeded
This will create in place a directory called cn=config and a file cn=config.ldif. Now go to new created sub-directory ./cn=config/cn/schema/ and edit the file cn={0}nsaProject
root@ldapserver:/tmp/ldapworkingdir# cd cn\=config/cn\=schema/
The file must contains the following:
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. # CRC32 50a9d844 dn: cn={0}nsaproject objectClass: olcSchemaConfig cn: {0}nsaproject olcAttributeTypes: {0}( 2.25.896523589646542389.1 NAME 'mainDoorKey' SUP descr iption EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VA LUE ) olcAttributeTypes: {1}( 2.25.896523589646542389.2 NAME 'safeKey' SUP descripti on EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE ) olcAttributeTypes: {2}( 2.25.896523589646542389.3 NAME 'nsaID' SUP description EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE ) olcObjectClasses: {0}( 2.25.896523589646542389.10 NAME 'nsaEngineer' STRUCTURA L MUST ( mainDoorKey $ safeKey $ nsaID ) MAY description ) structuralObjectClass: olcSchemaConfig entryUUID: 51ee4aea-79c9-1033-958d-ef361bf34673 creatorsName: cn=config createTimestamp: 20140527090205Z entryCSN: 20140527090205.718989Z#000000#000#000000 modifiersName: cn=config modifyTimestamp: 20140527090205Z
You must keep only the following things and delete the rest.
- dn: cn={0}nsaproject
- objectClass: olcSchemaConfig
- cn: {0}nsaproject
- olcAttributeTypes:
- olcObjectClasses:
You must modify dn: and cn: (just remove {0} for cn but write the correct dn for the schema ! (dn:cn=nsaproject,cn=schema,cn=config) ). After these modifications, the file is like this:
dn: cn=nsaproject,cn=schema,cn=config objectClass: olcSchemaConfig cn: nsaproject olcAttributeTypes: {0}( 2.25.896523589646542389.1 NAME 'mainDoorKey' SUP descr iption EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VA LUE ) olcAttributeTypes: {1}( 2.25.896523589646542389.2 NAME 'safeKey' SUP descripti on EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE ) olcAttributeTypes: {2}( 2.25.896523589646542389.3 NAME 'nsaID' SUP description EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE ) olcObjectClasses: {0}( 2.25.896523589646542389.10 NAME 'nsaEngineer' STRUCTURA L MUST ( mainDoorKey $ safeKey $ nsaID ) MAY description )
That’s it ! Now we are ready to add this schema to the OpenLDAP server using this command
root@ldapserver:/tmp/ldapworkingdir/cn=config/cn=schema# ldapadd -Q -Y EXTERNAL -H ldapi:/// -W -f /tmp/ldapworkingdir/cn\=config/cn\=schema/cn\=\{0\}nsaproject.ldif Enter LDAP Password: adding new entry "cn=nsaproject,cn=schema,cn=config"
Now you can verify if the new schema is correctly added using a ldapsearch command like this :
root@ldapserver: ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config nsa* dn: cn=config dn: cn=module{0},cn=config dn: cn=schema,cn=config dn: cn={0}core,cn=schema,cn=config dn: cn={1}cosine,cn=schema,cn=config dn: cn={2}nis,cn=schema,cn=config dn: cn={3}inetorgperson,cn=schema,cn=config dn: cn={4}nsaproject,cn=schema,cn=config #yeah :-) dn: olcBackend={0}hdb,cn=config dn: olcDatabase={-1}frontend,cn=config dn: olcDatabase={0}config,cn=config dn: olcDatabase={1}hdb,cn=conf
Chopin – Raindrop Prelude (Op. 28 No. 15) – YouTube
Chopin – Nocturne in E Flat Major (Op. 9 No. 2)