diff options
| author | Jesse Wolfe <jes5199@gmail.com> | 2010-10-04 20:11:56 -0700 |
|---|---|---|
| committer | Jesse Wolfe <jes5199@gmail.com> | 2010-10-04 21:46:59 -0700 |
| commit | 7bdbd132634f61d91aeee401de15248d936ce71e (patch) | |
| tree | 146bb43d90478d373f9bb1c5ed3e04bd9d04dbbc /lib | |
| parent | 163ec172e06a2b8aab9f9c9247dd45bc0dea3f72 (diff) | |
| parent | 917c520f1abc0c72d7065531cffcef88259e32e0 (diff) | |
| download | puppet-7bdbd132634f61d91aeee401de15248d936ce71e.tar.gz puppet-7bdbd132634f61d91aeee401de15248d936ce71e.tar.xz puppet-7bdbd132634f61d91aeee401de15248d936ce71e.zip | |
Merge commit '2.6.2rc1' into next
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/puppet.rb | 2 | ||||
| -rw-r--r-- | lib/puppet/external/event-loop/event-loop.rb | 26 | ||||
| -rw-r--r-- | lib/puppet/network/http/webrick/rest.rb | 1 | ||||
| -rw-r--r-- | lib/puppet/network/http_pool.rb | 12 | ||||
| -rw-r--r-- | lib/puppet/parser/functions/extlookup.rb | 2 | ||||
| -rw-r--r-- | lib/puppet/parser/lexer.rb | 2 | ||||
| -rw-r--r-- | lib/puppet/parser/resource.rb | 1 | ||||
| -rw-r--r-- | lib/puppet/provider/nameservice.rb | 1 | ||||
| -rw-r--r-- | lib/puppet/provider/nameservice/objectadd.rb | 3 | ||||
| -rw-r--r-- | lib/puppet/provider/service/launchd.rb | 25 | ||||
| -rw-r--r-- | lib/puppet/provider/user/hpux.rb | 1 | ||||
| -rw-r--r-- | lib/puppet/provider/user/user_role_add.rb | 30 | ||||
| -rw-r--r-- | lib/puppet/provider/user/useradd.rb | 47 | ||||
| -rw-r--r-- | lib/puppet/reports/rrdgraph.rb | 2 | ||||
| -rwxr-xr-x | lib/puppet/type/user.rb | 55 | ||||
| -rw-r--r-- | lib/puppet/util/zaml.rb | 1 |
16 files changed, 160 insertions, 51 deletions
diff --git a/lib/puppet.rb b/lib/puppet.rb index 18c1e8cbd..0a90cf50c 100644 --- a/lib/puppet.rb +++ b/lib/puppet.rb @@ -24,7 +24,7 @@ require 'puppet/util/run_mode' # it's also a place to find top-level commands like 'debug' module Puppet - PUPPETVERSION = '2.6.1' + PUPPETVERSION = '2.6.2' def Puppet.version PUPPETVERSION diff --git a/lib/puppet/external/event-loop/event-loop.rb b/lib/puppet/external/event-loop/event-loop.rb index dc51a55ae..3b40f6e71 100644 --- a/lib/puppet/external/event-loop/event-loop.rb +++ b/lib/puppet/external/event-loop/event-loop.rb @@ -75,8 +75,10 @@ class EventLoop @notify_src, @notify_snk = IO.pipe # prevent file descriptor leaks - @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) - @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + if @notify_src.respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_SETFD) and defined?(Fcntl::FD_CLOEXEC) + @notify_src.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + @notify_snk.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) + end @notify_src.will_block = false @notify_snk.will_block = false @@ -234,19 +236,21 @@ class IO end def will_block? - require "fcntl" - fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0 + if respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_GETFL) and defined?(Fcntl::O_NONBLOCK) + fcntl(Fcntl::F_GETFL, 0) & Fcntl::O_NONBLOCK == 0 + end end def will_block= (wants_blocking) - require "fcntl" - flags = fcntl(Fcntl::F_GETFL, 0) - if wants_blocking - flags &= ~Fcntl::O_NONBLOCK - else - flags |= Fcntl::O_NONBLOCK + if respond_to?(:fcntl) and defined?(Fcntl) and defined?(Fcntl::F_GETFL) and defined?(Fcntl::O_NONBLOCK) + flags = fcntl(Fcntl::F_GETFL, 0) + if wants_blocking + flags &= ~Fcntl::O_NONBLOCK + else + flags |= Fcntl::O_NONBLOCK + end + fcntl(Fcntl::F_SETFL, flags) end - fcntl(Fcntl::F_SETFL, flags) end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index 91008aa1a..d5c146d88 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -1,5 +1,6 @@ require 'puppet/network/http/handler' require 'resolv' +require 'webrick' class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet diff --git a/lib/puppet/network/http_pool.rb b/lib/puppet/network/http_pool.rb index a3b055572..7d227b4d4 100644 --- a/lib/puppet/network/http_pool.rb +++ b/lib/puppet/network/http_pool.rb @@ -58,18 +58,6 @@ module Puppet::Network::HttpPool http.cert = ssl_host.certificate.content http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.key = ssl_host.key.content - http.verify_callback = self.method(:ssl_verify_callback).to_proc if Puppet[:debug] - end - - def self.ssl_verify_callback(peer_ok, x509_store_ctx) - if not peer_ok - Puppet.debug "OpenSSL: Error(#{x509_store_ctx.error}): #{x509_store_ctx.error_string}" - Puppet.debug "OpenSSL: Cert: #{x509_store_ctx.current_cert.issuer}" - Puppet.debug "OpenSSL: Current CRL: #{x509_store_ctx.current_crl}" - Puppet.debug "OpenSSL: Chain:" - x509_store_ctx.chain.each_index { |i| Puppet.debug "OpenSSL: \t#{i} #{x509_store_ctx.chain[i].issuer}" } - end - peer_ok end # Retrieve a cached http instance if caching is enabled, else return diff --git a/lib/puppet/parser/functions/extlookup.rb b/lib/puppet/parser/functions/extlookup.rb index 63d49e563..bc55410b9 100644 --- a/lib/puppet/parser/functions/extlookup.rb +++ b/lib/puppet/parser/functions/extlookup.rb @@ -52,7 +52,7 @@ the exact same outcome: $snmp_contact = extlookup(\"snmp_contact\") -The obove code shows some other features, you can use any fact or variable that +The above code shows some other features, you can use any fact or variable that is in scope by simply using %{varname} in your data files, you can return arrays by just having multiple values in the csv after the initial variable name. diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb index a25a17e3f..9036d652e 100644 --- a/lib/puppet/parser/lexer.rb +++ b/lib/puppet/parser/lexer.rb @@ -520,7 +520,7 @@ class Puppet::Parser::Lexer def slurpstring(terminators,escapes=%w{ \\ $ ' " n t s }+["\n"],ignore_invalid_escapes=false) # we search for the next quote that isn't preceded by a # backslash; the caret is there to match empty strings - str = @scanner.scan_until(/([^\\]|^)[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'" + str = @scanner.scan_until(/([^\\]|^|[^\\])([\\]{2})*[#{terminators}]/) or lex_error "Unclosed quote after '#{last}' in '#{rest}'" @line += str.count("\n") # literal carriage returns add to the line count. str.gsub!(/\\(.)/) { ch = $1 diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb index e34f284fc..c007d4dbe 100644 --- a/lib/puppet/parser/resource.rb +++ b/lib/puppet/parser/resource.rb @@ -64,6 +64,7 @@ class Puppet::Parser::Resource < Puppet::Resource # Retrieve the associated definition and evaluate it. def evaluate + return if evaluated? @evaluated = true if klass = resource_type and ! builtin_type? finish diff --git a/lib/puppet/provider/nameservice.rb b/lib/puppet/provider/nameservice.rb index 7339b646e..9830fab54 100644 --- a/lib/puppet/provider/nameservice.rb +++ b/lib/puppet/provider/nameservice.rb @@ -165,6 +165,7 @@ class Puppet::Provider::NameService < Puppet::Provider begin execute(self.addcmd) + execute(self.passcmd) if self.feature? :manages_password_age rescue Puppet::ExecutionFailure => detail raise Puppet::Error, "Could not create #{@resource.class.name} #{@resource.name}: #{detail}" end diff --git a/lib/puppet/provider/nameservice/objectadd.rb b/lib/puppet/provider/nameservice/objectadd.rb index 80c142982..dbb9f306f 100644 --- a/lib/puppet/provider/nameservice/objectadd.rb +++ b/lib/puppet/provider/nameservice/objectadd.rb @@ -13,7 +13,8 @@ class ObjectAdd < Puppet::Provider::NameService end def modifycmd(param, value) - cmd = [command(:modify), flag(param), value] + cmd = [command(param.to_s =~ /password_.+_age/ ? :password : :modify)] + cmd << flag(param) << value if @resource.allowdupe? && ((param == :uid) || (param == :gid and self.class.name == :groupadd)) cmd << "-o" end diff --git a/lib/puppet/provider/service/launchd.rb b/lib/puppet/provider/service/launchd.rb index 970359539..b296e0a38 100644 --- a/lib/puppet/provider/service/launchd.rb +++ b/lib/puppet/provider/service/launchd.rb @@ -38,6 +38,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do commands :launchctl => "/bin/launchctl" commands :sw_vers => "/usr/bin/sw_vers" + commands :plutil => "/usr/bin/plutil" defaultfor :operatingsystem => :darwin confine :operatingsystem => :darwin @@ -52,6 +53,12 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do Launchd_Overrides = "/var/db/launchd.db/com.apple.launchd/overrides.plist" + # Read a plist, whether its format is XML or in Apple's "binary1" + # format. + def self.read_plist(path) + Plist::parse_xml(plutil('-convert', 'xml1', '-o', '-', path)) + end + # returns a label => path map for either all jobs, or just a single # job if the label is specified def self.jobsearch(label=nil) @@ -62,8 +69,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do next if f =~ /^\..*$/ next if FileTest.directory?(f) fullpath = File.join(path, f) - job = Plist::parse_xml(fullpath) - if job and job.has_key?("Label") + if FileTest.file?(fullpath) and job = read_plist(fullpath) and job.has_key?("Label") if job["Label"] == label return { label => fullpath } else @@ -118,8 +124,11 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do def plist_from_label(label) job = self.class.jobsearch(label) job_path = job[label] - job_plist = Plist::parse_xml(job_path) - raise Puppet::Error.new("Unable to parse launchd plist at path: #{job_path}") if not job_plist + if FileTest.file?(job_path) + job_plist = self.class.read_plist(job_path) + else + raise Puppet::Error.new("Unable to parse launchd plist at path: #{job_path}") + end [job_path, job_plist] end @@ -200,9 +209,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do job_plist_disabled = job_plist["Disabled"] if job_plist.has_key?("Disabled") if self.class.get_macosx_version_major == "10.6": - overrides = Plist::parse_xml(Launchd_Overrides) - - unless overrides.nil? + if FileTest.file?(Launchd_Overrides) and overrides = self.class.read_plist(Launchd_Overrides) if overrides.has_key?(resource[:name]) overrides_disabled = overrides[resource[:name]]["Disabled"] if overrides[resource[:name]].has_key?("Disabled") end @@ -227,7 +234,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do # versions this is stored in the job plist itself. def enable if self.class.get_macosx_version_major == "10.6" - overrides = Plist::parse_xml(Launchd_Overrides) + overrides = self.class.read_plist(Launchd_Overrides) overrides[resource[:name]] = { "Disabled" => false } Plist::Emit.save_plist(overrides, Launchd_Overrides) else @@ -242,7 +249,7 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do def disable if self.class.get_macosx_version_major == "10.6" - overrides = Plist::parse_xml(Launchd_Overrides) + overrides = self.class.read_plist(Launchd_Overrides) overrides[resource[:name]] = { "Disabled" => true } Plist::Emit.save_plist(overrides, Launchd_Overrides) else diff --git a/lib/puppet/provider/user/hpux.rb b/lib/puppet/provider/user/hpux.rb index 50506c4cd..983970935 100644 --- a/lib/puppet/provider/user/hpux.rb +++ b/lib/puppet/provider/user/hpux.rb @@ -26,5 +26,4 @@ Puppet::Type.type(:user).provide :hpuxuseradd, :parent => :useradd do def modifycmd(param,value) super.insert(1,"-F") end - end diff --git a/lib/puppet/provider/user/user_role_add.rb b/lib/puppet/provider/user/user_role_add.rb index c13125925..7e7ad78e5 100644 --- a/lib/puppet/provider/user/user_role_add.rb +++ b/lib/puppet/provider/user/user_role_add.rb @@ -6,13 +6,15 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source => defaultfor :operatingsystem => :solaris - commands :add => "useradd", :delete => "userdel", :modify => "usermod", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod" + commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "chage", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod" options :home, :flag => "-d", :method => :dir options :comment, :method => :gecos options :groups, :flag => "-G" options :roles, :flag => "-R" options :auths, :flag => "-A" options :profiles, :flag => "-P" + options :password_min_age, :flag => "-m" + options :password_max_age, :flag => "-M" verify :gid, "GID must be an integer" do |value| value.is_a? Integer @@ -22,14 +24,14 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source => value !~ /\s/ end - has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac, :manages_passwords + has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac, :manages_passwords, :manages_password_age #must override this to hand the keyvalue pairs def add_properties cmd = [] Puppet::Type.type(:user).validproperties.each do |property| #skip the password because we can't create it with the solaris useradd - next if [:ensure, :password].include?(property) + next if [:ensure, :password, :password_min_age, :password_max_age].include?(property) # 1680 Now you can set the hashed passwords on solaris:lib/puppet/provider/user/user_role_add.rb # the value needs to be quoted, mostly because -c might # have spaces in it @@ -79,6 +81,7 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source => run(transition("normal"), "transition role to") else run(addcmd, "create") + run(passcmd, "change password policy for") end # added to handle case when password is specified self.password = @resource[:password] if @resource[:password] @@ -140,14 +143,23 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source => run([command(:modify)] + build_keys_cmd(keys_hash) << @resource[:name], "modify attribute key pairs") end - #Read in /etc/shadow, find the line for this user (skipping comments, because who knows) and return the hashed pw (the second entry) + #Read in /etc/shadow, find the line for this user (skipping comments, because who knows) and return it #No abstraction, all esoteric knowledge of file formats, yay + def shadow_entry + return @shadow_entry if defined? @shadow_entry + @shadow_entry = File.readlines("/etc/shadow").reject { |r| r =~ /^[^\w]/ }.collect { |l| l.chomp.split(':') }.find { |user, _| user == @resource[:name] } + end + def password - #got perl? - if ary = File.readlines("/etc/shadow").reject { |r| r =~ /^[^\w]/}.collect { |l| l.split(':')[0..1] }.find { |user, passwd| user == @resource[:name] } - pass = ary[1] - end - pass + shadow_entry[1] if shadow_entry + end + + def min_age + shadow_entry ? shadow_entry[3] : :absent + end + + def max_age + shadow_entry ? shadow_entry[4] : :absent end #Read in /etc/shadow, find the line for our used and rewrite it with the new pw diff --git a/lib/puppet/provider/user/useradd.rb b/lib/puppet/provider/user/useradd.rb index 7ef217d9e..9a62db464 100644 --- a/lib/puppet/provider/user/useradd.rb +++ b/lib/puppet/provider/user/useradd.rb @@ -3,11 +3,13 @@ require 'puppet/provider/nameservice/objectadd' Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameService::ObjectAdd do desc "User management via `useradd` and its ilk. Note that you will need to install the `Shadow Password` Ruby library often known as ruby-libshadow to manage user passwords." - commands :add => "useradd", :delete => "userdel", :modify => "usermod" + commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "chage" options :home, :flag => "-d", :method => :dir options :comment, :method => :gecos options :groups, :flag => "-G" + options :password_min_age, :flag => "-m" + options :password_max_age, :flag => "-M" verify :gid, "GID must be an integer" do |value| value.is_a? Integer @@ -17,9 +19,9 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ value !~ /\s/ end - has_features :manages_homedir, :allows_duplicates + has_features :manages_homedir, :allows_duplicates, :manages_expiry - has_feature :manages_passwords if Puppet.features.libshadow? + has_features :manages_passwords, :manages_password_age if Puppet.features.libshadow? def check_allow_dup @resource.allowdupe? ? ["-o"] : [] @@ -35,10 +37,20 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ cmd end + def check_manage_expiry + cmd = [] + if @resource[:expiry] + cmd << "-e #{@resource[:expiry]}" + end + + cmd + end + def add_properties cmd = [] Puppet::Type.type(:user).validproperties.each do |property| next if property == :ensure + next if property.to_s =~ /password_.+_age/ # the value needs to be quoted, mostly because -c might # have spaces in it if value = @resource.should(property) and value != "" @@ -53,9 +65,38 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ cmd += add_properties cmd += check_allow_dup cmd += check_manage_home + cmd += check_manage_expiry cmd << @resource[:name] end + def passcmd + cmd = [command(:password)] + [:password_min_age, :password_max_age].each do |property| + if value = @resource.should(property) + cmd << flag(property) << value + end + end + cmd << @resource[:name] + end + + def min_age + if Puppet.features.libshadow? + if ent = Shadow::Passwd.getspnam(@resource.name) + return ent.sp_min + end + end + :absent + end + + def max_age + if Puppet.features.libshadow? + if ent = Shadow::Passwd.getspnam(@resource.name) + return ent.sp_max + end + end + :absent + end + # Retrieve the password using the Shadow Password library def password if Puppet.features.libshadow? diff --git a/lib/puppet/reports/rrdgraph.rb b/lib/puppet/reports/rrdgraph.rb index 2357e233e..517fa8f03 100644 --- a/lib/puppet/reports/rrdgraph.rb +++ b/lib/puppet/reports/rrdgraph.rb @@ -122,7 +122,7 @@ Puppet::Reports.register_report(:rrdgraph) do # that means we record the total time, the config time, and that's about # it. We should probably send each type's time as a separate metric. def timeclean(metric) - metric.values = metric.values.find_all { |name, label, value| [:total, :config_retrieval].include?(name) } + metric.values = metric.values.find_all { |name, label, value| ['total', 'config_retrieval'].include?(name.to_s) } end end diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index 007b760bc..c8110bb69 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -24,9 +24,16 @@ module Puppet "The provider can modify user passwords, by accepting a password hash." + feature :manages_password_age, + "The provider can set age requirements and restrictions for + passwords." + feature :manages_solaris_rbac, "The provider can manage roles and normal users" + feature :manages_expiry, + "The provider can manage the expiry date for a user." + newproperty(:ensure, :parent => Puppet::Property::Ensure) do newvalue(:present, :event => :user_created) do provider.create @@ -157,6 +164,43 @@ module Puppet end end + newproperty(:password_min_age, :required_features => :manages_password_age) do + desc "The minimum amount of time in days a password must be used before it may be changed" + + munge do |value| + case value + when String + Integer(value) + else + value + end + end + + validate do |value| + if value.to_s !~ /^\d+$/ + raise ArgumentError, "Password minimum age must be provided as a number" + end + end + end + + newproperty(:password_max_age, :required_features => :manages_password_age) do + desc "The maximum amount of time in days a password may be used before it must be changed" + + munge do |value| + case value + when String + Integer(value) + else + value + end + end + + validate do |value| + if value.to_s !~ /^\d+$/ + raise ArgumentError, "Password maximum age must be provided as a number" + end + end + end newproperty(:groups, :parent => Puppet::Property::List) do desc "The groups of which the user is a member. The primary @@ -210,6 +254,17 @@ module Puppet end end + newproperty(:expiry, :required_features => :manages_expiry) do + desc "The expiry date for this user. Must be provided in + a zero padded YYYY-MM-DD format - e.g 2010-02-19." + + validate do |value| + if value !~ /^\d{4}-\d{2}-\d{2}$/ + raise ArgumentError, "Expiry dates must be YYYY-MM-DD" + end + end + end + # Autorequire the group, if it's around autorequire(:group) do autos = [] diff --git a/lib/puppet/util/zaml.rb b/lib/puppet/util/zaml.rb index b60e639ff..ae4da8612 100644 --- a/lib/puppet/util/zaml.rb +++ b/lib/puppet/util/zaml.rb @@ -242,7 +242,6 @@ class String when self =~ /\n/ if self[-1..-1] == "\n" then z.emit('|+') else z.emit('|-') end z.nested { split("\n",-1).each { |line| z.nl; z.emit(line.chomp("\n")) } } - z.nl else z.emit(self) end |
