Download raw body.
puppet: user resource: fix changing passwords
The problem:
$ cat test.pp
user { 'test':
# echo secret | encrypt
password => '$2b$08$ZN1ywlySByQ79VoNNzHT5.riIraLxU/LVfXonHuPimCIyIAcNMArO';
}
# puppet apply ./test.pp
Warning: Facter: Unable to getenv for pid 1, 'uninitialized constant Facter::Util::Linux'
Notice: Compiled catalog for atar in environment production in 0.02 seconds
Error: Could not set password on user[test]: No command chpasswd defined for provider openbsd
Error: /Stage[main]/Main/User[test]/password: change from [redacted] to [redacted] failed: Could not set password on user[test]: No command chpasswd defined for provider openbsd
Notice: Applied catalog in 0.01 seconds
We don't have chpasswd, so nothing is executed to change the password.
Current code expects a new value on stdin, so they create a tempfile, etc.
Our usermod(8) -p takes it as argument and, as confimed by ktrace, Puppet
executes the command directly without shell, so use that instead:
# make update
# puppet apply ./test.pp
Warning: Facter: Unable to getenv for pid 1, 'uninitialized constant Facter::Util::Linux'
Notice: Compiled catalog for atar in environment production in 0.02 seconds
Notice: /Stage[main]/Main/User[test]/password: changed [redacted] to [redacted]
Notice: Applied catalog in 0.05 seconds
master.passwd(5) now gets updated correctly.
Puppet 7 has the same issue, but is EOL since 2025, so I'd rather remove it.
Feedback? OK?
Index: Makefile
===================================================================
RCS file: /cvs/ports/sysutils/ruby-puppet/8/Makefile,v
diff -u -p -r1.6 Makefile
--- Makefile 28 Jun 2025 00:36:32 -0000 1.6
+++ Makefile 27 Aug 2025 20:33:30 -0000
@@ -1,7 +1,7 @@
PORTROACH= limit:^8
VERSION= 8.10.0
-REVISION= 0
+REVISION= 1
RUN_DEPENDS+= converters/ruby-multi_json,${MODRUBY_FLAVOR}>=1.13,<2 \
devel/ruby-concurrent-ruby,${MODRUBY_FLAVOR}>=1,<2 \
Index: patches/patch-lib_puppet_provider_user_useradd_rb
===================================================================
RCS file: patches/patch-lib_puppet_provider_user_useradd_rb
diff -N patches/patch-lib_puppet_provider_user_useradd_rb
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-lib_puppet_provider_user_useradd_rb 28 Aug 2025 22:07:49 -0000
@@ -0,0 +1,41 @@
+Use usermod(8) -p to update to fix changing a user's password.
+
+Index: lib/puppet/provider/user/useradd.rb
+--- lib/puppet/provider/user/useradd.rb.orig
++++ lib/puppet/provider/user/useradd.rb
+@@ -14,7 +14,7 @@ Puppet::Type.type(:user).provide :useradd, :parent =>
+ To use the `forcelocal` parameter, you need to install the `libuser` package (providing
+ `/usr/sbin/lgroupadd` and `/usr/sbin/luseradd`)."
+
+- commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "chage", :chpasswd => "chpasswd"
++ commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "chage", :chpasswd => "usermod"
+
+ options :home, :flag => "-d", :method => :dir
+ options :comment, :method => :gecos
+@@ -189,25 +189,14 @@ Puppet::Type.type(:user).provide :useradd, :parent =>
+ user = @resource[:name]
+ tempfile = Tempfile.new('puppet', :encoding => Encoding::UTF_8)
+ begin
+- # Puppet execute does not support strings as input, only files.
+- # The password is expected to be in an encrypted format given -e is specified:
+- tempfile << "#{user}:#{value}\n"
+- tempfile.flush
+-
+- # Options '-e' use encrypted password
+- # Must receive "user:enc_password" as input
+- # command, arguments = {:failonfail => true, :combine => true}
+- cmd = [command(:chpasswd), '-e']
++ cmd = [command(:chpasswd), '-p', value, user]
+ execute_options = {
+ :failonfail => false,
+ :combine => true,
+- :stdinfile => tempfile.path,
+ :sensitive => has_sensitive_data?
+ }
+ output = execute(cmd, execute_options)
+ rescue => detail
+- tempfile.close
+- tempfile.delete
+ raise Puppet::Error, "Could not set password on #{@resource.class.name}[#{@resource.name}]: #{detail}", detail.backtrace
+ end
+
puppet: user resource: fix changing passwords