summaryrefslogtreecommitdiff
path: root/lib/chef/provider/group
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/provider/group')
-rw-r--r--lib/chef/provider/group/aix.rb70
-rw-r--r--lib/chef/provider/group/dscl.rb129
-rw-r--r--lib/chef/provider/group/gpasswd.rb65
-rw-r--r--lib/chef/provider/group/groupadd.rb96
-rw-r--r--lib/chef/provider/group/groupmod.rb120
-rw-r--r--lib/chef/provider/group/pw.rb93
-rw-r--r--lib/chef/provider/group/suse.rb60
-rw-r--r--lib/chef/provider/group/usermod.rb68
-rw-r--r--lib/chef/provider/group/windows.rb79
9 files changed, 780 insertions, 0 deletions
diff --git a/lib/chef/provider/group/aix.rb b/lib/chef/provider/group/aix.rb
new file mode 100644
index 0000000000..9dedef351a
--- /dev/null
+++ b/lib/chef/provider/group/aix.rb
@@ -0,0 +1,70 @@
+#
+# Author:: Doug MacEachern (<dougm@vmware.com>)
+# Copyright:: Copyright (c) 2010 VMware, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/group/usermod'
+
+class Chef
+ class Provider
+ class Group
+ class Aix < Chef::Provider::Group::Usermod
+
+ def required_binaries
+ [ "/usr/bin/mkgroup",
+ "/usr/bin/chgroup",
+ "/usr/sbin/rmgroup" ]
+ end
+
+ def create_group
+ command = "mkgroup"
+ command << set_options << " #{@new_resource.group_name}"
+ run_command(:command => command)
+ modify_group_members
+ end
+
+ def manage_group
+ command = "chgroup"
+ options = set_options
+ #Usage: chgroup [-R load_module] "attr=value" ... group
+ if options.size > 0
+ command << options << " #{@new_resource.group_name}"
+ run_command(:command => command)
+ end
+ modify_group_members
+ end
+
+ def remove_group
+ run_command(:command => "rmgroup #{@new_resource.group_name}")
+ end
+
+ def set_options
+ opts = ""
+ { :gid => "id" }.sort { |a,b| a[0] <=> b[0] }.each do |field, option|
+ if @current_resource.send(field) != @new_resource.send(field)
+ if @new_resource.send(field)
+ Chef::Log.debug("#{@new_resource} setting #{field.to_s} to #{@new_resource.send(field)}")
+ opts << " '#{option}=#{@new_resource.send(field)}'"
+ end
+ end
+ end
+ opts
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/group/dscl.rb b/lib/chef/provider/group/dscl.rb
new file mode 100644
index 0000000000..a8ba32641c
--- /dev/null
+++ b/lib/chef/provider/group/dscl.rb
@@ -0,0 +1,129 @@
+#
+# Author:: Dreamcat4 (<dreamcat4@gmail.com>)
+# Copyright:: Copyright (c) 2009 OpsCode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Provider
+ class Group
+ class Dscl < Chef::Provider::Group
+
+ def dscl(*args)
+ host = "."
+ stdout_result = ""; stderr_result = ""; cmd = "dscl #{host} -#{args.join(' ')}"
+ status = popen4(cmd) do |pid, stdin, stdout, stderr|
+ stdout.each { |line| stdout_result << line }
+ stderr.each { |line| stderr_result << line }
+ end
+ return [cmd, status, stdout_result, stderr_result]
+ end
+
+ def safe_dscl(*args)
+ result = dscl(*args)
+ return "" if ( args.first =~ /^delete/ ) && ( result[1].exitstatus != 0 )
+ raise(Chef::Exceptions::Group,"dscl error: #{result.inspect}") unless result[1].exitstatus == 0
+ raise(Chef::Exceptions::Group,"dscl error: #{result.inspect}") if result[2] =~ /No such key: /
+ return result[2]
+ end
+
+ # This is handled in providers/group.rb by Etc.getgrnam()
+ # def group_exists?(group)
+ # groups = safe_dscl("list /Groups")
+ # !! ( groups =~ Regexp.new("\n#{group}\n") )
+ # end
+
+ # get a free GID greater than 200
+ def get_free_gid(search_limit=1000)
+ gid = nil; next_gid_guess = 200
+ groups_gids = safe_dscl("list /Groups gid")
+ while(next_gid_guess < search_limit + 200)
+ if groups_gids =~ Regexp.new("#{Regexp.escape(next_gid_guess.to_s)}\n")
+ next_gid_guess += 1
+ else
+ gid = next_gid_guess
+ break
+ end
+ end
+ return gid || raise("gid not found. Exhausted. Searched #{search_limit} times")
+ end
+
+ def gid_used?(gid)
+ return false unless gid
+ groups_gids = safe_dscl("list /Groups gid")
+ !! ( groups_gids =~ Regexp.new("#{Regexp.escape(gid.to_s)}\n") )
+ end
+
+ def set_gid
+ @new_resource.gid(get_free_gid) if [nil,""].include? @new_resource.gid
+ raise(Chef::Exceptions::Group,"gid is already in use") if gid_used?(@new_resource.gid)
+ safe_dscl("create /Groups/#{@new_resource.group_name} PrimaryGroupID #{@new_resource.gid}")
+ end
+
+ def set_members
+ unless @new_resource.append
+ Chef::Log.debug("#{@new_resource} removing group members #{@current_resource.members.join(' ')}") unless @current_resource.members.empty?
+ safe_dscl("create /Groups/#{@new_resource.group_name} GroupMembers ''") # clear guid list
+ safe_dscl("create /Groups/#{@new_resource.group_name} GroupMembership ''") # clear user list
+ end
+ unless @new_resource.members.empty?
+ Chef::Log.debug("#{@new_resource} setting group members #{@new_resource.members.join(', ')}")
+ safe_dscl("append /Groups/#{@new_resource.group_name} GroupMembership #{@new_resource.members.join(' ')}")
+ end
+ end
+
+ def define_resource_requirements
+ super
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/bin/dscl") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/dscl for #{@new_resource.name}"
+ # No whyrun alternative: this component should be available in the base install of any given system that uses it
+ end
+ end
+
+ def load_current_resource
+ super
+ end
+
+ def create_group
+ dscl_create_group
+ set_gid
+ set_members
+ end
+
+ def manage_group
+ if @new_resource.group_name && (@current_resource.group_name != @new_resource.group_name)
+ dscl_create_group
+ end
+ if @new_resource.gid && (@current_resource.gid != @new_resource.gid)
+ set_gid
+ end
+ if @new_resource.members && (@current_resource.members != @new_resource.members)
+ set_members
+ end
+ end
+
+ def dscl_create_group
+ safe_dscl("create /Groups/#{@new_resource.group_name}")
+ safe_dscl("create /Groups/#{@new_resource.group_name} Password '*'")
+ end
+
+ def remove_group
+ safe_dscl("delete /Groups/#{@new_resource.group_name}")
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/group/gpasswd.rb b/lib/chef/provider/group/gpasswd.rb
new file mode 100644
index 0000000000..7fb27a7777
--- /dev/null
+++ b/lib/chef/provider/group/gpasswd.rb
@@ -0,0 +1,65 @@
+#
+# Author:: AJ Christensen (<aj@opscode.com>)
+# Copyright:: Copyright (c) 2008 OpsCode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/group/groupadd'
+require 'chef/mixin/shell_out'
+
+class Chef
+ class Provider
+ class Group
+ class Gpasswd < Chef::Provider::Group::Groupadd
+
+ include Chef::Mixin::ShellOut
+
+ def load_current_resource
+ super
+ end
+
+ def define_resource_requirements
+ super
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/bin/gpasswd") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/bin/gpasswd for #{@new_resource}"
+ # No whyrun alternative: this component should be available in the base install of any given system that uses it
+ end
+ end
+
+ def modify_group_members
+ if(@new_resource.append)
+ unless @new_resource.members.empty?
+ @new_resource.members.each do |member|
+ Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
+ shell_out!("gpasswd -a #{member} #{@new_resource.group_name}")
+ end
+ else
+ Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add")
+ end
+ else
+ unless @new_resource.members.empty?
+ Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
+ shell_out!("gpasswd -M #{@new_resource.members.join(',')} #{@new_resource.group_name}")
+ else
+ Chef::Log.debug("#{@new_resource} setting group members to: none")
+ shell_out!("gpasswd -M \"\" #{@new_resource.group_name}")
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/group/groupadd.rb b/lib/chef/provider/group/groupadd.rb
new file mode 100644
index 0000000000..544fee4304
--- /dev/null
+++ b/lib/chef/provider/group/groupadd.rb
@@ -0,0 +1,96 @@
+#
+# Author:: AJ Christensen (<aj@opscode.com>)
+# Copyright:: Copyright (c) 2008 OpsCode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Provider
+ class Group
+ class Groupadd < Chef::Provider::Group
+
+ def required_binaries
+ [ "/usr/sbin/groupadd",
+ "/usr/sbin/groupmod",
+ "/usr/sbin/groupdel" ]
+ end
+
+ def load_current_resource
+ super
+ end
+
+ def define_resource_requirements
+ super
+ required_binaries.each do |required_binary|
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?(required_binary) }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary #{required_binary} for #{@new_resource}"
+ # No whyrun alternative: this component should be available in the base install of any given system that uses it
+ end
+ end
+ end
+
+ # Create the group
+ def create_group
+ command = "groupadd"
+ command << set_options
+ command << groupadd_options
+ run_command(:command => command)
+ modify_group_members
+ end
+
+ # Manage the group when it already exists
+ def manage_group
+ command = "groupmod"
+ command << set_options
+ run_command(:command => command)
+ modify_group_members
+ end
+
+ # Remove the group
+ def remove_group
+ run_command(:command => "groupdel #{@new_resource.group_name}")
+ end
+
+ def modify_group_members
+ raise Chef::Exceptions::Group, "you must override modify_group_members in #{self.to_s}"
+ end
+ # Little bit of magic as per Adam's useradd provider to pull the assign the command line flags
+ #
+ # ==== Returns
+ # <string>:: A string containing the option and then the quoted value
+ def set_options
+ opts = ""
+ { :gid => "-g" }.sort { |a,b| a[0] <=> b[0] }.each do |field, option|
+ if @current_resource.send(field) != @new_resource.send(field)
+ if @new_resource.send(field)
+ opts << " #{option} '#{@new_resource.send(field)}'"
+ Chef::Log.debug("#{@new_resource} set #{field.to_s} to #{@new_resource.send(field)}")
+ end
+ end
+ end
+ opts << " #{@new_resource.group_name}"
+ end
+
+ def groupadd_options
+ opts = ''
+ opts << " -r" if @new_resource.system
+ opts
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/group/groupmod.rb b/lib/chef/provider/group/groupmod.rb
new file mode 100644
index 0000000000..10fc680d78
--- /dev/null
+++ b/lib/chef/provider/group/groupmod.rb
@@ -0,0 +1,120 @@
+#
+# Author:: Dan Crosta (<dcrosta@late.am>)
+# Copyright:: Copyright (c) 2012 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/mixin/shell_out'
+
+class Chef
+ class Provider
+ class Group
+ class Groupmod < Chef::Provider::Group
+
+ include Chef::Mixin::ShellOut
+
+ def load_current_resource
+ super
+ [ "group", "user" ].each do |binary|
+ raise Chef::Exceptions::Group, "Could not find binary /usr/sbin/#{binary} for #{@new_resource}" unless ::File.exists?("/usr/sbin/#{binary}")
+ end
+ end
+
+ # Create the group
+ def create_group
+ command = "group add"
+ command << set_options
+ shell_out!(command)
+
+ add_group_members(@new_resource.members)
+ end
+
+ # Manage the group when it already exists
+ def manage_group
+ if @new_resource.append
+ to_add = @new_resource.members.dup
+ to_add.reject! { |user| @current_resource.members.include?(user) }
+
+ to_delete = Array.new
+
+ Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add") if to_add.empty?
+ else
+ to_add = @new_resource.members.dup
+ to_add.reject! { |user| @current_resource.members.include?(user) }
+
+ to_delete = @current_resource.members.dup
+ to_delete.reject! { |user| @new_resource.members.include?(user) }
+
+ Chef::Log.debug("#{@new_resource} setting group members to: none") if @new_resource.members.empty?
+ end
+
+ if to_delete.empty?
+ # If we are only adding new members to this group, then
+ # call add_group_members with only those users
+ add_group_members(to_add)
+ else
+ Chef::Log.debug("#{@new_resource} removing members #{to_delete.join(', ')}")
+
+ # This is tricky, but works: rename the existing group to
+ # "<name>_bak", create a new group with the same GID and
+ # "<name>", then set correct members on that group
+ rename = "group mod -n #{@new_resource.group_name}_bak #{@new_resource.group_name}"
+ shell_out!(rename)
+
+ create = "group add"
+ create << set_options(:overwrite_gid => true)
+ shell_out!(create)
+
+ # Ignore to_add here, since we're replacing the group we
+ # have to add all members who should be in the group.
+ add_group_members(@new_resource.members)
+
+ remove = "group del #{@new_resource.group_name}_bak"
+ shell_out!(remove)
+ end
+ end
+
+ # Remove the group
+ def remove_group
+ shell_out!("group del #{@new_resource.group_name}")
+ end
+
+ # Adds a list of usernames to the group using `user mod`
+ def add_group_members(members)
+ Chef::Log.debug("#{@new_resource} adding members #{members.join(', ')}") if !members.empty?
+ members.each do |user|
+ shell_out!("user mod -G #{@new_resource.group_name} #{user}")
+ end
+ end
+
+ # Little bit of magic as per Adam's useradd provider to pull and assign the command line flags
+ #
+ # ==== Returns
+ # <string>:: A string containing the option and then the quoted value
+ def set_options(overwrite_gid=false)
+ opts = ""
+ if overwrite_gid || @new_resource.gid && (@current_resource.gid != @new_resource.gid)
+ opts << " -g '#{@new_resource.gid}'"
+ end
+ if overwrite_gid
+ opts << " -o"
+ end
+ opts << " #{@new_resource.group_name}"
+ opts
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/group/pw.rb b/lib/chef/provider/group/pw.rb
new file mode 100644
index 0000000000..3bf67a515a
--- /dev/null
+++ b/lib/chef/provider/group/pw.rb
@@ -0,0 +1,93 @@
+#
+# Author:: Stephen Haynes (<sh@nomitor.com>)
+# Copyright:: Copyright (c) 2009 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+class Chef
+ class Provider
+ class Group
+ class Pw < Chef::Provider::Group
+
+ def load_current_resource
+ super
+ end
+
+ def define_resource_requirements
+ super
+
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/sbin/pw") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/pw for #{@new_resource}"
+ # No whyrun alternative: this component should be available in the base install of any given system that uses it
+ end
+ end
+
+ # Create the group
+ def create_group
+ command = "pw groupadd"
+ command << set_options
+ command << set_members_option
+ run_command(:command => command)
+ end
+
+ # Manage the group when it already exists
+ def manage_group
+ command = "pw groupmod"
+ command << set_options
+ command << set_members_option
+ run_command(:command => command)
+ end
+
+ # Remove the group
+ def remove_group
+ run_command(:command => "pw groupdel #{@new_resource.group_name}")
+ end
+
+ # Little bit of magic as per Adam's useradd provider to pull and assign the command line flags
+ #
+ # ==== Returns
+ # <string>:: A string containing the option and then the quoted value
+ def set_options
+ opts = " #{@new_resource.group_name}"
+ if @new_resource.gid && (@current_resource.gid != @new_resource.gid)
+ Chef::Log.debug("#{@new_resource}: current gid (#{@current_resource.gid}) doesnt match target gid (#{@new_resource.gid}), changing it")
+ opts << " -g '#{@new_resource.gid}'"
+ end
+ opts
+ end
+
+ # Set the membership option depending on the current resource states
+ def set_members_option
+ opt = ""
+ unless @new_resource.members.empty?
+ opt << " -M #{@new_resource.members.join(',')}"
+ Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
+ else
+ # New member list is empty so we should delete any old group members
+ unless @current_resource.members.empty?
+ opt << " -d #{@current_resource.members.join(',')}"
+ Chef::Log.debug("#{@new_resource} removing group members #{@current_resource.members.join(', ')}")
+ else
+ Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
+ end
+ end
+ opt
+ end
+
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/group/suse.rb b/lib/chef/provider/group/suse.rb
new file mode 100644
index 0000000000..0b66c1f912
--- /dev/null
+++ b/lib/chef/provider/group/suse.rb
@@ -0,0 +1,60 @@
+#
+# Author:: AJ Christensen (<aj@opscode.com>)
+# Copyright:: Copyright (c) 2008 OpsCode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/group/groupadd'
+require 'chef/mixin/shell_out'
+
+class Chef
+ class Provider
+ class Group
+ class Suse < Chef::Provider::Group::Groupadd
+
+ include Chef::Mixin::ShellOut
+
+ def load_current_resource
+ super
+ end
+
+ def define_resource_requirements
+ super
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/sbin/groupmod") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/groupmod for #{@new_resource.name}"
+ # No whyrun alternative: this component should be available in the base install of any given system that uses it
+ end
+ end
+
+ def modify_group_members
+ unless @new_resource.members.empty?
+ if(@new_resource.append)
+ @new_resource.members.each do |member|
+ Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
+ shell_out!("groupmod -A #{member} #{@new_resource.group_name}")
+ end
+ else
+ Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
+ shell_out!("groupmod -A #{@new_resource.members.join(',')} #{@new_resource.group_name}")
+ end
+ else
+ Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/group/usermod.rb b/lib/chef/provider/group/usermod.rb
new file mode 100644
index 0000000000..f0a9282831
--- /dev/null
+++ b/lib/chef/provider/group/usermod.rb
@@ -0,0 +1,68 @@
+#
+# Author:: AJ Christensen (<aj@opscode.com>)
+# Copyright:: Copyright (c) 2008 OpsCode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/group/groupadd'
+
+class Chef
+ class Provider
+ class Group
+ class Usermod < Chef::Provider::Group::Groupadd
+
+ def load_current_resource
+ super
+ end
+
+ def define_resource_requirements
+ super
+
+ requirements.assert(:all_actions) do |a|
+ a.assertion { ::File.exists?("/usr/sbin/usermod") }
+ a.failure_message Chef::Exceptions::Group, "Could not find binary /usr/sbin/usermod for #{@new_resource}"
+ # No whyrun alternative: this component should be available in the base install of any given system that uses it
+ end
+
+ requirements.assert(:modify, :create) do |a|
+ a.assertion { @new_resource.members.empty? || @new_resource.append }
+ a.failure_message Chef::Exceptions::Group, "setting group members directly is not supported by #{self.to_s}, must set append true in group"
+ # No whyrun alternative - this action is simply not supported.
+ end
+ end
+
+ def modify_group_members
+ case node[:platform]
+ when "openbsd", "netbsd", "aix", "solaris2"
+ append_flags = "-G"
+ when "solaris"
+ append_flags = "-a -G"
+ end
+
+ unless @new_resource.members.empty?
+ if(@new_resource.append)
+ @new_resource.members.each do |member|
+ Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
+ run_command(:command => "usermod #{append_flags} #{@new_resource.group_name} #{member}" )
+ end
+ end
+ else
+ Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/provider/group/windows.rb b/lib/chef/provider/group/windows.rb
new file mode 100644
index 0000000000..88280408cd
--- /dev/null
+++ b/lib/chef/provider/group/windows.rb
@@ -0,0 +1,79 @@
+#
+# Author:: Doug MacEachern (<dougm@vmware.com>)
+# Copyright:: Copyright (c) 2010 VMware, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/provider/user'
+if RUBY_PLATFORM =~ /mswin|mingw32|windows/
+ require 'chef/util/windows/net_group'
+end
+
+class Chef
+ class Provider
+ class Group
+ class Windows < Chef::Provider::Group
+
+ def initialize(new_resource,run_context)
+ super
+ @net_group = Chef::Util::Windows::NetGroup.new(@new_resource.name)
+ end
+
+ def load_current_resource
+ @current_resource = Chef::Resource::Group.new(@new_resource.name)
+ @current_resource.group_name(@new_resource.group_name)
+
+ members = nil
+ begin
+ members = @net_group.local_get_members
+ rescue => e
+ @group_exists = false
+ Chef::Log.debug("#{@new_resource} group does not exist")
+ end
+
+ if members
+ @current_resource.members(members)
+ end
+
+ @current_resource
+ end
+
+ def create_group
+ @net_group.local_add
+ manage_group
+ end
+
+ def manage_group
+ if @new_resource.append
+ begin
+ #ERROR_MEMBER_IN_ALIAS if a member already exists in the group
+ @net_group.local_add_members(@new_resource.members)
+ rescue
+ members = @new_resource.members + @current_resource.members
+ @net_group.local_set_members(members.uniq)
+ end
+ else
+ @net_group.local_set_members(@new_resource.members)
+ end
+ end
+
+ def remove_group
+ @net_group.local_delete
+ end
+
+ end
+ end
+ end
+end