This file is indexed.

/usr/share/pcsd/permissions.rb is in pcs 0.9.149-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
require 'orderedhash'

module Permissions

  TYPE_USER = 'user'
  TYPE_GROUP = 'group'

  READ = 'read'
  WRITE = 'write'
  GRANT = 'grant'
  FULL = 'full'

  def self.get_user_types()
    return [
      {
        'code' => TYPE_USER,
        'label' => 'User',
        'description' => '',
      },
      {
        'code' => TYPE_GROUP,
        'label' => 'Group',
        'description' => '',
      }
    ]
  end

  def self.get_permission_types()
    return [
      {
        'code' => READ,
        'label' => 'Read',
        'description' => 'Allows to view cluster settings',
      },
      {
        'code' => WRITE,
        'label' => 'Write',
        'description' => 'Allows to modify cluster settings except permissions and ACLs',
      },
      {
        'code' => GRANT,
        'label' => 'Grant',
        'description' => 'Allows to modify cluster permissions and ACLs',
      },
      {
        'code' => FULL,
        'label' => 'Full',
        'description' => ('Allows unrestricted access to a cluster including '\
          + 'adding and removing nodes and access to keys and certificates'),
      }
    ]
  end

  def self.is_user_type(type)
    return [TYPE_USER, TYPE_GROUP].include?(type)
  end

  def self.is_permission_type(permission)
    return [READ, WRITE, GRANT, FULL].include?(permission)
  end

  def self.permissions_dependencies()
    return {
      'also_allows' => {
        WRITE => [READ],
        FULL => [READ, WRITE, GRANT],
      },
    }
  end

  class EntityPermissions
    attr_reader :type, :name, :allow_list

    def initialize(type, name, allow_list)
      # possibility to add deny_list
      @type = type
      @name = name
      @allow_list = allow_list.uniq
    end

    def applies_to(type, name)
      return (type == @type and name == @name)
    end

    def allows?(action)
      # - possibility to extend to more elaborate evaluation
      #   e.g. "read" allows both "read_nodes" and "read_resources"
      # - possibility to add deny_list
      if @allow_list.include?(action)
        return true
      else
        deps = Permissions.permissions_dependencies()
        deps['also_allows'].each { |new_action, also_allows|
          if also_allows.include?(action) and @allow_list.include?(new_action)
            return true
          end
        }
      end
      return false
    end

    def merge!(other)
      @allow_list = (@allow_list + other.allow_list).uniq
    end

    def to_hash()
      perm_hash = OrderedHash.new
      perm_hash['type'] = @type
      perm_hash['name'] = @name
      perm_hash['allow'] = @allow_list.uniq.sort
      return perm_hash
    end
  end

  class PermissionsSet
    def initialize(entity_permissions_list)
      @permissions = {
        TYPE_USER => {},
        TYPE_GROUP => {},
      }
      entity_permissions_list.each{ |perm|
        if not @permissions.key?(perm.type)
          @permissions[perm.type] = {}
        end
        if @permissions[perm.type][perm.name]
          @permissions[perm.type][perm.name].merge!(perm)
        else
          @permissions[perm.type][perm.name] = perm
        end
      }
    end

    def entity_permissions_list()
      return @permissions.values.collect { |perm| perm.values }.flatten
    end

    def to_hash()
      perm_set = []
      entity_permissions_list.each { |perm|
        perm_set << perm.to_hash()
      }
      return perm_set.sort { |a, b|
        a['type'] == b['type'] ? a['name'] <=> b['name'] : a['type'] <=> b['type']
      }
    end

    def allows?(username, groups, action)
      $logger.debug(
        "permission check action=#{action} username=#{username} groups=#{groups.join(' ')}"
      )

      if ::SUPERUSER == username
        $logger.debug('permission granted for superuser')
        return true
      end

      if @permissions[TYPE_USER].key?(username)
        if @permissions[TYPE_USER][username].allows?(action)
          $logger.debug("permission granted for user #{username}")
          return true
        end
      end

      groups.each { |group|
        if (
          @permissions[TYPE_GROUP].key?(group)\
          and\
          @permissions[TYPE_GROUP][group].allows?(action)
        )
          $logger.debug("permission granted for group #{group}")
          return true
        end
      }

      $logger.debug('permission denied')
      return false
    end
  end

end