@@ -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. |
@@ -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 |
@@ -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 +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')) |
@@ -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 |
@@ -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 |
@@ -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() |
@@ -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() | |||
@@ -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'} |
@@ -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) |
@@ -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 |
@@ -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"] | |||
) | |||
@@ -0,0 +1 @@ | |||
# Calculate append=skip cl_name==calculate-ldap |
@@ -0,0 +1 @@ | |||
# Calculate append=skip cl_ldap_setup_action==up |
@@ -0,0 +1,2 @@ | |||
# Calculate belong()!=&&pkg(net-nds/openldap)!= path=/etc name=openldap | |||
@@ -0,0 +1,2 @@ | |||
# Calculate append=skip cl_pass_step==1 | |||
@@ -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 |
@@ -0,0 +1,2 @@ | |||
# Calculate append=skip cl_pass_step==2 | |||
@@ -0,0 +1,3 @@ | |||
# Calculate format=ldap chmod=0640 chown=root:ldap append=join | |||
!rootdn del | |||
!rootpw del |