Wipe existing reply attributes in rlm_files
Phil Mayers
p.mayers at imperial.ac.uk
Sat Oct 2 14:07:26 CEST 2010
On 10/02/2010 11:05 AM, Brian Candler wrote:
>> Why don't you just do whatever "if()" logic before adding the attributes?
>
> It's complicated :-)
>
> Partly it's policy. We configure as much of this logic in users files as
> possible, because they can be updated without needing to restart radiusd.
The obvious solution to this is SQL, but you're already planning on
moving to that.
>
> But in future it will be a necessity. The project I'm working on involves
> authenticating users based on some attribute which identifies their physical
> location, not their User-Name. So decisions you might have made in the past
> solely based on realm and NAS-IP (e.g. tunnel to X) have to be made after a
> database lookup.
We do something similar with per-location MAC auth; when the request
comes in, the Calling-Station-Id and NAS-IP-Address are fed into an SQL
stored procedure that does the heavy lifting; a machines get the
"closest" match VLAN for the given switch, based on a mapping of IPv4
subnets to vlans, and MAC to IP addresses and fallback zones/vlans.
My point being, the logic is all done in the lookup (but see below for
how I also permit overriding without attribute removal)
>
> That database lookup may add reply attributes, which will be needed by the
> terminating LNS, but not when tunnel switching. So if the database
> identifies the user as category X, *and* the request comes from NAS-IP Y,
> then we have to strip the reply attributes and replace with tunnelling ones.
The approach I take is to have the database lookup add a local
(non-wire) attribute set to the request (not reply) pairs. I then copy
that (conditionally) into the reply. It more or less works like so:
authorize {
# do the SQL lookup
update control {
Tmp-String-0 := "%{sql:select vlan||','||zone from proc('...')}"
}
if (control:Tmp-String-0 =~ /(.+),(.+)/) {
update request {
MyVlan = "%{0}"
MyZone = "%{1}"
}
}
else {
# SQL failed?
reject
}
# permit manual overrides
override_files
if (ok) {
# do nothing more
}
# obviously here you could have elif() statements
# that generate reply pairs in many different ways
else {
update reply {
Tunnel-Private-Group-Id = "%{MyVlan}"
}
}
}
"override_files" is just a "files" module in which we can put things
which the database module lookup can't (or shouldn't) handle, like
temporary testing hacks and such. Since we're using a "files" module for
this, the attribute I add from the database need to go into the request
pairs, so I can do things like:
DEFAULT NAS-IP-Address == ..., MyVlan == 1234
Vendor-Thing = "tagged-vlan=%{MyVlan}"
...and other such junk.
The point of all this is that you can add attributes into the request or
control pairs, or non-wire attributes into the reply, and then do
conditional logic on those, and not have to worry about stripping them
out - for request/control pairs, obviously because they're not sent in
the reply, and for non-wire reply pairs, because they're not sent on the
wire.
By "non-wire" I mean anything with an attribute number >255 - such as
Tmp-String-0, or any other attributes you care to define in a local
dictionary (FreeRadius reserves 3000-3999 for this purpose)
HTH
More information about the Freeradius-Users
mailing list