Samba avec LDAP

Samba permet de gérer les domaines Windows. Les utilisateurs du domaine sont habituellement stockés dans un fichier à plat, cependant il est possible d'utiliser une base LDAP pour les stocker. Cet article donne la configuration de Samba mais pas celle du serveur LDAP.

Configuration du serveur

Installer le serveur samba en version 3. Modifier le fichier /etc/samba/smb.conf pour configurer Samba. Le serveur Samba doit être client du serveur LDAP si l'on stocke les fichiers des utilisateurs sur le serveur samba lui-même. Cela lui permet également de gérer correctement les droits d'accès à travers Samba (pour faire de la machine Samba un client du LDAP voir l'article correspondant).

Pour avoir un serveur samba qui fait office de PDC (Controleur Primaire de Domaine) et de serveur de home, il faut la configuration suivante :

#########
# P D C #
#########
[global]
#############################
# identification du serveur #
#############################
    ; nom du domaine
    workgroup = EXAMPLE

    ; nom du serveur dans le domain
    netbios name = PDC

    ; description qui sera affichée chez les clients
    server string = Samba Server %v on %L

#########################
# controleur de domaine #
#########################
    ; les clients peuvent s'authentifier sur ce serveur
    domain logons = yes

    ; le serveur fait office de serveur wins
    wins support = yes

    ; ce serveur sera toujours le serveur maitre avec un
    ; niveau de 255, pour l'instant (2005) les produits
    ; microsoft doivent être au alentour de 70 au maximum
    os level = 255

    ; tiens à jour la liste de toutes les machines du domaine
    ; ce role doit etre accordé à la machine qui agit en
    ; tant que PDC
    domain master = yes

    ; ce serveur est le serveur de son sous reseau
    local master = yes

    ; astuce pour etre certain de devenir le local
    ; master browser de son sous reseau
    prefered master = yes

    ; l'authentification est faite sur cette machine
    security = user

    ; les mot de passe sont cryptés
    encrypt passwords = true

    ; authorise les clients à synchroniser leur horloge
    time server = yes
    host msdfs = yes

    ; option censé augmenté les performance tcp/ip
    socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192

    ; methode de resolution des noms
    name resolve order = wins hosts bcast

    ; hote authorisé à se connecté
    ;hosts allow = 192.168.0., 192.168.1.

    ; serveur wins annexe qui doit etre synchronisé
    ;remote browse sync = 192.168.0.2

    ; alias des comptes
        username map = /etc/samba/smbusers

####################
# profile et logon #
####################
    ; chemin d'acces aux profiles
    logon path = \\%L\profiles\%U

    ; script à executer lorsque un utilisateur se connecte
    logon script = logon.bat

    ; lettre du lecteur sur lequel sera le home de l'utilisateur
        logon drive = Z:

    obey pam restrictions = no
    ldap passwd sync = yes

#############################
# parametre d'acces au LDAP #
#############################
    ; adresse du serveur LDAP
    ; le fait de definir 2 sources de donnees authorise
    ; la creation de comptes machines sur le serveur
    ; samba et non sur le serveur ldap. comme cela
    ; chacun gere ses machines mais les utilisateurs
    ; sont géré de facon globale
    passdb backend = smbpasswd ldapsam:ldap://ldap.example.com/

    ; dn de l'admin du LDAP, il faut authoriser samba
    ; a modifier et ajouter certain attributs du LDAP
    ldap admin dn = cn=samba,ou=DSA,dc=example,dc=com

    ; suffixe de la base LDAP
    ldap suffix = dc=example,dc=com

    ; ou sont les groupes
    ldap group suffix = ou=groups

    ; ou sont les utilisateur
    ldap user suffix = ou=people

    ; ou sont les machines
    ;ldap machine suffix = ou=computers

    ; parametre ssl
    # si on veut du tls :
    #ldap ssl = start tls
    # si on en veut pas :
    ldap ssl = no

    ldap delete dn = no

##################
# journalisation #
##################
    ; niveau de log
    log level = 2

    ; le log se fait par machine
    log file = /var/log/samba/log.%m

    ; taille maximum d'un fichier de log
    max log size = 1000

    ; horodatage des actions loggées
    debug timestamp = yes

##################################
# option concernant les fichiers #
##################################
    ; option pour la casse des noms de fichiers
    case sensitive = yes
    default case = lower
    preserve case = yes
    short preserve case = yes

    ; encodage des caracteres
    Dos charset = 850
    Unix charset = ISO8859-1

    ; masque de creation des fichiers
    create mask = 0744
    directory mask = 0750

    ; fichier cache
    hide dot files = yes

    ; lien symbolique
    follow symlinks = yes
    wide links = no

    ; pas de compte invite
    guest ok = no

[homes]
    comment = repertoire de %U, %u
    read only = no
    writeable = yes
    browseable = no
    delete read only = yes
    map archive = yes
#   preexec = echo "(`date`) connection %u, machine %m\" >> /tmp/samba.log
#   postexec = echo "(`date`) deconnection %u, machine %m\" >> /tmp/samba.log

[netlogon]
    path = /var/samba/netlogon
    browseable = no
    writable = no
    read only = yes

[profiles]
    path = /var/samba/profiles
    writeable = yes
    read only = no
    browseable = no
    create mask = 0640
    directory mask = 0700

Connexion de Samba au service LDAP

Il faut ensuite indiquer à samba le mot de passe qu'il doit utiliser pour se connecter à LDAP. La connection se faisant avec le compte indiqué par l'attribut ldap admin dn. Ce mot de passe est stocké dans le fichier /var/lib/samba/sercet.tdb.

smbpasswd -w mot_de_passe

Création des répertoires

Il faut également créer les répertoires netlogon et profiles :

mkdir /var/samba
mkdir /var/samba/netlogon
mkdir /var/samba/profiles
chmod 711 /var/samba
chmod 777 /var/samba/profiles
chmod 755 /var/samba/netlogon
echo 'NET USE Z: \\SMB-HOME\homes' | sed "s/$/^M/" | sed "$ s/$/^Z/" > /var/samba/netlogon/logon.bat
chmod 744 /var/samba/netlogon/logon.bat

SID

Le numéro du serveur samba peut être forcé :

net setlocalsid S-1-5-21-20043454-3907201459-4213964173

Alias

Pour faciliter l'administration du serveur on peut donner plusieurs nom au compte administrateur :

  • créer un fichier /etc/samba/smbusers
  • y mettre : "Administrator = administrateur admin root administrator"

Il est possible de donner des alias à d'autres comptes.

Ajouter une machine cliente (serveur ou poste de travail)

Pour ajouter une machine au domaine géré par samba, il faut créer un compte sur le serveur samba. Le compte doit être un compte système et Samba pour que cela fonctionne. J'utilise un script qui prend en entrée un fichier qui contient un nom de machine par ligne :

#!/usr/bin/perl
# Script qui cree des comptes pour les machines

use strict;
use warnings;
use Net::LDAP;

my $source = 'liste-machine.txt';
my $min = 30000;

my %ldap = (
        host    => 'ldap.example.com',
        base    => 'dc=example,dc=com',
        );

$ldap{cxn} = Net::LDAP->new($ldap{host}) or die "$@";
$ldap{cxn}->bind;

sub existe_dans_ldap {
    my $arg = shift(@_);
    my $msg = $ldap{cxn}->search(
        base => $ldap{base},
        filter => "(|(uidNumber=$arg)(uid=$arg))",
        attrs => ['1.1']
        );
    $msg->code && die "Problem! " . $msg->error;
    return ($msg->count != 0);
}

sub existe_dans_smbpasswd {
    my $uid = shift(@_);
    my $exist = 0;
    open(PASSWD, "</etc/samba/smbpasswd");
    while (<PASSWD>) {
        chomp;
        if (/(.+)\$:.*/ && $1 eq $uid) {
            $exist = 1;
            last;
        }
    }
    close PASSWD;
    return $exist;
}

sub existe_dans_passwd {
    my $uid = shift(@_);
    my $exist = 0;
    open(PASSWD, "</etc/passwd");
    while (<PASSWD>) {
        chomp;
        if (/(.+)(:.*){6}/ && $1 eq $uid) {
            $exist = 1;
            last;
        }
    }
    close PASSWD;
    return $exist;
}

sub trouve_uidnumber_libre {
    my $num = $min;
    my @liste = ();
    open(PASSWD, "</etc/passwd");
    while (<PASSWD>) {
        chomp;
        push(@liste,$2) if (/(.+:){2}(.+)(:.*){4}/);
    }
    close PASSWD;
    while (grep(/$num/, @liste) > 0) {
        $num++;
    }
    return $num;
}

sub ajoute_au_systeme {
    my($nom, $num) = @_;
    my $res = `/usr/sbin/useradd -c \"Machine $nom\" -d /dev/null -s /bin/false -u $num $nom\$`;
    print "$nom -> $res ";
    $res = `smbpasswd -a -m $nom`;
    print ", $res\n";
}

open(ENTREE, "<$source");
my $nom;
while (defined($nom = <ENTREE>)) {
    chomp($nom);
    if (existe_dans_smbpasswd($nom)) {
        warn("$nom : existe dans /etc/samba/smbpasswd !\n");
        next;
    }
    if (existe_dans_passwd($nom)) {
        warn("$nom : existe dans /etc/passwd !\n");
        next;
    }
    if (existe_dans_ldap($nom)) {
        warn("$nom : existe dans ldap !\n");
        next;
    }
    my $uidnumber = trouve_uidnumber_libre;
    ajoute_au_systeme($nom, $uidnumber);
}

Il est à noter que le $ à la fin du useradd indique à samba que c'est un compte représentant une machine.

Autre serveur Samba (facultatif)

Pour connecter un autre serveur samba au domaine, il faut configurer le serveur de tel sorte qu'il s'authentifie sur le PDC et qu'il fasse partie du même workgroup (domaine) :

#######################
# serveur de fichiers #
#######################
[global]
        ; le nom du domaine
        workgroup = EXAMPLE

        ; le nom du serveur
        netbios name = SMB-HOME

        ; il n'est pas le PDC
        domain master = no

        ; l'authentification se fait sur le PDC
        security = domain

        ; le niveau du serveur doit etr moindre que le PDC
        os level = 50

        ; si le serveur et le PDC ne sont pas sur le meme reseau
        ; le serveur doit etre maitre sur son sous reseau
        prefered master = no
        local master = no

        name resolve order = wins hosts bcast


[homes]
       read only = no
       writeable = yes
       browseable = no
       delete read only = yes
       map archive = yes
       path = /home

Sur le serveur que l'on souhaite ajouté au domaine, il faut taper la commande qui suit ; le -I indique l'adresse du PDC, le -U indique le compte LDAP representant l'administrateur du domaine windows. La commande demande le mot de passe du compte Administrateur (ou tout autre compte ayant les droit d'admninistration du domaine). Ensuite, le serveur appartient au domaine.

net join -I pdc.example.com -U Administrateur