浏览代码

The initial project files.

tags/3.5.0_alpha1
Самоукин Алексей 10 年前
当前提交
1e644fcbc9
共有 21 个文件被更改,包括 1245 次插入0 次删除
  1. +202
    -0
      LICENCE
  2. +15
    -0
      README
  3. 二进制
      i18n/cl_ldap_ru.mo
  4. +31
    -0
      ldif/base.ldif
  5. +0
    -0
      pym/__init__.py
  6. +81
    -0
      pym/cl_fill_ldap.py
  7. +184
    -0
      pym/cl_ldap_api.py
  8. +239
    -0
      pym/cl_ldap_service.py
  9. +108
    -0
      pym/cl_ldap_setup_cmd.py
  10. +78
    -0
      pym/cl_share_cmd.py
  11. +77
    -0
      pym/cl_vars_ldap.py
  12. +65
    -0
      scripts/cl-ldap-setup
  13. +5
    -0
      setup.cfg
  14. +89
    -0
      setup.py
  15. +1
    -0
      templates/.calculate_directory
  16. +1
    -0
      templates/setup/.calculate_directory
  17. +2
    -0
      templates/setup/openldap/.calculate_directory
  18. +2
    -0
      templates/setup/openldap/step-1/.calculate_directory
  19. +60
    -0
      templates/setup/openldap/step-1/slapd.conf
  20. +2
    -0
      templates/setup/openldap/step-2/.calculate_directory
  21. +3
    -0
      templates/setup/openldap/step-2/slapd.conf

+ 202
- 0
LICENCE 查看文件

@@ -0,0 +1,202 @@

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.

"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.

"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.

"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.

"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.

"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.

"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).

"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.

"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."

"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:

(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and

(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and

(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and

(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.

You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

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.

+ 15
- 0
README 查看文件

@@ -0,0 +1,15 @@
AUTHOR: Calculate Ltd. <support@calculate.ru>

INSTALL
-------

calculate-server needs the following library version installed, in order to run:
python >= 2.5
python-ldap >= 2.0.0
pyxml >= 0.8
calculate-lib >= 2.2.0.0

To install calculate-ldap, just execute the install script 'setup.py'.
Example:

./setup.py install

二进制
i18n/cl_ldap_ru.mo 查看文件


+ 31
- 0
ldif/base.ldif 查看文件

@@ -0,0 +1,31 @@
# Directory Server
dn: #-ld_base_dn-#
objectClass: dcObject
objectClass: organization
dc: #-ld_base_root-#
o: Calculate Directory Server

# Services
dn: ou=Services,#-ld_base_dn-#
objectClass: top
objectClass: organizationalUnit
ou: Services

# Admin
dn: #-ld_admin_dn-#
cn: #-ld_admin_login-#
sn: #-ld_admin_login-#
objectClass: person
objectClass: top
description: LDAP Administrator stuff
userPassword: #-ld_admin_hash-#

# Bind
dn: #-ld_bind_dn-#
cn: #-ld_bind_login-#
sn: #-ld_bind_login-#
objectClass: person
objectClass: top
description: LDAP Proxy User
userPassword: #-ld_bind_hash-#


+ 0
- 0
pym/__init__.py 查看文件


+ 81
- 0
pym/cl_fill_ldap.py 查看文件

@@ -0,0 +1,81 @@
#-*- coding: utf-8 -*-

# Copyright 2008-2010 Mir Calculate Ltd. 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 os
from cl_datavars import glob_attr
from cl_utils import genpassword
from encrypt import encrypt

class fillVars(glob_attr):
encryptObj = encrypt()
addDn = lambda x,*y: ",".join(y)
genDn = lambda x,*y: "=".join(y)

def getHash(self, password, encrypt):
"""Получить хеш пароля

password - пароль
encrypt - алгоритм шифрования, например 'ssha'
"""
hashPwd = self.encryptObj.getHashPasswd(password, encrypt.lower())
if hashPwd:
return hashPwd
else:
print "Error encrypt password, method getHash()"
exit(1)

def get_ld_base_dn(self):
"""базовый DN LDAP"""
return self.genDn("dc", self.Get('ld_base_root'))

def get_ld_bind_dn(self):
"""bind DN LDAP"""
return self.addDn(self.genDn("cn", self.Get('ld_bind_login')),
self.Get('ld_base_dn'))

def get_ld_bind_hash(self):
"""hash пароля для пользователя для чтения"""
return self.getHash(self.Get('ld_bind_pw'), self.Get('ld_encrypt'))

def get_ld_temp_dn(self):
#DN временного пользователя root (для инициализации базы данных)
return self.addDn(self.genDn("cn", "ldaproot"), self.Get('ld_base_dn'))

def get_ld_temp_pw(self):
"""пароль временного пользователя root"""
return genpassword()

def get_ld_temp_hash(self):
"""hash пароля временного root"""
return self.getHash(self.Get('ld_temp_pw'), self.Get('ld_encrypt'))

def get_ld_admin_dn(self):
"""DN пользователя root"""
return self.addDn(self.genDn("cn", self.Get('ld_admin_login')),
self.Get('ld_base_dn'))

def get_ld_admin_hash(self):
"""hash пароля root"""
return self.getHash(self.Get('ld_admin_pw'), self.Get('ld_encrypt'))

def get_ld_admin_pw(self):
"""пароль root"""
return genpassword()

def get_ld_services_dn(self):
"""DN для всех сервисов"""
return self.addDn(self.genDn("ou", self.Get('ld_services')),
self.Get('ld_base_dn'))

+ 184
- 0
pym/cl_ldap_api.py 查看文件

@@ -0,0 +1,184 @@
#-*- coding: utf-8 -*-

# Copyright 2008-2010 Mir Calculate Ltd. 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 os, sys, re
from cl_print import color_print
from cl_datavars import DataVars
from server.utils import execProg

from cl_lang import lang
lang().setLanguage(sys.modules[__name__])

from cl_abstract import abs_api

class DataVarsLdap(DataVars):
"""Хранение переменных"""
# Имя секции в calculate2.env
envSection = "ldap"

def importLdap(self, **args):
'''Импорт переменных для calculate-ldap'''
# Импорт переменных
self.importData(self.envSection, ('cl_vars_ldap','cl_fill_ldap'))

class shareVars:
"""share methods template vars"""
# template variables
clVars = False

def createClVars(self, clVars=False):
"""Создает объект Vars"""
if not clVars:
clVars = DataVarsLdap()
# Импортируем переменные
clVars.importLdap()
# Заменяем значения переменных переменными из env файлов
clVars.flIniFile()
# Устанавливаем у объекта атрибут объект переменных
self.clVars = clVars
return True

class serviceAPI(color_print, shareVars, abs_api):
'''Methods ldap service'''
prioritet = 25
nameService = "ldap"
nameDaemon = 'slapd'
_templDict = {'name':nameDaemon}
# files
pidFile = '/var/run/openldap/%(name)s.pid' %_templDict
# command
cmdPath = '/etc/init.d/%(name)s' %_templDict
_templDict.update({'cmd':cmdPath})
cmdStart = '%(cmd)s start' %_templDict
cmdReStart = '%(cmd)s restart' %_templDict
cmdStop = '%(cmd)s stop' %_templDict
cmdShowDaemons = 'rc-update show default'
reShowDaemons = re.compile("(.+)\s+\|\s+.+")
cmdAddRunlevel = 'rc-update add %(name)s default' %_templDict
cmdDelRunlevel = 'rc-update del %(name)s default' %_templDict

def getServiceName(self):
'''Get name service'''
return self.nameService

def isSetup(self):
'''Is setup service (True/False)'''
self.createClVars(self.clVars)
return self.clVars.Get('sr_ldap_set') == "on"

def _getRunlevelDaemons(self):
"""Получаем всех демонов в default уровне"""
textLines = execProg(self.cmdShowDaemons)
if textLines is False:
self.printERROR(_("ERROR") + ": " + self.cmdShowDaemons)
return False
else:
daemons = []
for line in textLines:
res = self.reShowDaemons.search(line)
if res:
daemon = res.groups(0)[0]
daemons.append(daemon)
return daemons

def isStart(self):
'''Run ldap server (True/False)'''
if os.access(self.pidFile, os.R_OK):
pid = open(self.pidFile).read().strip()
if pid:
procDir = "/proc"+"/"+pid
if os.access(procDir, os.F_OK):
return True
return False

def start(self):
'''Запускает LDAP сервер'''
if execProg(self.cmdStart) is False:
self.printERROR(_("Can't execute '%s'") %self.cmdStart)
self.printNotOK(_("Starting LDAP") + " ...")
return False
else:
return True

def restart(self):
'''Перезапускает LDAP сервер'''
if execProg(self.cmdReStart) is False:
self.printERROR(_("Can't execute '%s'") %self.cmdReStart)
self.printNotOK(_("Restarting LDAP")+ " ...")
return False
else:
return True

def stop(self):
'''Останавливает LDAP сервер'''
if execProg(self.cmdStop) is False:
self.printERROR(_("Can't execute '%s'") %self.cmdStop)
self.printNotOK(_("Stopping LDAP")+ " ...")
return False
else:
return True

def isRunlevel(self):
'''Находится ли LDAP в автозагрузке'''
daemons = self._getRunlevelDaemons()
if daemons is False:
return False
if self.nameDaemon in daemons:
return True
else:
return False

def addRunlevel(self):
'''Add daemon to runlevel'''
if not self.isRunlevel():
if execProg(self.cmdAddRunlevel) is False:
self.printERROR(_("Can't execute '%s'") %self.cmdAddRunlevel)
self.printNotOK(_("service %(name)s added to runlevel")\
%self._templDict + " ...")
return False
return True

def delRunlevel(self):
'''Delete daemon from runlevel'''
if self.isRunlevel():
if execProg(self.cmdDelRunlevel) is False:
self.printERROR(_("Can't execute '%s'") %self.cmdDelRunlevel)
self.printNotOK(_("service %(name)s removed from runlevel")\
%self._templDict + " ...")
return False
return True

def getRunPrioritet(self):
'''Get run daemon prioritet'''
return self.prioritet

def delVarsFromEnv(self):
'''Delete template vars in env files
'''
self.createClVars(self.clVars)
deleteVariables = ("sr_ldap_set",)
locations = map(lambda x: x[0], self.clVars.Get("cl_env_data"))
for varName in deleteVariables:
for locate in locations:
if not self.clVars.Delete(varName, location=locate,
header=self.clVars.envSection):
fileName = filter(lambda x: x[0] == locate,
self.clVars.Get("cl_env_data"))[0][1]
self.printERROR(_("Can't delete variable '%(name)s' "
"in file %(file)s") %{'name':varName,
'file':fileName})
return False
return True

+ 239
- 0
pym/cl_ldap_service.py 查看文件

@@ -0,0 +1,239 @@
#-*- coding: utf-8 -*-

# Copyright 2008-2010 Mir Calculate Ltd. 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.

__version__ = "2.2.0.0"
__app__ = "calculate-ldap"

import os, sys

from server.utils import dialogYesNo
from cl_print import color_print

from cl_ldap_api import serviceAPI, shareVars
from cl_template import template
from server.services import services
from server.ldap import iniLdapParser, ldapFunction, shareldap
from server.utils import genSleep
from cl_utils import removeDir, _error, appendProgramToEnvFile,\
removeProgramToEnvFile

from cl_lang import lang
lang().setLanguage(sys.modules[__name__])

class ldapService(shareVars, shareldap):
"""Методы севисa Ldap"""
# Базовый ldif файл
ldifFileBase = '/usr/lib/calculate-2.2/calculate-ldap/ldif/base.ldif'
apiFile = '/usr/lib/calculate-2.2/calculate-ldap/pym/cl_ldap_api.py'
APIObj = serviceAPI()
servObj = services()

def applyTemplates(self):
"""Apply templates"""
clTempl = template(self.clVars)
dirsFiles = clTempl.applyTemplates()
if clTempl.getError():
self.printERROR(clTempl.getError().strip())
return False
else:
return dirsFiles

def removeLdapDatabase(self):
"""Удаляем предыдущую базу данных"""
pathDatabase = "/var/lib/openldap-data"
if os.path.exists(pathDatabase) and os.listdir(pathDatabase):
if os.system("rm /var/lib/openldap-data/* &>/dev/null") !=0:
self.printERROR("Can't remove /var/lib/openldap-data/*")
return False
return True
if os.path.exists(pathDatabase) and os.listdir(pathDatabase):
removeDir(pathDatabase)
self.printOK(_("Erased LDAP Database") + " ...")
return True

def connectLdapServer(self):
"""Соединяемся с LDAP сервером

используем DN и пароль временного админстратора
"""
# Если раннее была ошибка то выходим
if self.getError():
self.printERROR (_("ERROR") + ": " +\
self.getError().strip())
return False
tmpDn = self.clVars.Get("ld_temp_dn")
tmpPw = self.clVars.Get("ld_temp_pw")
ldapObj = ldapFunction(tmpDn, tmpPw)
# Генератор задержек
wait = genSleep()
while ldapObj.getError():
try:
# Задержка
wait.next()
except StopIteration:
break
# Очистка ошибки
_error.error = []
ldapObj = ldapFunction(tmpDn, tmpPw)
self.ldapObj = ldapObj
self.conLdap = ldapObj.conLdap
if ldapObj.getError():
# Удаляем одинаковые ошибки
listError = []
for e in ldapObj.error:
if not e in listError:
listError.append(e)
_error.error = listError
self.printERROR(_("Can not connected to LDAP server"))
return False
return True

def installProg(self):
'''Install this program'''
apiDict = self.clVars.Get("cl_api")
apiDict.update({__app__:self.apiFile})
self.clVars.Write("cl_api", force=True)
if not appendProgramToEnvFile(__app__, self.clVars):
self.printERROR(_("Can not save '%s'") %__app__ + " " +\
_("to %s") %self.clVars.Get("cl_env_path")[0])
return False
self.printOK(_("Save install variables"))
return True

def uninstallProg(self):
'''Uninstall this program'''
apiDict = self.clVars.Get("cl_api")
if __app__ in apiDict:
apiDict.pop(__app__)
self.clVars.Write("cl_api", force=True)
if not removeProgramToEnvFile(__app__, self.clVars):
self.printERROR(_("Can not remove '%s' to %s")%(__app__,
self.clVars.Get("cl_env_path")[0]))
return False
self.printOK(_("Delete install variables"))
return True

def setup(self, force=False):
"""Настройка LDAP сервиса (создание дерева)"""
# Принудительная установка
if self.clVars.Get("sr_ldap_set") == "on" and not force:
self.printWARNING (_("WARNING") + ": " +\
_("LDAP server is configured")+ ".")
return True
if not force:
# предупреждение при выполнении этой программы будут изменены
# конфигурационные файлы и база данных сервиса LDAP а также
# конфигурационные файлы установленных сервисов
self.printWARNING (_("WARNING") + ": " +\
_("Executing of the program will change") + " " +\
_("the configuration files and database of LDAP service")+\
".")
# если вы готовы продолжить работу программы нажмите Y если нет n
messDialog = \
_("If you are ready to continue executing the program")+", "+\
_("input 'yes'") +", "+ _("if not 'no'")
if not dialogYesNo(messDialog):
return True
else:
# делаем backup
# Проверим запущен ли ldap
if not self.APIObj.isStart():
# Запускаем LDAP сервер
if not self.APIObj.start():
return False
#if not self.backupServer():
#return False
if self.APIObj.isRunlevel():
# Удаляем из автозапуска демона
if not self.APIObj.delRunlevel():
return False
# Останавливаем все установленные сервисы
if not self.servObj.stopAllServices():
return False
# Останавливаем LDAP
if self.APIObj.isStart():
self.APIObj.stop()
# Удаляем из автозагрузки все установленные сервисы
if not self.servObj.delRunlevelAllServices():
return False
# Удаляем из крона скрипт для чистки удаленых пользователей
# создаем объект репликации
#objRepl = servRepl()
#if not objRepl.cronReplicationOFF():
#return False
# Удаляем из share файл .replrun
#if not self.servSambaObj.delReplFile(self.clVars):
#return False
# Удаляем переменные
if not self.servObj.delVarsFromAllServices():
return False
# Получим путь к ldap файлу
ldapParser = iniLdapParser()
ldapFile = ldapParser.nameIniFile
# Удаляем ldap файл
if os.path.exists(ldapFile):
os.remove(ldapFile)
self.clVars.Write("sr_ldap_set", "off",force=True)
self.clVars.Set("sr_ldap_set", "on", force=True)
self.clVars.Set("cl_ldap_setup_action","up", force=True)
# Первый проход
self.clVars.Set("cl_pass_step", "1", True)
if self.applyTemplates() is False:
self.printERROR(_("Can not apply templates") + ":" + " " +\
_("first pass"))
return False
# Удаляем старую базу данных
if not self.removeLdapDatabase():
return False
# Запускаем LDAP сервер
if not self.APIObj.start():
return False
# Соединяемся с LDAP временным пользователем
if not self.connectLdapServer():
return False
# Получаем текст нужного ldif-a
baseLdif = self.createLdif(self.ldifFileBase)
# Если нет ошибок при соединении применяем ldif
if not self.ldapObj.getError():
self.ldapObj.ldapAdd(baseLdif)
if self.ldapObj.getError():
print _("LDAP Error") + ": " + self.ldapObj.getError().strip()
return False
self.printOK(_("Added ldif file") + " ...")
# Второй проход,
# удаляем временного пользователя root из конфигурационного файла
self.clVars.Set("cl_pass_step","2",True)
if self.applyTemplates() is False:
self.printERROR(_("Can not apply profiles") +":"+ _("second pass"))
return False
# Перезапускаем LDAP сервер
if not self.APIObj.restart():
return False
# Записываем данные администратора сервера
ldapParser.setVar("admin",
{"DN":self.clVars.Get("ld_admin_dn"),
"PASS":self.clVars.Get("ld_admin_pw")})
# Устанавливаем автозапуск демона
if not self.APIObj.addRunlevel():
return False
# Записываем переменные для пользователя
#clientVars = ["ur_organization", "ur_signature"]
#if not self.saveVarsClient(clientVars):
#return False
self.clVars.Write("sr_ldap_set","on",force=True)
self.printOK(_("LDAP service configured") + " ...")
return True

+ 108
- 0
pym/cl_ldap_setup_cmd.py 查看文件

@@ -0,0 +1,108 @@
#-*- coding: utf-8 -*-

# Copyright 2010 Calculate Ltd. 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.
from cl_ldap_service import ldapService, __app__, __version__
from cl_opt import opt
import sys
from cl_share_cmd import share_cmd

# Перевод сообщений для программы
from cl_lang import lang
lang().setLanguage(sys.modules[__name__])

# Использование программы
USAGE = _("%prog [options]")

# Коментарии к использованию программы
COMMENT_EXAMPLES = _("Create LDAP tree")

# Пример использования программы
EXAMPLES = _("%prog")

# Описание программы (что делает программа)
DESCRIPTION = _("Creating LDAP tree")

# Опции командной строки
CMD_OPTIONS = [{'shortOption':"f",
'longOption':"force",
'help':_("forced setup service ldap")},
{'longOption':"install",
'help':_("configure the system to install this package")},
{'longOption':"uninstall",
'help':_("configure the system to uninstall this package")}]

class ldap_setup_cmd(share_cmd):
def __init__(self):
# Объект опций командной строки
self.optobj = opt(package=__app__,
version=__version__,
usage=USAGE,
examples=EXAMPLES,
comment_examples=COMMENT_EXAMPLES,
description=DESCRIPTION,
option_list=CMD_OPTIONS +\
opt.variable_control+opt.color_control,
check_values=self.checkOpts)
# Создаем объект логики
self.logicObj = ldapService()
# Создаем переменные
self.logicObj.createClVars()
# Названия несовместимых опций
self.optionsNamesIncompatible = ["install", "uninstall", "f"]

def getIncompatibleOptions(self, optObj):
"""Получаем несовместимые опции"""
retList = []
for nameOpt in self.optionsNamesIncompatible:
retList.append(getattr(optObj, nameOpt))
return retList

def _getNamesAllSetOptions(self):
"""Выдает словарь измененных опций"""
setOptDict = self.optobj.values.__dict__.items()
defaultOptDict = self.optobj.get_default_values().__dict__.items()
return dict(set(setOptDict) - set(defaultOptDict)).keys()

def getStringIncompatibleOptions(self):
"""Форматированная строка несовместимых опций разделенных ','"""
listOpt = list(set(self.optionsNamesIncompatible) &\
set(self._getNamesAllSetOptions()))
return ", ".join(map(lambda x: len(x) == 1 and "'-%s'"%x or "'--%s'"%x,\
listOpt))

def checkOpts(self, optObj, args):
"""Check command line opt and arg"""
if len(filter(lambda x: x, self.getIncompatibleOptions(optObj)))>1:
errMsg = _("incompatible options")+":"+" %s"\
%self.getStringIncompatibleOptions()
self.optobj.error(errMsg)
return False
if args:
errMsg = _("incorrect argument") + ":" + " %s" %" ".join(args)
self.optobj.error(errMsg)
return False
return optObj, args

def setup(self, force=False):
"""Setup program"""
return self.logicObj.setup(force=force)

def install(self):
"""Инсталяция программы"""
return self.logicObj.installProg()

def uninstall(self):
"""Удаление программы"""
return self.logicObj.uninstallProg()

+ 78
- 0
pym/cl_share_cmd.py 查看文件

@@ -0,0 +1,78 @@
#-*- coding: utf-8 -*-

# Copyright 2010 Calculate Ltd. 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 sys

from cl_print import color_print
from cl_utils import _error

# Перевод сообщений для программы
from cl_lang import lang
lang().setLanguage(sys.modules[__name__])

class share_cmd(color_print, _error):
"""Класс общих методов обработки опций командной строки"""

def printVars(self, optObj):
"""Печать переменных"""
if optObj.v:
varsFilter = None
varsNames = []
format = "default"
# Фильтрование переменных
if optObj.filter:
optCmd = optObj.filter
if ',' in optCmd:
varsNames = optCmd.split(",")
elif '*' in optCmd:
varsFilter = optCmd.replace("*", ".*")
else:
varsNames.append(optCmd)
if optObj.xml:
format = "xml"
self.logicObj.printVars(varsFilter, varsNames, outFormat=format)

def setVars(self, optObj):
"""Установка переменных"""
if optObj.set:
for vals in optObj.set:
for val in vals.split(','):
k,o,v = val.partition('=')
if self.logicObj.clVars.exists(k):
if not self.logicObj.clVars.SetWriteVar(k,v):
return False
else:
self.printERROR(_('variable %s not found')%k)
return False
return True

def writeVars(self, optObj):
"""Запись переменных"""
if optObj.set:
if not self.logicObj.clVars.WriteVars():
errMsg = self.getError()
if errMsg:
self.printERROR(errMsg.strip())
self.printERROR(_('Can not write template variables'))
return False
return True

def setPrintNoColor(self, optObj):
"""Установка печати сообщений без цвета"""
if optObj.color and optObj.color=="never":
color_print.colorPrint = lambda *arg : sys.stdout.write(arg[-1]) or\
sys.stdout.flush()

+ 77
- 0
pym/cl_vars_ldap.py 查看文件

@@ -0,0 +1,77 @@
#-*- coding: utf-8 -*-

# Copyright 2008-2010 Mir Calculate Ltd. 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.


class Data:
#базовый суффикс LDAP
ld_base_dn = {}

#bind суффикс LDAP
ld_bind_dn = {}

#пользователь только для чтения
ld_bind_login = {'value':'proxyuser'}

#hash пароля для пользователя для чтения
ld_bind_hash = {}

#пароль для пользователя для чтения
ld_bind_pw = {'value':'calculate'}

#алгоритм шифрования паролей
ld_encrypt = {'value':'ssha'}

#имя для базового суффикса LDAP
ld_base_root = {'value':'calculate'}

#временный пользователь root для инициализации базы данных
ld_temp_dn = {}

#hash пароля временного root
ld_temp_hash = {}

#пароль временного пользователя root
ld_temp_pw = {}

#DN пользователя root
ld_admin_dn = {}

#имя пользователя root для LDAP
ld_admin_login = {'value':'ldapadmin'}

#hash пароля root
ld_admin_hash = {}

#пароль root
ld_admin_pw = {}

#Имя для всех сервисов
ld_services= {'value' : 'Services'}

#DN всех сервисов
ld_services_dn = {}

#Настроен или нет сервис LDAP
sr_ldap_set = {'mode':"w",'value':'off'}

# имя программы
cl_name = {'value':'calculate-ldap'}

# версия программы
cl_ver = {'value':'2.2.0.0'}

# действие программа устанавливает сервис
cl_ldap_setup_action = {'value':'down'}

+ 65
- 0
scripts/cl-ldap-setup 查看文件

@@ -0,0 +1,65 @@
#!/usr/bin/python
#-*- coding: utf-8 -*-

# Copyright 2010 Calculate Ltd. 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 sys
import os
sys.path.insert(0,os.path.abspath('/usr/lib/calculate-2.2/calculate-lib/pym'))
sys.path.insert(0,\
os.path.abspath('/usr/lib/calculate-2.2/calculate-ldap/pym'))

from cl_ldap_setup_cmd import ldap_setup_cmd

from cl_lang import lang
tr = lang()
tr.setGlobalDomain('cl_ldap')
tr.setLanguage(sys.modules[__name__])

if __name__ == "__main__":
obj = ldap_setup_cmd()
ret = obj.optobj.parse_args()
if ret is False:
sys.exit(1)
opts, args = ret
# Установка цвета при печати сообщений
obj.setPrintNoColor(opts)
# Установка переменных
if not obj.setVars(opts):
sys.exit(1)
# Печать переменных
obj.printVars(opts)
# Если нет печати переменных выполняем логику программы
if not opts.v and not opts.filter and not opts.xml:
if not filter(lambda x: x[1], obj.optobj.values.__dict__.items()):
# Setup
if not obj.setup():
sys.exit(1)
elif opts.f:
# Force setup
if not obj.setup(force=True):
sys.exit(1)
elif opts.install:
# Install
if not obj.install():
sys.exit(1)
elif opts.uninstall:
# Uninstall
if not obj.uninstall():
sys.exit(1)
# Запись переменных
if not obj.writeVars(opts):
sys.exit(1)
sys.exit(0)

+ 5
- 0
setup.cfg 查看文件

@@ -0,0 +1,5 @@
[install]
install-scripts=/usr/bin
install-purelib=/usr/lib/calculate-2.2
install-platlib=/usr/lib/calculate-2.2
install-data=/usr/lib/calculate-2.2/calculate-ldap

+ 89
- 0
setup.py 查看文件

@@ -0,0 +1,89 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# setup.py --- Setup script for calculate-client

#Copyright 2010 Calculate Pack, 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 os
import stat
from distutils.core import setup, Extension


__version__ = "2.2.0.0"
__app__ = "calculate-ldap"


data_files = []

var_data_files = []

data_dirs_template = ['templates']
data_dirs_ldif = ['ldif']
data_dirs_share = ['i18n']
share_calculate_dir = "/usr/share/calculate"
template_calculate_dir = os.path.join(share_calculate_dir, "templates")
template_replace_dirname = "ldap"

def __scanDir(scanDir, prefix, replace_dirname, dirData, flagDir=False):
"""Scan directory"""
files = []
dirs = []
if flagDir or stat.S_ISDIR(os.stat(scanDir)[stat.ST_MODE]):
for fileOrDir in os.listdir(scanDir):
absPath = os.path.join(scanDir,fileOrDir)
statInfo = os.stat(absPath)[stat.ST_MODE]
if stat.S_ISREG(statInfo):
files.append(absPath)
elif stat.S_ISDIR(statInfo):
dirs.append(absPath)
if replace_dirname:
listDirs = list(scanDir.partition("/"))[1:]
listDirs.insert(0,replace_dirname)
scanDir = "".join(listDirs)
if prefix:
scanDir = os.path.join(prefix,scanDir)
dirData.append((scanDir, files))
for sDir in dirs:
__scanDir(sDir, prefix, replace_dirname, dirData, True)
return dirData

def create_data_files(data_dirs, prefix="", replace_dirname=""):
"""Create data_files"""
data_files = []
for data_dir in data_dirs:
data = []
data_files += __scanDir(data_dir, prefix, replace_dirname, data)
return data_files

data_files += create_data_files (data_dirs_template, template_calculate_dir,
template_replace_dirname)
data_files += create_data_files (data_dirs_share, share_calculate_dir)
data_files += create_data_files (data_dirs_ldif)


setup(
name = __app__,
version = __version__,
description = "The program for configuring LDAP server",
author = "Mir Calculate Ltd.",
author_email = "support@calculate.ru",
url = "http://calculate-linux.org",
license = "http://www.apache.org/licenses/LICENSE-2.0",
package_dir = {'calculate-ldap': "."},
packages = ['calculate-ldap.pym'],
data_files = data_files,
scripts=["./scripts/cl-ldap-setup"]
)


+ 1
- 0
templates/.calculate_directory 查看文件

@@ -0,0 +1 @@
# Calculate append=skip cl_name==calculate-ldap

+ 1
- 0
templates/setup/.calculate_directory 查看文件

@@ -0,0 +1 @@
# Calculate append=skip cl_ldap_setup_action==up

+ 2
- 0
templates/setup/openldap/.calculate_directory 查看文件

@@ -0,0 +1,2 @@
# Calculate belong()!=&&pkg(net-nds/openldap)!= path=/etc name=openldap


+ 2
- 0
templates/setup/openldap/step-1/.calculate_directory 查看文件

@@ -0,0 +1,2 @@
# Calculate append=skip cl_pass_step==1


+ 60
- 0
templates/setup/openldap/step-1/slapd.conf 查看文件

@@ -0,0 +1,60 @@
# Calculate format=ldap chmod=0640 chown=root:ldap append=replace
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/misc.schema
#?pkg(net-nds/openldap)<2.4#schemacheck on#pkg#

pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.arg

# Уровень отладочных сообщений
loglevel 0
allow bind_v2
modulepath /usr/lib/openldap/openldap

# Доступ к аттрибуту userPassword
access to attrs=userPassword
by self write
by dn="#-ld_admin_dn-#" write
by * auth

# Доступ к администратору сервера LDAP
access to dn.base="#-ld_admin_dn-#"
by dn="#-ld_admin_dn-#" write
by * none

# Закрываем доступ к веткам
access to dn.regex=".*,#-ld_services_dn-#"
by dn="#-ld_admin_dn-#" write
by * none

# Доступ ко всем аттрибутам
access to *
by dn="#-ld_admin_dn-#" write
by self write
by * read

# Доступ по умолчанию только для чтения
#?pkg(net-nds/openldap)<2.4#defaultaccess none#pkg#

# Тип базы данных
#?pkg(net-nds/openldap)<2.4#database ldbm#pkg#
#?pkg(net-nds/openldap)>2.4#database bdb#pkg#
suffix "#-ld_base_dn-#"
rootdn "#-ld_temp_dn-#"
rootpw #-ld_temp_hash-#
checkpoint 1024 5
cachesize 10000
# Размер ответа на запрос
sizelimit unlimited
directory /var/lib/openldap-data

index objectClass eq
index cn pres,sub,eq
index sn pres,sub,eq
index uid pres,sub,eq
index uidNumber eq
index gidNumber eq
index default sub

+ 2
- 0
templates/setup/openldap/step-2/.calculate_directory 查看文件

@@ -0,0 +1,2 @@
# Calculate append=skip cl_pass_step==2


+ 3
- 0
templates/setup/openldap/step-2/slapd.conf 查看文件

@@ -0,0 +1,3 @@
# Calculate format=ldap chmod=0640 chown=root:ldap append=join
!rootdn del
!rootpw del

正在加载...
取消
保存