From 3f9a74387f07d6d08ec936dd39ebe9545121723b Mon Sep 17 00:00:00 2001 From: tylercloke Date: Thu, 21 Mar 2013 15:38:07 -0700 Subject: Very basics of windows file permissions reporting. Refactored ScanAccessControl to have a Unix and Windows subclass similar to FileAccessControl. Removed the special case of returning before ScanAccessControl processing in the file provider if Windows. TODO: still need to have scan_access_control/windows.rb actually find the windows file perms. --- lib/chef/provider/file.rb | 6 -- lib/chef/scan_access_control.rb | 97 +++-------------------- lib/chef/scan_access_control/unix.rb | 133 ++++++++++++++++++++++++++++++++ lib/chef/scan_access_control/windows.rb | 41 ++++++++++ 4 files changed, 185 insertions(+), 92 deletions(-) create mode 100644 lib/chef/scan_access_control/unix.rb create mode 100644 lib/chef/scan_access_control/windows.rb diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb index 91280e13b1..f26986755f 100644 --- a/lib/chef/provider/file.rb +++ b/lib/chef/provider/file.rb @@ -230,12 +230,6 @@ class Chef end end - if Chef::Platform.windows? - # TODO: To work around CHEF-3554, add support for Windows - # equivalent, or implicit resource reporting won't work for - # Windows. - return - end acl_scanner = ScanAccessControl.new(@new_resource, resource) acl_scanner.set_all! end diff --git a/lib/chef/scan_access_control.rb b/lib/chef/scan_access_control.rb index 1384656a8b..95c82753a8 100644 --- a/lib/chef/scan_access_control.rb +++ b/lib/chef/scan_access_control.rb @@ -1,6 +1,6 @@ -#-- -# Author:: Daniel DeLeo () -# Copyright:: Copyright (c) 2012 Opscode, Inc. +# +# Author:: Tyler Cloke () +# Copyright:: Copyright (c) 2008, 2010 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -34,8 +34,14 @@ class Chef # progress towards the end goal. # # TODO: figure out if all this works with OS X's negative uids - # TODO: windows class ScanAccessControl + if Chef::Platform.windows? + require 'chef/scan_access_control/windows.rb' + include ScanAccessControl::Windows + else + require 'chef/scan_access_control/unix.rb' + include ScanAccessControl::Unix + end attr_reader :new_resource attr_reader :current_resource @@ -44,90 +50,9 @@ class Chef @new_resource, @current_resource = new_resource, current_resource end - # Modifies @current_resource, setting the current access control state. + # must be overrode by children unix.rb and windows.rb def set_all! - if ::File.exist?(new_resource.path) - set_owner - set_group - set_mode - else - # leave the values as nil. - end - end - - # Set the owner attribute of +current_resource+ to whatever the current - # state is. Attempts to match the format given in new_resource: if the - # new_resource specifies the owner as a string, the username for the uid - # will be looked up and owner will be set to the username, and vice versa. - def set_owner - @current_resource.owner(current_owner) - end - - def current_owner - case new_resource.owner - when String, nil - lookup_uid - when Integer - stat.uid - else - Chef::Log.error("The `owner` parameter of the #@new_resource resource is set to an invalid value (#{new_resource.owner.inspect})") - raise ArgumentError, "cannot resolve #{new_resource.owner.inspect} to uid, owner must be a string or integer" - end - end - - def lookup_uid - unless (pwent = Etc.getpwuid(stat.uid)).nil? - pwent.name - else - stat.uid - end - rescue ArgumentError - stat.uid - end - - # Set the group attribute of +current_resource+ to whatever the current state is. - def set_group - @current_resource.group(current_group) end - def current_group - case new_resource.group - when String, nil - lookup_gid - when Integer - stat.gid - else - Chef::Log.error("The `group` parameter of the #@new_resource resource is set to an invalid value (#{new_resource.owner.inspect})") - raise ArgumentError, "cannot resolve #{new_resource.group.inspect} to gid, group must be a string or integer" - end - end - - def lookup_gid - unless (pwent = Etc.getgrgid(stat.gid)).nil? - pwent.name - else - stat.gid - end - rescue ArgumentError - stat.gid - end - - def set_mode - @current_resource.mode(current_mode) - end - - def current_mode - case new_resource.mode - when String, Integer, nil - "0#{(stat.mode & 07777).to_s(8)}" - else - Chef::Log.error("The `mode` parameter of the #@new_resource resource is set to an invalid value (#{new_resource.mode.inspect})") - raise ArgumentError, "Invalid value #{new_resource.mode.inspect} for `mode` on resource #@new_resource" - end - end - - def stat - @stat ||= @new_resource.instance_of?(Chef::Resource::Link) ? ::File.lstat(@new_resource.path) : ::File.stat(@new_resource.path) - end end end diff --git a/lib/chef/scan_access_control/unix.rb b/lib/chef/scan_access_control/unix.rb new file mode 100644 index 0000000000..1384656a8b --- /dev/null +++ b/lib/chef/scan_access_control/unix.rb @@ -0,0 +1,133 @@ +#-- +# Author:: Daniel DeLeo () +# 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. +# + +class Chef + # == ScanAccessControl + # Reads Access Control Settings on a file and writes them out to a resource + # (should be the current_resource), attempting to match the style used by the + # new resource, that is, if users are specified with usernames in + # new_resource, then the uids from stat will be looked up and usernames will + # be added to current_resource. + # + # === Why? + # FileAccessControl objects may operate on a temporary file, in which case we + # won't know if the access control settings changed (ex: rendering a template + # with both a change in content and ownership). For auditing purposes, we + # need to record the current state of a file system entity. + #-- + # Not yet sure if this is the optimal way to solve the problem. But it's + # progress towards the end goal. + # + # TODO: figure out if all this works with OS X's negative uids + # TODO: windows + class ScanAccessControl + + attr_reader :new_resource + attr_reader :current_resource + + def initialize(new_resource, current_resource) + @new_resource, @current_resource = new_resource, current_resource + end + + # Modifies @current_resource, setting the current access control state. + def set_all! + if ::File.exist?(new_resource.path) + set_owner + set_group + set_mode + else + # leave the values as nil. + end + end + + # Set the owner attribute of +current_resource+ to whatever the current + # state is. Attempts to match the format given in new_resource: if the + # new_resource specifies the owner as a string, the username for the uid + # will be looked up and owner will be set to the username, and vice versa. + def set_owner + @current_resource.owner(current_owner) + end + + def current_owner + case new_resource.owner + when String, nil + lookup_uid + when Integer + stat.uid + else + Chef::Log.error("The `owner` parameter of the #@new_resource resource is set to an invalid value (#{new_resource.owner.inspect})") + raise ArgumentError, "cannot resolve #{new_resource.owner.inspect} to uid, owner must be a string or integer" + end + end + + def lookup_uid + unless (pwent = Etc.getpwuid(stat.uid)).nil? + pwent.name + else + stat.uid + end + rescue ArgumentError + stat.uid + end + + # Set the group attribute of +current_resource+ to whatever the current state is. + def set_group + @current_resource.group(current_group) + end + + def current_group + case new_resource.group + when String, nil + lookup_gid + when Integer + stat.gid + else + Chef::Log.error("The `group` parameter of the #@new_resource resource is set to an invalid value (#{new_resource.owner.inspect})") + raise ArgumentError, "cannot resolve #{new_resource.group.inspect} to gid, group must be a string or integer" + end + end + + def lookup_gid + unless (pwent = Etc.getgrgid(stat.gid)).nil? + pwent.name + else + stat.gid + end + rescue ArgumentError + stat.gid + end + + def set_mode + @current_resource.mode(current_mode) + end + + def current_mode + case new_resource.mode + when String, Integer, nil + "0#{(stat.mode & 07777).to_s(8)}" + else + Chef::Log.error("The `mode` parameter of the #@new_resource resource is set to an invalid value (#{new_resource.mode.inspect})") + raise ArgumentError, "Invalid value #{new_resource.mode.inspect} for `mode` on resource #@new_resource" + end + end + + def stat + @stat ||= @new_resource.instance_of?(Chef::Resource::Link) ? ::File.lstat(@new_resource.path) : ::File.stat(@new_resource.path) + end + end +end diff --git a/lib/chef/scan_access_control/windows.rb b/lib/chef/scan_access_control/windows.rb new file mode 100644 index 0000000000..be273d6069 --- /dev/null +++ b/lib/chef/scan_access_control/windows.rb @@ -0,0 +1,41 @@ +#-- +# Author:: Tyler Cloke () +# 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. +# + +class Chef + class ScanAccessControl + class Windows + + # Modifies @current_resource, setting the current ACL state. + def set_all! + if ::File.exist?(new_resource.path) + # for each person, set sid + # for each sid, set {type, access, inherited_from} + puts "new resource"*100 + puts @new_resource + puts "current resource"*100 + puts @current_resouce + else + # leave the values as nil. + end + end + + + + end + end +end -- cgit v1.2.1