diff options
author | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 10:39:35 -0400 |
---|---|---|
committer | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 10:39:35 -0400 |
commit | 24dc69a9a97e82a6e4207de68d6dcc664178249b (patch) | |
tree | 19bb289c9f88b4bbab066bc56b95d6d222fd5c35 /lib/chef/scan_access_control.rb | |
parent | 9348c1c9c80ee757354d624b7dc1b78ebc7605c4 (diff) | |
download | chef-24dc69a9a97e82a6e4207de68d6dcc664178249b.tar.gz |
[OC-3564] move core Chef to the repo root \o/ \m/
The opscode/chef repository now only contains the core Chef library code
used by chef-client, knife and chef-solo!
Diffstat (limited to 'lib/chef/scan_access_control.rb')
-rw-r--r-- | lib/chef/scan_access_control.rb | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/lib/chef/scan_access_control.rb b/lib/chef/scan_access_control.rb new file mode 100644 index 0000000000..5863a8c7c4 --- /dev/null +++ b/lib/chef/scan_access_control.rb @@ -0,0 +1,135 @@ +#-- +# Author:: Daniel DeLeo (<dan@opscode.com>) +# 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, nil + (stat.mode & 007777).to_s(8) + when Integer + stat.mode & 007777 + 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 |