~ubuntu-branches/ubuntu/lucid/puppet/lucid-security

« back to all changes in this revision

Viewing changes to lib/puppet/provider/macauthorization/macauthorization.rb

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2009-12-23 00:48:10 UTC
  • mfrom: (1.1.10 upstream) (3.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091223004810-3i4oryds922g5n59
Tags: 0.25.1-3ubuntu1
* Merge from debian testing.  Remaining changes:
  - debian/rules:
    + Don't start puppet when first installing puppet.
  - debian/puppet.conf, lib/puppet/defaults.rb:
    + Move templates to /etc/puppet
  - lib/puppet/defaults.rb:
    + Fix /var/lib/puppet/state ownership.
  - man/man8/puppet.conf.8: 
    + Fix broken URL in manpage.
  - debian/control:
    + Update maintainer accordint to spec.
    + Puppetmaster Recommends -> Suggests
    + Created puppet-testsuite as a seperate. Allow the users to run puppet's 
      testsuite.
  - tests/Rakefile: Fix rakefile so that the testsuite can acutally be ran.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 
8
8
    desc "Manage Mac OS X authorization database rules and rights.
9
9
 
10
 
  "
 
10
    "
11
11
 
12
12
    commands :security => "/usr/bin/security"
13
13
    commands :sw_vers => "/usr/bin/sw_vers"
14
 
    
 
14
 
15
15
    confine :operatingsystem => :darwin
16
 
    
 
16
 
17
17
    # This should be confined based on macosx_productversion once
18
 
    # http://projects.reductivelabs.com/issues/show/1796 
 
18
    # http://projects.reductivelabs.com/issues/show/1796
19
19
    # is resolved.
20
20
    if FileTest.exists?("/usr/bin/sw_vers")
21
21
        product_version = sw_vers "-productVersion"
22
 
    
 
22
 
23
23
        confine :true => if /^10.5/.match(product_version) or /^10.6/.match(product_version)
24
24
            true
25
25
        end
26
26
    end
27
 
       
 
27
 
28
28
    defaultfor :operatingsystem => :darwin
29
 
    
 
29
 
30
30
    AuthDB = "/etc/authorization"
31
 
    
 
31
 
32
32
    @rights = {}
33
33
    @rules = {}
34
34
    @parsed_auth_db = {}
35
35
    @comment = ""  # Not implemented yet. Is there any real need to?
36
 
    
 
36
 
37
37
    # This map exists due to the use of hyphens and reserved words in
38
38
    # the authorization schema.
39
39
    PuppetToNativeAttributeMap = {  :allow_root => "allow-root",
40
 
                                    :authenticate_user => "authenticate-user",                                    
 
40
                                    :authenticate_user => "authenticate-user",
41
41
                                    :auth_class => "class",
42
42
                                    :k_of_n => "k-of-n",
43
43
                                    :session_owner => "session-owner", }
44
 
    
 
44
 
45
45
    class << self
46
46
        attr_accessor :parsed_auth_db
47
47
        attr_accessor :rights
48
48
        attr_accessor :rules
49
49
        attr_accessor :comments  # Not implemented yet.
50
 
    
 
50
 
51
51
        def prefetch(resources)
52
52
            self.populate_rules_rights
53
53
        end
54
 
    
 
54
 
55
55
        def instances
56
56
            if self.parsed_auth_db == {}
57
57
                self.prefetch(nil)
60
60
                new(:name => k)
61
61
            end
62
62
        end
63
 
    
 
63
 
64
64
        def populate_rules_rights
65
65
            auth_plist = Plist::parse_xml(AuthDB)
66
66
            if not auth_plist
71
71
            self.parsed_auth_db = self.rights.dup
72
72
            self.parsed_auth_db.merge!(self.rules.dup)
73
73
        end
74
 
    
 
74
 
75
75
    end
76
 
    
 
76
 
77
77
    # standard required provider instance methods
78
 
    
 
78
 
79
79
    def initialize(resource)
80
80
        if self.class.parsed_auth_db == {}
81
81
            self.class.prefetch(resource)
82
82
        end
83
83
        super
84
84
    end
85
 
    
86
 
    
 
85
 
 
86
 
87
87
    def create
88
 
        # we just fill the @property_hash in here and let the flush method 
 
88
        # we just fill the @property_hash in here and let the flush method
89
89
        # deal with it rather than repeating code.
90
90
        new_values = {}
91
91
        validprops = Puppet::Type.type(resource.class.name).validproperties
109
109
            raise Puppet::Error.new("Must specify auth_type when destroying.")
110
110
        end
111
111
    end
112
 
    
 
112
 
113
113
    def exists?
114
114
        if self.class.parsed_auth_db.has_key?(resource[:name])
115
115
            return true
117
117
            return false
118
118
        end
119
119
    end
120
 
    
121
 
    
 
120
 
 
121
 
122
122
    def flush
123
123
        # deletion happens in the destroy methods
124
124
        if resource[:ensure] != :absent
133
133
            @property_hash.clear
134
134
        end
135
135
    end
136
 
    
137
 
    
 
136
 
 
137
 
138
138
    # utility methods below
139
 
    
 
139
 
140
140
    def destroy_right
141
141
        security "authorizationdb", :remove, resource[:name]
142
142
    end
143
 
    
 
143
 
144
144
    def destroy_rule
145
145
        authdb = Plist::parse_xml(AuthDB)
146
146
        authdb_rules = authdb["rules"].dup
153
153
            end
154
154
        end
155
155
    end
156
 
    
 
156
 
157
157
    def flush_right
158
 
        # first we re-read the right just to make sure we're in sync for 
159
 
        # values that weren't specified in the manifest. As we're supplying 
160
 
        # the whole plist when specifying the right it seems safest to be 
 
158
        # first we re-read the right just to make sure we're in sync for
 
159
        # values that weren't specified in the manifest. As we're supplying
 
160
        # the whole plist when specifying the right it seems safest to be
161
161
        # paranoid given the low cost of quering the db once more.
162
 
        cmds = [] 
 
162
        cmds = []
163
163
        cmds << :security << "authorizationdb" << "read" << resource[:name]
164
164
        output = execute(cmds, :combine => false)
165
165
        current_values = Plist::parse_xml(output)
168
168
        end
169
169
        specified_values = convert_plist_to_native_attributes(@property_hash)
170
170
 
171
 
        # take the current values, merge the specified values to obtain a 
 
171
        # take the current values, merge the specified values to obtain a
172
172
        # complete description of the new values.
173
173
        new_values = current_values.merge(specified_values)
174
174
        set_right(resource[:name], new_values)
175
175
    end
176
 
    
 
176
 
177
177
    def flush_rule
178
178
        authdb = Plist::parse_xml(AuthDB)
179
179
        authdb_rules = authdb["rules"].dup
185
185
        new_values = current_values.merge(specified_values)
186
186
        set_rule(resource[:name], new_values)
187
187
    end
188
 
    
 
188
 
189
189
    def set_right(name, values)
190
190
        # Both creates and modifies rights as it simply overwrites them.
191
191
        # The security binary only allows for writes using stdin, so we
194
194
        tmp = Tempfile.new('puppet_macauthorization')
195
195
        begin
196
196
            Plist::Emit.save_plist(values, tmp.path)
197
 
            cmds = [] 
 
197
            cmds = []
198
198
            cmds << :security << "authorizationdb" << "write" << name
199
199
            output = execute(cmds, :combine => false,
200
200
                             :stdinfile => tmp.path.to_s)
205
205
            tmp.unlink
206
206
        end
207
207
    end
208
 
    
 
208
 
209
209
    def set_rule(name, values)
210
 
        # Both creates and modifies rules as it overwrites the entry in the 
211
 
        # rules dictionary.  Unfortunately the security binary doesn't 
212
 
        # support modifying rules at all so we have to twiddle the whole 
 
210
        # Both creates and modifies rules as it overwrites the entry in the
 
211
        # rules dictionary.  Unfortunately the security binary doesn't
 
212
        # support modifying rules at all so we have to twiddle the whole
213
213
        # plist... :( See Apple Bug #6386000
214
214
        values = convert_plist_to_native_attributes(values)
215
215
        authdb = Plist::parse_xml(AuthDB)
221
221
            raise Puppet::Error.new("Error writing to: #{AuthDB}")
222
222
        end
223
223
    end
224
 
    
 
224
 
225
225
    def convert_plist_to_native_attributes(propertylist)
226
226
        # This mainly converts the keys from the puppet attributes to the
227
 
        # 'native' ones, but also enforces that the keys are all Strings 
228
 
        # rather than Symbols so that any merges of the resultant Hash are 
229
 
        # sane.
 
227
        # 'native' ones, but also enforces that the keys are all Strings
 
228
        # rather than Symbols so that any merges of the resultant Hash are
 
229
        # sane. The exception is booleans, where we coerce to a proper bool
 
230
        # if they come in as a symbol.
230
231
        newplist = {}
231
232
        propertylist.each_pair do |key, value|
232
233
            next if key == :ensure     # not part of the auth db schema.
233
234
            next if key == :auth_type  # not part of the auth db schema.
 
235
            case value
 
236
            when true, :true
 
237
                value = true
 
238
            when false, :false
 
239
                value = false
 
240
            end
234
241
            new_key = key
235
242
            if PuppetToNativeAttributeMap.has_key?(key)
236
243
                new_key = PuppetToNativeAttributeMap[key].to_s
241
248
        end
242
249
        newplist
243
250
    end
244
 
    
 
251
 
245
252
    def retrieve_value(resource_name, attribute)
246
 
        
 
253
        # We set boolean values to symbols when retrieving values
247
254
        if not self.class.parsed_auth_db.has_key?(resource_name)
248
255
            raise Puppet::Error.new("Cannot find #{resource_name} in auth db")
249
256
        end
250
 
       
 
257
 
251
258
        if PuppetToNativeAttributeMap.has_key?(attribute)
252
259
            native_attribute = PuppetToNativeAttributeMap[attribute]
253
260
        else
257
264
        if self.class.parsed_auth_db[resource_name].has_key?(native_attribute)
258
265
            value = self.class.parsed_auth_db[resource_name][native_attribute]
259
266
            case value
260
 
            when true, "true", :true
 
267
            when true, :true
261
268
                value = :true
262
 
            when false, "false", :false
 
269
            when false, :false
263
270
                value = :false
264
271
            end
265
272
 
270
277
            return ""  # so ralsh doesn't display it.
271
278
        end
272
279
    end
273
 
    
274
 
    
 
280
 
 
281
 
275
282
    # property methods below
276
283
    #
277
284
    # We define them all dynamically apart from auth_type which is a special
278
285
    # case due to not being in the actual authorization db schema.
279
 
    
 
286
 
280
287
    properties = [  :allow_root, :authenticate_user, :auth_class, :comment,
281
288
                    :group, :k_of_n, :mechanisms, :rule, :session_owner,
282
289
                    :shared, :timeout, :tries ]
290
297
            @property_hash[field] = value
291
298
        end
292
299
    end
293
 
    
 
300
 
294
301
    def auth_type
295
302
        if resource.should(:auth_type) != nil
296
303
            return resource.should(:auth_type)
307
314
            raise Puppet::Error.new("auth_type required for new resources.")
308
315
        end
309
316
    end
310
 
    
 
317
 
311
318
    def auth_type=(value)
312
319
        @property_hash[:auth_type] = value
313
320
    end
314
 
    
 
321
 
315
322
end