Les sous-sections suivantes décrivent les méthodes d'authentification en détail.
Quand l'authentification trust est utilisée, PostgreSQL™ considère que quiconque peut se connecter au serveur est autorisé à accéder à la base de données quel que soit le nom d'utilisateur de bases de données qu'il fournit (même les noms des super-utilisateurs). Les restrictions apportées dans les colonnes database et user continuent évidemment de s'appliquer. Cette méthode ne doit être utilisée que si le système assure un contrôle adéquat des connexions au serveur.
L'authentification trust est appropriée et très pratique pour les connexions locales sur une station de travail mono-utilisateur. Elle n'est généralement pas appropriée en soi sur une machine multi-utilisateur. Cependant, trust peut tout de même être utilisé sur une machine multi-utilisateur, si l'accès au fichier socket de domaine Unix est restreint par les permissions du système de fichiers. Pour ce faire, on peut positionner les paramètres de configuration unix_socket_permissions (et au besoin unix_socket_group) comme cela est décrit dans la Section 18.3, « Connexions et authentification ». On peut également positionner le paramètre de configuration unix_socket_directories pour placer le fichier de socket dans un répertoire à l'accès convenablement restreint.
Le réglage des droits du système de fichiers n'a d'intérêt que le cas de connexions par les sockets Unix. Les droits du système de fichiers ne restreignent pas les connexions TCP/IP locales. Ainsi, pour utiliser les droits du système de fichiers pour assurer la sécurité locale, il faut supprimer la ligne host ...127.0.0.1 ... de pg_hba.conf ou la modifier pour utiliser une méthode d'authentification différente de trust.
L'authentification trust n'est envisageable, pour les connexions TCP/IP, que si chaque utilisateur de chaque machine autorisée à se connecter au serveur par les lignes trust du fichier pg_hba.conf est digne de confiance. Il est rarement raisonnable d'utiliser trust pour les connexions autres que celles issues de localhost (127.0.0.1).
Les méthodes fondées sur une authentification par mot de passe sont md5 et password. Ces méthodes fonctionnent de façon analogue à l'exception du mode d'envoi du mot de passe à travers la connexion : respectivement, hachage MD5 et texte en clair.
S'il existe un risque d'attaque par « interception (sniffing) » des mots de passe, il est préférable d'utiliser md5. L'utilisation de password, en clair, est toujours à éviter quand c'est possible. Néanmoins, md5 ne peut pas être utilisé avec la fonctionnalité db_user_namespace. Si la connexion est protégée par un chiffrement SSL, alors password peut être utilisé avec sûreté (bien que l'authentification par certificat SSL pourrait être un meilleur choix s'il y a dépendance au sujet de l'utilisation de SSL).
Les mots de passe PostgreSQL™ sont distincts des mots de passe du système d'exploitation. Le mot de passe de chaque utilisateur est enregistré dans le catalogue système pg_authid. Ils peuvent être gérés avec les commandes SQL CREATE USER(7) et ALTER ROLE(7). Ainsi, par exemple, CREATE USER foo WITH PASSWORD 'secret';. Si aucun mot de passe n'est enregistré pour un utilisateur, le mot de passe enregistré est nul et l'authentification par mot de passe échoue systématiquement pour cet utilisateur.
GSSAPI™ est un protocole du standard de l'industrie pour l'authentification sécurisée définie dans RFC 2743. PostgreSQL™ supporte GSSAPI™ avec l'authentification Kerberos™ suivant la RFC 1964. GSSAPI™ fournit une authentification automatique (single sign-on) pour les systèmes qui le supportent. L'authentification elle-même est sécurisée mais les données envoyées sur la connexion seront en clair sauf si SSL est utilisé.
Quand GSSAPI™ passe par Kerberos™, il utilise un principal standard dans le format nomservice/nomhôte@domaine. Pour des informations sur les parties du principal et sur la façon de configurer les clés requises, voir Section 19.3.5, « Authentification Kerberos ».
Le support de GSSAPI doit être activé lors de la construction de PostgreSQL™ ; voir Chapitre 15, Procédure d'installation de PostgreSQL™ du code source pour plus d'informations.
Les options de configuration suivantes sont supportées pour GSSAPI™ :
Si configuré à 1, le nom du royaume provenant du principal de l'utilisateur authentifié est inclus dans le nom de l'utilisateur système qui est passé au système de correspondance d'utilisateur (Section 19.2, « Correspondances d'utilisateurs »). Ceci est utile pour gérer des utilisateurs provenant de plusieurs royaumes.
Permet la mise en correspondance entre les noms système et base de données. Voir Section 19.2, « Correspondances d'utilisateurs » pour plus de détails. Pour un principal Kerberos username/hostbased@EXAMPLE.COM, le nom d'utilisateur utilisé pour la correspondance est nomutilisateur/hote si include_realm est désactivé, et username/hostbased@EXAMPLE.COM si include_realm est activé.
Configure le royaume pour la correspondance du principal de l'utilisateur. Si ce paramètre est configuré, seuls les utilisateurs de ce royaume seront acceptés. S'il n'est pas configuré, les utilisateurs de tout royaume peuvent se connecter, à condition que la correspondance du nom de l'utilisateur est faite.
SSPI™ est une technologie Windows™ pour l'authentification sécurisée avec single sign-on. PostgreSQL™ utilise SSPI dans un mode de négociation (negotiate) qui utilise Kerberos™ si possible et NTLM™ sinon. L'authentification SSPI™ ne fonctionne que lorsque serveur et client utilisent Windows™ ou, sur les autres plateformes, quand GSSAPI™ est disponible.
Lorsque Kerberos™ est utilisé, SSPI™ fonctionne de la même façon que GSSAPI™. Voir Section 19.3.3, « Authentification GSSAPI » pour les détails.
Les options de configuration suivantes sont supportées pour SSPI™ :
Si configuré à 1, le nom du royaume provenant du principal de l'utilisateur authentifié est inclus dans le nom de l'utilisateur système qui est passé au système de correspondance d'utilisateur (Section 19.2, « Correspondances d'utilisateurs »). Ceci est utile pour gérer des utilisateurs provenant de plusieurs royaumes.
Permet la mise en correspondance entre les noms système et base de données. Voir Section 19.2, « Correspondances d'utilisateurs » pour plus de détails.
Configure le royaume pour la correspondance du principal de l'utilisateur. Si ce paramètre est configuré, seuls les utilisateurs de ce royaume seront acceptés. S'il n'est pas configuré, les utilisateurs de tout royaume peuvent se connecter, à condition que la correspondance du nom de l'utilisateur est faite.
L'authentification Kerberos native est obsolète et ne doit être utilisée que pour assurer la compatibilité ascendante. Les nouvelles installations et les mises à jour utiliseront préférentiellement le standard d'authentification de l'industrie, GSSAPI™ (voir Section 19.3.3, « Authentification GSSAPI »).
Kerberos™ est un système d'authentification sécurisée de standard industriel destiné à l'informatique distribuée sur un réseau public. La description de Kerberos™ dépasse les objectifs de ce document même dans les généralités, c'est assez complexe (bien que puissant). La FAQ Kerberos ou la page Kerberos du MIT sont un bon point de départ à l'exploration. Il existe plusieurs sources de distribution Kerberos™. Kerberos™ fournit une authentification sécurisée mais ne chiffre pas les requêtes ou les données passées sur le réseau ; pour cela, SSL doit être utilisé.
PostgreSQL™ supporte Kerberos version 5. Le support de Kerberos doit être activé lors de la construction de PostgreSQL™ ; voir le Chapitre 15, Procédure d'installation de PostgreSQL™ du code source pour plus d'informations.
PostgreSQL™ opère comme un service Kerberos normal. Le nom du service principal est nomservice/nomhôte@domaine.
nomservice peut être configuré du côté serveur en utilisant le paramètre de configuration krb_srvname (voir aussi Section 31.1.2, « Mots clés de la chaîne de connexion »). La valeur par défaut à l'installation, postgres, peut être modifiée lors de la construction avec ./configure --with-krb-srvnam=quelquechose. Dans la plupart des environnements, il est inutile de modifier cette valeur. Néanmoins, cela devient nécessaire pour supporter plusieurs installations de PostgreSQL™ sur le même hôte. Quelques implantations de Kerberos peuvent imposer un nom de service différent, comme Microsoft Active Directory qui réclame un nom du service en majuscules (POSTGRES).
nom_hote est le nom de l'hôte pleinement qualifié (fully qualified host name) de la machine serveur. Le domaine du service principal (client) est le domaine préféré du serveur.
Les principaux (clients) doivent contenir le nom de leur utilisateur PostgreSQL™ comme premier composant, nomutilisateurpg@domaine, par exemple. Sinon, vous pouvez utiliser une correspondance du nom d'utilisateur qui établit la correspondance à partir du premier composant du nom du principal vers le nom d'utilisateur de la base de données Par défaut, le domaine du client n'est pas vérifié par PostgreSQL™. Si l'authentification inter-domaine (cross-realm) est activée, on utilise le paramètre krb_realm ou activer include_realm et utiliser la correspondance du nom d'utilisateur pour vérifier le royaume.
Le fichier de clés du serveur doit être lisible (et de préférence uniquement lisible) par le compte serveur PostgreSQL™ (voir aussi la Section 17.1, « Compte utilisateur PostgreSQL™ »). L'emplacement du fichier de clés est indiqué grâce au paramètre de configuration krb_server_keyfile fourni à l'exécution. La valeur par défaut est /etc/srvtab, si Kerberos 4 est utilisé, et /usr/local/pgsql/etc/krb5.keytab sinon (ou tout autre répertoire indiqué comme sysconfdir à la compilation).
Le fichier de clés est engendré par le logiciel Kerberos ; voir la documentation de Kerberos pour les détails. L'exemple suivant correspond à des implantations de Kerberos 5 compatibles avec MIT :
kadmin% ank -randkey postgres/server.my.domain.org kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org
Lors de la connexion à la base de données, il faut s'assurer de posséder un ticket pour le principal correspondant au nom d'utilisateur de base de données souhaité. Par exemple, pour le nom d'utilisateur PostgreSQL fred, le principal fred@EXAMPLE.COM pourrait se connecter. Pour autoriser aussi le principal fred/users.example.com@EXAMPLE.COM, utiliser une correspondance de nom d'utilisateur, comme décrit dans Section 19.2, « Correspondances d'utilisateurs ».
Si mod_auth_kerb et mod_perl sont utilisés sur le serveur web Apache™, AuthType KerberosV5SaveCredentials peut être utilisé avec un script mod_perl. Cela fournit un accès sûr aux bases de données, sans demander de mot de passe supplémentaire.
Les options de configuration suivantes sont supportées pour Kerberos™ :
Permet la mise en correspondance entre les noms système et base de données. Voir Section 19.2, « Correspondances d'utilisateurs » pour plus de détails.
Si configuré à 1, le nom du royaume provenant du principal de l'utilisateur authentifié est inclus dans le nom de l'utilisateur système qui est passé au système de correspondance d'utilisateur (Section 19.2, « Correspondances d'utilisateurs »). Ceci est utile pour gérer des utilisateurs provenant de plusieurs royaumes.
Configure le royaume pour la correspondance du principal de l'utilisateur. Si ce paramètre est configuré, seuls les utilisateurs de ce royaume seront acceptés. S'il n'est pas configuré, les utilisateurs de tout royaume peuvent se connecter, à condition que la correspondance du nom de l'utilisateur est faite.
Précise le nom d'hôte du service principal. Cela, combiné avec krb_srvname, est utilisé pour généré le nom complet du service principal, qui est krb_srvname/krb_server_hostname@REALM. S'il n'est pas renseigné, la valeur par défaut est le nom d'hôte du serveur.
La méthode d'authentification ident fonctionne en obtenant le nom de l'opérateur du système depuis le serveur ident distant et en l'appliquant comme nom de l'utilisateur de la base de données (et après une éventuelle mise en correspondance). Cette méthode n'est supportée que pour les connexions TCP/IP.
Lorsqu'ident est spécifié pour une connexion locale (c'est-à-dire non TCP/IP), l'authentification peer (voir Section 19.3.7, « Peer Authentication ») lui est automatiquement substituée.
Les options de configuration suivantes sont supportées pour ident™ :
Permet la mise en correspondance entre les noms système et base de données. Voir Section 19.2, « Correspondances d'utilisateurs » pour plus de détails.
Le « protocole d'identification » est décrit dans la RFC 1413. Théoriquement, chaque système d'exploitation de type Unix contient un serveur ident qui écoute par défaut sur le port TCP 113. La fonctionnalité basique d'un serveur ident est de répondre aux questions telles que : « Quel utilisateur a initié la connexion qui sort du port X et se connecte à mon port Y? ». Puisque PostgreSQL™ connaît X et Y dès lors qu'une connexion physique est établie, il peut interroger le serveur ident de l'hôte du client qui se connecte et peut ainsi théoriquement déterminer l'utilisateur du système d'exploitation pour n'importe quelle connexion.
Le revers de cette procédure est qu'elle dépend de l'intégrité du client : si la machine cliente est douteuse ou compromise, un attaquant peut lancer n'importe quel programme sur le port 113 et retourner un nom d'utilisateur de son choix. Cette méthode d'authentification n'est, par conséquent, appropriée que dans le cas de réseaux fermés dans lesquels chaque machine cliente est soumise à un contrôle strict et dans lesquels les administrateurs système et de bases de données opèrent en étroite collaboration. En d'autres mots, il faut pouvoir faire confiance à la machine hébergeant le serveur d'identification. Cet avertissement doit être gardé à l'esprit :
Le protocole d'identification n'a pas vocation à être un protocole d'autorisation ou de contrôle d'accès. |
||
--RFC 1413 |
Certains serveurs ident ont une option non standard qui chiffre le nom de l'utilisateur retourné à l'aide d'une clé connue du seul administrateur de la machine dont émane la connexion. Cette option ne doit pas être employée lorsque le serveur ident est utilisé avec PostgreSQL™ car PostgreSQL™ n'a aucun moyen de déchiffrer la chaîne renvoyée pour déterminer le nom réel de l'utilisateur.
La méthode d'authentification peer utilise les services du système d'exploitation afin d'obtenir le nom de l'opérateur ayant lancé la commande client de connexion et l'utilise (après une éventuelle mise en correspondance) comme nom d'utilisateur de la base de données. Cette méthode n'est supportée que pour les connexions locales.
Les options de configuration suivantes sont supportées pour l'authentification peer™ :
Autorise la mise en correspondance entre le nom d'utilisateur fourni par le système d'exploitation et le nom d'utilisateur pour la base de données. Voir Section 19.2, « Correspondances d'utilisateurs » pour plus de détails.
L'authentification peer n'est disponible que sur les systèmes d'exploitation fournissant la fonction getpeereid(), le paramètre SO_PEERCRED pour les sockets ou un mécanisme similaire. Actuellement, cela inclut Linux, la plupart des variantes BSD (et donc Mac OS X), ainsi que Solaris.
Ce mécanisme d'authentification opère de façon similaire à password à ceci près qu'il utilise LDAP comme méthode de vérification des mots de passe. LDAP n'est utilisé que pour valider les paires nom d'utilisateur/mot de passe. De ce fait, pour pouvoir utiliser LDAP comme méthode d'authentification, l'utilisateur doit préalablement exister dans la base.
L'authentification LDAP peut opérer en deux modes. Dans le premier mode, que nous appelerons le mode « simple bind », le serveur fera un « bind » sur le nom distingué comme préfixe nom_utilisateur suffixe. Typiquement, le paramètre prefix est utilisé pour spécifier cn= ou DOMAIN\ dans un environnement Active Directory. suffix est utilisé pour spécifier le reste du DN dans un environnement autre qu'Active Directory.
Dans le second mode, que nous appelerons mode « search+bind », le serveur commence un « bind » sur le répertoire LDAP avec un nom d'utilisateur et un mot de passe fixés, qu'il indique à ldapbinddn et ldapbindpasswd. Il réalise une recherche de l'utilisateur en essayant de se connecter à la base de données. Si aucun utilisateur et aucun mot de passe n'est configuré, un « bind » anonyme sera tenté sur le répertoire. La recherche sera réalisée sur le sous-arbre sur ldapbasedn, et essaiera une correspondance exacte de l'attribut indiqué par ldapsearchattribute. Une fois que l'utilisateur a été trouvé lors de cette recherche, le serveur se déconnecte et effectue un nouveau « bind » au répertoire en tant que cet utilisateur, en utilisant le mot de passe indiqué par le client pour vérifier que la chaîne de connexion est correcte. Ce mode est identique à celui utilisé par les schémas d'authentification LDAP dans les autres logiciels, tels que les modules Apache mod_authnz_ldap et pam_ldap. Cette méthode permet une plus grande flexibilité sur l'emplacement des objets utilisateurs dans le répertoire mais demandera deux connexions au serveur LDAP.
Les options de configuration suivantes sont utilisées dans les deux modes :
Noms ou adresses IP des serveurs LDAP auxquels se connecter. Plusieurs serveurs peuvent être indiqués, en les séparant par des espaces.
Numéro de port du serveur LDAP auquel se connecter. Si aucun port n'est spécifié, le port par défaut de la bibliothèque LDAP sera utilisé.
Positionnez à 1 pour que la connexion entre PostgreSQL et le serveur LDAP utilise du chiffrage TLS. Notez que ceci ne chiffre que le trafic jusqu'au serveur LDAP -- la connexion vers le client peut toujours ne pas être chiffrée sauf si SSL est utilisé.
Les options suivantes sont utilisées uniquement dans le mode « simple bind » :
Chaîne à préfixer au nom de l'utilisateur pour former le DN utilisé comme lien lors d'une simple authentification bind.
Chaîne à suffixer au nom de l'utilisateur pour former le DN utilisé comme lien lors d'une simple authentification bind.
Les options suivantes sont utilisées uniquement dans le mode « search+bind » :
Racine DN pour commencer la recherche de l'utilisateur lors d'une authentification search+bind.
DN de l'utilisateur pour se lier au répertoire avec lequel effectuer la recherche lors d'une authentification search+bind.
Mot de passe de l'utilisateur pour se lier au répertoire avec lequel effectuer la recherche lors d'une authentification search+bind.
Attribut à faire correspondre au nom d'utilisateur dans la recherche lors d'une authentification search+bind. Si aucun attribut n'est indiqué, l'attribut uid sera utilisé.
Une URL LDAP dont le format est spécifié par la RFC 4516. C'est une autre façon d'écrire certaines options LDAP d'une façon plus compacte et standard. Le format est :
ldap://hote[:port]/basedn[?[attribut][?[scope]]]
scope doit faire partie des possibilités suivantes : base, one, sub. Ce sera généralement la dernière possibilité. Seulement un attribut est utilisé. Quelques autres composants des URL LDAP standards comme les filtres et les extensions ne sont pas supportés.
Pour les « bind » non anonymes, ldapbinddn et ldapbindpasswd doivent être spécifiées comme des options séparées.
Pour utiliser les connexions LDAP chiffrées, l'option ldaptls doit être utilisée avec ldapurl. Le schéma d'URL ldaps (connexion SSL directe) n'est pas supporté.
Les URL LDAP sont actuellement seulement supportées par OpenLDAP, et pas sous Windows.
Mixer les options de configurations du mode « simple bind » et du mode « search+bind » est une erreur.
Voici un exemple de configuration LDAP pour le mode « simple bind » :
host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
Quand une connexion au serveur de base de données est demandée en tant que un_utilisateur, PostgreSQL tentera un « bind » vers le serveur LDAP en utilisant le DN cn=un_utilisateur, dc=example, dc=net et le mot de passe fourni par le client. Si cette connexion réussit, l'accès à la base de données est accepté.
Voici un exemple de configuration LDAP pour le mode « search+bind » :
host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid
Quand une connexion au serveur de base de données est demandée en tant que un_utilisateur, PostgreSQL tentera un « bind » anonyme (car ldapbinddn n'a pas été précisé) au serveur LDAP, effectuera une recherche pour (uid=un_utilisateur) sous la base DN spécifiée. Si une entrée est trouvée, il tentera alors de faire un « bind » en utilisant l'information trouvée et le mot de passe fourni par le client. Si cette deuxième connexion réussit, l under the specified base DN. If an entry is found, it will then attempt to bind using that found information and the password supplied by the client. If that second connection succeeds, l'accès à la base de données est accepté.
Voici la même configuration « search+bind » écrite sous la forme d'une URL :
host ... ldap lapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
D'autres logiciels qui supportent l'authentification LDAP utilisent le même format d'URL donc cela facilitera le partage de configuration.
Comme LDAP utilise souvent des virgules et des espaces pour séparer les différentes parties d'un DN, il est souvent nécessaire d'utiliser des paramètres entourés de guillements durant le paramétrage des options LDAP, comme montré dans les exemples.
Cette méthode d'authentification opère de façon similaire à password sauf qu'il existe la méthode RADIUS pour la vérification du mot de passe. RADIUS est seulement utilisé pour valider des pairs nom utilisateur / mot de passe. Du coup, l'utilisateur doit déjà exister dans la base de données avant que RADIUS puisse être utilisé pour l'authentification.
Lors de l'utilisation de l'authentification RADIUS, un message de demande d'accès (Access Request) sera envoyé au serveur RADIUS configuré. Cette demande sera du type « authentification seule » (Authenticate Only) et incluera les paramètres pour le nom de l'utilisateur, son mot de passe (chiffré) et un identifiant NAS (NAS Identifier). La demande sera chiffrée en utilisant un secret partagé avec le serveur. Le serveur RADIUS répondre au serveur soit la réussite (Access Accept) soit l'échec (Access Reject) de l'accès. Il n'y a pas de support des comptes RADIUS.
Les options de configuration suivantes sont supportées par RADIUS :
Le nom ou l'adresse IP sur serveur RADIUS pour l'authentification. Ce paramètre est requis.
Le secret partagé utilisé lors de discussions sécurisées avec le serveur RADIUS. Il doit y avoir exactement la même valeur sur le serveur PostgreSQL et sur le serveur RADIUS. Il est recommandé d'utiliser une chaîne d'au moins 16 caractères. Ce paramètre est requis.
Le vecteur de chiffrement utilisé sera un chiffrement fort seulement si PostgreSQL™ a été compilé avec le support d'OpenSSL™. Dans les autres cas, la transmission au serveur RADIUS peut seulement être considérée comme caché, et non pas sécurisé, et des mesures de sécurité externes doivent être appliquées si nécessaire.
Le numéro de port sur le serveur RADIUS pour la connexion. Si aucun port n'est indiqué, le port par défaut, 1812, sera utilisé.
La chaîne utilisée comme identifiant NAS (NAS Identifier) dans les demandes RADIUS. Ce paramètre peut être utilisé comme second paramètre identifiant par exemple l'utilisateur de bases de données pour la connexion. C'est utilisable pour des vérifications sur le serveur RADIUS. Si aucune identifiant n'est spécifié, la valeur par défaut, postgresql, sera utilisée.
Cette méthode d'authentification utilise des clients SSL pour procéder à l'authentification. Elle n'est par conséquent disponible que pour les connexions SSL. Quand cette méthode est utilisée, le serveur exigera que le client fournisse un certificat valide. Aucune invite de saisie de mot de passe ne sera envoyée au client. L'attribut cn (Common Name) du certificat sera comparé au nom d'utilisateur de base de données demandé. S'ils correspondent, la connexion sera autorisée. La correspondance des noms d'utilisateurs peut être utilisé pour permettre au cn d'être différent du nom d'utilisateur de la base de données.
Les options de configuration suivantes sont supportées pour l'authentification par certificat SSL :
Permet la correspondance entre les noms d'utilisateur système et les noms d'utilisateurs de bases de données. Voir Section 19.2, « Correspondances d'utilisateurs » pour les détails.
Ce mécanisme d'authentification fonctionne de façon similaire à password à ceci près qu'il utilise PAM (Pluggable Authentication Modules) comme méthode d'authentification. Le nom du service PAM par défaut est postgresql. PAM n'est utilisé que pour valider des paires nom utilisateur/mot de passe. De ce fait, avant de pouvoir utiliser PAM pour l'authentification, l'utilisateur doit préalablement exister dans la base de données. Pour plus d'informations sur PAM, merci de lire la page Linux-PAM™.
Les options suivantes sont supportées pour PAM :
Nom de service PAM.
Si PAM est configuré pour lire /etc/shadow, l'authentification échoue car le serveur PostgreSQL est exécuté en tant qu'utilisateur standard. Ce n'est toutefois pas un problème quand PAM est configuré pour utiliser LDAP ou les autres méthodes d'authentification.