Difference between revisions of "LDAP"

From Nuclear Physics Group Documentation Pages
Jump to navigationJump to search
 
(38 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
Clients on the network use LDAP to authenticate user logins.  We are running an LDAP server on Einstein. This server serves up the user information (passwd and shadow) and also lists of servers and workstations which tie into various permission schemes.
 
Clients on the network use LDAP to authenticate user logins.  We are running an LDAP server on Einstein. This server serves up the user information (passwd and shadow) and also lists of servers and workstations which tie into various permission schemes.
 +
 +
NOTE: Centos/RHEL installs starting from release 6 onwards use SSSD for their authentication. Please see [[SSSD]] for more information on setting up authentication for these machines.
 +
 +
<font color=red>'''[[Emergency LDAP Rescue Procedure]]'''</font>
 +
 
== Organization ==
 
== Organization ==
LDAP runs on einstein. For passwords and such it is protected with TSL encryption. (See [[Certificates]].) The certificate is valid for einstein.unh.edu and einstein.farm.physics.unh.edu. The service program ''slapd'' handles requests from clients.
+
LDAP runs on einstein. The service program ''slapd'' handles requests from clients. For passwords and such it is protected with TSL encryption. (See [[Certificates]].) The certificate "unh_physics_ca.crt" is used.
 +
 
 +
[http://www.redhat.com/docs/manuals/enterprise/RHEL-5-manual/Deployment_Guide-en-US/ch-ldap.html Good instructions for setting up a single LDAP server.]
 +
 
 +
=== Setting up a master/slave server pair ===
 +
From [http://linuxgazette.net/124/pfeiffer.html "Migrating a Mail Server to Postfix/Cyrus/OpenLDAP"]:
 +
<blockquote>The OpenLDAP slave servers have a similar configuration to the master server. You have to keep some important things in mind.
 +
* The slave has neither replica nor replogfile directives. '''(the master does, though)'''
 +
* The slave has an additional updatedn option that must be the same as the binddn used in the master config file. '''("binddn" is part of the master's replica directive)'''
 +
* The DN mentioned in the updatedn option must have write access to the tree.
 +
* If you wish to write to your slave server, you have to include an updateref directive that points to your master server. Clients issuing write operations will then be redirected to the master.
 +
Introducing a new slave server needs synchronisation with the master database. OpenLDAP cannot copy the whole master data. The master only transfers changes to the slaves. The initial distribution of the whole LDAP tree must be done manually.
 +
# Shut down the master server.
 +
# Extract a copy of the master's data in LDIF notation by executing slapcat -f /etc/ldap/openldap/slapd.conf master_dump.ldif.
 +
# Copy the resulting master_dump.ldif file to your slave server.
 +
# Fill the slave's database by executing slapadd -f /etc/ldap/openldap/slapd.conf master_dump.ldif. Make sure the OpenLDAP server there is shut down!
 +
#Restart the master server.
 +
#Start the slave server.
 +
 
 +
After that, your master server should log into the slave and send updates as soon as you modify the master LDAP tree. Master and slaves have a steady TCP connection that you can see by using netstat. Important note: Don't forget to create a new key and certificate for the slave or else the encryption won't work.</blockquote>
 +
 
 
== Configuration ==
 
== Configuration ==
For clients, configuration for LDAP is in '''two locations''': ''/etc/ldap.conf'' and ''/etc/openldap/ldap.conf''. Here you set the host(s) that is serving the information.  Specifically, einstein.unh.edu or einstein.farm.physics.unh.  Also, ldap must be referenced in ''/etc/nsswitch.conf'' like so:
+
For clients, configuration for LDAP is in '''two locations''': ''/etc/ldap.conf'' and ''/etc/openldap/ldap.conf''. Here you set the host(s) that is serving the information.  Specifically, einstein.unh.edu or einstein.farm.physics.unh (prefer the farm name for machines on the farm).  Also, ldap must be referenced in ''/etc/nsswitch.conf'' like so:
 
<pre>passwd:    files ldap
 
<pre>passwd:    files ldap
 
shadow:    files ldap
 
shadow:    files ldap
 
group:      files ldap</pre>
 
group:      files ldap</pre>
Those '''may not''' be the only entries requiring a reference to ldap, but the GUI tool ''authconfig-gtk.'' is good at taking care of things.  If a machine doesn't have that program, it's safe to look at another machine's files.
+
Those '''may not''' be the only entries requiring a reference to ldap, but the GUI tool ''system-config-authentication'' is good at taking care of things.  If a machine doesn't have that program, it's safe to look at another machine's files.
  
 
Once a user is authenticated, the client mounts the user's home directory.  See [[Automount]].
 
Once a user is authenticated, the client mounts the user's home directory.  See [[Automount]].
 +
 
== Troubleshooting ==
 
== Troubleshooting ==
 
The best way to check whether LDAP is working is <code>getent passwd</code>, which should show user passwords. If it does not work, then <code>env HOME=/root ldapsearch -ZZ '(uid=someusername)'</code> may give more diagnostics. Try <code>ldapsearch -x '(uid=someusername)'</code> to test LDAP without using the encryption layer.
 
The best way to check whether LDAP is working is <code>getent passwd</code>, which should show user passwords. If it does not work, then <code>env HOME=/root ldapsearch -ZZ '(uid=someusername)'</code> may give more diagnostics. Try <code>ldapsearch -x '(uid=someusername)'</code> to test LDAP without using the encryption layer.
  
If your node has a bad system time, the certificate may look like it is from the future and will not be accepted. So check system time if users cannot log in.
+
Another thing to check is if the client is able to connect to the LDAP server, and that the server is referenced in the appropriate configuration files.
  
Another thing to check is if the client is able to connect to the LDAP server, and that the server is referenced in the appropriate configuration files.
+
If LDAP isn't configured properly, and the machine cannot reach the LDAP server, then the machine may experience a very long boot time (usually hanging during "Starting system message bus..."). The solution to this is to edit /etc/ldap.conf to have "bind_policy soft".
  
If LDAP isn't configured properly, or the machine cannot reach the LDAP server, then the machine may experience a very long boot time (usually hanging during "Starting system message bus...").
+
=== What is needed for a succesful login? ===
 +
* Entry in ldap tables or /etc/password and /etc/shadow
 +
* Be in the correct group. Which group is correct is controlled by [[PAM]] in /etc/security/access.conf
 +
* Make sure the time on the client is correct. Einstein will reject things that don't sound right, such as crazy times in the past or future.
  
== Administration ==
+
=== Errors We've Had ===
Administrators can use the programs ''/usr/sbin/luseradd'', ''/usr/sbin/luserdel'', and ''/usr/sbin/lusermod'' to add, delete, and modify users from the directory. There is also a more-friendly(??) program for adding users: ''/usr/local/bin/adduser-npg'', however it requires that the above programs and more be accessible via the PATH environmental variable (root has the appropriate path set up, but ''sudo'' won't use it).
+
Error:  
 +
bdb_db_open unclean shutdown detected
  
== What is needed for a succesful login? ==
+
Solution:
 +
stop ldap
 +
slapd_db_recover -v -h /var/lib/ldap/
 +
start ldap
  
* Entry in ldap tables or /etc/password and /etc/shadow
+
== Administration ==
* Be in the correct group. Which group is correct is controlled by [[PAM]] in /etc/security/access.conf
+
Administrators can use the programs ''/usr/sbin/luseradd'', ''/usr/sbin/luserdel'', and ''/usr/sbin/lusermod'' to add, delete, and modify users from the directory. There is also a more-friendly(??) program for adding users: ''/usr/local/bin/adduser-npg'', however it requires that the above programs and more be accessible via the PATH environmental variable (root has the appropriate path set up, but ''sudo'' won't use it). When running any of these programs, it is important that the HOME environment variable is set to "/root". Best way to use them is: "env HOME=/root /usr/local/bin/adduser-npg".  
  
I still cannot quite figure out how access to say, the farm nodes, is controlled. What groups you need to be in? Only npg and farm?
+
There appears to be a problem with the libuser stuff in that a new user is added with objectClass of "posixUser" and "account", and you cannot (as far as I (Maurik) could figure out) change "account" to "person". The "account" has a mandatory field for "userid" which is redundant with "uid" and actually gets translated to "uid" when you add something there (in JXplorer). The result is that you cannot modify anything in the account, since you must have something for "userid" which must be different from "uid". See below for the difficult way of changing user info, which works.
  
== External Information ==
+
[http://tools.ietf.org/html/rfc4519 Standard defining things like dn, cn, ou, and object classes]
* [http://www.redhat.com/docs/manuals/linux/RHL-8.0-Manual/ref-guide/s1-ldap-pam.html Setup information]
 
* [http://www.openldap.org/doc/admin23/ OpenLDAP Software 2.3 Administrator's Guide]
 
* [http://www.openldap.org/faq/data/cache/1.html  OpenLDAP Faq-O-Matic]
 
  
== Some Useful LDAP Hints ==
+
Servers must have certificates signed by the Certificate Authority on roentgen.
  
* Add a user account: Use '''env HOME=/root  /user/local/bin/adduser-npg'''
+
=== Some Useful LDAP Hints ===
 
* You can look at and manipulate the tables with JXplorer (installed on improv). Login as root with the standard password for ldap.
 
* You can look at and manipulate the tables with JXplorer (installed on improv). Login as root with the standard password for ldap.
* <font color="red" size=+1>'''Be careful: slapcat, slapadd etc commands can only be run when slapd is NOT running'''
+
* slapcat, slappadd can be used to dump and restore the entire ldap database. <font color="red">'''Be careful: The slapadd command can only be run when slapd is NOT running''' </font>
 
* Modify user items (i.e. shell, home, uid, gid) '''env HOME=/root /usr/sbin/lusermod --shell /bin/false minuti'''
 
* Modify user items (i.e. shell, home, uid, gid) '''env HOME=/root /usr/sbin/lusermod --shell /bin/false minuti'''
 
* Add a user to a group:  '''env HOME=/root /usr/sbin/lgroupmod --member-add uid group'''
 
* Add a user to a group:  '''env HOME=/root /usr/sbin/lgroupmod --member-add uid group'''
 +
 +
We've got to do something about needing the "env HOME=/root" stuff to get those scripts to work properly.  The representation of the programs used in a script shouldn't be dependent on a certain user's PATH variable.  It's already annoying enough when we've got a bunch of scripts that are dependent on a bunch of non-default programs, and the only ways to find out what they are is to pour over the entire source code, or try to run the script over and over, seeing what program it fails to find each time, hoping that what did run didn't mess the system up.
 +
 +
=== Changing Items the "hard" way: ldapadd & ldapmodify ===
 +
 +
This is NOT the easy way, but it works when the easy way does not. You need to create a file which contains "ldif" commands for LDAP. That is the hard part. There is information on the [http://www.openldap.org/software/man.cgi LDAP man pages], but this is pretty terse stuff.
 +
 +
It seems that some of our tables refuse to be modified by "JXplorer" and the like. The same occurs when you try to use the "ldapmodify" trick. This may have to do with and issue in the structure of the tables that we don't (as of yet) understand. One set of tables that suffers from this is the "Netgroup" tables.
 +
 +
Here is a hack, which is a little dangerous, that works around these issues:
 +
 +
First, dump out the record you want to change (for user "editme"):
 +
  ldapsearch -x -L 'uid=editme' > editme.ldif
 +
Next edit the editme.ldif file. In the case of making someone a person, you want to change the "objectClass: account" to "objectClass:person". The person class has a MUST field "sn" or sirname, so add a line: "sn: LastName". You now need to delete the old entry, and for me "ldapdelete" did not work since I could not get the correct credentials (?). Instead I used ldapmodify with the following input script:
 +
  dn: uid=editme,ou=People,dc=physics,dc=unh,dc=edu  # This is the first line of the editme.ldif
 +
  changetype: delete
 +
Save the file and run:
 +
  env HOME=/root ldapmodify -x -W -D "cn=root,dc=physics,dc=unh,dc=edu" -v -f editme_delete.ldif
 +
  env HOME=/root ldapadd  -x -W -D "cn=root,dc=physics,dc=unh,dc=edu" -v -f editme.ldif
 +
The second command restores the record, with the changes you wanted.
 +
 +
It is sometimes easier to use ldapmodify, see the man pages. This would not let me change the objectClass though.
 +
 +
==== Changing a User Password if you only know the Encrypted Version ====
 +
 +
This is one of those things that most of the GUIs just won't let you do. A new user is added and you want to use the encrypted password that the user provided, or perhaps you want to change a forgotten password. How do I put this into LDAP?
 +
 +
The '''BETTER''' way to create your password is to use a random salt, and use $6$ encoding instead of the $1$ (which is SHA-1 and is insecure). The Python command line script is:
 +
python -c 'import crypt,getpass;from base64 import b64encode;from os import urandom;salt=b64encode(urandom(8)); p=getpass.getpass(); print crypt.crypt(p, "$6$"+salt+"$")'
 +
Yes, all in one long line.
 +
 +
Assuming the user is named "Joe", and everything else is setup already for this account, you now create a newpass.ldif file with the following:
 +
dn: uid=joe,ou=People,dc=physics,dc=unh,dc=edu
 +
changetype: modify
 +
replace: userPassword
 +
userPassword: {crypt}$6$bq4QzVsUtXOSX9gr$//M1Z8qWRWIF9zl3GujSr1
 +
 +
Note the {crypt}. Without that the password would be considered a normal password that still needs to be encrypted. <br>
 +
Next, put this into LDAP with
 +
env HOME=/root ldapmodify -x -W -D "cn=root,dc=physics,dc=unh,dc=edu" -v -f newpass.ldif
 +
 +
== Adding users with LUMA ==
 +
 +
Right now the only GUI application for ldap that works is LUMA which is available on most workstations (benfranklin, feynman, parity, etc.)
 +
 +
#After LUMA has started go to the sidebar and click "User Management"
 +
#Follow the steps making sure to put them into the correct group "npg" and under the category "People"
 +
#Also make sure to create the user directory at /home/ and the mail directory at /mail/, both with the username as the folder with the right permissions.  Run chown -R 'username':npg 'userfolder'.
 +
 +
For more information see the [[Luma]] page.
 +
 +
== Fixes ==
 +
 +
We have modified /etc/openldap/schema/nis.schema to fix a bug in the nisNetgroupTriple according to [http://www.openldap.org/lists/openldap-software/200501/msg00309.html http://www.openldap.org/lists/openldap-software/200501/msg00309.html]. The schema should read:
 +
 +
attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
 +
        DESC 'Netgroup triple'
 +
        EQUALITY caseIgnoreIA5Match
 +
        SUBSTR caseIgnoreIA5SubstringsMatch
 +
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
 +
 +
After this fix the Netgroup tables are editable.
 +
 +
 +
== External Information ==
 +
* <strike>[http://www.redhat.com/docs/manuals/linux/RHL-8.0-Manual/ref-guide/s1-ldap-pam.html  Setup information]</strike>
 +
* [http://www.redhat.com/docs/manuals/enterprise/RHEL-5-manual/Deployment_Guide-en-US/ch-ldap.html Documentation for RHEL 5]
 +
* [http://www.openldap.org/doc/admin23/ OpenLDAP Software 2.3 Administrator's Guide]
 +
* [http://www.openldap.org/faq/data/cache/1.html  OpenLDAP Faq-O-Matic]

Latest revision as of 20:52, 9 February 2018

Clients on the network use LDAP to authenticate user logins. We are running an LDAP server on Einstein. This server serves up the user information (passwd and shadow) and also lists of servers and workstations which tie into various permission schemes.

NOTE: Centos/RHEL installs starting from release 6 onwards use SSSD for their authentication. Please see SSSD for more information on setting up authentication for these machines.

Emergency LDAP Rescue Procedure

Organization

LDAP runs on einstein. The service program slapd handles requests from clients. For passwords and such it is protected with TSL encryption. (See Certificates.) The certificate "unh_physics_ca.crt" is used.

Good instructions for setting up a single LDAP server.

Setting up a master/slave server pair

From "Migrating a Mail Server to Postfix/Cyrus/OpenLDAP":

The OpenLDAP slave servers have a similar configuration to the master server. You have to keep some important things in mind.

  • The slave has neither replica nor replogfile directives. (the master does, though)
  • The slave has an additional updatedn option that must be the same as the binddn used in the master config file. ("binddn" is part of the master's replica directive)
  • The DN mentioned in the updatedn option must have write access to the tree.
  • If you wish to write to your slave server, you have to include an updateref directive that points to your master server. Clients issuing write operations will then be redirected to the master.

Introducing a new slave server needs synchronisation with the master database. OpenLDAP cannot copy the whole master data. The master only transfers changes to the slaves. The initial distribution of the whole LDAP tree must be done manually.

  1. Shut down the master server.
  2. Extract a copy of the master's data in LDIF notation by executing slapcat -f /etc/ldap/openldap/slapd.conf master_dump.ldif.
  3. Copy the resulting master_dump.ldif file to your slave server.
  4. Fill the slave's database by executing slapadd -f /etc/ldap/openldap/slapd.conf master_dump.ldif. Make sure the OpenLDAP server there is shut down!
  5. Restart the master server.
  6. Start the slave server.

After that, your master server should log into the slave and send updates as soon as you modify the master LDAP tree. Master and slaves have a steady TCP connection that you can see by using netstat. Important note: Don't forget to create a new key and certificate for the slave or else the encryption won't work.

Configuration

For clients, configuration for LDAP is in two locations: /etc/ldap.conf and /etc/openldap/ldap.conf. Here you set the host(s) that is serving the information. Specifically, einstein.unh.edu or einstein.farm.physics.unh (prefer the farm name for machines on the farm). Also, ldap must be referenced in /etc/nsswitch.conf like so:

passwd:     files ldap
shadow:     files ldap
group:      files ldap

Those may not be the only entries requiring a reference to ldap, but the GUI tool system-config-authentication is good at taking care of things. If a machine doesn't have that program, it's safe to look at another machine's files.

Once a user is authenticated, the client mounts the user's home directory. See Automount.

Troubleshooting

The best way to check whether LDAP is working is getent passwd, which should show user passwords. If it does not work, then env HOME=/root ldapsearch -ZZ '(uid=someusername)' may give more diagnostics. Try ldapsearch -x '(uid=someusername)' to test LDAP without using the encryption layer.

Another thing to check is if the client is able to connect to the LDAP server, and that the server is referenced in the appropriate configuration files.

If LDAP isn't configured properly, and the machine cannot reach the LDAP server, then the machine may experience a very long boot time (usually hanging during "Starting system message bus..."). The solution to this is to edit /etc/ldap.conf to have "bind_policy soft".

What is needed for a succesful login?

  • Entry in ldap tables or /etc/password and /etc/shadow
  • Be in the correct group. Which group is correct is controlled by PAM in /etc/security/access.conf
  • Make sure the time on the client is correct. Einstein will reject things that don't sound right, such as crazy times in the past or future.

Errors We've Had

Error:

bdb_db_open unclean shutdown detected

Solution:

stop ldap
slapd_db_recover -v -h /var/lib/ldap/
start ldap

Administration

Administrators can use the programs /usr/sbin/luseradd, /usr/sbin/luserdel, and /usr/sbin/lusermod to add, delete, and modify users from the directory. There is also a more-friendly(??) program for adding users: /usr/local/bin/adduser-npg, however it requires that the above programs and more be accessible via the PATH environmental variable (root has the appropriate path set up, but sudo won't use it). When running any of these programs, it is important that the HOME environment variable is set to "/root". Best way to use them is: "env HOME=/root /usr/local/bin/adduser-npg".

There appears to be a problem with the libuser stuff in that a new user is added with objectClass of "posixUser" and "account", and you cannot (as far as I (Maurik) could figure out) change "account" to "person". The "account" has a mandatory field for "userid" which is redundant with "uid" and actually gets translated to "uid" when you add something there (in JXplorer). The result is that you cannot modify anything in the account, since you must have something for "userid" which must be different from "uid". See below for the difficult way of changing user info, which works.

Standard defining things like dn, cn, ou, and object classes

Servers must have certificates signed by the Certificate Authority on roentgen.

Some Useful LDAP Hints

  • You can look at and manipulate the tables with JXplorer (installed on improv). Login as root with the standard password for ldap.
  • slapcat, slappadd can be used to dump and restore the entire ldap database. Be careful: The slapadd command can only be run when slapd is NOT running
  • Modify user items (i.e. shell, home, uid, gid) env HOME=/root /usr/sbin/lusermod --shell /bin/false minuti
  • Add a user to a group: env HOME=/root /usr/sbin/lgroupmod --member-add uid group

We've got to do something about needing the "env HOME=/root" stuff to get those scripts to work properly. The representation of the programs used in a script shouldn't be dependent on a certain user's PATH variable. It's already annoying enough when we've got a bunch of scripts that are dependent on a bunch of non-default programs, and the only ways to find out what they are is to pour over the entire source code, or try to run the script over and over, seeing what program it fails to find each time, hoping that what did run didn't mess the system up.

Changing Items the "hard" way: ldapadd & ldapmodify

This is NOT the easy way, but it works when the easy way does not. You need to create a file which contains "ldif" commands for LDAP. That is the hard part. There is information on the LDAP man pages, but this is pretty terse stuff.

It seems that some of our tables refuse to be modified by "JXplorer" and the like. The same occurs when you try to use the "ldapmodify" trick. This may have to do with and issue in the structure of the tables that we don't (as of yet) understand. One set of tables that suffers from this is the "Netgroup" tables.

Here is a hack, which is a little dangerous, that works around these issues:

First, dump out the record you want to change (for user "editme"):

 ldapsearch -x -L 'uid=editme' > editme.ldif

Next edit the editme.ldif file. In the case of making someone a person, you want to change the "objectClass: account" to "objectClass:person". The person class has a MUST field "sn" or sirname, so add a line: "sn: LastName". You now need to delete the old entry, and for me "ldapdelete" did not work since I could not get the correct credentials (?). Instead I used ldapmodify with the following input script:

 dn: uid=editme,ou=People,dc=physics,dc=unh,dc=edu  # This is the first line of the editme.ldif
 changetype: delete

Save the file and run:

 env HOME=/root ldapmodify -x -W -D "cn=root,dc=physics,dc=unh,dc=edu" -v -f editme_delete.ldif
 env HOME=/root ldapadd  -x -W -D "cn=root,dc=physics,dc=unh,dc=edu" -v -f editme.ldif

The second command restores the record, with the changes you wanted.

It is sometimes easier to use ldapmodify, see the man pages. This would not let me change the objectClass though.

Changing a User Password if you only know the Encrypted Version

This is one of those things that most of the GUIs just won't let you do. A new user is added and you want to use the encrypted password that the user provided, or perhaps you want to change a forgotten password. How do I put this into LDAP?

The BETTER way to create your password is to use a random salt, and use $6$ encoding instead of the $1$ (which is SHA-1 and is insecure). The Python command line script is:

python -c 'import crypt,getpass;from base64 import b64encode;from os import urandom;salt=b64encode(urandom(8)); p=getpass.getpass(); print crypt.crypt(p, "$6$"+salt+"$")'

Yes, all in one long line.

Assuming the user is named "Joe", and everything else is setup already for this account, you now create a newpass.ldif file with the following:

dn: uid=joe,ou=People,dc=physics,dc=unh,dc=edu
changetype: modify
replace: userPassword
userPassword: {crypt}$6$bq4QzVsUtXOSX9gr$//M1Z8qWRWIF9zl3GujSr1

Note the {crypt}. Without that the password would be considered a normal password that still needs to be encrypted.
Next, put this into LDAP with

env HOME=/root ldapmodify -x -W -D "cn=root,dc=physics,dc=unh,dc=edu" -v -f newpass.ldif

Adding users with LUMA

Right now the only GUI application for ldap that works is LUMA which is available on most workstations (benfranklin, feynman, parity, etc.)

  1. After LUMA has started go to the sidebar and click "User Management"
  2. Follow the steps making sure to put them into the correct group "npg" and under the category "People"
  3. Also make sure to create the user directory at /home/ and the mail directory at /mail/, both with the username as the folder with the right permissions. Run chown -R 'username':npg 'userfolder'.

For more information see the Luma page.

Fixes

We have modified /etc/openldap/schema/nis.schema to fix a bug in the nisNetgroupTriple according to http://www.openldap.org/lists/openldap-software/200501/msg00309.html. The schema should read:

attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
        DESC 'Netgroup triple'
        EQUALITY caseIgnoreIA5Match
        SUBSTR caseIgnoreIA5SubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

After this fix the Netgroup tables are editable.


External Information