auth.py 20 KB
Newer Older
moamoak's avatar
moamoak committed
1
# -*- mode: python; coding: utf-8 -*-
2 3 4 5
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
6
# Copyirght © 2017  Daniel Stan
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
# Copyright © 2017  Gabriel Détraz
# Copyright © 2017  Goulven Kermarec
# Copyright © 2017  Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Gabriel Detraz's avatar
Gabriel Detraz committed
25 26 27 28 29 30 31 32 33
"""
Backend python pour freeradius.

Ce fichier contient la définition de plusieurs fonctions d'interface à
freeradius qui peuvent être appelées (suivant les configurations) à certains
moment de l'authentification, en WiFi, filaire, ou par les NAS eux-mêmes.

Inspirés d'autres exemples trouvés ici :
https://github.com/FreeRADIUS/freeradius-server/blob/master/src/modules/rlm_python/
34 35

Inspiré du travail de Daniel Stan au Crans
Gabriel Detraz's avatar
Gabriel Detraz committed
36 37
"""

moamoak's avatar
moamoak committed
38 39
import os
import sys
moamoak's avatar
moamoak committed
40
import logging
klafyvel's avatar
klafyvel committed
41
import traceback
moamoak's avatar
moamoak committed
42
import radiusd  # Module magique freeradius (radiusd.py is dummy)
moamoak's avatar
moamoak committed
43

moamoak's avatar
moamoak committed
44
from django.core.wsgi import get_wsgi_application
moamoak's avatar
moamoak committed
45
from django.db.models import Q
moamoak's avatar
moamoak committed
46

47 48 49 50 51 52 53 54 55 56 57
proj_path = "/var/www/re2o/"
# This is so Django knows where to find stuff.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "re2o.settings")
sys.path.append(proj_path)

# This is so my local_settings.py gets loaded.
os.chdir(proj_path)

# This is so models get loaded.
application = get_wsgi_application()

klafyvel's avatar
klafyvel committed
58 59 60
from machines.models import Interface, IpList, Nas, Domain
from topologie.models import Port, Switch
from users.models import User
61
from preferences.models import RadiusOption
klafyvel's avatar
klafyvel committed
62 63


Gabriel Detraz's avatar
Gabriel Detraz committed
64 65 66 67
#: Serveur radius de test (pas la prod)
TEST_SERVER = bool(os.getenv('DBG_FREERADIUS', False))


moamoak's avatar
moamoak committed
68
# Logging
Gabriel Detraz's avatar
Gabriel Detraz committed
69 70 71 72 73 74 75 76 77 78 79
class RadiusdHandler(logging.Handler):
    """Handler de logs pour freeradius"""

    def emit(self, record):
        """Process un message de log, en convertissant les niveaux"""
        if record.levelno >= logging.WARN:
            rad_sig = radiusd.L_ERR
        elif record.levelno >= logging.INFO:
            rad_sig = radiusd.L_INFO
        else:
            rad_sig = radiusd.L_DBG
klafyvel's avatar
klafyvel committed
80
        radiusd.radlog(rad_sig, record.msg.encode('utf-8'))
Gabriel Detraz's avatar
Gabriel Detraz committed
81

moamoak's avatar
moamoak committed
82

Gabriel Detraz's avatar
Gabriel Detraz committed
83 84 85 86 87 88 89 90
# Initialisation d'un logger (pour logguer unifié)
logger = logging.getLogger('auth.py')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(name)s: [%(levelname)s] %(message)s')
handler = RadiusdHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)

moamoak's avatar
moamoak committed
91

Gabriel Detraz's avatar
Gabriel Detraz committed
92 93
def radius_event(fun):
    """Décorateur pour les fonctions d'interfaces avec radius.
moamoak's avatar
moamoak committed
94 95
    Une telle fonction prend un uniquement argument, qui est une liste de
    tuples (clé, valeur) et renvoie un triplet dont les composantes sont :
Gabriel Detraz's avatar
Gabriel Detraz committed
96 97 98 99 100 101 102 103 104 105
     * le code de retour (voir radiusd.RLM_MODULE_* )
     * un tuple de couples (clé, valeur) pour les valeurs de réponse (accès ok
       et autres trucs du genre)
     * un tuple de couples (clé, valeur) pour les valeurs internes à mettre à
       jour (mot de passe par exemple)

    On se contente avec ce décorateur (pour l'instant) de convertir la liste de
    tuples en entrée en un dictionnaire."""

    def new_f(auth_data):
moamoak's avatar
moamoak committed
106 107
        """ The function transforming the tuples as dict """
        if isinstance(auth_data, dict):
Gabriel Detraz's avatar
Gabriel Detraz committed
108 109 110 111 112 113 114 115
            data = auth_data
        else:
            data = dict()
            for (key, value) in auth_data or []:
                # Beware: les valeurs scalaires sont entre guillemets
                # Ex: Calling-Station-Id: "une_adresse_mac"
                data[key] = value.replace('"', '')
        try:
moamoak's avatar
moamoak committed
116 117
            # TODO s'assurer ici que les tuples renvoyés sont bien des
            # (str,str) : rlm_python ne digère PAS les unicodes
Gabriel Detraz's avatar
Gabriel Detraz committed
118 119 120
            return fun(data)
        except Exception as err:
            logger.error('Failed %r on data %r' % (err, auth_data))
klafyvel's avatar
klafyvel committed
121
            logger.debug('Function %r, Traceback: %s' % (fun, repr(traceback.format_stack())))
122
            return radiusd.RLM_MODULE_FAIL
Gabriel Detraz's avatar
Gabriel Detraz committed
123 124 125

    return new_f

126

Gabriel Detraz's avatar
Gabriel Detraz committed
127 128 129 130 131 132
@radius_event
def instantiate(*_):
    """Utile pour initialiser les connexions ldap une première fois (otherwise,
    do nothing)"""
    logger.info('Instantiation')
    if TEST_SERVER:
133
        logger.info(u'DBG_FREERADIUS is enabled')
Gabriel Detraz's avatar
Gabriel Detraz committed
134

moamoak's avatar
moamoak committed
135

Gabriel Detraz's avatar
Gabriel Detraz committed
136 137
@radius_event
def authorize(data):
138
    """On test si on connait le calling nas:
moamoak's avatar
moamoak committed
139 140
    - si le nas est inconnue, on suppose que c'est une requète 802.1X, on la
      traite
141
    - si le nas est connu, on applique 802.1X si le mode est activé
moamoak's avatar
moamoak committed
142 143
    - si le nas est connu et si il s'agit d'un nas auth par mac, on repond
      accept en authorize
144
    """
145
    # Pour les requetes proxifiees, on split
146 147 148
    nas = data.get('NAS-IP-Address', data.get('NAS-Identifier', None))
    nas_instance = find_nas_from_request(nas)
    # Toutes les reuquètes non proxifiées
Gabriel Detraz's avatar
Gabriel Detraz committed
149
    nas_type = None
150
    if nas_instance:
151 152
        nas_type = Nas.objects.filter(nas_type=nas_instance.type).first()
    if not nas_type or nas_type.port_access_mode == '802.1X':
153
        user = data.get('User-Name', '').decode('utf-8', errors='replace')
154
        user = user.split('@', 1)[0]
155
        mac = data.get('Calling-Station-Id', '')
moamoak's avatar
moamoak committed
156 157 158 159 160
        result, log, password = check_user_machine_and_register(
            nas_type,
            user,
            mac
        )
161
        logger.info(log.encode('utf-8'))
162 163
        logger.info(user.encode('utf-8'))

164 165 166
        if not result:
            return radiusd.RLM_MODULE_REJECT
        else:
moamoak's avatar
moamoak committed
167 168 169 170 171 172
            return (
                radiusd.RLM_MODULE_UPDATED,
                (),
                (
                    (str("NT-Password"), str(password)),
                ),
173
            )
Gabriel Detraz's avatar
Gabriel Detraz committed
174

175
    else:
moamoak's avatar
moamoak committed
176 177 178 179 180 181
        return (
            radiusd.RLM_MODULE_UPDATED,
            (),
            (
                ("Auth-Type", "Accept"),
            ),
182
        )
Gabriel Detraz's avatar
Gabriel Detraz committed
183

moamoak's avatar
moamoak committed
184

Gabriel Detraz's avatar
Gabriel Detraz committed
185 186
@radius_event
def post_auth(data):
moamoak's avatar
moamoak committed
187 188 189
    """ Function called after the user is authenticated
    """

190
    nas = data.get('NAS-IP-Address', data.get('NAS-Identifier', None))
root's avatar
root committed
191
    nas_instance = find_nas_from_request(nas)
192
    # Toutes les reuquètes non proxifiées
193
    if not nas_instance:
194
        logger.info(u"Requete proxifiee, nas inconnu".encode('utf-8'))
195 196 197
        return radiusd.RLM_MODULE_OK
    nas_type = Nas.objects.filter(nas_type=nas_instance.type).first()
    if not nas_type:
moamoak's avatar
moamoak committed
198
        logger.info(
199
            u"Type de nas non enregistre dans la bdd!".encode('utf-8')
moamoak's avatar
moamoak committed
200
        )
201
        return radiusd.RLM_MODULE_OK
202

Gabriel Detraz's avatar
Gabriel Detraz committed
203
    mac = data.get('Calling-Station-Id', None)
204

moamoak's avatar
moamoak committed
205 206
    # Switch et bornes héritent de machine et peuvent avoir plusieurs
    # interfaces filles
207
    nas_machine = nas_instance.machine
208
    # Si il s'agit d'un switch
209
    if hasattr(nas_machine, 'switch'):
210
        port = data.get('NAS-Port-Id', data.get('NAS-Port', None))
moamoak's avatar
moamoak committed
211 212
        # Pour les infrastructures possédant des switchs Juniper :
        # On vérifie si le switch fait partie d'un stack Juniper
213
        instance_stack = nas_machine.switch.stack
214 215 216
        if instance_stack:
            # Si c'est le cas, on resélectionne le bon switch dans la stack
            id_stack_member = port.split("-")[1].split('/')[0]
moamoak's avatar
moamoak committed
217 218 219 220 221
            nas_machine = (Switch.objects
                           .filter(stack=instance_stack)
                           .filter(stack_member_id=id_stack_member)
                           .prefetch_related(
                               'interface_set__domain__extension'
moamoak's avatar
moamoak committed
222
                           )
moamoak's avatar
moamoak committed
223 224 225
                           .first())
        # On récupère le numéro du port sur l'output de freeradius.
        # La ligne suivante fonctionne pour cisco, HP et Juniper
226
        port = port.split(".")[0].split('/')[-1][-2:]
227
        out = decide_vlan_switch(nas_machine, nas_type, port, mac)
228 229 230 231 232 233 234 235 236 237
        sw_name, room, reason, vlan_id, decision = out

        if decision:
            log_message = '(fil) %s -> %s [%s%s]' % (
                sw_name + u":" + port + u"/" + str(room),
                mac,
                vlan_id,
                (reason and u': ' + reason).encode('utf-8')
            )
            logger.info(log_message)
238

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
            # Filaire
            return (
                radiusd.RLM_MODULE_UPDATED,
                (
                    ("Tunnel-Type", "VLAN"),
                    ("Tunnel-Medium-Type", "IEEE-802"),
                    ("Tunnel-Private-Group-Id", '%d' % int(vlan_id)),
                ),
                ()
            )
        else:
            log_message = '(fil) %s -> %s [Reject:%s]' % (
                sw_name + u":" + port + u"/" + str(room),
                mac,
                (reason and u': ' + reason).encode('utf-8')
            )
            logger.info(log_message)
256

257
            return radiusd.RLM_MODULE_REJECT
Gabriel Detraz's avatar
Gabriel Detraz committed
258

259 260
    else:
        return radiusd.RLM_MODULE_OK
Gabriel Detraz's avatar
Gabriel Detraz committed
261

moamoak's avatar
moamoak committed
262

moamoak's avatar
moamoak committed
263
# TODO : remove this function
Gabriel Detraz's avatar
Gabriel Detraz committed
264 265 266 267 268
@radius_event
def dummy_fun(_):
    """Do nothing, successfully. (C'est pour avoir un truc à mettre)"""
    return radiusd.RLM_MODULE_OK

moamoak's avatar
moamoak committed
269

Gabriel Detraz's avatar
Gabriel Detraz committed
270 271
def detach(_=None):
    """Appelé lors du déchargement du module (enfin, normalement)"""
moamoak's avatar
moamoak committed
272
    print("*** goodbye from auth.py ***")
Gabriel Detraz's avatar
Gabriel Detraz committed
273 274
    return radiusd.RLM_MODULE_OK

moamoak's avatar
moamoak committed
275

276
def find_nas_from_request(nas_id):
moamoak's avatar
moamoak committed
277
    """ Get the nas object from its ID """
moamoak's avatar
moamoak committed
278 279 280 281 282 283 284
    nas = (Interface.objects
           .filter(
               Q(domain=Domain.objects.filter(name=nas_id)) |
               Q(ipv4=IpList.objects.filter(ipv4=nas_id))
           )
           .select_related('type')
           .select_related('machine__switch__stack'))
root's avatar
root committed
285
    return nas.first()
286

287

288
def check_user_machine_and_register(nas_type, username, mac_address):
moamoak's avatar
moamoak committed
289 290
    """Verifie le username et la mac renseignee. L'enregistre si elle est
    inconnue.
291 292 293
    Renvoie le mot de passe ntlm de l'user si tout est ok
    Utilise pour les authentifications en 802.1X"""
    interface = Interface.objects.filter(mac_address=mac_address).first()
Gabriel Detraz's avatar
Gabriel Detraz committed
294
    user = User.objects.filter(pseudo__iexact=username).first()
295
    if not user:
296 297
        return (False, u"User inconnu", '')
    if not user.has_access():
298
        return (False, u"Adherent non cotisant", '')
299 300
    if interface:
        if interface.machine.user != user:
moamoak's avatar
moamoak committed
301
            return (False,
302
                    u"Machine enregistree sur le compte d'un autre "
moamoak's avatar
moamoak committed
303 304
                    "user...",
                    '')
305
        elif not interface.is_active:
306
            return (False, u"Machine desactivee", '')
307 308 309
        elif not interface.ipv4:
            interface.assign_ipv4()
            return (True, u"Ok, Reassignation de l'ipv4", user.pwd_ntlm)
310
        else:
311
            return (True, u"Access ok", user.pwd_ntlm)
312
    elif nas_type:
313
        if nas_type.autocapture_mac:
314 315
            result, reason = user.autoregister_machine(mac_address, nas_type)
            if result:
moamoak's avatar
moamoak committed
316 317 318
                return (True,
                        u'Access Ok, Capture de la mac...',
                        user.pwd_ntlm)
319
            else:
320
                return (False, u'Erreur dans le register mac %s' % reason, '')
321 322
        else:
            return (False, u'Machine inconnue', '')
323
    else:
324
        return (False, u"Machine inconnue", '')
325 326


327
def decide_vlan_switch(nas_machine, nas_type, port_number,
328
                       mac_address):
moamoak's avatar
moamoak committed
329 330
    """Fonction de placement vlan pour un switch en radius filaire auth par
    mac.
331
    Plusieurs modes :
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
        - tous les modes:
            - nas inconnu: VLAN_OK
            - port inconnu: Politique définie dans RadiusOption
        - pas de radius sur le port: VLAN_OK
        - force: placement sur le vlan indiqué dans la bdd
        - mode strict:
            - pas de chambre associée: Politique définie
              dans RadiusOption
            - pas d'utilisateur dans la chambre : Rejet
              (redirection web si disponible)
            - utilisateur de la chambre banni ou désactivé : Rejet
              (redirection web si disponible)
            - utilisateur de la chambre non cotisant et non whiteslist:
              Politique définie dans RadiusOption

            - sinon passe à common (ci-dessous)
        - mode common :
            - interface connue (macaddress):
                - utilisateur proprio non cotisant / machine désactivée:
                    Politique définie dans RadiusOption
                - utilisateur proprio banni :
                    Politique définie dans RadiusOption
                - user à jour : VLAN_OK (réassignation de l'ipv4 au besoin)
            - interface inconnue :
                - register mac désactivé : Politique définie
                  dans RadiusOption
                - register mac activé: redirection vers webauth
    Returns:
        tuple avec :
            - Nom du switch (str)
            - chambre (str)
            - raison de la décision (str)
            - vlan_id (int)
            - decision (bool)
366
    """
367
    # Get port from switch and port number
368
    extra_log = ""
369
    # Si le NAS est inconnu, on place sur le vlan defaut
370
    if not nas_machine:
klafyvel's avatar
klafyvel committed
371
        return ('?', u'Chambre inconnue', u'Nas inconnu', RadiusOption.get_cached_value('vlan_decision_ok').vlan_id, True)
372

373
    sw_name = str(getattr(nas_machine, 'short_name', str(nas_machine)))
374

moamoak's avatar
moamoak committed
375 376 377 378 379 380
    port = (Port.objects
            .filter(
                switch=Switch.objects.filter(machine_ptr=nas_machine),
                port=port_number
            )
            .first())
klafyvel's avatar
klafyvel committed
381

moamoak's avatar
moamoak committed
382
    # Si le port est inconnu, on place sur le vlan defaut
chirac's avatar
chirac committed
383 384
    # Aucune information particulière ne permet de déterminer quelle
    # politique à appliquer sur ce port
385
    if not port:
386 387 388 389
        return (
            sw_name,
            "Chambre inconnue",
            u'Port inconnu',
390 391
            getattr(RadiusOption.get_cached_value('unknown_port_vlan'), 'vlan_id', None),
            RadiusOption.get_cached_value('unknown_port')!= RadiusOption.REJECT
392
        )
393

394
    # On récupère le profil du port
klafyvel's avatar
klafyvel committed
395
    port_profile = port.get_port_profile
396

klafyvel's avatar
klafyvel committed
397
    # Si un vlan a été précisé dans la config du port,
chirac's avatar
chirac committed
398
    # on l'utilise pour VLAN_OK
klafyvel's avatar
klafyvel committed
399 400
    if port_profile.vlan_untagged:
        DECISION_VLAN = int(port_profile.vlan_untagged.vlan_id)
401 402
        extra_log = u"Force sur vlan " + str(DECISION_VLAN)
    else:
klafyvel's avatar
klafyvel committed
403
        DECISION_VLAN = RadiusOption.get_cached_value('vlan_decision_ok').vlan_id
404

405
    # Si le port est désactivé, on rejette la connexion
406
    if not port.state:
407
        return (sw_name, port.room, u'Port desactive', None, False)
408

chirac's avatar
chirac committed
409
    # Si radius est désactivé, on laisse passer
klafyvel's avatar
klafyvel committed
410
    if port_profile.radius_type == 'NO':
moamoak's avatar
moamoak committed
411 412 413
        return (sw_name,
                "",
                u"Pas d'authentification sur ce port" + extra_log,
414 415
                DECISION_VLAN,
                True)
416

417 418
    # Si le 802.1X est activé sur ce port, cela veut dire que la personne a
    # été accept précédemment
chirac's avatar
chirac committed
419
    # Par conséquent, on laisse passer sur le bon vlan
420
    if (nas_type.port_access_mode, port_profile.radius_type) == ('802.1X', '802.1X'):
chirac's avatar
chirac committed
421
        room = port.room or "Chambre/local inconnu"
422 423 424 425 426 427 428
        return (
            sw_name,
            room,
            u'Acceptation authentification 802.1X',
            DECISION_VLAN,
            True
        )
chirac's avatar
chirac committed
429 430 431

    # Sinon, cela veut dire qu'on fait de l'auth radius par mac
    # Si le port est en mode strict, on vérifie que tous les users
432 433 434 435
    # rattachés à ce port sont bien à jour de cotisation. Sinon on rejette
    # (anti squattage)
    # Il n'est pas possible de se connecter sur une prise strict sans adhérent
    # à jour de cotis dedans
klafyvel's avatar
klafyvel committed
436
    if port_profile.radius_mode == 'STRICT':
437 438
        room = port.room
        if not room:
439 440 441 442
            return (
                sw_name,
                "Inconnue",
                u'Chambre inconnue',
443 444
                getattr(RadiusOption.get_cached_value('unknown_room_vlan'), 'vlan_id', None),
                RadiusOption.get_cached_value('unknown_room')!= RadiusOption.REJECT
445
            )
446

moamoak's avatar
moamoak committed
447 448 449
        room_user = User.objects.filter(
            Q(club__room=port.room) | Q(adherent__room=port.room)
        )
450
        if not room_user:
451 452 453 454 455 456 457
            return (
                sw_name,
                room,
                u'Chambre non cotisante -> Web redirect',
                None,
                False
            )
458
        for user in room_user:
klafyvel's avatar
klafyvel committed
459
            if user.is_ban() or user.state != User.STATE_ACTIVE:
460 461 462
                return (
                    sw_name,
                    room,
463
                    u'Utilisateur banni ou desactive -> Web redirect',
464 465 466
                    None,
                    False
                )
klafyvel's avatar
klafyvel committed
467
            elif not (user.is_connected() or user.is_whitelisted()):
468 469 470 471
                return (
                    sw_name,
                    room,
                    u'Utilisateur non cotisant',
472 473
                    getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
                    RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT
474
                )
475 476
        # else: user OK, on passe à la verif MAC

477 478
    # Si on fait de l'auth par mac, on cherche l'interface
    # via sa mac dans la bdd
klafyvel's avatar
klafyvel committed
479
    if port_profile.radius_mode == 'COMMON' or port_profile.radius_mode == 'STRICT':
480
        # Authentification par mac
moamoak's avatar
moamoak committed
481 482 483 484 485
        interface = (Interface.objects
                     .filter(mac_address=mac_address)
                     .select_related('machine__user')
                     .select_related('ipv4')
                     .first())
486
        if not interface:
487
            room = port.room
488 489 490 491 492 493 494 495 496 497 498 499
            # On essaye de register la mac, si l'autocapture a été activée,
            # on rejette pour faire une redirection web si possible.
            if nas_type.autocapture_mac:
                return (
                    sw_name,
                    room,
                    u'Machine Inconnue -> Web redirect',
                    None,
                    False
                )
            # Sinon on bascule sur la politique définie dans les options
            # radius.
500
            else:
501 502 503 504
                return (
                    sw_name,
                    "",
                    u'Machine inconnue',
505 506
                    getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None),
                    RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT
507 508 509 510
                )

        # L'interface a été trouvée, on vérifie qu'elle est active,
        # sinon on reject
chirac's avatar
chirac committed
511 512
        # Si elle n'a pas d'ipv4, on lui en met une
        # Enfin on laisse passer sur le vlan pertinent
513
        else:
514
            room = port.room
515
            if interface.machine.user.is_ban():
516 517 518 519
                return (
                    sw_name,
                    room,
                    u'Adherent banni',
520 521
                    getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None),
                    RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT
522
                )
523
            if not interface.is_active:
524 525 526 527
                return (
                    sw_name,
                    room,
                    u'Machine non active / adherent non cotisant',
528 529
                    getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None),
                    RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT
530 531 532
                )
            # Si on choisi de placer les machines sur le vlan
            # correspondant à leur type :
klafyvel's avatar
klafyvel committed
533
            if RadiusOption.get_cached_value('radius_general_policy') == 'MACHINE':
534 535
                DECISION_VLAN = interface.type.ip_type.vlan.vlan_id
            if not interface.ipv4:
536
                interface.assign_ipv4()
537 538 539 540 541 542 543
                return (
                    sw_name,
                    room,
                    u"Ok, Reassignation de l'ipv4" + extra_log,
                    DECISION_VLAN,
                    True
                )
544
            else:
545 546 547 548 549 550 551
                return (
                    sw_name,
                    room,
                    u'Machine OK' + extra_log,
                    DECISION_VLAN,
                    True
                )