Hi, so, I'm now down to a simplistic setup: two vservers, two scenarios 1) vserver 2 gets packet -> Auth-Type Reject 2) vserver 1 gets packet -> proxy to vserver 2 -> Auth-Type Accept I can confirm that internal proxying is at fault. I also ran a gdb "step" for both scenarios and tried to spot differences (yuck). One thing which caught my eye (not sure if it's the neuralgic spot, but looks good): authorize/pap only gets called by vserver 2, so breaking at mod_authoirze of rlm_pap: Scenario 1) - correct behaviour: Breakpoint 1, mod_authorize (instance=0x8766e0, request=0x88fc30) at src/modules/rlm_pap/rlm_pap.c:177 177 rlm_pap_t *inst = instance; (gdb) 178 bool auth_type = false; (gdb) 179 bool found_pw = false; (gdb) 183 rad_assert(request != NULL); (gdb) 185 for (vp = fr_cursor_init(&cursor, &request->config_items); (gdb) _fr_cursor_init (cursor=0x7fffffffb508, node=0x88fc58) at src/lib/cursor.c:34 34 memset(cursor, 0, sizeof(*cursor)); (gdb) 36 if (!node || !cursor) { (gdb) 40 memcpy(&cursor->first, &node, sizeof(cursor->first)); (gdb) 41 cursor->current = *cursor->first; (gdb) 43 if (cursor->current) { (gdb) 44 VERIFY_VP(cursor->current); (gdb) 45 cursor->next = cursor->current->next; (gdb) 48 return cursor->current; (gdb) 49 } (gdb) mod_authorize (instance=0x8766e0, request=0x88fc30) at src/modules/rlm_pap/rlm_pap.c:188 188 switch (vp->da->attr) { (gdb) 296 if (inst->normify) { (gdb) 297 normify(request, vp, 16); /* ensure it's in the right format */ (gdb) normify (request=0x88fc30, vp=0x890510, min_length=16) at src/modules/rlm_pap/rlm_pap.c:128 Scenario 2) - wrong behaviour: Breakpoint 1, mod_authorize (instance=0x8766e0, request=0x88fc20) at src/modules/rlm_pap/rlm_pap.c:177 177 rlm_pap_t *inst = instance; (gdb) 178 bool auth_type = false; (gdb) 179 bool found_pw = false; (gdb) 183 rad_assert(request != NULL); (gdb) 185 for (vp = fr_cursor_init(&cursor, &request->config_items); (gdb) _fr_cursor_init (cursor=0x7fffffffb388, node=0x88fc48) at src/lib/cursor.c:34 34 memset(cursor, 0, sizeof(*cursor)); (gdb) 36 if (!node || !cursor) { (gdb) 40 memcpy(&cursor->first, &node, sizeof(cursor->first)); (gdb) 41 cursor->current = *cursor->first; (gdb) 43 if (cursor->current) { (gdb) 44 VERIFY_VP(cursor->current); (gdb) 45 cursor->next = cursor->current->next; (gdb) 48 return cursor->current; (gdb) 49 } (gdb) mod_authorize (instance=0x8766e0, request=0x88fc20) at src/modules/rlm_pap/rlm_pap.c:188 188 switch (vp->da->attr) { (gdb) 325 REALM *realm = realm_find(vp->vp_strvalue); (gdb) realm_find (name=0x890950 "TO-STAFF") at src/main/realms.c:1998 1998 if (!name) name = "NULL"; (gdb) 2000 myrealm.name = name; (gdb) 2001 realm = rbtree_finddata(realms_byname, &myrealm); (gdb) rbtree_finddata (tree=0x827930, data=0x7fffffffb1a8) at src/lib/rbtree.c:539 539 x = rbtree_find(tree, data); (gdb) Apparently, the previously-proxied request still has Proxy-To-Realm TO-STAFF in its request structure; and rlm_pap goes a different way due to that. I would think the control items list from the first vserver does not get proxied - but it is? Greetings, Stefan Winter On 15.04.2014 10:26, Stefan Winter wrote:
Hi,
posting to devel, as this is possibly a severe bug. Apologies if not.
In FR 2, I authenticated our staff against a users-style file, setting NT-Password := ...
Their passwords were checked.
In FreeRADIUS 3, I retained this, NT-Passwords are found, pap returns noop(?), authorize returns ok, and then I see
Auth-Type = Accept, accepting the user
*regardless of his password* ?
I've rolled back the one affected vserver that had this problem, but would be really interested in an explanation. here is the -X flow:
rad_recv: Access-Request packet from host 158.64.1.65 port 46814, id=96, length=63 User-Name = 'ctompers' User-Password = '' NAS-Identifier = 'AAI-Staff-IdP' (11) # Executing section authorize from file /usr/local/freeradius/config/raddb/sites-enabled/AAI (11) authorize { (11) if ( NAS-Identifier == "AAI-Staff-IdP" ) (11) if ( NAS-Identifier == "AAI-Staff-IdP" ) -> TRUE (11) if ( NAS-Identifier == "AAI-Staff-IdP" ) { (11) update request { (11) RESTENA-Service-Type := 'Staff-AAI' (11) } # update request = noop (11) } # if ( NAS-Identifier == "AAI-Staff-IdP" ) = noop (11) ... skipping else for request 11: Preceding "if" was taken (11) suffix : No '@' in User-Name = "ctompers", looking up realm NULL (11) suffix : No such realm "NULL" (11) [suffix] = noop (11) if ( NAS-Identifier == "AAI-Staff-IdP" ) (11) if ( NAS-Identifier == "AAI-Staff-IdP" ) -> TRUE (11) if ( NAS-Identifier == "AAI-Staff-IdP" ) { (11) update control { (11) Proxy-To-Realm := 'TO-STAFF' (11) } # update control = noop (11) } # if ( NAS-Identifier == "AAI-Staff-IdP" ) = noop (11) ... skipping else for request 11: Preceding "if" was taken (11) } # authorize = noop Proxying to virtual server staff (11) # Executing section authorize from file /usr/local/freeradius/config/raddb/sites-enabled/staff (11) authorize { (11) if ( "%{NAS-Identifier}" == "ejabberd" ) (11) EXPAND %{NAS-Identifier} (11) --> AAI-Staff-IdP (11) if ( "%{NAS-Identifier}" == "ejabberd" ) -> FALSE (11) elsif ( "%{NAS-Identifier}" == "AAI-Staff-IdP" ) (11) EXPAND %{NAS-Identifier} (11) --> AAI-Staff-IdP (11) elsif ( "%{NAS-Identifier}" == "AAI-Staff-IdP" ) -> TRUE (11) elsif ( "%{NAS-Identifier}" == "AAI-Staff-IdP" ) { (11) update request { (11) RESTENA-Service-Type = 'Staff-AAI' (11) } # update request = noop (11) } # elsif ( "%{NAS-Identifier}" == "AAI-Staff-IdP" ) = noop (11) ... skipping else for request 11: Preceding "if" was taken (11) if ( "%{client:staff_type}" == "Nagios-Login" && User-Name == "testuser.monitor" ) (11) Client does not contain config item "staff_type" (11) EXPAND %{client:staff_type} (11) --> (11) if ( "%{client:staff_type}" == "Nagios-Login" && User-Name == "testuser.monitor" ) -> FALSE (11) if ( "%{RESTENA-Service-Type}" == "Staff-Jabber" ) (11) EXPAND %{RESTENA-Service-Type} (11) --> Staff-AAI (11) if ( "%{RESTENA-Service-Type}" == "Staff-Jabber" ) -> FALSE (11) auth_log_silent : EXPAND /var/log/radius/radacct/%Y%m%d/%{RESTENA-Service-Type}-service/auth-detail (11) auth_log_silent : --> /var/log/radius/radacct/20140415/Staff-AAI-service/auth-detail (11) auth_log_silent : /var/log/radius/radacct/%Y%m%d/%{RESTENA-Service-Type}-service/auth-detail expands to /var/log/radius/radacct/20140415/Staff-AAI-service/auth-detail (11) auth_log_silent : EXPAND %t (11) auth_log_silent : --> Tue Apr 15 09:57:57 2014 (11) [auth_log_silent] = ok (11) if ( "%{RESTENA-Service-Type}" == "Staff-IMAP" && "%{strlen:%{User-Password}}" == "96" ) (11) EXPAND %{RESTENA-Service-Type} (11) --> Staff-AAI (11) if ( "%{RESTENA-Service-Type}" == "Staff-IMAP" && "%{strlen:%{User-Password}}" == "96" ) -> FALSE (11) else else { (11) staff-auth : users: Matched entry ctompers at line 22 (11) [staff-auth] = ok (11) } # else else = ok (11) if ( "%{RESTENA-Service-Type}" == "Staff-AAI" ) (11) EXPAND %{RESTENA-Service-Type} (11) --> Staff-AAI (11) if ( "%{RESTENA-Service-Type}" == "Staff-AAI" ) -> TRUE (11) if ( "%{RESTENA-Service-Type}" == "Staff-AAI" ) { (11) staff-attributes : users: Matched entry ctompers at line 45 (11) [staff-attributes] = ok (11) } # if ( "%{RESTENA-Service-Type}" == "Staff-AAI" ) = ok (11) [mschap] = noop (11) [eap-staff] = noop (11) [pap] = noop (11) if ( "%{Packet-Src-IP-Address}" == "158.64.1.229" ) (11) EXPAND %{Packet-Src-IP-Address} (11) --> 158.64.1.65 (11) if ( "%{Packet-Src-IP-Address}" == "158.64.1.229" ) -> FALSE (11) } # authorize = ok (11) Auth-Type = Accept, accepting the user (11) # Executing section post-auth from file /usr/local/freeradius/config/raddb/sites-enabled/staff (11) post-auth { (11) restena_log_policy restena_log_policy {
You see two files matches:
the first one, "staff-auth : users: Matched entry ctompers at line 22" is the NT-Password:
[...] ctompers NT-Password := EA38E7ADC559499F31CF4FA0F195ABCD [...]
(the password hash is edited)
The second match is a series of reply attributes, none of which is Auth-Type of course. The match at that line 45 is expected.
But... WHY does it not check the password against the NT-Password? This same config works with FreeRADIUS 2; pap returns updated, authorize returns updated, and authenticate checks the input against the configured password?
Greetings,
Stefan Winter
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
-- Stefan WINTER Ingenieur de Recherche Fondation RESTENA - Réseau Téléinformatique de l'Education Nationale et de la Recherche 6, rue Richard Coudenhove-Kalergi L-1359 Luxembourg Tel: +352 424409 1 Fax: +352 422473 PGP key updated to 4096 Bit RSA - I will encrypt all mails if the recipient's key is known to me http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xC0DE6A358A39DC66