Puppet: System Administration Automated

Puppet Training Schedule
Next Class July 27-29
New York, New York
Discount before July 1st

Adding a User and their Home directory

This might help someone. If you're using a version higher than 0.22.1, this is probably fixed already, so you can simply check the reference to see how you should add a homedir directly from the user {} declaration. Otherwise, you can use this component:

define user_homedir ($group, $fullname, $ingroups) {
  user { "$name":
    ensure => present,
    comment => "$fullname",
    gid => "$group",
    groups => $ingroups,
    membership => minimum,
    shell => "/bin/bash",
    home => "/home/$name",
    require => Group[$group],
  }

  exec { "$name homedir":
    command => "/bin/cp -R /etc/skel /home/$name; /bin/chown -R $name:$group /home/$name",
    creates => "/home/$name",
    require => User[$name],
  }
}

You can use it like this:

user_homedir { "donkeyman":
  group => "donkeys",
  fullname => "Equus Asinus",
  ingroups => ["animalia", "chrodata", "mammalia", "perissodactyla", "equidae", "equus"],
}

Adding a User, Home directory, and a password hash

This might help someone else. If you're using a higher version, this could be fixed already, you can check the reference to see how you should add a homedir directly and hash from the user {} declaration. Otherwise, you can use this component:

define user_homedir_hash ($fullname, $myuid, $hash) {
  user { "$name":
    uid => "$myuid",
    comment => "$fullname",
    home => "/home/$name"
  }

  exec { "$name homedir":
    command => "cp -R /etc/skel /home/$name; chown -R $name /home/$name",
    path => "/bin:/usr/sbin",
    creates => "/home/$name",
    require => User[$name],
  }

  exec { "$name hash":
    command => "echo '$hash' | pw user mod $name -H /dev/stdin",
    onlyif => "pw usermod help 2>&1 | grep -q H\ fd && grep -q '$name:\*:' /etc/master.passwd",
    path => "/bin:/usr/sbin:/usr/bin",
    require => User[$name],
  }
}

Notes: I found that different systems put binarys in other locations, I used path to sort this out. I also removed every option I didn't need to set.

Usefulness: This is obviously an extension to the pw provider used by FreeBSD, I'm sure the concept can be extended to other providers that are missing features. This code should be safe on all non-pw systems.

You can use it like this:

user_homedir_hash { "donkeyman":
  fullname => "Equus Asinus",
  myuid => 71830,
  hash => 'balhblahblah'
}

Other code: This code I've used to insert passwords when there is no OS support for managing hashes. It could be helpful as part of other puppet providers. The down side is that it was written in TCL/expect.

send "PS1=ttaany\r"

    proc nupasswd {username PASSWD_HASH REAL_NAME} {
        send "EDITOR=ed vipw\r"
        expect "EDITOR=ed vipw\r"
        send "/^$username\::/\n"
        expect {
          "\\?" {
            send "q\r"
            expect "q\r"
            expect "ttaany"
            return 1
          }
          $REAL_NAME
        }
        sleep 1
        send ".,s%::%:$PASSWD_HASH\:%1\n"
        expect ".,s%::%:$PASSWD_HASH\:%1"
        sleep 1
        send ".\n"
        expect "."
        expect "$PASSWD_HASH"
        sleep 1
        send "w\n"
        expect "w"
        sleep 1
        send "q\n"
        expect "q"
        expect "vipw"
        expect "ttaany"
    }