summaryrefslogtreecommitdiff
path: root/lib/chef/win32/security/securable_object.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/win32/security/securable_object.rb')
-rw-r--r--lib/chef/win32/security/securable_object.rb109
1 files changed, 109 insertions, 0 deletions
diff --git a/lib/chef/win32/security/securable_object.rb b/lib/chef/win32/security/securable_object.rb
new file mode 100644
index 0000000000..00655c9bab
--- /dev/null
+++ b/lib/chef/win32/security/securable_object.rb
@@ -0,0 +1,109 @@
+#
+# Author:: John Keiser (<jkeiser@opscode.com>)
+# Copyright:: Copyright 2011 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/win32/security'
+require 'chef/win32/security/acl'
+require 'chef/win32/security/sid'
+
+class Chef
+ module ReservedNames::Win32
+ class Security
+ class SecurableObject
+
+ def initialize(path, type = :SE_FILE_OBJECT)
+ @path = path
+ @type = type
+ end
+
+ attr_reader :path
+ attr_reader :type
+
+ SecurityConst = Chef::ReservedNames::Win32::API::Security
+
+ # This method predicts what the rights mask would be on an object
+ # if you created an ACE with the given mask. Specifically, it looks for
+ # generic attributes like GENERIC_READ, and figures out what specific
+ # attributes will be set. This is important if you want to try to
+ # compare an existing ACE with one you want to create.
+ def predict_rights_mask(generic_mask)
+ mask = generic_mask
+ #mask |= Chef::ReservedNames::Win32::API::Security::STANDARD_RIGHTS_READ if (mask | Chef::ReservedNames::Win32::API::Security::GENERIC_READ) != 0
+ #mask |= Chef::ReservedNames::Win32::API::Security::STANDARD_RIGHTS_WRITE if (mask | Chef::ReservedNames::Win32::API::Security::GENERIC_WRITE) != 0
+ #mask |= Chef::ReservedNames::Win32::API::Security::STANDARD_RIGHTS_EXECUTE if (mask | Chef::ReservedNames::Win32::API::Security::GENERIC_EXECUTE) != 0
+ #mask |= Chef::ReservedNames::Win32::API::Security::STANDARD_RIGHTS_ALL if (mask | Chef::ReservedNames::Win32::API::Security::GENERIC_ALL) != 0
+ if type == :SE_FILE_OBJECT
+ mask |= Chef::ReservedNames::Win32::API::Security::FILE_GENERIC_READ if (mask & Chef::ReservedNames::Win32::API::Security::GENERIC_READ) != 0
+ mask |= Chef::ReservedNames::Win32::API::Security::FILE_GENERIC_WRITE if (mask & Chef::ReservedNames::Win32::API::Security::GENERIC_WRITE) != 0
+ mask |= Chef::ReservedNames::Win32::API::Security::FILE_GENERIC_EXECUTE if (mask & Chef::ReservedNames::Win32::API::Security::GENERIC_EXECUTE) != 0
+ mask |= Chef::ReservedNames::Win32::API::Security::FILE_ALL_ACCESS if (mask & Chef::ReservedNames::Win32::API::Security::GENERIC_ALL) != 0
+ else
+ raise "Unimplemented object type for predict_security_mask: #{type}"
+ end
+ mask &= ~(Chef::ReservedNames::Win32::API::Security::GENERIC_READ | Chef::ReservedNames::Win32::API::Security::GENERIC_WRITE | Chef::ReservedNames::Win32::API::Security::GENERIC_EXECUTE | Chef::ReservedNames::Win32::API::Security::GENERIC_ALL)
+ mask
+ end
+
+ def security_descriptor(include_sacl = false)
+ security_information = Chef::ReservedNames::Win32::API::Security::OWNER_SECURITY_INFORMATION | Chef::ReservedNames::Win32::API::Security::GROUP_SECURITY_INFORMATION | Chef::ReservedNames::Win32::API::Security::DACL_SECURITY_INFORMATION
+ if include_sacl
+ security_information |= Chef::ReservedNames::Win32::API::Security::SACL_SECURITY_INFORMATION
+ Security.with_privileges("SeSecurityPrivilege") do
+ Security.get_named_security_info(path, type, security_information)
+ end
+ else
+ Security.get_named_security_info(path, type, security_information)
+ end
+ end
+
+ def dacl=(val)
+ Security.set_named_security_info(path, type, :dacl => val)
+ end
+
+ # You don't set dacl_inherits without also setting dacl,
+ # because Windows gets angry and denies you access. So
+ # if you want to do that, you may as well do both at once.
+ def set_dacl(dacl, dacl_inherits)
+ Security.set_named_security_info(path, type, :dacl => dacl, :dacl_inherits => dacl_inherits)
+ end
+
+ def group=(val)
+ Security.set_named_security_info(path, type, :group => val)
+ end
+
+ def owner=(val)
+ # TODO to fix serious permissions problems, we may need to enable SeBackupPrivilege. But we might need it (almost) everywhere else, too.
+ Security.with_privileges("SeTakeOwnershipPrivilege", "SeRestorePrivilege") do
+ Security.set_named_security_info(path, type, :owner => val)
+ end
+ end
+
+ def sacl=(val)
+ Security.with_privileges("SeSecurityPrivilege") do
+ Security.set_named_security_info(path, type, :sacl => val)
+ end
+ end
+
+ def set_sacl(sacl, sacl_inherits)
+ Security.with_privileges("SeSecurityPrivilege") do
+ Security.set_named_security_info(path, type, :sacl => sacl, :sacl_inherits => sacl_inherits)
+ end
+ end
+ end
+ end
+ end
+end