summaryrefslogtreecommitdiff
path: root/keystone/cmd/doctor/ldap.py
blob: 96e006840fbf57dcd328d9d04899c1a8f17e0aec (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
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
# 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.

from __future__ import print_function

import os
import re

import configparser

import keystone.conf


CONF = keystone.conf.CONF
CONFIG_REGEX = r'^keystone\..*?\.conf$'


def symptom_LDAP_user_enabled_emulation_dn_ignored():
    """`[ldap] user_enabled_emulation_dn` is being ignored.

    There is no reason to set this value unless `keystone.conf [ldap]
    user_enabled_emulation` is also enabled.
    """
    return (
        not CONF.ldap.user_enabled_emulation
        and CONF.ldap.user_enabled_emulation_dn is not None)


def symptom_LDAP_user_enabled_emulation_use_group_config_ignored():
    """`[ldap] user_enabled_emulation_use_group_config` is being ignored.

    There is no reason to set this value unless `keystone.conf [ldap]
    user_enabled_emulation` is also enabled.
    """
    return (
        not CONF.ldap.user_enabled_emulation
        and CONF.ldap.user_enabled_emulation_use_group_config)


def symptom_LDAP_group_members_are_ids_disabled():
    """`[ldap] group_members_are_ids` is not enabled.

    Because you've set `keystone.conf [ldap] group_objectclass = posixGroup`,
    we would have also expected you to enable set `keystone.conf [ldap]
    group_members_are_ids` because we suspect you're using Open Directory,
    which would contain user ID's in a `posixGroup` rather than LDAP DNs, as
    other object classes typically would.
    """
    return (
        CONF.ldap.group_objectclass == 'posixGroup'
        and not CONF.ldap.group_members_are_ids)


def symptom_LDAP_file_based_domain_specific_configs():
    """Domain specific driver directory is invalid or contains invalid files.

    If `keystone.conf [identity] domain_specific_drivers_enabled` is set
    to `true`, then support is enabled for individual domains to have their
    own identity drivers. The configurations for these can either be stored
    in a config file or in the database. The case we handle in this symptom
    is when they are stored in config files, which is indicated by
    `keystone.conf [identity] domain_configurations_from_database`
    being set to `false`.
    """
    if (not CONF.identity.domain_specific_drivers_enabled or
            CONF.identity.domain_configurations_from_database):
        return False

    invalid_files = []
    filedir = CONF.identity.domain_config_dir
    if os.path.isdir(filedir):
        for filename in os.listdir(filedir):
            if not re.match(CONFIG_REGEX, filename):
                invalid_files.append(filename)
        if invalid_files:
            invalid_str = ', '.join(invalid_files)
            print('Warning: The following non-config files were found: %s\n'
                  'If they are intended to be config files then rename them '
                  'to the form of `keystone.<domain_name>.conf`. '
                  'Otherwise, ignore this warning' % invalid_str)
            return True
    else:
        print('Could not find directory ', filedir)
        return True

    return False


def symptom_LDAP_file_based_domain_specific_configs_formatted_correctly():
    """LDAP domain specific configuration files are not formatted correctly.

    If `keystone.conf [identity] domain_specific_drivers_enabled` is set
    to `true`, then support is enabled for individual domains to have their
    own identity drivers. The configurations for these can either be stored
    in a config file or in the database. The case we handle in this symptom
    is when they are stored in config files, which is indicated by
    `keystone.conf [identity] domain_configurations_from_database`
    being set to false. The config files located in the directory specified
    by `keystone.conf [identity] domain_config_dir` should be in the
    form of `keystone.<domain_name>.conf` and their contents should look
    something like this:

    [ldap]
    url = ldap://ldapservice.thecustomer.com
    query_scope = sub

    user_tree_dn = ou=Users,dc=openstack,dc=org
    user_objectclass = MyOrgPerson
    user_id_attribute = uid
    ...
    """
    filedir = CONF.identity.domain_config_dir
    # NOTE(gagehugo): If domain_specific_drivers_enabled = false or
    # the value set in domain_config_dir is nonexistent/invalid, then
    # there is no point in continuing with this check.
    # symptom_LDAP_file_based_domain_specific_config will catch and
    # report this issue.
    if (not CONF.identity.domain_specific_drivers_enabled or
            CONF.identity.domain_configurations_from_database or
            not os.path.isdir(filedir)):
        return False

    invalid_files = []
    for filename in os.listdir(filedir):
        if re.match(CONFIG_REGEX, filename):
            try:
                parser = configparser.ConfigParser()
                parser.read(os.path.join(filedir, filename))
            except configparser.Error:
                invalid_files.append(filename)

    if invalid_files:
        invalid_str = ', '.join(invalid_files)
        print('Error: The following config files are formatted incorrectly: ',
              invalid_str)
        return True

    return False