puppetlabs/puppet · error · Puppet::Error

OS X 10.7 requires a Salted SHA512 hash password of 136 char

Error message

OS X 10.7 requires a Salted SHA512 hash password of 136 characters.  Please check your password and try again.

What it means

Raised by Puppet's macOS DirectoryService user provider on OS X 10.7 when the `password` property value is not exactly 136 characters — the length of a salted SHA-512 hash as Apple stores it in the 10.7 ShadowHashData plist. The provider validates length before writing the plist, because it cannot set passwords via dscl without plaintext.

Source

Thrown at lib/puppet/provider/user/directoryservice.rb:357

      merge_attribute_with_dscl('Groups', group, 'GroupMembership', @resource.name)
      merge_attribute_with_dscl('Groups', group, 'GroupMembers', guid)
    end
  end

  # If you thought GETTING a password was bad, try SETTING it. This method
  # makes me want to cry. A thousand tears...
  #
  # I've been unsuccessful in tracking down a way to set the password for
  # a user using dscl that DOESN'T require passing it as plaintext. We were
  # also unable to get dsimport to work like this. Due to these downfalls,
  # the sanest method requires opening the user's plist, dropping in the
  # password hash, and serializing it back to disk. The problems with THIS
  # method revolve around dscl. Any time you directly modify a user's plist,
  # you need to flush the cache that dscl maintains.
  def password=(value)
    if self.class.get_os_version == '10.7'
      if value.length != 136
        raise Puppet::Error, "OS X 10.7 requires a Salted SHA512 hash password of 136 characters.  Please check your password and try again."
      end
    else
      if value.length != 256
        raise Puppet::Error, "OS X versions > 10.7 require a Salted SHA512 PBKDF2 password hash of 256 characters. Please check your password and try again."
      end

      assert_full_pbkdf2_password
    end

    # Methods around setting the password on OS X are the ONLY methods that
    # cannot use dscl (because the only way to set it via dscl is by passing
    # a plaintext password - which is bad). Because of this, we have to change
    # the user's plist directly. DSCL has its own caching mechanism, which
    # means that every time we call dscl in this provider we're not directly
    # changing values on disk (instead, those calls are cached and written
    # to disk according to Apple's prioritization algorithms). When Puppet
    # needs to set the password property on OS X > 10.6, the provider has to
    # tell dscl to write its cache to disk before modifying the user's

View on GitHub (pinned to e227c27540)

Solutions

  1. Generate a correct salted SHA-512: salt (up to 8 chars) + SHA-512(salt+password) hex — verify total length is 136 characters.
  2. Do not pass plaintext; the provider writes the hash directly into the user's plist.
  3. Keep OS-version-specific password data in Hiera keyed by os.major, or gate the password property with an `if` on the OS version.
  4. If you cannot produce a 10.7-format hash, manage the password outside Puppet (e.g., MDM) on those hosts.

Example fix

# before (10.7 node)
user { 'alice': ensure => present, password => 'plaintext-or-128-char-hash' }
# after - 136-char salted SHA512 (salt 'abcdefgh' + 128-hex digest)
user { 'alice': ensure => present, password => 'abcdefgh<128 hex chars...>' }
Defensive patterns

Strategy: type-guard

Validate before calling

raise 'expected 136 chars' unless hash.length == 136

Type guard

def valid_salted_sha512_10_7?(hash)
  hash.is_a?(String) && hash.length == 136 && hash.match?(/\A[0-9a-fA-F]+\z/)
end

Prevention

When it happens

Trigger: Managing `password` on an OS X 10.7 user and supplying a plaintext password, a SHA-512 hex digest without salt (128 chars), or the newer 256-char PBKDF2 hash instead of the required 136-char salted SHA-512 form.

Common situations: Manifests written for 10.8+ (PBKDF2) reused on 10.7; Linux-style crypt strings passed through; salt/format omitted when generating the hash with OpenSSL.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/db0703982dda7ae9. Report an issue: GitHub.