diff options
author | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-04-11 18:58:56 +0200 |
---|---|---|
committer | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-04-23 20:52:02 +0200 |
commit | 22b82abcd27834e43426f2758fba5728c146be61 (patch) | |
tree | 0ff8d542a0a1baf4bcfbecbc92a43455680d3671 /lib | |
parent | 15abe1709aa52bb45fe228139f4c0352dc8905df (diff) | |
download | puppet-22b82abcd27834e43426f2758fba5728c146be61.tar.gz puppet-22b82abcd27834e43426f2758fba5728c146be61.tar.xz puppet-22b82abcd27834e43426f2758fba5728c146be61.zip |
Add dynamic authorization to authstore
The idea is to have allow/deny authorization directives
that are dynamic: their evaluation is deferred until
we perform the authorization checking in allowed?.
This is done to allow replacing backreferences in allow/deny
directives by parameters of the match that selected this right.
For instance, it is possible to:
allow $1.$2
And using Right::interpolate() with the result of a regex match
using 2 captures, will evaluate $1.$2 to those captures.
For instance, if we captured [host, reductivelabs.com], then the
allow directive is replaced by:
allow host.reductivelabs.com
It is then safe to call allowed?, after which we can reset the
interpolation.
This interpolation is thread-safe.
Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
authconfig regex support
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/puppet/network/authstore.rb | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/lib/puppet/network/authstore.rb b/lib/puppet/network/authstore.rb index 7341f8a1e..6f7a7df25 100755 --- a/lib/puppet/network/authstore.rb +++ b/lib/puppet/network/authstore.rb @@ -45,7 +45,7 @@ module Puppet return true end - if decl = @declarations.find { |d| d.match?(name, ip) } + if decl = declarations.find { |d| d.match?(name, ip) } return decl.result end @@ -72,8 +72,29 @@ module Puppet "authstore" end + def interpolate(match) + declarations = @declarations.collect do |ace| + ace.interpolate(match) + end + declarations.sort! + Thread.current[:declarations] = declarations + end + + def reset_interpolation + Thread.current[:declarations] = nil + end + private + # returns our ACEs list, but if we have a modification of it + # in our current thread, let's return it + # this is used if we want to override the this purely immutable list + # by a modified version in a multithread safe way. + def declarations + return Thread.current[:declarations] if Thread.current[:declarations] + @declarations + end + # Store the results of a pattern into our hash. Basically just # converts the pattern and sticks it into the hash. def store(type, pattern) @@ -193,6 +214,21 @@ module Puppet @type = type end + # interpolate a pattern to replace any + # backreferences by the given match + # for instance if our pattern is $1.reductivelabs.com + # and we're called with a MatchData whose capture 1 is puppet + # we'll return a pattern of puppet.reductivelabs.com + def interpolate(match) + return self if @name == :ip + + clone = dup + clone.pattern = clone.pattern.reverse.collect do |p| + p.gsub(/\$(\d)/) { |m| match[$1.to_i] } + end.join(".") + clone + end + private # Returns nil if both values are true or both are false, returns @@ -277,6 +313,9 @@ module Puppet @pattern = munge_name(value) @pattern.pop # take off the '*' @length = @pattern.length + when /\$\d+/ # a backreference pattern ala $1.reductivelabs.com or 192.168.0.$1 or $1.$2 + @name = :dynamic + @pattern = munge_name(value) else # Else, use the IPAddr class to determine if we've got a # valid IP address. |