diff --git a/library/system/group b/library/system/group
index eb93d93c2d6..034baa514d3 100644
--- a/library/system/group
+++ b/library/system/group
@@ -61,8 +61,8 @@ import platform
 class Group(object):
     """
     This is a generic Group manipulation class that is subclassed
-    based on platform.  
-    
+    based on platform.
+
     A subclass may wish to override the following action methods:-
       - group_del()
       - group_add()
@@ -96,7 +96,7 @@ class Group(object):
     def group_del(self):
         cmd = [self.module.get_bin_path('groupdel', True), self.name]
         return self.execute_command(cmd)
- 
+
     def group_add(self, **kwargs):
         cmd = [self.module.get_bin_path('groupadd', True)]
         for key in kwargs:
@@ -107,7 +107,7 @@ class Group(object):
                 cmd.append('-r')
         cmd.append(self.name)
         return self.execute_command(cmd)
- 
+
     def group_mod(self, **kwargs):
         cmd = [self.module.get_bin_path('groupmod', True)]
         info = self.group_info()
@@ -122,14 +122,14 @@ class Group(object):
             return (True, '', '')
         cmd.append(self.name)
         return self.execute_command(cmd)
- 
+
     def group_exists(self):
         try:
             if grp.getgrnam(self.name):
                 return True
         except KeyError:
             return False
-    
+
     def group_info(self):
         if not self.group_exists():
             return False
@@ -162,7 +162,7 @@ class SunOS(Group):
                 cmd.append(kwargs[key])
         cmd.append(self.name)
         return self.execute_command(cmd)
-         
+
 
 # ===========================================
 
@@ -228,25 +228,111 @@ class FreeBsdGroup(Group):
         cmd = [self.module.get_bin_path('pw', True), 'groupdel', self.name]
         return self.execute_command(cmd)
 
-    def group_add(self,**kwargs):
+    def group_add(self, **kwargs):
         cmd = [self.module.get_bin_path('pw', True), 'groupadd', self.name]
         if self.gid is not None:
-                cmd.append('-g %d' % int(self.gid))
+            cmd.append('-g %d' % int(self.gid))
         return self.execute_command(cmd)
 
-    def group_mod(self,**kwargs):
+    def group_mod(self, **kwargs):
         cmd = [self.module.get_bin_path('pw', True), 'groupmod', self.name]
         info = self.group_info()
         cmd_len = len(cmd)
         if self.gid is not None and int(self.gid) != info[2]:
-                cmd.append('-g %d' % int(self.gid))
+            cmd.append('-g %d' % int(self.gid))
         # modify the group if cmd will do anything
         if cmd_len != len(cmd):
+            if self.module.check_mode:
+                return (True, '', '')
             return self.execute_command(cmd)
         return (None, '', '')
 
 # ===========================================
 
+class OpenBsdGroup(Group):
+    """
+    This is a OpenBSD Group manipulation class.
+
+    This overrides the following methods from the generic class:-
+      - group_del()
+      - group_add()
+      - group_mod()
+    """
+
+    platform = 'OpenBSD'
+    distribution = None
+    GROUPFILE = '/etc/group'
+
+    def group_del(self):
+        cmd = [self.module.get_bin_path('groupdel', True), self.name]
+        return self.execute_command(cmd)
+
+    def group_add(self, **kwargs):
+        cmd = [self.module.get_bin_path('groupadd', True)]
+        if self.gid is not None:
+            cmd.append('-g')
+            cmd.append('%d' % int(self.gid))
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+    def group_mod(self, **kwargs):
+        cmd = [self.module.get_bin_path('groupmod', True)]
+        info = self.group_info()
+        cmd_len = len(cmd)
+        if self.gid is not None and int(self.gid) != info[2]:
+            cmd.append('-g')
+            cmd.append('%d' % int(self.gid))
+        if len(cmd) == 1:
+            return (None, '', '')
+        if self.module.check_mode:
+            return (True, '', '')
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+# ===========================================
+
+class NetBsdGroup(Group):
+    """
+    This is a NetBSD Group manipulation class.
+
+    This overrides the following methods from the generic class:-
+      - group_del()
+      - group_add()
+      - group_mod()
+    """
+
+    platform = 'NetBSD'
+    distribution = None
+    GROUPFILE = '/etc/group'
+
+    def group_del(self):
+        cmd = [self.module.get_bin_path('groupdel', True), self.name]
+        return self.execute_command(cmd)
+
+    def group_add(self, **kwargs):
+        cmd = [self.module.get_bin_path('groupadd', True)]
+        if self.gid is not None:
+            cmd.append('-g')
+            cmd.append('%d' % int(self.gid))
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+    def group_mod(self, **kwargs):
+        cmd = [self.module.get_bin_path('groupmod', True)]
+        info = self.group_info()
+        cmd_len = len(cmd)
+        if self.gid is not None and int(self.gid) != info[2]:
+            cmd.append('-g')
+            cmd.append('%d' % int(self.gid))
+        if len(cmd) == 1:
+            return (None, '', '')
+        if self.module.check_mode:
+            return (True, '', '')
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+# ===========================================
+
 def main():
     module = AnsibleModule(
         argument_spec = dict(
diff --git a/library/system/user b/library/system/user
index 2f9924b4868..88f79aab246 100644
--- a/library/system/user
+++ b/library/system/user
@@ -106,6 +106,10 @@ options:
         description:
             - When used with C(state=absent), behavior is as with
               C(userdel --force).
+    login_class:
+        required: false
+        description:
+            - Optionally sets the user's login class for FreeBSD, OpenBSD and NetBSD systems.
     remove:
         required: false
         default: "no"
@@ -215,6 +219,7 @@ class User(object):
         self.remove     = module.params['remove']
         self.createhome = module.params['createhome']
         self.system     = module.params['system']
+        self.login_class = module.params['login_class']
         self.append     = module.params['append']
         self.sshkeygen  = module.params['generate_ssh_key']
         self.ssh_bits   = module.params['ssh_key_bits']
@@ -526,7 +531,7 @@ class FreeBsdUser(User):
     This is a FreeBSD User manipulation class - it uses the pw command
     to manipulate the user database, followed by the chpass command
     to change the password.
-    
+
     This overrides the following methods from the generic class:-
       - create_user()
       - remove_user()
@@ -554,7 +559,7 @@ class FreeBsdUser(User):
             self.module.get_bin_path('pw', True),
             'useradd',
             '-n',
-            self.name 
+            self.name,
         ]
 
         if self.uid is not None:
@@ -590,6 +595,10 @@ class FreeBsdUser(User):
             cmd.append('-s')
             cmd.append(self.shell)
 
+        if self.login_class is not None:
+            cmd.append('-L')
+            cmd.append(self.login_class)
+
         # system cannot be handled currently - should we error if its requested?
         # create the user
         (rc, out, err) = self.execute_command(cmd)
@@ -645,6 +654,10 @@ class FreeBsdUser(User):
             cmd.append('-s')
             cmd.append(self.shell)
 
+        if self.login_class is not None:
+            cmd.append('-L')
+            cmd.append(self.login_class)
+
         if self.groups is not None:
             current_groups = self.user_group_membership()
             groups = self.get_groups_set()
@@ -690,6 +703,308 @@ class FreeBsdUser(User):
 
 # ===========================================
 
+class OpenBSDUser(User):
+    """
+    This is a OpenBSD User manipulation class.
+    Main differences are that OpenBSD:-
+     - has no concept of "system" account.
+     - has no force delete user
+
+    This overrides the following methods from the generic class:-
+      - create_user()
+      - remove_user()
+      - modify_user()
+    """
+
+    platform = 'OpenBSD'
+    distribution = None
+    SHADOWFILE = '/etc/master.passwd'
+
+    def create_user(self):
+        cmd = [self.module.get_bin_path('useradd', True)]
+
+        if self.uid is not None:
+            cmd.append('-u')
+            cmd.append(self.uid)
+
+        if self.non_unique:
+            cmd.append('-o')
+
+        if self.group is not None:
+            if not self.group_exists(self.group):
+                self.module.fail_json(msg="Group %s does not exist" % self.group)
+            cmd.append('-g')
+            cmd.append(self.group)
+
+        if self.groups is not None:
+            groups = self.get_groups_set()
+            cmd.append('-G')
+            cmd.append(','.join(groups))
+
+        if self.comment is not None:
+            cmd.append('-c')
+            cmd.append(self.comment)
+
+        if self.home is not None:
+            cmd.append('-d')
+            cmd.append(self.home)
+
+        if self.shell is not None:
+            cmd.append('-s')
+            cmd.append(self.shell)
+
+        if self.login_class is not None:
+            cmd.append('-L')
+            cmd.append(self.login_class)
+
+        if self.password is not None:
+            cmd.append('-p')
+            cmd.append(self.password)
+
+        if self.createhome:
+            cmd.append('-m')
+
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+    def remove_user_userdel(self):
+        cmd = [self.module.get_bin_path('userdel', True)]
+        if self.remove:
+            cmd.append('-r')
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+    def modify_user(self):
+        cmd = [self.module.get_bin_path('usermod', True)]
+        info = self.user_info()
+
+        if self.uid is not None and info[2] != int(self.uid):
+            cmd.append('-u')
+            cmd.append(self.uid)
+
+        if self.non_unique:
+            cmd.append('-o')
+
+        if self.group is not None:
+            if not self.group_exists(self.group):
+                self.module.fail_json(msg="Group %s does not exist" % self.group)
+            ginfo = self.group_info(self.group)
+            if info[3] != ginfo[2]:
+                cmd.append('-g')
+                cmd.append(self.group)
+
+        if self.groups is not None:
+            current_groups = self.user_group_membership()
+            groups_need_mod = False
+            groups_option = '-G'
+            groups = []
+
+            if self.groups == '':
+                if current_groups and not self.append:
+                    groups_need_mod = True
+            else:
+                groups = self.get_groups_set()
+                group_diff = set(current_groups).symmetric_difference(groups)
+
+                if group_diff:
+                    if self.append:
+                        for g in groups:
+                            if g in group_diff:
+                                groups_option = '-S'
+                                groups_need_mod = True
+                                break
+                    else:
+                        groups_need_mod = True
+
+            if groups_need_mod:
+                cmd.append(groups_option)
+                cmd.append(','.join(groups))
+
+        if self.comment is not None and info[4] != self.comment:
+            cmd.append('-c')
+            cmd.append(self.comment)
+
+        if self.home is not None and info[5] != self.home:
+            cmd.append('-d')
+            cmd.append(self.home)
+
+        if self.shell is not None and info[6] != self.shell:
+            cmd.append('-s')
+            cmd.append(self.shell)
+
+        if self.login_class is not None:
+            cmd.append('-L')
+            cmd.append(self.login_class)
+
+        if self.password is not None and info[1] != self.password:
+            cmd.append('-p')
+            cmd.append(self.password)
+
+        # skip if no changes to be made
+        if len(cmd) == 1:
+            return (None, '', '')
+        elif self.module.check_mode:
+            return (0, '', '')
+
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+
+# ===========================================
+
+class NetBSDUser(User):
+    """
+    This is a NetBSD User manipulation class.
+    Main differences are that NetBSD:-
+     - has no concept of "system" account.
+     - has no force delete user
+
+
+    This overrides the following methods from the generic class:-
+      - create_user()
+      - remove_user()
+      - modify_user()
+    """
+
+    platform = 'NetBSD'
+    distribution = None
+    SHADOWFILE = '/etc/master.passwd'
+
+    def create_user(self):
+        cmd = [self.module.get_bin_path('useradd', True)]
+
+        if self.uid is not None:
+            cmd.append('-u')
+            cmd.append(self.uid)
+
+        if self.non_unique:
+            cmd.append('-o')
+
+        if self.group is not None:
+            if not self.group_exists(self.group):
+                self.module.fail_json(msg="Group %s does not exist" % self.group)
+            cmd.append('-g')
+            cmd.append(self.group)
+
+        if self.groups is not None:
+            groups = self.get_groups_set()
+            if len(groups) > 16:
+                self.module.fail_json(msg="Too many groups (%d) NetBSD allows for 16 max." % len(groups))
+            cmd.append('-G')
+            cmd.append(','.join(groups))
+
+        if self.comment is not None:
+            cmd.append('-c')
+            cmd.append(self.comment)
+
+        if self.home is not None:
+            cmd.append('-d')
+            cmd.append(self.home)
+
+        if self.shell is not None:
+            cmd.append('-s')
+            cmd.append(self.shell)
+
+        if self.login_class is not None:
+            cmd.append('-L')
+            cmd.append(self.login_class)
+
+        if self.password is not None:
+            cmd.append('-p')
+            cmd.append(self.password)
+
+        if self.createhome:
+            cmd.append('-m')
+
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+    def remove_user_userdel(self):
+        cmd = [self.module.get_bin_path('userdel', True)]
+        if self.remove:
+            cmd.append('-r')
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+    def modify_user(self):
+        cmd = [self.module.get_bin_path('usermod', True)]
+        info = self.user_info()
+
+        if self.uid is not None and info[2] != int(self.uid):
+            cmd.append('-u')
+            cmd.append(self.uid)
+
+        if self.non_unique:
+            cmd.append('-o')
+
+        if self.group is not None:
+            if not self.group_exists(self.group):
+                self.module.fail_json(msg="Group %s does not exist" % self.group)
+            ginfo = self.group_info(self.group)
+            if info[3] != ginfo[2]:
+                cmd.append('-g')
+                cmd.append(self.group)
+
+        if self.groups is not None:
+            current_groups = self.user_group_membership()
+            groups_need_mod = False
+            groups = []
+
+            if self.groups == '':
+                if current_groups and not self.append:
+                    groups_need_mod = True
+            else:
+                groups = self.get_groups_set()
+                group_diff = set(current_groups).symmetric_difference(groups)
+
+                if group_diff:
+                    if self.append:
+                        for g in groups:
+                            if g in group_diff:
+                                groups = set(current_groups).union(groups)
+                                groups_need_mod = True
+                                break
+                    else:
+                        groups_need_mod = True
+
+            if groups_need_mod:
+                if len(groups) > 16:
+                    self.module.fail_json(msg="Too many groups (%d) NetBSD allows for 16 max." % len(groups))
+                cmd.append('-G')
+                cmd.append(','.join(groups))
+
+        if self.comment is not None and info[4] != self.comment:
+            cmd.append('-c')
+            cmd.append(self.comment)
+
+        if self.home is not None and info[5] != self.home:
+            cmd.append('-d')
+            cmd.append(self.home)
+
+        if self.shell is not None and info[6] != self.shell:
+            cmd.append('-s')
+            cmd.append(self.shell)
+
+        if self.login_class is not None:
+            cmd.append('-L')
+            cmd.append(self.login_class)
+
+        if self.password is not None and info[1] != self.password:
+            cmd.append('-p')
+            cmd.append(self.password)
+
+        # skip if no changes to be made
+        if len(cmd) == 1:
+            return (None, '', '')
+        elif self.module.check_mode:
+            return (0, '', '')
+
+        cmd.append(self.name)
+        return self.execute_command(cmd)
+
+
+# ===========================================
+
 class SunOS(User):
     """
     This is a SunOS User manipulation class - The main difference between
@@ -1024,6 +1339,7 @@ def main():
             home=dict(default=None, type='str'),
             shell=dict(default=None, type='str'),
             password=dict(default=None, type='str'),
+            login_class=dict(default=None, type='str'),
             # following options are specific to userdel
             force=dict(default='no', type='bool'),
             remove=dict(default='no', type='bool'),