$OpenBSD: patch-lib_puppet_provider_user_openbsd_rb,v 1.4 2014/12/29 18:56:55 jasper Exp $

- From 986281e1d2e45ca2f6a2a902c508c9d66e66da50 Mon Sep 17 00:00:00 2001
  From: Jasper Lievisse Adriaanse <jasper@humppa.nl>
  Date: Sun, 2 Nov 2014 16:44:42 +0100
  Subject: [PATCH] (PUP-3605) Add new OpenBSD user provider

- From fc4cb831e7203b6568e090ebb671bf5bbb9cb910 Mon Sep 17 00:00:00 2001
  From: Jasper Lievisse Adriaanse <jasper@humppa.nl>
  Date: Tue, 2 Dec 2014 20:38:11 +0100
  Subject: [PATCH] (PUP-3723) Add new loginclass parameter to user type

--- lib/puppet/provider/user/openbsd.rb.orig	Mon Dec 29 19:55:22 2014
+++ lib/puppet/provider/user/openbsd.rb	Mon Dec 29 19:55:49 2014
@@ -0,0 +1,76 @@
+require 'date'
+require 'time'
+require 'puppet/error'
+
+Puppet::Type.type(:user).provide :openbsd, :parent => :useradd do
+  desc "User management via `useradd` and its ilk for OpenBSD. Note that you
+    will need to install Ruby's shadow password library (package known as
+    `ruby-shadow`) if you wish to manage user passwords."
+
+  commands :add      => "useradd",
+           :delete   => "userdel",
+           :modify   => "usermod",
+           :password => "passwd"
+
+  defaultfor :operatingsystem => :openbsd
+
+  options :home, :flag => "-d", :method => :dir
+  options :comment, :method => :gecos
+  options :groups, :flag => "-G"
+  options :password, :method => :sp_pwdp
+  options :loginclass, :flag => '-L', :method => :sp_loginclass
+  options :expiry, :method => :sp_expire,
+    :munge => proc { |value|
+      if value == :absent
+        ''
+      else
+        # OpenBSD uses a format like "january 1 1970"
+        Time.parse(value).strftime('%B %d %Y')
+      end
+    },
+    :unmunge => proc { |value|
+      if value == -1
+        :absent
+      else
+        # Expiry is days after 1970-01-01
+        (Date.new(1970,1,1) + value).strftime('%Y-%m-%d')
+      end
+    }
+
+  [:expiry, :password, :loginclass].each do |shadow_property|
+    define_method(shadow_property) do
+      if Puppet.features.libshadow?
+        if ent = Shadow::Passwd.getspnam(@resource.name)
+          method = self.class.option(shadow_property, :method)
+          # ruby-shadow may not be new enough (< 2.4.1) and therefore lack the
+          # sp_loginclass field.
+          begin
+            return unmunge(shadow_property, ent.send(method))
+          rescue => detail
+            Puppet.warning "ruby-shadow doesn't support #{method}"
+          end
+        end
+      end
+      :absent
+    end
+  end
+
+  has_features :manages_homedir, :manages_expiry, :system_users
+  has_features :manages_shell
+  if Puppet.features.libshadow?
+    has_features :manages_passwords, :manages_loginclass
+  end
+
+  def loginclass=(value)
+    set("loginclass", value)
+  end
+
+  def modifycmd(param, value)
+    cmd = super
+    if param == :groups
+      idx = cmd.index('-G')
+      cmd[idx] = '-S'
+    end
+    cmd
+  end
+end
