24929333 puppet: user resource's "password_max_age" parameter doesn't understand -1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ruby/puppet/patches/puppet-10-PUP-2975.patch Thu Mar 09 10:47:46 2017 -0800
@@ -0,0 +1,87 @@
+This bug is fixed upstream as :
+https://tickets.puppetlabs.com/browse/PUP-229
+
+----
+From 6940de68efcc97a0af946f62ebfbfe53ad410d5d Mon Sep 17 00:00:00 2001
+From: Rahul Gopinath <[email protected]>
+Date: Thu, 14 Aug 2014 18:38:19 -0700
+Subject: [PATCH] (PUP 229) Fix /etc/shadow parsing so that max/min_age is
+ reported correctly
+
+Before this patch, parsing /etc/shadow, when empty trailing fields were
+present, they were discarded, and inturn a nil check was used to ensure that
+the fields did not exist. However, this ran into trouble when a value was
+appended to the end, causing all the empty fields to be returned as empty
+strings instead, failing the nil checks.
+
+This patch ensures that all empty fields are returned as empty strings, and
+a check for empty string is used to check whether the field exists or not.
+---
+
+--- puppet-3.6.2/lib/puppet/provider/user/user_role_add.rb.orig
++++ puppet-3.6.2/lib/puppet/provider/user/user_role_add.rb
+@@ -177,7 +177,8 @@
+ return @shadow_entry if defined? @shadow_entry
+ @shadow_entry = File.readlines(target_file_path).
+ reject { |r| r =~ /^[^\w]/ }.
+- collect { |l| l.chomp.split(':') }.
++ # PUP-229 dont suppress the empty fields
++ collect { |l| l.chomp.split(':', -1) }.
+ find { |user, _| user == @resource[:name] }
+ end
+
+@@ -186,12 +187,12 @@
+ end
+
+ def password_min_age
+- shadow_entry ? shadow_entry[3] : :absent
++ shadow_entry[3].empty? ? -1 : shadow_entry[3]
+ end
+
+ def password_max_age
+ return :absent unless shadow_entry
+- shadow_entry[4] || -1
++ shadow_entry[4].empty? ? -1 : shadow_entry[4]
+ end
+
+ # Read in /etc/shadow, find the line for our used and rewrite it with the
+
+--- puppet-3.6.2/spec/unit/provider/user/user_role_add_spec.rb.orig
++++ puppet-3.6.2/spec/unit/provider/user/user_role_add_spec.rb
+@@ -317,7 +317,7 @@ def write_fixture(content)
+ describe "#shadow_entry" do
+ it "should return the line for the right user" do
+ File.stubs(:readlines).returns(["someuser:!:10:5:20:7:1::\n", "fakeval:*:20:10:30:7:2::\n", "testuser:*:30:15:40:7:3::\n"])
+- provider.shadow_entry.should == ["fakeval", "*", "20", "10", "30", "7", "2"]
++ provider.shadow_entry.should == ["fakeval", "*", "20", "10", "30", "7", "2", "", ""]
+ end
+ end
+
+@@ -331,5 +331,27 @@ def write_fixture(content)
+ File.stubs(:readlines).returns(["fakeval:NP:12345::::::\n"])
+ provider.password_max_age.should == -1
+ end
++
++ it "should return -1 for no maximum when failed attempts are present" do
++ File.stubs(:readlines).returns(["fakeval:NP:12345::::::3\n"])
++ provider.password_max_age.should == -1
++ end
++ end
++
++ describe "#password_min_age" do
++ it "should return a minimum age number" do
++ File.stubs(:readlines).returns(["fakeval:NP:12345:10:50::::\n"])
++ provider.password_min_age.should == "10"
++ end
++
++ it "should return -1 for no minimum" do
++ File.stubs(:readlines).returns(["fakeval:NP:12345::::::\n"])
++ provider.password_min_age.should == -1
++ end
++
++ it "should return -1 for no minimum when failed attempts are present" do
++ File.stubs(:readlines).returns(["fakeval:NP:12345::::::3\n"])
++ provider.password_min_age.should == -1
++ end
+ end
+ end