From: Klemens Nanni Subject: puppet: user resource: fix changing passwords To: ports , Sebastian Reitenbach Date: Thu, 28 Aug 2025 22:37:31 +0000 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 +