Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
documentation.suse.com / SUSE Linux Enterprise Desktop Documentation / Security and Hardening Guide / Local security / User management
Applies to SUSE Linux Enterprise Desktop 15 SP5

14 User management

14.1 Various account checks

14.1.1 Unlocked accounts

It is important that all system and vendor accounts that are not used for logins are locked. To get a list of unlocked accounts on your system, you can check for accounts that do not have an encrypted password string starting with ! or * in the /etc/shadow file. If you lock an account using either passwd -l or usermod -L, it puts a ! in front of the encrypted password, effectively disabling the password. Many system and shared accounts are locked by default by having a * ,!! or !* as the password field which renders the encrypted password into an invalid string. Hence, to get a list of all unlocked (encryptable) accounts, run the following command:

# egrep -v ':\*|:\!' /etc/shadow | awk -F: '{print $1}'

Also make sure all accounts have an x in the password field in /etc/passwd. The following command lists all accounts that do not have a x in the password field:

# grep -v ':x:' /etc/passwd

An x in the password field means that the password has been shadowed, for example, the encrypted password needs to be looked up in the /etc/shadow file. If the password field in /etc/passwd is empty, then the system does not look up the shadow file and it prompts the user for a password at the login prompt.

14.1.2 Unused accounts

All system or vendor accounts that are not being used by users, applications, by the system or by daemons should be removed from the system. You can use the following command to find out if there are any files owned by a specific account:

# find / -path /proc -prune -o -user ACCOUNT -ls

The -prune option in this example is used to skip the /proc file system. If you are sure that an account can be deleted, you can remove the account using the following command:

# userdel -r ACCOUNT

Without the -r option, userdel does not delete the user's home directory and mail spool (/var/spool/mail/USER). Many system accounts do not have a home directory.

14.2 Enabling password aging

Password expiration is a general best practice, but might need to be excluded for certain system and shared accounts (for example, Oracle). Expiring passwords on those accounts could lead to system outages if the application account expires.

Typically a corporate policy should be developed that dictates rules/procedures regarding password changes for system and shared accounts. However, normal user account passwords should expire automatically. The following example shows how password expiration can be set up for individual user accounts.

The following files and parameters in the table can be used when a new account is created with the useradd command. Settings such as these are stored for each user account in the /etc/shadow file. If using the YaST tool (User and Group Management) to add users, the settings are available on a per-user basis. Here are the various settings, some of which can also be system-wide (for example, modification of /etc/login.defs and /etc/default/useradd):

/etc/login.defs

PASS_MAX_DAYS

Maximum number of days a password is valid.

/etc/login.defs

PASS_MIN_DAYS

Minimum number of days before a user can change the password since the last change.

/etc/login.defs

PASS_WARN_AGE

Number of days between the last password change and the next password change reminder.

/etc/default/useradd

INACTIVE

Number of days after password expiration until the account is disabled.

/etc/default/useradd

EXPIRE

Account expiration date in the format YYYY-MM-DD.

Note
Note: Existing users not affected

Users created before these modifications are not affected.

Ensure that the above parameters are changed in the /etc/login.defs and /etc/default/useradd files. A review of the /etc/shadow file shows how these settings are stored after adding a user.

To create a new user account, execute the following command:

# useradd -c "TEST_USER" -g USERS TEST

The -g option specifies the primary group for this account:

# id TEST
uid=509(test) gid=100(users) groups=100(users)

The settings in /etc/login.defs and /etc/default/useradd are recorded for the test user in the /etc/shadow file as follows:

# grep TEST /etc/shadow
test:!!:12742:7:60:7:14::

Password aging can be modified at any time by use of the chage command. To disable password aging for system and shared accounts, you can run the following chage command:

# chage -M -1 SYSTEM_ACCOUNT_NAME

To get password expiration information:

# chage -l SYSTEM_ACCOUNT_NAME

For example:

# chage -l TEST
Minimum: 7
Maximum: 60
Warning: 7
Inactive: 14
Last Change: Jan 11, 2015
Password Expires: Mar 12, 2015
Password Inactive: Mar 26, 2015
Account Expires: Never

14.3 Stronger password enforcement

On an audited system, it is important to restrict people from using simple passwords that can be cracked too easily. Writing down complex passwords is all right if stored securely. Some argue that strong passwords protect you against dictionary attacks, and those types of attacks can be defeated by locking accounts after a few failed attempts. However, this is not always an option. If set up like this, locking system accounts could bring down your applications and systems, which would be nothing short of a denial-of-service attack—another issue.

At any rate, it is important to practice effective password management security. Most companies require that passwords have at least a number, one lowercase letter, and one uppercase letter. Policies vary, but maintaining a balance between password strength/complexity and management can be difficult.

14.4 Password and login management with PAM

Linux-PAM (Pluggable Authentication Modules for Linux) is a suite of shared libraries that enable the local system administrator to choose how applications authenticate users.

It is strongly recommended to familiarize oneself with the capabilities of PAM and how this architecture can be leveraged to provide the best authentication setup for an environment. This configuration can be done once, and implemented across all systems (a standard), or can be enhanced for individual hosts (enhanced security—by host/service/application). The key is to realize how flexible the architecture is.

To learn more about the PAM architecture, find PAM documentation in the /usr/share/doc/packages/pam directory (in a variety of formats).

The following discussions are examples of how to modify the default PAM stacks—specifically around password policies—for example password strength, password re-use, and account locking. While these are only a few of the possibilities, they serve as a good start and demonstrate PAM's flexibility.

Important
Important: pam-config limitations

The pam-config tool can be used to configure the common-{account,auth,password,session} PAM configuration files, which contain global options. These files include the following comment:

# This file is autogenerated by pam-config. All changes
# will be overwritten.

Individual service files, such as login, password, sshd, and su must be edited directly. You can elect to edit all files directly, and not use pam-config, though pam-config includes useful features such as converting an older configuration, updating your current configuration, and sanity checks. For more information, see man 8 pam-config.

14.4.1 Password strength

SUSE Linux Enterprise Desktop can leverage the pam_cracklib library to test for weak passwords—and to suggest using a stronger one if it determines obvious weakness. The following parameters represent an example that could be part of a corporate password policy or something required because of audit constraints.

The PAM libraries follow a defined flow. The best way to design the perfect stack usually is to consider all of the requirements and policies and draw out a flow chart.

Table 14.1: Sample rules/constraints for password enforcement

pam_cracklib.so

minlen=8

Minimum length of password is 8

pam_cracklib.so

lcredit=-1

Minimum number of lowercase letters is 1

pam_cracklib.so

ucredit=-1

Minimum number of uppercase letters is 1

pam_cracklib.so

dcredit=-1

Minimum number of digits is 1

pam_cracklib.so

ocredit=-1

Minimum number of other characters is 1

To set up these password restrictions, use the pam-config tool to specify the parameters you want to configure. For example, the minimum length parameter could be modified like this:

> sudo pam-config -a --cracklib-minlen=8 --cracklib-retry=3 \
--cracklib-lcredit=-1 --cracklib-ucredit=-1 --cracklib-dcredit=-1 \
--cracklib-ocredit=-1 --cracklib

Now verify that the new password restrictions work for new passwords. Log in to a non-root account and change the password using the passwd command. Note that the above requirements are not enforced if you run the passwd command under root.

14.4.2 Restricting use of previous passwords

The pam_pwhistory module can be used to configure the number of previous passwords that cannot be reused. The following command implements password restrictions on a system so that a password cannot be reused for at least six months:

> sudo pam-config -a --pwhistory --pwhistory-remember=26

Recall that in the section Section 14.2, “Enabling password aging” we set PASS_MIN_DAYS to 7, which specifies the minimum number of days allowed between password changes. Therefore, if pam_unix is configured to remember 26 passwords, then the previously used passwords cannot be reused for at least six months (26*7 days).

The PAM configuration (/etc/pam.d/common-password) resulting from the pam-config command looks like the following:

auth      required   pam_env.so
auth      required   pam_unix.so     try_first_pass
account   required   pam_unix.so     try_first_pass
password  requisite   pam_cracklib.so
password  required   pam_pwhistory.so        remember=26
password  optional   pam_gnome_keyring.so    use_authtok
password  required   pam_unix.so     use_authtok nullok shadow try_first_pass
session   required   pam_limits.so
session   required   pam_unix.so     try_first_pass
session   optional   pam_umask.so

14.4.3 Locking user accounts after too many login failures

Locking accounts after a defined number of failed ssh, login, su, or sudo attempts is a common security practice. However, this could lead to outages if an application, admin, or root user is locked out.

Important
Important: Denial-of-service attacks

Password failure counts can easily be abused to cause denial-of-service attacks by deliberately creating login failures.

Only use password failure counts if you have to. Restrict locking to the necessary minimum, and do not lock critical accounts. Keep in mind that locking not only applies to human users but also to system accounts used to provide services.

SUSE Linux Enterprise Desktop does not lock accounts by default, but provides PAM module pam_tally2 to easily implement password failure counts. Add the following line to the top of /etc/pam.d/login to lock out all users (except for root) after six failed logins, and to automatically unlock the accounts after ten minutes:

auth required pam_tally2.so deny=6 unlock_time=600

This is an example of a complete /etc/pam.d/login file:

#%PAM-1.0
auth     requisite      pam_nologin.so
auth     include        common-auth
auth     required       pam_tally2.so deny=6 unlock_time=600
account  include        common-account
account  required       pam_tally2.so
password include        common-password
session  required       pam_loginuid.so
session  include        common-session
#session  optional       pam_lastlog.so nowtmp showfailed
session  optional       pam_mail.so standard

You can also lock out root, though obviously you must be very certain you want to do this:

auth required pam_tally2.so deny=6 even_deny_root unlock_time=600

You can define a different lockout time for root:

auth required pam_tally2.so deny=6 root_unlock_time=120  unlock_time=600

If you want to require the administrator to unlock accounts, leave out the unlock_time option. The next two example commands display the number of failed login attempts and how to unlock a user account:

> sudo pam_tally2 -u username
Login           Failures Latest failure     From
username            6    12/17/19 13:49:43  pts/1

> sudo pam_tally2 -r -u username

The default location for attempted accesses is recorded in /var/log/tallylog.

If the user succeeds in logging in after the login timeout expires, or after the administrator resets their account, the counter resets to 0.

Configure other login services to use pam_tally2 in their individual configuration files in /etc/pam.d/: sshd, su, sudo, sudo-i, and su-l.

14.5 Restricting root logins

By default, the root user is assigned a password and can log in using various methods—for example, on a local terminal, in a graphical session, or remotely via SSH. These methods should be restricted as far as possible. Shared usage of the root account should be avoided. Instead, individual administrators should use tools such as su or sudo (for more information, type man 1 su or man 8 sudo) to obtain elevated privileges. This allows associating root logins with particular users. This also adds another layer of security; not only the root password, but both the root and the password of an administrator's regular account would need to be compromised to gain full root access. This section explains how to limit direct root logins on the different levels of the system.

14.5.1 Restricting local text console logins

TTY devices provide text-mode system access via the console. For desktop systems these are accessed via the local keyboard or—in case of server systems—via input devices connected to a KVM switch or a remote management card (for example, ILO and DRAC). By default, Linux offers six different consoles, which can be switched to via the key combinations AltF1 to AltF6, when running in text mode, or CtrlAltF1 to CtrlAltF6 when running in a graphical session. The associated terminal devices are named tty1 to tty6.

The following steps restrict root access to the first TTY. Even this access method is only meant for emergency access to the system and should never be used for everyday system administration tasks.

Note
Note

The steps shown here are tailored towards PC architectures (x86 and AMD64/Intel 64). On architectures such as POWER, different terminal device names than tty1 can be used. Be careful not to lock yourself out by specifying wrong terminal device names. You can determine the device name of the terminal you are currently logged in to by running the tty command. Be careful not to do this in a virtual terminal, such as via SSH or in a graphical session (device names /dev/pts/N), but only from an actual login terminal reachable via AltFN.

Procedure 14.1: Restricting root logins on local TTYs
  1. Ensure that the PAM stack configuration file /etc/pam.d/login contains the pam_securetty module in the auth block:

    auth     requisite      pam_nologin.so
     auth     [user_unknown=ignore success=ok ignore=ignore auth_err=die default=bad] pam_securetty.so noconsole
     auth     include        common-auth

    This includes the pam_securetty module during the authentication process on local consoles, which restricts root to logging in only on TTY devices that are listed in the file /etc/securetty.

  2. Remove all entries from /etc/securetty except one. This limits the access to TTY devices for root.

    #
    # This file contains the device names of tty lines (one per line,
    # without leading /dev/) on which root is allowed to login.
    #
    tty1
  3. Check whether logins to other terminals are rejected for root. A login on tty2, for example, should be rejected immediately, without even querying the account password. Also make sure that you can still successfully log in to tty1 and thus that root is not locked out of the system.

Important
Important: Do not add pam_securetty module

Do not add the pam_securetty module to the /etc/pam.d/common-auth file. This would break the su and sudo commands, because these tools would then also reject root authentications.

Important
Important

These configuration changes also cause root logins on serial consoles such as /dev/ttyS0 to be denied. In case you require such use cases, you need to list the respective TTY devices additionally in the /etc/securetty file.

14.5.2 Restricting graphical session logins

To improve security on your server, avoid using graphical environments at all. Graphical programs are often not designed to be run as root and can contain security issues than console programs. If you require a graphical login, use a non-root login. Configure your system to disallow root from logging in to graphical sessions.

To prevent root from logging in to graphical sessions, you can apply the same basic steps as outlined in Section 14.5.1, “Restricting local text console logins”. Just add the pam_securetty module to the PAM stack file belonging to the display manager—for example, /etc/pam.d/gdm for GDM. The graphical session also runs on a TTY device: by default, tty7. Therefore, if you restrict root logins to tty1, then root is denied login in the graphical session.

14.5.3 Restricting SSH logins

By default, the root user is also allowed to log in to a machine remotely via the SSH network protocol (if the SSH port is not blocked by the firewall). To restrict this, make the following change to the OpenSSH configuration:

  1. Edit /etc/ssh/sshd_config and adjust the following parameter:

    PermitRootLogin no
  2. Restart the sshd service to make the changes effective:

    systemctl restart sshd.service
Note
Note

Using the PAM pam_securetty module is not suitable in case of OpenSSH, because not all SSH logins go through the PAM stack during authorization (for example, when using SSH public-key authentication). Additionally, an attacker could differentiate between a wrong password and a successful login that was only rejected later on by policy.

14.6 Restricting sudo users

The sudo command allows users to execute commands in the context of another user, typically the root user. The sudo configuration consists of a rule-set that defines the mappings between commands to execute and their allowed source and target users and groups. The configuration is stored in the file /etc/sudoers. For more information about sudo, refer to Chapter 2, sudo basics.

By default, sudo asks for the root password on SUSE systems. Unlike su however, sudo remembers the password and allows further commands to be executed as root without asking for the password again for five minutes. Therefore, sudo should be enabled for selected administrator users only.

Procedure 14.2: Restricting sudo for normal users
  1. Edit file /etc/sudoers, for example by executing visudo.

  2. Comment out the line that allows every user to run every command as long as they know the password of the user they want to use. Afterwards, it should look like this:

    #ALL ALL=(ALL) ALL # WARNING! Only use this together with 'Defaults targetpw'!
  3. Uncomment the following line:

    %wheel ALL=(ALL) ALL

    This limits the functionality described above to members of the group wheel. You can use a different group as wheel might have other implications that might not be suitable depending on your setup.

  4. Add users that should be allowed to use sudo to the chosen group. To add the user tux to the group wheel, use:

    usermod -aG wheel tux

    To get the new group membership, users have to log out and back in again.

  5. Verify the change by running a command with a user not in the group you have chosen for access control. You should see the error message:

    wilber is not in the sudoers file.  This incident will be reported.

    Next, try the same with a member of the group. They should still be able to execute commands via sudo.

This configuration only limits the sudo functionality. The su command is still available to all users. If there are other ways to access the system, users with knowledge of the root password can easily execute commands via this vector.

14.7 Setting an inactivity timeout for interactive shell sessions

It can be a good idea to terminate an interactive shell session after a certain period of inactivity. For example, to prevent open, unguarded sessions, or to avoid wasting system resources.

By default, there is no inactivity timeout for shells. Nothing happens if a shell stays open and unused for days or even years. However, it is possible to configure most shells so that idle sessions terminate automatically after a certain amount of time. The following example shows how to set an inactivity timeout for several common types of shells.

The inactivity timeout can be configured for login shells only or for all interactive shells. In the latter case, the inactivity timeout runs individually for each shell instance. This means that timeouts accumulate. When a sub- or child-shell is started, a new timeout begins for the sub- or child-shell, and only afterwards the timeout of the parent continues running.

The following table contains configuration details for a selection of common shells shipped with SUSE Linux Enterprise Desktop:

packageshell personalitiesshell variabletime unitreadonly settingconfig path (only login shell)config path (all shells)

bash

bash, sh

TMOUT

seconds

read-only TMOUT=

/etc/profile.local, /etc/profile.d/

/etc/bash.bashrc

mksh

ksh, lksh, mksh, pdksh

TMOUT

seconds

read-only TMOUT=

/etc/profile.local, /etc/profile.d/

/etc/ksh.kshrc.local

tcsh

csh, tcsh

autologout

minutes

set -r autologout=

/etc/csh.login.local

/etc/csh.cshrc.local

zsh

zsh

TMOUT

seconds

readonly TMOUT=

/etc/profile.local, /etc/profile.d/

/etc/zsh.zshrc.local

Every listed shell supports an internal timeout shell variable that can be set to a specific time value to cause the inactivity timeout. If you want to prevent users from overriding the timeout setting, you can mark the corresponding shell timeout variable as read-only. The corresponding variable declaration syntax is also found in the table above.

Note
Note: No protection from hostile users

This feature is only helpful for avoiding risks if a user is forgetful or follows unsafe practices. It does not protect against hostile users. The timeout only applies to interactive wait states of a shell. A malicious user can always find ways to circumvent the timeout and keep their session open regardless.

To configure the inactivity timeout, you need to add the matching timeout variable declaration to each shell's start-up script. Use either the path for login shells only, or the one for all shells, as listed in the table. The following example uses paths and settings that are suitable for bash and ksh to set up a read-only login shell timeout that cannot be overridden by users. Create the file /etc/profile.d/timeout.sh with the following content:

# /etc/profile.d/timeout.sh for SUSE Linux
#
# Timeout in seconds until the bash/ksh session is terminated
# in case of inactivity.
# 24h = 86400 sec
readonly TMOUT=86400
Tip
Tip

We recommend using the screen tool to detach sessions before logging out. screen sessions are not terminated and can be re-attached whenever required. An active session can be locked without logging out (read about CtrlAX / lockscreen in man screen for details).

14.8 Preventing accidental denial of service

Linux allows you to set limits on the amount of system resources that users and groups can consume. This is also useful if bugs in programs cause them to use up too many resources (for example, memory leaks), slow down the machine, or even render the system unusable. Incorrect settings can allow programs to use too many resources, which might make the server unresponsive to new connections or even local logins (for example, if a program uses up all available file handles on the host). This can also be a security concern if someone is allowed to consume all system resources and therefore cause a denial-of-service attack—either unplanned, or worse, planned. Setting resource limits for users and groups might be an effective way to protect systems, depending on the environment.

14.8.1 Example for restricting system resources

The following example demonstrates the practical usage of setting or restricting system resource consumption for an Oracle user account. For a list of system resource settings, see /etc/security/limits.conf or man limits.conf.

Most shells, such as Bash, provide control over various resources (for example, the maximum allowable number of open file descriptors or the maximum number of processes) that are available on a per-user basis. To examine all current limits in the shell, execute:

# ulimit -a

For more information on ulimit for the Bash shell, examine the Bash man pages.

Important
Important: Setting limits for SSH sessions

Setting hard and soft limits might not have the expected results when using an SSH session. To see valid behavior, it might be necessary to log in as root, and then su to the ID with limits (for example, Oracle in these examples). Resource limits should also work assuming the application was started automatically during the boot process. It might be necessary to set UsePrivilegeSeparation in /etc/ssh/sshd_config to no and restart the SSH daemon (systemctl restart sshd) if it seems that the changes to resource limits are not working (via SSH). However, this is not generally recommended, as it weakens a system's security.

Tip
Tip: Disabling password logins via ssh

You can add extra security to your server by disabling password authentication for SSH. Remember that you need to have SSH keys configured, otherwise you cannot access the server. To disable password login, add the following lines to /etc/ssh/sshd_config:

UseLogin no
UsePAM no
PasswordAuthentication no
PubkeyAuthentication yes

In this example, a change to the number of file handles or open files that the user oracle can use is made by editing /etc/security/limits.conf as root making the following changes:

oracle           soft    nofile          4096
oracle           hard    nofile          63536

The soft limit in the first line defines the limit on the number of file handles (open files) that the oracle user has after login. If the user sees error messages about running out of file handles, then the user can increase the number of file handles like in this example up to the hard limit (in this example 63536) by executing:

# ulimit -n 63536

You can set the soft and hard limits higher if necessary.

Note
Note: Caution with using ulimits

It is important to be judicious with the usage of ulimits. Allowing a hard limit for nofile for a user that is equal to the kernel limit (/proc/sys/fs/file-max) is bad. If the user consumes all the available file handles, the system cannot initiate new logins, since it is not possible to access the PAM modules required to perform a login.

You also need to ensure that pam_limits is either configured globally in /etc/pam.d/common-auth, or for individual services like SSH, su, login and telnet in:

/etc/pam.d/sshd (for SSH)
/etc/pam.d/su (for su)
/etc/pam.d/login (local logins and telnet)

If you do not want to enable it for all logins, there is a specific PAM module that reads the /etc/security/limits.conf file. Entries in PAM configuration directives have entries like:

session     required      /lib/security/pam_limits.so
session     required      /lib/security/pam_unix.so

Changes are not immediate and require a new login session:

# su - oracle
> ulimit -n
4096

Note that these examples are specific to the Bash shell; ulimit options are different for other shells. The default limit for the user oracle is 4096. To increase the number of file handles the user oracle can use to 63536, execute:

# su - oracle
> ulimit -n
4096
> ulimit -n 63536
> ulimit -n
63536

Making this permanent requires the addition of the setting, ulimit -n 63536, (again, for Bash) to the user's profile (~/.bashrc or ~/.profile file), which is the user start-up file for the Bash shell on SUSE Linux Enterprise Desktop (to verify your shell, run: echo $SHELL). To do this you could run the following commands for the Bash shell of the user oracle:

# su - oracle
> cat >> ~oracle/.bash_profile << EOF
ulimit -n 63536
EOF

14.9 Displaying login banners

It is often necessary to place a banner on login screens on all servers for legal/audit policy reasons or to give security instructions to users.

To print a login banner after a user logs in on a text based terminal, for example, using SSH or on a local console, you can use the file /etc/motd (motd = message of the day). The file exists by default on SUSE Linux Enterprise Desktop, but it is empty. Simply add content to the file that is applicable/required by the organization.

Note
Note: Banner length

Try to keep the login banner content to a single terminal page (or less), as it scrolls the screen if it does not fit, making it more difficult to read.

You can also have a login banner printed before a user logs in on a text based terminal. For local console logins, you can edit the /etc/issue file, which causes the banner to be displayed before the login prompt. For logins via SSH, you can edit the Banner parameter in the /etc/ssh/sshd_config file, which then appropriately displays the banner text before the SSH login prompt.

For graphical logins via GDM, you can follow the GNOME admin guide to set up a login banner. Furthermore, you can make the following changes to require a user to acknowledge the legal banner by selecting Yes or No. Edit the /etc/gdm/Xsession file and add the following lines at the beginning of the script:

if ! /usr/bin/gdialog --yesno '\nThis system is classified...\n' 10 10; then
    /usr/bin/gdialog --infobox 'Aborting login'
    exit 1;
fi

The text This system is classified... needs to be replaced with the desired banner text. Note that this dialog does not prevent a login from progressing. For more information about GDM scripting, refer to the GDM Admin Manual.

14.10 Connection accounting utilities

Here is a list of commands you can use to get data about user logins:

who Lists currently logged in users.

w Shows who is logged in and what they are doing.

last Shows a list of the most recent logged in users, including login time, logout time, login IP address, etc.

lastb Same as last, except that by default it shows /var/log/btmp, which contains all the bad login attempts.

lastlog This command reports data maintained in /var/log/lastlog, which is a record of the last time a user logged in.

ac Available after installing the acct package. Prints the connect time in hours on a per-user basis or daily basis, etc. This command reads /var/log/wtmp.

dump-utmp Converts raw data from /var/run/utmp or /var/log/wtmp into ASCII-parseable format.

Also check the /var/log/messages file, or the output of journalctl if no logging facility is running. See Chapter 21, journalctl: query the systemd journal for more information on the systemd journal.