diff --git a/freeradius/auth.py b/freeradius/auth.py index 61deecfb..6ec275b9 100644 --- a/freeradius/auth.py +++ b/freeradius/auth.py @@ -26,7 +26,8 @@ test_v6 = [ u'00:26:c7:a6:9e:16', # cerveaulent (machine de b2moo) ] -USERNAME_SUFFIX = '.wifi.crans.org' +USERNAME_SUFFIX_WIFI = '.wifi.crans.org' +USERNAME_SUFFIX_FIL = '.crans.org' ## -*- Logging -*- # Initialisation d'un logger pour faire des stats etc @@ -91,8 +92,15 @@ def radius_event(f): return new_f @use_ldap -def get_machines(data, conn): +def get_machines(data, conn, is_wifi=True, proprio=None): """Obtient la liste de machine essayant actuellement de se connecter""" + if is_wifi: + suffix = USERNAME_SUFFIX_WIFI + base = u'(objectclass=machineWifi)' + else: + suffix = USERNAME_SUFFIX_FIL + base = u'(objectclass=machineFixe)' + mac = data.get('Calling-Station-Id', None) if mac: try: @@ -103,29 +111,34 @@ def get_machines(data, conn): username = data.get('User-Name', None) if username: username = escape_ldap(username.decode('ascii', 'ignore')) - if username.endswith(USERNAME_SUFFIX): - username = username[:-len(USERNAME_SUFFIX)] - - base = u'(objectclass=machine)' + if username.endswith(suffix): + username = username[:-len(suffix)] if mac is None: radiusd.radlog(radiusd.L_ERR, 'Cannot read client MAC from AP !') if username is None: radiusd.radlog(radiusd.L_ERR, 'Cannot read client User-Name !') - # Liste de filtres ldap à essayer - search_strats = [ - # Case 1: Search by mac (reported by AP) - u'(&%s(macAddress=%s))' % (base, mac), - # Case 2: unregistered mac - u'(&%s(macAddress=)(host=%s%s))' % - (base, username, USERNAME_SUFFIX), - ] + # Liste de recherches ldap à essayer, dans l'ordre + # ** Case 1: Search by mac + res = conn.search(u'(&%s(macAddress=%s))' % (base, mac)) + if res: + return res - for filter_s in search_strats: - res = conn.search(filter_s) - if res: - break + # Si proprio fourni, on ne cherche désormais que parmi ses machines + # (opt est le dico des params optionnels de search) + opt = {} + if proprio is not None: + opt['dn'] = proprio.dn + # Filaire: pas de username. + if not is_wifi: + username = '*' + + # ** Case 2: unregistered mac : il nous faut au moins un username ou être sûr + # du propriétaire + if username != '*' or proprio is not None: + res = conn.search(u'(&%s(macAddress=)(host=%s%s))' % + (base, username, suffix), **opt) return res @@ -220,9 +233,6 @@ def authorize_wifi(data): machine = items[0] - if '' in machine['macAddress']: - register_mac(data, machine) - proprio = machine.proprio() if isinstance(proprio, lc_ldap.objets.AssociationCrans): radiusd.radlog(radiusd.L_ERR, 'Crans machine trying to authenticate !') @@ -316,21 +326,31 @@ def decide_vlan(data, is_wifi, conn): "wifi" si wifi """ + # Switch de remplissage decision par défaut, port, hebergeurs if is_wifi: decision = 'wifi', u'' port = data.get('Called-Station-Id', '?') + hebergeurs = [] else: decision = 'adherent', u'' prise, chbre = get_prise_chbre(data) port = "%s/%s" % (prise, chbre) - items = get_machines(data) + chbre = escape_ldap(chbre) + hebergeurs = conn.search(u'(&(chbre=%s)(|(cid=*)(aid=*)))' % chbre) + + # Prend la première machine candidat dans la base, ou exit + items = get_machines(data, is_wifi=is_wifi, proprio=(hebergeurs+[None])[0]) if not items: return (port, 'accueil', 'Machine inconnue') - machine = items[0] + proprio = machine.proprio() + # Avant de continuer, on assigne la mac à la machine candidat + if '' in machine['macAddress']: + register_mac(data, machine) + if not machine['ipHostNumber']: decision = 'v6only', u'No IPv4' elif unicode(machine['macAddress'][0]) in test_v6: @@ -355,8 +375,6 @@ def decide_vlan(data, is_wifi, conn): if chbre is None and not is_ma: decision = "accueil", u"Chambre inconnue" elif chbre is not None: - chbre = escape_ldap(chbre) - hebergeurs = conn.search(u'(&(chbre=%s)(|(cid=*)(aid=*)))' % chbre) for hebergeur in hebergeurs: # Si on est hébergé par un adhérent ok, ou que c'est notre # chambre, pas de problème