summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/file/posix.rb
blob: 43b745d372c3c15e3785f2e4f854ad68d84a6ef0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
Puppet::Type.type(:file).provide :posix do
    desc "Uses POSIX functionality to manage file's users and rights."

    confine :feature => :posix

    include Puppet::Util::POSIX
    include Puppet::Util::Warnings

    require 'etc'

    def id2name(id)
        return id.to_s if id.is_a?(Symbol)
        return nil if id > Puppet[:maximum_uid].to_i

        begin
            user = Etc.getpwuid(id)
        rescue TypeError
            return nil
        rescue ArgumentError
            return nil
        end

        if user.uid == ""
            return nil
        else
            return user.name
        end
    end

    def insync?(current, should)
        return true unless should

        should.each do |value|
            if value =~ /^\d+$/
                uid = Integer(value)
            elsif value.is_a?(String)
                fail "Could not find user %s" % value unless uid = uid(value)
            else
                uid = value
            end

            return true if uid == current
        end

        unless Puppet.features.root?
            warnonce "Cannot manage ownership unless running as root"
            return true
        end

        return false
    end

    # Determine if the user is valid, and if so, return the UID
    def validuser?(value)
        begin
            number = Integer(value)
            return number
        rescue ArgumentError
            number = nil
        end
        if number = uid(value)
            return number
        else
            return false
        end
    end
    
    def retrieve(resource)
        unless stat = resource.stat(false)
            return :absent
        end

        currentvalue = stat.uid

        # On OS X, files that are owned by -2 get returned as really
        # large UIDs instead of negative ones.  This isn't a Ruby bug,
        # it's an OS X bug, since it shows up in perl, too.
        if currentvalue > Puppet[:maximum_uid].to_i
            self.warning "Apparently using negative UID (%s) on a platform that does not consistently handle them" % currentvalue
            currentvalue = :silly
        end

        return currentvalue
    end
    
    def sync(path, links, should)
        # Set our method appropriately, depending on links.
        if links == :manage
            method = :lchown
        else
            method = :chown
        end

        uid = nil
        should.each do |user|
            break if uid = validuser?(user)
        end

        raise Puppet::Error, "Could not find user(s) %s" % should.join(",") unless uid

        begin
            File.send(method, uid, nil, path)
        rescue => detail
            raise Puppet::Error, "Failed to set owner to '%s': %s" % [uid, detail]
        end

        return :file_changed
    end
end