diff --git a/freeradius_utils/auth.py b/freeradius_utils/auth.py index 7245013e..1c74303d 100644 --- a/freeradius_utils/auth.py +++ b/freeradius_utils/auth.py @@ -225,7 +225,7 @@ def post_auth(data): # La ligne suivante fonctionne pour cisco, HP et Juniper port = port.split(".")[0].split('/')[-1][-2:] out = decide_vlan_switch(nas_machine, nas_type, port, mac) - sw_name, room, reason, vlan_id, decision = out + sw_name, room, reason, vlan_id, decision, attributes = out if decision: log_message = '(fil) %s -> %s [%s%s]' % ( @@ -243,7 +243,7 @@ def post_auth(data): ("Tunnel-Type", "VLAN"), ("Tunnel-Medium-Type", "IEEE-802"), ("Tunnel-Private-Group-Id", '%d' % int(vlan_id)), - ), + ) + attributes, () ) else: @@ -254,7 +254,11 @@ def post_auth(data): ) logger.info(log_message) - return radiusd.RLM_MODULE_REJECT + return ( + radiusd.RLM_MODULE_REJECT, + attributes, + () + ) else: return radiusd.RLM_MODULE_OK @@ -363,12 +367,20 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, - raison de la décision (str) - vlan_id (int) - decision (bool) + - Attributs supplémentaires (attribut:str, operateur:str, valeur:str) """ # Get port from switch and port number extra_log = "" # Si le NAS est inconnu, on place sur le vlan defaut if not nas_machine: - return ('?', u'Chambre inconnue', u'Nas inconnu', RadiusOption.get_cached_value('vlan_decision_ok').vlan_id, True) + return ( + '?', + u'Chambre inconnue', + u'Nas inconnu', + RadiusOption.get_cached_value('vlan_decision_ok').vlan_id, + True, + RadiusOption.get_attributes('ok_attributes') + ) sw_name = str(getattr(nas_machine, 'short_name', str(nas_machine))) @@ -385,10 +397,11 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, if not port: return ( sw_name, - "Chambre inconnue", + "Port inconnu", u'Port inconnu', getattr(RadiusOption.get_cached_value('unknown_port_vlan'), 'vlan_id', None), - RadiusOption.get_cached_value('unknown_port')!= RadiusOption.REJECT + RadiusOption.get_cached_value('unknown_port')!= RadiusOption.REJECT, + RadiusOption.get_attributes('unknown_port_attributes') ) # On récupère le profil du port @@ -399,12 +412,14 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, if port_profile.vlan_untagged: DECISION_VLAN = int(port_profile.vlan_untagged.vlan_id) extra_log = u"Force sur vlan " + str(DECISION_VLAN) + attributes = () else: DECISION_VLAN = RadiusOption.get_cached_value('vlan_decision_ok').vlan_id + attributes = RadiusOption.get_attributes('ok_attributes') # Si le port est désactivé, on rejette la connexion if not port.state: - return (sw_name, port.room, u'Port desactive', None, False) + return (sw_name, port.room, u'Port desactive', None, False, ()) # Si radius est désactivé, on laisse passer if port_profile.radius_type == 'NO': @@ -412,7 +427,9 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, "", u"Pas d'authentification sur ce port" + extra_log, DECISION_VLAN, - True) + True, + attributes + ) # Si le 802.1X est activé sur ce port, cela veut dire que la personne a # été accept précédemment @@ -424,7 +441,8 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, room, u'Acceptation authentification 802.1X', DECISION_VLAN, - True + True, + attributes ) # Sinon, cela veut dire qu'on fait de l'auth radius par mac @@ -441,7 +459,8 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, "Inconnue", u'Chambre inconnue', getattr(RadiusOption.get_cached_value('unknown_room_vlan'), 'vlan_id', None), - RadiusOption.get_cached_value('unknown_room')!= RadiusOption.REJECT + RadiusOption.get_cached_value('unknown_room')!= RadiusOption.REJECT, + RadiusOption.get_attributes('unknown_room_attributes'), ) room_user = User.objects.filter( @@ -451,18 +470,20 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, return ( sw_name, room, - u'Chambre non cotisante -> Web redirect', - None, - False + u'Chambre non cotisante', + getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None), + RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT, + RadiusOption.get_attributes('non_member_attributes'), ) for user in room_user: if user.is_ban() or user.state != User.STATE_ACTIVE: return ( sw_name, room, - u'Utilisateur banni ou desactive -> Web redirect', - None, - False + u'Utilisateur banni ou desactive', + getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None), + RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT, + RadiusOption.get_attributes('banned_attributes'), ) elif not (user.is_connected() or user.is_whitelisted()): return ( @@ -470,7 +491,8 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, room, u'Utilisateur non cotisant', getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None), - RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT + RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT, + RadiusOption.get_attributes('non_member_attributes'), ) # else: user OK, on passe à la verif MAC @@ -491,9 +513,10 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, return ( sw_name, room, - u'Machine Inconnue -> Web redirect', - None, - False + u'Machine Inconnue', + getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None), + RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT, + RadiusOption.get_attributes('unknown_machine_attributes'), ) # Sinon on bascule sur la politique définie dans les options # radius. @@ -503,7 +526,8 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, "", u'Machine inconnue', getattr(RadiusOption.get_cached_value('unknown_machine_vlan'), 'vlan_id', None), - RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT + RadiusOption.get_cached_value('unknown_machine')!= RadiusOption.REJECT, + RadiusOption.get_attributes('unknown_machine_attributes'), ) # L'interface a été trouvée, on vérifie qu'elle est active, @@ -518,7 +542,8 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, room, u'Adherent banni', getattr(RadiusOption.get_cached_value('banned_vlan'), 'vlan_id', None), - RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT + RadiusOption.get_cached_value('banned')!= RadiusOption.REJECT, + RadiusOption.get_attributes('banned_attributes'), ) if not interface.is_active: return ( @@ -526,7 +551,8 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, room, u'Machine non active / adherent non cotisant', getattr(RadiusOption.get_cached_value('non_member_vlan'), 'vlan_id', None), - RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT + RadiusOption.get_cached_value('non_member')!= RadiusOption.REJECT, + RadiusOption.get_attributes('non_member_attributes'), ) # Si on choisi de placer les machines sur le vlan # correspondant à leur type : @@ -539,7 +565,8 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, room, u"Ok, Reassignation de l'ipv4" + extra_log, DECISION_VLAN, - True + True, + attributes ) else: return ( @@ -547,5 +574,6 @@ def decide_vlan_switch(nas_machine, nas_type, port_number, room, u'Machine OK' + extra_log, DECISION_VLAN, - True + True, + attributes ) diff --git a/preferences/models.py b/preferences/models.py index ea7e9dd5..098d9b18 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -637,6 +637,9 @@ class RadiusAttribute(RevMixin, AclMixin, models.Model): def __str__(self): return ' '.join([self.attribute, self.operator, self.value]) + def as_tuple(self): + return (self.attribute, self.operator, self.value) + class RadiusOption(AclMixin, PreferencesModel): class Meta: @@ -786,6 +789,13 @@ class RadiusOption(AclMixin, PreferencesModel): help_text=_("Answer attributes for accepted users."), ) + @classmethod + def get_attributes(cls, name): + return ( + attribute.as_tuple() + for attribute in cls.get_cached_value(name).all() + ) + def default_invoice(): tpl, _ = DocumentTemplate.objects.get_or_create(