You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-lib/pym/calculate/lib/cl_ldap.py

255 lines
10 KiB

9 years ago
# -*- coding: utf-8 -*-
# Copyright 2008-2016 Mir Calculate. http://www.calculate-linux.org
#
# 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.
import ldap
from utils.common import _error
9 years ago
from collections import defaultdict
class ldapFun(_error):
9 years ago
"""
Объект для работы с LDAP сервером
подключение к серверу и поиск данных
"""
def __init__(self, dnUser, password, host="localhost"):
self.conLdap = False
# Получаем соединение с LDAP
try:
self.conLdap = self.__ldapConnect(dnUser, password, host)
except ldap.LDAPError, e:
self.setError(e[0]['desc'])
def __ldapConnect(self, dnUser, password, host):
"""Соединение с LDAP сервером"""
9 years ago
con_ldap = ldap.initialize('ldap://%s' % host)
con_ldap.simple_bind_s(dnUser, password)
return con_ldap
9 years ago
def ldapSearch(self, base_dn, search_scope, search_filter, retrieve_attrs):
try:
9 years ago
ldap_result_id = self.conLdap.search(base_dn, search_scope,
search_filter,
retrieve_attrs)
result_set = []
while 1:
9 years ago
result_type, result_data = self.conLdap.result(
ldap_result_id, 0)
if isinstance(result_data, list) and not result_data:
break
else:
if result_type == ldap.RES_SEARCH_ENTRY:
result_set.append(result_data)
except ldap.NO_SUCH_OBJECT:
return []
9 years ago
except Exception:
return False
return result_set
9 years ago
class ldapUser(_error):
"""Получение данных для пользователя из LDAP"""
# Данные из /etc/ldap.conf
_dictData = {}
# Объект LDAP
ldapObj = False
# Подключение к LDAP
conLdap = False
def addDN(self, *arg):
"""
Append text DN elements
"""
9 years ago
return ",".join(x for x in arg if x)
15 years ago
def getDataInLdapConf(self, bindData=True, cache=True):
"""Получение данных из /etc/ldap.conf"""
9 years ago
data = [("host", 'host'),
("usersDN", 'nss_base_passwd'),
("groupsDN", 'nss_base_group')]
if bindData:
9 years ago
data += [("bindDn", 'binddn'), ("bindPw", 'bindpw')]
names_data = [x[0] for x in data]
15 years ago
# Данные из кеша, если он есть
9 years ago
if (cache and self._dictData and
set(names_data) <= set(self._dictData.keys())):
15 years ago
return self._dictData
9 years ago
file_name = "/etc/ldap.conf"
get_str_list = lambda x: reduce(lambda x, y: [x, y.upper()], ([x] * 2))
workdata = map(lambda x: (x[0], get_str_list(x[1]), len(x[1])), data)
dict_data = defaultdict(list)
delimeter = (" ", "\t")
try:
9 years ago
for line in open(file_name):
for name, keys, lenKey in workdata:
if (name not in dict_data.keys() and
any(line.startswith(x) for x in keys) and
len(line) > lenKey):
spl = line[lenKey]
9 years ago
if spl in delimeter:
param_value = line.rpartition(spl)[2]
if name in ("usersDN", "groupsDN"):
dict_data[name].append(
param_value.partition('?')[0].strip())
else:
9 years ago
dict_data[name].append(param_value.strip())
except Exception:
# self.setError(_("Can not open %s")%fileName)
return False
9 years ago
if set(dict_data.keys()) == set(names_data):
15 years ago
# Кеширование данных
if cache:
self._dictData.clear()
9 years ago
self._dictData.update(dict_data)
return dict_data
else:
return {}
15 years ago
def getBindConnectData(self):
"""Получение данных для соединения с LDAP bind пользователем"""
configdata = self.getDataInLdapConf()
if configdata:
9 years ago
bind_dn = configdata["bindDn"][0]
bind_pw = configdata["bindPw"][0]
15 years ago
host = configdata["host"][0]
9 years ago
return bind_dn, bind_pw, host
15 years ago
return False
def getUsersDN(self):
"""Получение DN пользователей"""
configdata = self.getDataInLdapConf(bindData=False)
if configdata:
9 years ago
return self._dictData["usersDN"][0]
15 years ago
return False
def getHost(self):
"""Получение LDAP хоста"""
configdata = self.getDataInLdapConf(bindData=False)
if configdata:
9 years ago
return configdata["host"][0]
return False
15 years ago
def getGroupsDN(self):
"""Получение списка DN групп"""
configdata = self.getDataInLdapConf(bindData=False)
if configdata:
9 years ago
return self._dictData["groupsDN"]
15 years ago
return False
def connectLdap(self):
"""
Connect to LDAP
"""
15 years ago
connectData = self.getBindConnectData()
if not connectData:
15 years ago
return {}
15 years ago
bindDn, bindPw, host = connectData
9 years ago
self.getUsersDN()
# Соединяемся с LDAP
return self.ldapConnect(bindDn, bindPw, host)
9 years ago
def getUserLdapInfo(self, user_name, shadowAttr=False):
"""Выдаем информацию о пользователе из LDAP"""
if not self.connectLdap():
return False
9 years ago
users_dn = self.getUsersDN()
groups_dn = self.getGroupsDN()
search_user = self.ldapObj.ldapSearch(users_dn, ldap.SCOPE_ONELEVEL,
"uid=%s" % user_name, None)
if not search_user:
return False
9 years ago
convert_dict = {'uid': ('user', 'uidNumber'),
'gid': ('user', 'gidNumber'),
'fullName': ('user', 'cn'),
'mail': ('user', 'mail'),
'jid': ('user', 'registeredAddress'),
'home': ('user', 'homeDirectory'),
'group': ('group', 'cn')}
if shadowAttr:
9 years ago
convert_dict.update({'loginShell': ('user', 'loginShell'),
'shadowLastChange': (
'user', 'shadowLastChange'),
'shadowMin': ('user', 'shadowMin'),
'shadowMax': ('user', 'shadowMax'),
'shadowWarning': ('user', 'shadowWarning'),
'shadowExpire': ('user', 'shadowExpire'),
'shadowFlag': ('user', 'shadowFlag'),
'groups': ('group', 'memberUid')})
list_user_attr = [k for k, v in convert_dict.items() if v[0] == "user"]
list_group_attr = [k for k, v in convert_dict.items()
if v[0] == "group"]
uid = ""
gid = ""
9 years ago
dict_out = {}
for dict_attr in list_user_attr:
ldap_attr = convert_dict[dict_attr][1]
if ldap_attr in search_user[0][0][1]:
dict_out[dict_attr] = search_user[0][0][1][ldap_attr][0]
else:
9 years ago
dict_out[dict_attr] = ""
if dict_attr == 'uid':
uid = dict_out[dict_attr]
if dict_attr == 'gid':
gid = dict_out[dict_attr]
if gid:
9 years ago
for dict_attr in list_group_attr:
search_group = []
ldap_attr = convert_dict[dict_attr][1]
if dict_attr == "group":
for groupDN in groups_dn:
search_group = self.ldapObj.ldapSearch(
groupDN, ldap.SCOPE_ONELEVEL, "gidNumber=%s" % gid,
None)
if search_group:
break
9 years ago
if search_group:
data = search_group[0][0][1]
if ldap_attr in data:
dict_out[dict_attr] = data[ldap_attr][0]
else:
9 years ago
dict_out[dict_attr] = ""
else:
9 years ago
dict_out[dict_attr] = ""
elif dict_attr == "groups":
user_groups_data = []
for groupDN in groups_dn:
search_group = self.ldapObj.ldapSearch(
groupDN, ldap.SCOPE_ONELEVEL,
"%s=%s" % (ldap_attr, user_name),
["cn", "gidNumber"])
if search_group:
user_groups_data.extend(
[(x[0][1]["cn"][0], x[0][1]["gidNumber"][0])
for x in search_group])
dict_out[dict_attr] = user_groups_data
if uid and gid:
9 years ago
return dict_out
else:
return {}
9 years ago
def ldapConnect(self, bind_dn, bind_pw, host):
"""Подключение к LDAP"""
if not self.ldapObj:
9 years ago
ldap_obj = ldapFun(bind_dn, bind_pw, host)
if ldap_obj.getError():
ldap_obj.clearErrors()
return False
# Устанавливаем у объекта соединение и объект LDAP функций
9 years ago
self.ldapObj = ldap_obj
self.conLdap = ldap_obj.conLdap
return True