This file is indexed.

/usr/lib/python2.7/dist-packages/ipaserver/plugins/serverroles.py is in python-ipaserver 4.7.0~pre1+git20180411-2ubuntu2.

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
#
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
#


"""
serverroles backend
=======================================

The `serverroles` backend has access to all roles and attributes stored in
module-level lists exposed in `ipaserver/servroles.py` module. It uses these
lists to populate populate its internal stores with instances of the
roles/attributes. The information contained in them can be accessed by
the following methods:

    *api.Backend.serverroles.server_role_search(
            server_server=None, role_servrole=None status=None)
        search for roles matching the given substrings and return the status of
        the matched roles. Optionally filter the result by role status. If
        `server_erver` is not None, the search is limited to a single master.
        Otherwise, the status is computed for all masters in the topology. If
        `role_servrole` is None, the all configured roled are queried

    *api.Backend.serverroles.server_role_retrieve(server_server, role_servrole)
        retrieve the status of a single role on a given master

    *api.Backend.serverroles.config_retrieve(role_servrole)
        return a configuration object given role name. This object is a
        dictionary containing a list of enabled masters and all attributes
        associated with the role along with master(s) on which they are set.

    *api.Backend.serverroles.config_update(**attrs_values)
        update configuration object. Since server roles are currently
        immutable, only attributes can be set

Note that attribute/role names are searched/matched case-insensitively. Also
note that the `serverroles` backend does not create/destroy any LDAP connection
by itself, so make sure `ldap2` backend connections are taken care of
in the calling code
"""


import six

from ipalib import errors, _
from ipalib.backend import Backend
from ipalib.plugable import Registry
from ipaserver.servroles import (attribute_instances, ENABLED, role_instances)
from ipaserver.servroles import SingleValuedServerAttribute


if six.PY3:
    unicode = str


register = Registry()


@register()
class serverroles(Backend):
    """
    This Backend can be used to query various information about server roles
    and attributes configured in the topology.
    """

    def __init__(self, api_instance):
        super(serverroles, self).__init__(api_instance)

        self.role_names = {
            obj.name.lower(): obj for obj in role_instances}

        self.attributes = {
            attr.attr_name: attr for attr in attribute_instances}

    def _get_role(self, role_name):
        key = role_name.lower()

        try:
            return self.role_names[key]
        except KeyError:
            raise errors.NotFound(
                reason=_("{role}: role not found".format(role=role_name)))

    def _get_enabled_masters(self, role_name):
        result = {}
        role = self._get_role(role_name)

        enabled_masters = [
            r[u'server_server'] for r in role.status(self.api, server=None) if
            r[u'status'] == ENABLED]

        if enabled_masters:
            result.update({role.attr_name: enabled_masters})

        return result

    def _get_assoc_attributes(self, role_name):
        role = self._get_role(role_name)
        assoc_attributes = {
            name: attr for name, attr in self.attributes.items() if
            attr.associated_role is role}

        if not assoc_attributes:
            raise NotImplementedError(
                "Role {} has no associated attribute to set".format(role.name))

        return assoc_attributes

    def server_role_search(self, server_server=None, role_servrole=None,
                           status=None):
        if role_servrole is None:
            found_roles = self.role_names.values()
        else:
            try:
                found_roles = [self._get_role(role_servrole)]
            except errors.NotFound:
                found_roles = []

        result = []
        for found_role in found_roles:
            role_status = found_role.status(self.api, server=server_server)

            result.extend(role_status)

        if status is not None:
            return [r for r in result if r[u'status'] == status]

        return result

    def server_role_retrieve(self, server_server, role_servrole):
        return self._get_role(role_servrole).status(
            self.api, server=server_server)

    def config_retrieve(self, servrole):
        result = self._get_enabled_masters(servrole)

        try:
            assoc_attributes = self._get_assoc_attributes(servrole)
        except NotImplementedError:
            return result

        for name, attr in assoc_attributes.items():
            attr_value = attr.get(self.api)

            if attr_value:
                # attr can be a SingleValuedServerAttribute
                # in this case, the API expects a value, not a list of values
                if isinstance(attr, SingleValuedServerAttribute):
                    attr_value = attr_value[0]
                result.update({name: attr_value})

        return result

    def config_update(self, **attrs_values):
        for attr, value in attrs_values.items():
            try:
                # when the attribute is single valued, it will be stored
                # in a SingleValuedServerAttribute. The set method expects
                # a list containing a single value.
                # We need to convert value to a list containing value
                if isinstance(self.attributes[attr],
                              SingleValuedServerAttribute):
                    value = [value]
                self.attributes[attr].set(self.api, value)
            except KeyError:
                raise errors.NotFound(
                    reason=_('{attr}: no such attribute'.format(attr=attr)))