summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBrice Figureau <brice-puppet@daysofwonder.com>2009-04-11 18:58:56 +0200
committerBrice Figureau <brice-puppet@daysofwonder.com>2009-04-23 20:52:02 +0200
commit22b82abcd27834e43426f2758fba5728c146be61 (patch)
tree0ff8d542a0a1baf4bcfbecbc92a43455680d3671 /lib
parent15abe1709aa52bb45fe228139f4c0352dc8905df (diff)
downloadpuppet-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-xlib/puppet/network/authstore.rb41
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.