|
|
|
|
#-*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
#Copyright 2008 Calculate Pack, http://www.calculate-linux.ru
|
|
|
|
|
#
|
|
|
|
|
# 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 sys
|
|
|
|
|
import re
|
|
|
|
|
#import popen2
|
|
|
|
|
import ldap
|
|
|
|
|
import cStringIO
|
|
|
|
|
from ldif import LDIFParser
|
|
|
|
|
import cl_base
|
|
|
|
|
import cl_profile
|
|
|
|
|
import cl_utils2
|
|
|
|
|
import cl_utils
|
|
|
|
|
# Для подсчета символов
|
|
|
|
|
import termios, fcntl, struct
|
|
|
|
|
# Ввод pwd
|
|
|
|
|
import getpass
|
|
|
|
|
# Статистика файла
|
|
|
|
|
import stat
|
|
|
|
|
|
|
|
|
|
Version = "calculate-server 0.0.1"
|
|
|
|
|
|
|
|
|
|
tr = cl_base.lang()
|
|
|
|
|
tr.setLanguage(sys.modules[__name__])
|
|
|
|
|
|
|
|
|
|
CONWIDTH = 78
|
|
|
|
|
pcs = cl_utils.prettyColumnStr
|
|
|
|
|
|
|
|
|
|
def unicList(lst):
|
|
|
|
|
"""Список уникальных элементов из списка не уникальных"""
|
|
|
|
|
if len(lst) > 1:
|
|
|
|
|
lst.sort()
|
|
|
|
|
outLst = []
|
|
|
|
|
prVal = False
|
|
|
|
|
for val in lst:
|
|
|
|
|
if prVal != val:
|
|
|
|
|
outLst.append(val)
|
|
|
|
|
prVal = val
|
|
|
|
|
return outLst
|
|
|
|
|
return lst
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class iniLdapParser(cl_base.iniParser):
|
|
|
|
|
"""Класс для работы c ini-файлом ldap"""
|
|
|
|
|
def __init__(self):
|
|
|
|
|
# название ini файла
|
|
|
|
|
nameIniFile = "/etc/calculate2/calculate.ldap"
|
|
|
|
|
cl_base.iniParser.__init__(self,nameIniFile)
|
|
|
|
|
# права создаваемого ini-файла
|
|
|
|
|
self.setMode(0600)
|
|
|
|
|
pathIniFile = os.path.split(nameIniFile)[0]
|
|
|
|
|
if not os.path.exists(pathIniFile):
|
|
|
|
|
os.makedirs(pathIniFile)
|
|
|
|
|
|
|
|
|
|
class addLdif(LDIFParser):
|
|
|
|
|
"""Класс необходимый для добавления записей в LDAP"""
|
|
|
|
|
def __init__(self, strInput,ldapCon):
|
|
|
|
|
FD = cStringIO.StringIO(strInput)
|
|
|
|
|
LDIFParser.__init__(self, FD)
|
|
|
|
|
self.ldapCon = ldapCon
|
|
|
|
|
|
|
|
|
|
def handle(self, dn, entry):
|
|
|
|
|
self.ldapCon.add_s(dn, entry.items())
|
|
|
|
|
|
|
|
|
|
class ldapFunction(cl_profile._error):
|
|
|
|
|
'''Объект для работы с LDAP сервером'''
|
|
|
|
|
def __init__(self, dnUser, password):
|
|
|
|
|
self.conLdap = False
|
|
|
|
|
# Получаем соединение с LDAP
|
|
|
|
|
try:
|
|
|
|
|
self.conLdap = self.__ldapConnect(dnUser, password)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.setError(e[0]['desc'])
|
|
|
|
|
|
|
|
|
|
def __ldapConnect(self, dnUser, password):
|
|
|
|
|
"""Соединение с LDAP сервером"""
|
|
|
|
|
conLdap = ldap.initialize('ldap://localhost')
|
|
|
|
|
conLdap.simple_bind_s(dnUser, password)
|
|
|
|
|
return conLdap
|
|
|
|
|
|
|
|
|
|
def ldapSearch(self,baseDN, searchScope, searchFilter, retrieveAttributes):
|
|
|
|
|
try:
|
|
|
|
|
ldap_result_id = self.conLdap.search(baseDN, searchScope,
|
|
|
|
|
searchFilter,
|
|
|
|
|
retrieveAttributes)
|
|
|
|
|
result_set = []
|
|
|
|
|
while 1:
|
|
|
|
|
result_type, result_data = self.conLdap.result(ldap_result_id,
|
|
|
|
|
0)
|
|
|
|
|
if (result_data == []):
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
if result_type == ldap.RES_SEARCH_ENTRY:
|
|
|
|
|
result_set.append(result_data)
|
|
|
|
|
except ldap.NO_SUCH_OBJECT:
|
|
|
|
|
return []
|
|
|
|
|
except:
|
|
|
|
|
return False
|
|
|
|
|
return result_set
|
|
|
|
|
|
|
|
|
|
def ldapAdd(self, strLdif):
|
|
|
|
|
"""Добавляем строку содержащую ldif в LDAP
|
|
|
|
|
|
|
|
|
|
Если данные существуют - ошибка
|
|
|
|
|
"""
|
|
|
|
|
if self.conLdap:
|
|
|
|
|
try:
|
|
|
|
|
# Записываем параметры из ldif файла в LDAP сервер
|
|
|
|
|
parser = addLdif(strLdif,self.conLdap)
|
|
|
|
|
parser.parse()
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.setError(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.setError(_("No connect to LDAP server"))
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# Импортированные классы в cl_ldap
|
|
|
|
|
# Запись ошибок
|
|
|
|
|
imp_cl_err = cl_profile._error
|
|
|
|
|
# Работа с XML
|
|
|
|
|
imp_cl_xml = cl_profile.xmlShare
|
|
|
|
|
# Обработка параметров командной строки
|
|
|
|
|
imp_cl_par = cl_utils2.cl_params
|
|
|
|
|
# Форматированный вывод
|
|
|
|
|
imp_cl_con = cl_utils2.cl_smartconsole
|
|
|
|
|
class cl_ldap(imp_cl_err, imp_cl_xml, imp_cl_par, imp_cl_con):
|
|
|
|
|
"""Основной класс для работы с LDAP"""
|
|
|
|
|
def __init__(self, cmdName):
|
|
|
|
|
self.column_width = 32
|
|
|
|
|
# Алгоритм шифрования пароля для LDAP пользователя
|
|
|
|
|
self.userCrypt = "{SSHA}"
|
|
|
|
|
|
|
|
|
|
# ini файл
|
|
|
|
|
self.iniFile = "/etc/calculate2/calculate.ini"
|
|
|
|
|
servName = ""
|
|
|
|
|
if "user" in cmdName:
|
|
|
|
|
servName = _("user")
|
|
|
|
|
elif "group" in cmdName:
|
|
|
|
|
servName = _("group")
|
|
|
|
|
elif "setup" in cmdName:
|
|
|
|
|
servName = _("service")
|
|
|
|
|
|
|
|
|
|
self.chapter = [\
|
|
|
|
|
# расположение разделов на странице
|
|
|
|
|
# имя раздела, видимый или невидимый, кол. "\n" после
|
|
|
|
|
# названия раздела, кол. "\n" после раздела
|
|
|
|
|
("Copyright",False,0,2),
|
|
|
|
|
(_("Usage"),True,0,1),
|
|
|
|
|
("Function",False,0,2),
|
|
|
|
|
(_("Examples"),True,1,1),
|
|
|
|
|
(_("Options"),True,1,1),
|
|
|
|
|
(_("Services"),True,1,1),
|
|
|
|
|
(_("Informative output"),True,1,0),
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
self.chapterBloc = []
|
|
|
|
|
# разделы справки
|
|
|
|
|
for i in self.chapter:
|
|
|
|
|
self.chapterBloc.append("")
|
|
|
|
|
# имена используемых программ и их номера для доступа к переменным
|
|
|
|
|
# self.data
|
|
|
|
|
self.progName = { 'cl-groupadd':0,
|
|
|
|
|
'cl-groupdel':1,
|
|
|
|
|
'cl-groupmod':2,
|
|
|
|
|
'cl-useradd':3,
|
|
|
|
|
'cl-userdel':4,
|
|
|
|
|
'cl-usermod':5,
|
|
|
|
|
'cl-setup':6,
|
|
|
|
|
}
|
|
|
|
|
self.data = [\
|
|
|
|
|
# Options
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"gid",
|
|
|
|
|
'optVal':"GID",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("use GID for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':"COMMENT",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("set the GECOS field for the new group")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(0,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("print the gidNumber to stdout")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(2,),
|
|
|
|
|
'shortOption':"m",
|
|
|
|
|
'longOption':"member",
|
|
|
|
|
'optVal':"ADD_USERS",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("add members (comma delimited)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(2,),
|
|
|
|
|
'shortOption':"x",
|
|
|
|
|
'longOption':"member",
|
|
|
|
|
'optVal':"DEL_USERS",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("delete members (comma delimted)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"b",
|
|
|
|
|
'longOption':"base-dir",
|
|
|
|
|
'optVal':"BASE_DIR",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("base directory for the new user account home directory")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':"COMMENT",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("set the GECOS field for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"w",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("set the trust account (Windows Workstation)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"g",
|
|
|
|
|
'longOption':"gid",
|
|
|
|
|
'optVal':"GROUP",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("force use GROUP for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"G",
|
|
|
|
|
'longOption':"groups",
|
|
|
|
|
'optVal':"GROUPS",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("list of supplementary groups for the new user account")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(3,),
|
|
|
|
|
#'shortOption':"p",
|
|
|
|
|
#'longOption':"password",
|
|
|
|
|
#'optVal':"PASSWORD",
|
|
|
|
|
#'helpChapter':_("Options"),
|
|
|
|
|
#'help':_("use encrypted password for the new user account")
|
|
|
|
|
#},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"m",
|
|
|
|
|
'longOption':"create-home",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("create home directory for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"s",
|
|
|
|
|
'longOption':"shell",
|
|
|
|
|
'optVal':"SHELL",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("the login shell for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(3,),
|
|
|
|
|
'shortOption':"u",
|
|
|
|
|
'longOption':"uid",
|
|
|
|
|
'optVal':"UID",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("force use the UID for the new user account")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(4,),
|
|
|
|
|
'shortOption':"r",
|
|
|
|
|
'longOption':"remove",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("remove home directory")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"c",
|
|
|
|
|
'longOption':"comment",
|
|
|
|
|
'optVal':"COMMENT",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("new value of the GECOS field")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(5,),
|
|
|
|
|
#'shortOption':"d",
|
|
|
|
|
#'longOption':"home",
|
|
|
|
|
#'optVal':"HOME_DIR",
|
|
|
|
|
#'helpChapter':_("Options"),
|
|
|
|
|
#'help':_("new home directory for the user account")
|
|
|
|
|
#},
|
|
|
|
|
#{'progAccess':(5,),
|
|
|
|
|
#'shortOption':"g",
|
|
|
|
|
#'longOption':"gid",
|
|
|
|
|
#'optVal':"GROUP",
|
|
|
|
|
#'helpChapter':_("Options"),
|
|
|
|
|
#'help':_("force use GROUP as new primary group")
|
|
|
|
|
#},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"G",
|
|
|
|
|
'longOption':"groups",
|
|
|
|
|
'optVal':"GROUPS",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("new list of supplementary GROUPS")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"a",
|
|
|
|
|
'longOption':"append",
|
|
|
|
|
'optVal':"GROUPS",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("append the user to the supplemental GROUPS")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(5,),
|
|
|
|
|
#'shortOption':"l",
|
|
|
|
|
#'longOption':"login",
|
|
|
|
|
#'optVal':"NEW_LOGIN",
|
|
|
|
|
#'helpChapter':_("Options"),
|
|
|
|
|
#'help':_("new value of the login name")
|
|
|
|
|
#},
|
|
|
|
|
#{'progAccess':(5,),
|
|
|
|
|
#'shortOption':"m",
|
|
|
|
|
#'longOption':"move-home",
|
|
|
|
|
#'helpChapter':_("Options"),
|
|
|
|
|
#'help':_("move contents of the home directory to the new location\
|
|
|
|
|
#(use only with -d)")
|
|
|
|
|
#},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"p",
|
|
|
|
|
'longOption':"password",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("new password for the user account (from dialog)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"P",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("new password for the user account (from standart input)")
|
|
|
|
|
},
|
|
|
|
|
{'progAccess':(5,),
|
|
|
|
|
'shortOption':"s",
|
|
|
|
|
'longOption':"shell",
|
|
|
|
|
'optVal':"SHELL",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("new login shell for the user account")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(5,),
|
|
|
|
|
#'shortOption':"u",
|
|
|
|
|
#'longOption':"uid",
|
|
|
|
|
#'optVal':"UID",
|
|
|
|
|
#'helpChapter':_("Options"),
|
|
|
|
|
#'help':_("new UID for the user account")
|
|
|
|
|
#},
|
|
|
|
|
|
|
|
|
|
{'progAccess':(6,),
|
|
|
|
|
'shortOption':"f",
|
|
|
|
|
'longOption':"force",
|
|
|
|
|
'helpChapter':_("Options"),
|
|
|
|
|
'help':_("forced setup service")
|
|
|
|
|
},
|
|
|
|
|
#{'progAccess':(0,1,2,4,5,6),
|
|
|
|
|
#'shortOption':"s",
|
|
|
|
|
#'longOption':"set",
|
|
|
|
|
#'optVal':"<name>=<val>",
|
|
|
|
|
#'helpChapter':_("Options"),
|
|
|
|
|
#'help':_("change enviroment values")
|
|
|
|
|
#},
|
|
|
|
|
#{'shortOption':"e",
|
|
|
|
|
#'longOption':"env",
|
|
|
|
|
#'optVal':"filter",
|
|
|
|
|
#'helpChapter':_("Options"),
|
|
|
|
|
#'help':_("show enviroment values (filter for type, all - no filter)")
|
|
|
|
|
#},
|
|
|
|
|
# Services
|
|
|
|
|
{'helpChapter':_("Services"),
|
|
|
|
|
'help':pcs(" ldap", self.column_width,
|
|
|
|
|
"ldap " + servName, CONWIDTH-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{'helpChapter':_("Services"),
|
|
|
|
|
'help':pcs(" samba", self.column_width,
|
|
|
|
|
"samba " + servName, CONWIDTH-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" mail \t\t\tmail " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" ftp \t\t\tftp " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" proxy \t\tproxy " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" radius \t\tradius " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" jabber \t\tjabber " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" addressbook \t\taddressbook " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" dhcp \t\t\tdhcp " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" named \t\tnamed " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
##{'helpChapter':_("Services"),
|
|
|
|
|
##'help':" wiki \t\t\twiki " + servName + "\n"
|
|
|
|
|
##},
|
|
|
|
|
# Informative output
|
|
|
|
|
{'shortOption':"h",
|
|
|
|
|
'longOption':"help",
|
|
|
|
|
'helpChapter':_("Informative output"),
|
|
|
|
|
'help':_("display this help and exit")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
#'progAccess':(3,),
|
|
|
|
|
'helpChapter':"Copyright",
|
|
|
|
|
'help':Version
|
|
|
|
|
},
|
|
|
|
|
# Использование
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(0,),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " " + " [" + _("options") + "] " +\
|
|
|
|
|
_("group") + " " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(2,),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " " + " [" + _("options") + "] " +\
|
|
|
|
|
_("group") + " " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(3,),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " " + " [" + _("options") + "] " + _("user") +\
|
|
|
|
|
" " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(5,),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " " + " [" + _("options") + "] " + _("user") +\
|
|
|
|
|
" " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(6,),
|
|
|
|
|
'helpChapter':_("Usage"),
|
|
|
|
|
'help': cmdName + " " + " [" + _("options") + "] "+\
|
|
|
|
|
" " + _("service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(0,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Adds group in LDAP directory of service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(1,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Deletes group from LDAP of directory of service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(2,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Modifies group profiles from LDAP of directory of service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(3,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Adds user in LDAP directory of service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(4,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Deletes user from LDAP of directory of service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(5,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Modifies user profiles from LDAP of directory of service")
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(6,),
|
|
|
|
|
'helpChapter':"Function",
|
|
|
|
|
'help':_("Sets service in the system")
|
|
|
|
|
},
|
|
|
|
|
# Примеры
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(0,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs( " cl-groupadd guest ldap", self.column_width,
|
|
|
|
|
"# " + _("add group guest in service")+":\n# LDAP",
|
|
|
|
|
CONWIDTH-self.column_width )
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(2,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs( " cl-groupmod -m guest test ldap", self.column_width,
|
|
|
|
|
"# " + _("add user test to a group guest in service")+":\n# LDAP",
|
|
|
|
|
CONWIDTH-self.column_width )
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(1,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs( " cl-groupdel guest samba", self.column_width,
|
|
|
|
|
"# " + _("delete group guest in service samba") + "."
|
|
|
|
|
, CONWIDTH-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(2,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':""
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(3,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-useradd guest samba", self.column_width,
|
|
|
|
|
"# " +_("add user guest in service samba") + ".",
|
|
|
|
|
CONWIDTH - self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(4,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-userdel guest samba", self.column_width,
|
|
|
|
|
"# " + _("delete user guest in service samba") + ".",
|
|
|
|
|
CONWIDTH-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(5,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-usermod -a test guest samba",
|
|
|
|
|
self.column_width,
|
|
|
|
|
"# " + _("append user guest to the supplemental group test") +\
|
|
|
|
|
".",
|
|
|
|
|
CONWIDTH-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'progAccess':(6,),
|
|
|
|
|
'helpChapter':_("Examples"),
|
|
|
|
|
'help':pcs(" cl-setup samba", self.column_width,
|
|
|
|
|
"# "+_("set service") + " samba "+_("in the system") + ".",
|
|
|
|
|
CONWIDTH-self.column_width)
|
|
|
|
|
},
|
|
|
|
|
#{
|
|
|
|
|
#'helpChapter':_("Examples"),
|
|
|
|
|
#'help':pcs(" " + cmdName + " --env boot", self.column_width,
|
|
|
|
|
#"# "+_("show enviroment varibles which has type")+" 'boot'" +\
|
|
|
|
|
#".",
|
|
|
|
|
#CONWIDTH-self.column_width)
|
|
|
|
|
#},
|
|
|
|
|
#{'progAccess':(0,1,2,4,5,6),
|
|
|
|
|
#'helpChapter':_("Examples"),
|
|
|
|
|
#'help':pcs(" " + cmdName + " \\\n --set setup_march=x86_64",
|
|
|
|
|
#self.column_width, "# "+ _("modify some env") + ".",
|
|
|
|
|
#CONWIDTH-self.column_width)
|
|
|
|
|
#},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
cl_utils2.cl_params.__init__(self, cmdName)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Удаляем ненужный аттрибут класса cl_profile.xmlShare
|
|
|
|
|
self._createElement = False
|
|
|
|
|
delattr(self, "_createElement")
|
|
|
|
|
|
|
|
|
|
#Название всех сервисов
|
|
|
|
|
self.allServ = []
|
|
|
|
|
self.__setAllServ()
|
|
|
|
|
|
|
|
|
|
def __setAllServ(self):
|
|
|
|
|
"""Записывает в аттрибут self.allServ названия всех сервисов"""
|
|
|
|
|
sServ = re.compile("\s*([^\s]+)\s*")
|
|
|
|
|
for par in self.data:
|
|
|
|
|
if par.has_key('helpChapter') and\
|
|
|
|
|
par['helpChapter'] == _("Services") and\
|
|
|
|
|
par.has_key('help'):
|
|
|
|
|
res = sServ.search(par['help'])
|
|
|
|
|
if res:
|
|
|
|
|
self.allServ.append(res.group(1))
|
|
|
|
|
|
|
|
|
|
def getRunService(self, nameService):
|
|
|
|
|
"""Проверка, запущен ли сервис с данным именем"""
|
|
|
|
|
baseDir = "/var/run"
|
|
|
|
|
addDirDict = {"ldap":"openldap",
|
|
|
|
|
"samba":"samba"}
|
|
|
|
|
pidDir = baseDir + "/" + addDirDict[nameService]
|
|
|
|
|
if os.access(pidDir, os.F_OK) and os.listdir(pidDir):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def createLdif(self, ldifFile, objVars):
|
|
|
|
|
"""Cоздает ldif из ldif - профиля"""
|
|
|
|
|
if not os.access(ldifFile, os.F_OK):
|
|
|
|
|
self.setError(_("Not found file:") + "\n " + ldifFile)
|
|
|
|
|
return False
|
|
|
|
|
FD = open (ldifFile)
|
|
|
|
|
ldifProfile = FD.read()
|
|
|
|
|
FD.close()
|
|
|
|
|
clProf = cl_profile.profile(objVars)
|
|
|
|
|
# Применяем условия к профилю
|
|
|
|
|
ldifProfile = clProf.applyTermsProfile(ldifProfile,ldifFile)
|
|
|
|
|
# Заменяем переменные
|
|
|
|
|
ldifProfile = clProf.applyVarsProfile(ldifProfile)
|
|
|
|
|
return ldifProfile
|
|
|
|
|
|
|
|
|
|
def execProg(self, cmdStrProg, inStr=False):
|
|
|
|
|
"""Выполняет внешнюю программу
|
|
|
|
|
|
|
|
|
|
Параметры:
|
|
|
|
|
cmdStrProg внешняя программа
|
|
|
|
|
inStr данные передаваемые программе на страндартный вход.
|
|
|
|
|
Возвращаемые параметры:
|
|
|
|
|
строка которую выведет внешняя программа
|
|
|
|
|
"""
|
|
|
|
|
return cl_utils.runOsCommand(cmdStrProg, inStr, True)
|
|
|
|
|
|
|
|
|
|
def processOptionsForDatavars(self, options, datavars):
|
|
|
|
|
'''Обработать опции связанные с переменными окружения
|
|
|
|
|
|
|
|
|
|
Параметры:
|
|
|
|
|
options словарь опций ( <буква опции>:<значение>
|
|
|
|
|
обрабатывает буквы 's' для установки параметров
|
|
|
|
|
'e' для отображения)
|
|
|
|
|
datavars объект-хранилище переменных окружнения
|
|
|
|
|
|
|
|
|
|
Возвращаемые значения:
|
|
|
|
|
True удалось установить указанные параметры
|
|
|
|
|
False метод вызван для просмотра переменных окружения, или
|
|
|
|
|
установка переменных окружения прошла с ошибками.
|
|
|
|
|
'''
|
|
|
|
|
# если это установка параметров
|
|
|
|
|
if 's' in options:
|
|
|
|
|
# если установки параметрв не произошло
|
|
|
|
|
if not datavars.flFromCmdParam(options['s']):
|
|
|
|
|
# вывод
|
|
|
|
|
print _("Bad enviroment parameters")
|
|
|
|
|
return False
|
|
|
|
|
# если опция отображения параметров
|
|
|
|
|
if 'e' in options:
|
|
|
|
|
# вывод всех параметров
|
|
|
|
|
if options['e'] == '*':
|
|
|
|
|
datavars.printVars()
|
|
|
|
|
# вывод параметров, используюя фильтр
|
|
|
|
|
else:
|
|
|
|
|
datavars.printVars(
|
|
|
|
|
[i.strip() for i in options['e'].split(':')])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def setupLdapServer(self, options):
|
|
|
|
|
"""Начальная настройка LDAP сервиса"""
|
|
|
|
|
# Принудительная установка
|
|
|
|
|
forceOptions = False
|
|
|
|
|
if options.has_key("f"):
|
|
|
|
|
forceOptions = True
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
# прервать если была неудачная попытка установить новые параметры
|
|
|
|
|
# или были опция вывода на печать
|
|
|
|
|
#if not self.processOptionsForDatavars(options,clVars):
|
|
|
|
|
#return ""
|
|
|
|
|
# В случае если сервер установлен
|
|
|
|
|
if clVars.Get("soft_ldap_setup") == "yes" and\
|
|
|
|
|
not forceOptions:
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("LDAP server is configured")+ ".")
|
|
|
|
|
return True
|
|
|
|
|
# Проверим запущен ли ldap
|
|
|
|
|
if self.getRunService("ldap"):
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("The LDAP service is running") + ".")
|
|
|
|
|
print "1. " +_("Stop the LDAP service")
|
|
|
|
|
print " /etc/init.d/slapd stop"
|
|
|
|
|
print "2. " + _("You can save configuration files and a database \
|
|
|
|
|
LDAP in backup directory")
|
|
|
|
|
print "3. " + _("Restart the program")
|
|
|
|
|
return True
|
|
|
|
|
#self.setParamIniFile("setup_LDAP","no")
|
|
|
|
|
clVars.Write("soft_ldap_setup","no")
|
|
|
|
|
# Для тестовых целей устанавливаем директорию инсталяции
|
|
|
|
|
#clVars.Set("setup_path_install","/tmp/test1/")
|
|
|
|
|
# Устанавливаем переменную (говорит о том что первый проход)
|
|
|
|
|
clVars.Set("setup_pass_parser","1",True)
|
|
|
|
|
# Cоздаем объект профиль устанавливая директорию ldap для
|
|
|
|
|
# файлов профилей
|
|
|
|
|
clProf = cl_profile.profile(clVars,"ldap")
|
|
|
|
|
# Объединяем профили
|
|
|
|
|
clProf.applyProfiles()
|
|
|
|
|
# Удаляем предыдущую базу данных
|
|
|
|
|
self.execProg("rm -rf /var/lib/openldap-data/*")
|
|
|
|
|
self.printOK(_("Remove previons LDAP Database ..."))
|
|
|
|
|
# Запускаем LDAP сервер
|
|
|
|
|
textLine = self.execProg("/etc/init.d/slapd start")
|
|
|
|
|
ldifFile = "/usr/lib/calculate/calculate-server/ldif/ldap_base.ldif"
|
|
|
|
|
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
self.printOK(_("LDAP start ..."))
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("LDAP start ..."))
|
|
|
|
|
return False
|
|
|
|
|
baseLdif = self.createLdif(ldifFile, clVars)
|
|
|
|
|
#print baseLdif
|
|
|
|
|
#clVars.printVars()
|
|
|
|
|
ldapObj = ldapFunction(clVars.Get("soft_ldap_admin_tmp"),
|
|
|
|
|
clVars.Get("soft_ldap_adminpw_tmp"))
|
|
|
|
|
if not ldapObj.getError():
|
|
|
|
|
ldapObj.ldapAdd(baseLdif)
|
|
|
|
|
if ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + ldapObj.getError()
|
|
|
|
|
return False
|
|
|
|
|
self.printOK(_("Add ldif file ..."))
|
|
|
|
|
# Удаляем временного пользователя root из конфигурационного файла
|
|
|
|
|
clVars.Set("setup_pass_parser","2",True)
|
|
|
|
|
clProf.applyProfiles()
|
|
|
|
|
# Перезапускаем LDAP сервер
|
|
|
|
|
textLine = self.execProg("/etc/init.d/slapd restart")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
self.printOK(_("LDAP configure and restart ..."))
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("LDAP configure and restart ..."))
|
|
|
|
|
return False
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
ldapParser.setVar("admin",
|
|
|
|
|
{"DN":clVars.Get("soft_ldap_admin"),
|
|
|
|
|
"PASS":clVars.Get("soft_ldap_adminpw")})
|
|
|
|
|
clVars.Write("soft_ldap_setup","yes")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def setupSambaServer(self, options):
|
|
|
|
|
"""Начальная настройка Samba сервиса"""
|
|
|
|
|
# Принудительная установка
|
|
|
|
|
forceOptions = False
|
|
|
|
|
if options.has_key("f"):
|
|
|
|
|
forceOptions = True
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
# прервать если была неудачная попытка установить новые параметры
|
|
|
|
|
# или были опция вывода на печать
|
|
|
|
|
#if not self.processOptionsForDatavars(options,clVars):
|
|
|
|
|
#return ""
|
|
|
|
|
if clVars.Get("soft_ldap_setup") != "yes":
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("LDAP server is not configured")+ ".")
|
|
|
|
|
return False
|
|
|
|
|
# В случае если сервер установлен
|
|
|
|
|
if clVars.Get("soft_samba_setup") == "yes" and\
|
|
|
|
|
not forceOptions:
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("Samba server is configured")+ ".")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
# Проверим запущен ли сервис Samba
|
|
|
|
|
if self.getRunService("samba"):
|
|
|
|
|
self.printWARNING (_("WARNING") + ": " +\
|
|
|
|
|
_("The Samba service is running") + ".")
|
|
|
|
|
print "1. " +_("Stop the Samba service")
|
|
|
|
|
print " /etc/init.d/samba stop"
|
|
|
|
|
print "2. " + _("You can save configuration files \
|
|
|
|
|
Samba in backup directory")
|
|
|
|
|
print "3. " + _("Restart the program")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
# Установим права 777 на директории
|
|
|
|
|
dirs = ["/var/calculate/winnt/profiles",
|
|
|
|
|
"/var/calculate/share"]
|
|
|
|
|
for mDir in dirs:
|
|
|
|
|
if os.path.exists(mDir):
|
|
|
|
|
fd = os.open(mDir, os.O_RDONLY)
|
|
|
|
|
fst = os.fstat(fd)
|
|
|
|
|
mode = stat.S_IMODE(fst.st_mode)
|
|
|
|
|
os.close(fd)
|
|
|
|
|
if not mode == 0777:
|
|
|
|
|
os.chmod(mDir, 0777)
|
|
|
|
|
|
|
|
|
|
clVars.Write("soft_samba_setup","no")
|
|
|
|
|
# Cоздаем объект профиль устанавливая директорию samba для
|
|
|
|
|
# файлов профилей
|
|
|
|
|
clProf = cl_profile.profile(clVars,"samba")
|
|
|
|
|
# Объединяем профили
|
|
|
|
|
clProf.applyProfiles()
|
|
|
|
|
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
pswd = ldapParser.getVar("admin","PASS")
|
|
|
|
|
if not pswd:
|
|
|
|
|
self.printERROR(_("ERROR") + ": " +\
|
|
|
|
|
_("Not find Ldap admin password"))
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("smbpasswd -w %s" %(pswd))
|
|
|
|
|
if not "stored" in textLine:
|
|
|
|
|
self.printERROR(_("ERROR") + ": " +\
|
|
|
|
|
_("Add Ldap admin password"))
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("/etc/init.d/slapd restart")
|
|
|
|
|
if not "ok" in textLine:
|
|
|
|
|
self.printNotOK(_("LDAP restart ..."))
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("/etc/init.d/samba start")
|
|
|
|
|
if "ok" in textLine:
|
|
|
|
|
self.printOK(_("Samba start ..."))
|
|
|
|
|
else:
|
|
|
|
|
self.printNotOK(_("Samba start ..."))
|
|
|
|
|
return False
|
|
|
|
|
print _("Enter the ROOT password")
|
|
|
|
|
if not self.addUserSambaServer('root',{},clVars):
|
|
|
|
|
return False
|
|
|
|
|
clVars.Write("soft_samba_setup","yes")
|
|
|
|
|
self.printOK(_("Samba service configured ..."))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def addMashineSambaServer(self, machineName, options, clVars=False):
|
|
|
|
|
"""Добавляет Samba машину в LDAP-сервер"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
machineLogin = machineName.replace('$','') + "$"
|
|
|
|
|
res = self.searchLdapUser(machineLogin, ldapObj, clVars,"ou=Computers")
|
|
|
|
|
if res:
|
|
|
|
|
if res[0][0][1].has_key('sambaSID'):
|
|
|
|
|
self.printERROR(_("machine")+" "+machineLogin+" "+\
|
|
|
|
|
"found in LDAP")
|
|
|
|
|
return True
|
|
|
|
|
# добавляем Samba машину
|
|
|
|
|
textLine = self.execProg("smbpasswd -a -m %s" %machineLogin)
|
|
|
|
|
if "Added" in str(textLine):
|
|
|
|
|
self.printSUCCESS(_("Add machine in samba service ..."))
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Not add machine ..."))
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
# добавляем LDAP машину
|
|
|
|
|
if not self.addMashineLdapServer(machineLogin, options, clVars):
|
|
|
|
|
return False
|
|
|
|
|
# добавляем Samba машину
|
|
|
|
|
textLine = self.execProg("smbpasswd -a -m %s" %machineLogin)
|
|
|
|
|
if "Added" in str(textLine):
|
|
|
|
|
self.printSUCCESS(_("Add machine in samba service ..."))
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Not add machine ..."))
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def addMashineLdapServer(self, machineName, options, clVars=False):
|
|
|
|
|
"""Добавляет LDAP машину в LDAP-сервер"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
machineLogin = machineName.replace('$','') + "$"
|
|
|
|
|
groupName = clVars.Get('soft_ldap_machine_group_name')
|
|
|
|
|
groupId = clVars.Get('soft_ldap_machine_gid')
|
|
|
|
|
if not self.searchLdapGroupName(groupName, ldapObj, clVars):
|
|
|
|
|
res = self.searchLdapGid(groupId, ldapObj, clVars)
|
|
|
|
|
maxGid = self.getUidMax()
|
|
|
|
|
if res:
|
|
|
|
|
numberGid = int(groupId)
|
|
|
|
|
flagMaxGidError = False
|
|
|
|
|
while res:
|
|
|
|
|
numberGid += 1
|
|
|
|
|
res = self.searchLdapGid(str(numberGid), ldapObj, clVars)
|
|
|
|
|
if numberGid>=maxGid:
|
|
|
|
|
flagMaxGidError = True
|
|
|
|
|
break
|
|
|
|
|
if flagMaxGidError:
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("not foung free GID in ldap") + userGid)
|
|
|
|
|
return False
|
|
|
|
|
groupId = str(numberGid)
|
|
|
|
|
clVars.Write('soft_ldap_machine_gid', groupId)
|
|
|
|
|
options = {'g':groupId,'c':'Computer group'}
|
|
|
|
|
if not self.addGroupLdapServer(groupName, options, clVars):
|
|
|
|
|
return False
|
|
|
|
|
clVars.Set('soft_ldap_machine_login',machineLogin)
|
|
|
|
|
# Находим последний добавленный id компьютера
|
|
|
|
|
maxIdMachine = self.getMaxUidLdap(ldapObj, clVars, "ou=Computers")
|
|
|
|
|
idMachineStart = int(clVars.Get('soft_ldap_machine_id'))
|
|
|
|
|
if maxIdMachine:
|
|
|
|
|
userIdNumber = maxIdMachine + 1
|
|
|
|
|
else:
|
|
|
|
|
userIdNumber = idMachineStart
|
|
|
|
|
clVars.Set('soft_ldap_machine_id',str(userIdNumber))
|
|
|
|
|
clVars.Set('soft_ldap_machine_gid',groupId)
|
|
|
|
|
ldifFile="/usr/lib/calculate/calculate-server/ldif/ldap_machine.ldif"
|
|
|
|
|
userLdif = self.createLdif(ldifFile, clVars)
|
|
|
|
|
if not ldapObj.getError():
|
|
|
|
|
#Добавляем пользователя в LDAP
|
|
|
|
|
ldapObj.ldapAdd(userLdif)
|
|
|
|
|
if ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + ldapObj.getError()
|
|
|
|
|
return False
|
|
|
|
|
#clVars.Write("soft_ldap_user_id",str(int(userId)+1))
|
|
|
|
|
self.printSUCCESS(_("Add machine ..."))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUserInGroup(self, userName, ldapObj, clVars):
|
|
|
|
|
"""Удаление из групп в которые входит пользователь"""
|
|
|
|
|
userInGroups = self.searchLdapMemberGid(userName, ldapObj, clVars)
|
|
|
|
|
for group in userInGroups:
|
|
|
|
|
groupName = group[0][1]['cn'][0]
|
|
|
|
|
modAttrs = [(ldap.MOD_DELETE, 'memberUid', userName)]
|
|
|
|
|
try:
|
|
|
|
|
ldapObj.conLdap.modify_s("cn=%s,%s,%s"\
|
|
|
|
|
%(groupName,"ou=Groups",clVars.Get("soft_ldap_base")),
|
|
|
|
|
modAttrs)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delUserLdapServer(self, userName, options, clVars=False,
|
|
|
|
|
orgUnit="ou=Users"):
|
|
|
|
|
"""Удаляем LDAP пользователя"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
# Ищем пользователя в LDAP
|
|
|
|
|
resLdap = self.searchLdapUser(userName, ldapObj, clVars)
|
|
|
|
|
if not resLdap:
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("User") + " " + str(userName) + " " +\
|
|
|
|
|
_("not foung in LDAP"))
|
|
|
|
|
return False
|
|
|
|
|
deleteDN = "uid=%s,%s,%s"\
|
|
|
|
|
%(userName,orgUnit,clVars.Get("soft_ldap_base"))
|
|
|
|
|
#Удаление пользователя
|
|
|
|
|
try:
|
|
|
|
|
ldapObj.conLdap.delete_s(deleteDN)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем пользователя из групп
|
|
|
|
|
if not self.delUserInGroup(userName, ldapObj, clVars):
|
|
|
|
|
return False
|
|
|
|
|
if resLdap[0][0][1].has_key('gidNumber'):
|
|
|
|
|
gid = resLdap[0][0][1]['gidNumber'][0]
|
|
|
|
|
else:
|
|
|
|
|
resPasswd = self.searchPasswdUser(userName)
|
|
|
|
|
if resPasswd:
|
|
|
|
|
gid = resPasswd.split(":")[2]
|
|
|
|
|
#Находим основную группу пользователя
|
|
|
|
|
resGroup = False
|
|
|
|
|
if gid:
|
|
|
|
|
resGroup = self.searchLdapGid(gid, ldapObj, clVars)
|
|
|
|
|
if resGroup:
|
|
|
|
|
# В случае отсутствия других пользователей удаляем основную группу
|
|
|
|
|
if not resGroup[0][0][1].has_key('memberUid'):
|
|
|
|
|
groupName = resGroup[0][0][1]['cn'][0]
|
|
|
|
|
if not self.delGroupLdapServer(groupName, {}, clVars):
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('r') and\
|
|
|
|
|
resLdap[0][0][1].has_key('homeDirectory'):
|
|
|
|
|
#Домашняя директория пользователя
|
|
|
|
|
homeDir = resLdap[0][0][1]['homeDirectory'][0]
|
|
|
|
|
if self.removeHomeDir(homeDir):
|
|
|
|
|
self.printSUCCESS(_("Home dir") + " " + str(homeDir) + " " +\
|
|
|
|
|
_("deleted") + " ...")
|
|
|
|
|
self.printSUCCESS(_("User") + " " + userName + " " + _("deleted") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def addUserLdapServer(self, userName, options, clVars=False,optOut=False,
|
|
|
|
|
pwDialog=False):
|
|
|
|
|
"""Добавляет LDAP пользователя в LDAP-сервер"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
# прервать если была неудачная попытка установить новые параметры
|
|
|
|
|
# или были опция вывода на печать
|
|
|
|
|
#if not self.processOptionsForDatavars(options,clVars):
|
|
|
|
|
#return ""
|
|
|
|
|
#userId = clVars.Get("soft_ldap_user_id")
|
|
|
|
|
#if not userId:
|
|
|
|
|
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
|
|
|
|
|
# Добавление машины
|
|
|
|
|
if options.has_key('w'):
|
|
|
|
|
if self.addMashineLdapServer(userName, options, clVars):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# id нового пользователя
|
|
|
|
|
userId = str(self.getMaxUid(ldapObj, clVars))
|
|
|
|
|
#userId = str(userId)
|
|
|
|
|
#clVars.Set("soft_ldap_user_id",userId)
|
|
|
|
|
clVars.Set("soft_ldap_user_login",userName)
|
|
|
|
|
baseDir = "/home"
|
|
|
|
|
# Базовая домашняя директория
|
|
|
|
|
if options.has_key('b'):
|
|
|
|
|
baseDir = options['b']
|
|
|
|
|
# Устанавливаем базовую домашнюю директорию
|
|
|
|
|
homeDir = os.path.join(baseDir, clVars.Get("soft_ldap_user_login"))
|
|
|
|
|
clVars.Set("soft_ldap_user_home",homeDir)
|
|
|
|
|
|
|
|
|
|
fullNameUser = "CDS user"
|
|
|
|
|
# Полное имя пользователя
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
fullNameUser = options['c']
|
|
|
|
|
clVars.Set("soft_ldap_user_full_name",fullNameUser)
|
|
|
|
|
|
|
|
|
|
if self.searchLdapUser(userName, ldapObj, clVars):
|
|
|
|
|
self.printERROR(_("User exists in LDAP"))
|
|
|
|
|
return False
|
|
|
|
|
elif self.searchPasswdUser(userName):
|
|
|
|
|
self.printERROR(_("User exists in /etc/passwd"))
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
userShell = "/bin/bash"
|
|
|
|
|
# Оболочка пользователя
|
|
|
|
|
if options.has_key('s'):
|
|
|
|
|
userShell = options['s']
|
|
|
|
|
clVars.Set("soft_ldap_user_shell", userShell)
|
|
|
|
|
|
|
|
|
|
# id пользователя
|
|
|
|
|
if options.has_key('u'):
|
|
|
|
|
userId = options['u']
|
|
|
|
|
try:
|
|
|
|
|
int(userId)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("UID not number") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if self.searchUidLdap(userId, ldapObj, clVars):
|
|
|
|
|
self.printERROR("UID %s "%userId + _("exists in LDAP") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
if self.searchUidPasswd(userId):
|
|
|
|
|
self.printERROR("UID %s "%userId+_("exists in /etc/passwd")+\
|
|
|
|
|
" ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
clVars.Set("soft_ldap_user_id",userId)
|
|
|
|
|
|
|
|
|
|
# Добавляем пользователя в группы (находим имена групп)
|
|
|
|
|
if options.has_key('G'):
|
|
|
|
|
userGroups = options['G'].split(',')
|
|
|
|
|
#список имен добавляемых групп
|
|
|
|
|
userGroupNames = self.searchGroupsLdap(userGroups,
|
|
|
|
|
ldapObj, clVars)
|
|
|
|
|
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
userGid = str(self.getMaxGid(ldapObj, clVars))
|
|
|
|
|
# Группа пользователя
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
userGid = options['g']
|
|
|
|
|
userGidNamesLdap = self.searchGroupsLdap([userGid],
|
|
|
|
|
ldapObj, clVars, False)
|
|
|
|
|
userGidNamesPasswd = self.searchGroupsGroups([userGid], False)
|
|
|
|
|
if userGidNamesPasswd:
|
|
|
|
|
#Имя группы пользователя
|
|
|
|
|
groupName = userGidNamesPasswd[0]
|
|
|
|
|
elif userGidNamesLdap:
|
|
|
|
|
#Имя группы пользователя
|
|
|
|
|
groupName = userGidNamesLdap[0]
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Group") + " " + str(userGid) + " " +\
|
|
|
|
|
_("not found") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
#userPwd = "crypt{xxx}"
|
|
|
|
|
# Пароль пользователя зашифрованный
|
|
|
|
|
if options.has_key('p'):
|
|
|
|
|
userPwd = options['p']
|
|
|
|
|
else:
|
|
|
|
|
if pwDialog:
|
|
|
|
|
pwdA = getpass.getpass(pwDialog[0]+":")
|
|
|
|
|
pwdB = getpass.getpass(pwDialog[1]+":")
|
|
|
|
|
else:
|
|
|
|
|
pwdA = getpass.getpass(_("New password")+":")
|
|
|
|
|
pwdB = getpass.getpass(_("Retype new password")+":")
|
|
|
|
|
if not (pwdA == pwdB):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("password incorrect")+ ": " + _("try again"))
|
|
|
|
|
return False
|
|
|
|
|
userPwd = pwdA
|
|
|
|
|
|
|
|
|
|
userPwdHash =\
|
|
|
|
|
self.execProg("slappasswd -s %s -h %s" %(userPwd,self.userCrypt))
|
|
|
|
|
if userPwdHash:
|
|
|
|
|
userPwd = userPwdHash
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("create crypto password"))
|
|
|
|
|
return False
|
|
|
|
|
clVars.Set("soft_ldap_user_pw_hash",userPwd)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Добавление основной группы пользователя
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
resLdap = self.searchLdapGroupName(groupName, ldapObj, clVars)
|
|
|
|
|
resGroup = self.searchGroupGroupName(groupName)
|
|
|
|
|
if not (resLdap or resGroup):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("not found gid=") + userGid)
|
|
|
|
|
return False
|
|
|
|
|
if resGroup:
|
|
|
|
|
userGid = resGroup.split(":")[2]
|
|
|
|
|
if resLdap:
|
|
|
|
|
userGid = resLdap[0][0][1]['gidNumber'][0]
|
|
|
|
|
else:
|
|
|
|
|
self.addGroupLdapServer(userName,{},clVars)
|
|
|
|
|
clVars.Set("soft_ldap_user_gid",userGid)
|
|
|
|
|
|
|
|
|
|
ldifFile = "/usr/lib/calculate/calculate-server/ldif/ldap_user.ldif"
|
|
|
|
|
userLdif = self.createLdif(ldifFile, clVars)
|
|
|
|
|
if not ldapObj.getError():
|
|
|
|
|
#Добавляем пользователя в LDAP
|
|
|
|
|
ldapObj.ldapAdd(userLdif)
|
|
|
|
|
#Добавляем его в другие группы (опция G)
|
|
|
|
|
if options.has_key('G') and userGroupNames:
|
|
|
|
|
for group in userGroupNames:
|
|
|
|
|
self.addUserGroupLdap([userName],
|
|
|
|
|
group, ldapObj, clVars)
|
|
|
|
|
# не переделывать на else
|
|
|
|
|
if ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + ldapObj.getError()
|
|
|
|
|
return False
|
|
|
|
|
# Добавим домашнюю директорию
|
|
|
|
|
if options.has_key('m'):
|
|
|
|
|
if not os.path.exists(homeDir):
|
|
|
|
|
if not self.createHomeDir(userName, homeDir, ldapObj, clVars):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " + _("create HOME dir"))
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Create home dir")+ " " + homeDir + " ...")
|
|
|
|
|
self.printSUCCESS(_("Add user ..."))
|
|
|
|
|
# return passwd
|
|
|
|
|
if optOut and optOut =='passwd':
|
|
|
|
|
return userPwd
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def addUserGroupLdap(self, users, groupName, ldapObj, clVars):
|
|
|
|
|
"""Добавляет пользователей из списка в LDAP группу"""
|
|
|
|
|
if not self.searchLdapGroupName(groupName, ldapObj, clVars):
|
|
|
|
|
self.printERROR(_("group name not found in LDAP ..."))
|
|
|
|
|
return False
|
|
|
|
|
flagFalse = False
|
|
|
|
|
for userName in users:
|
|
|
|
|
if not (self.searchLdapUser(userName, ldapObj, clVars) or\
|
|
|
|
|
self.searchPasswdUser(userName)):
|
|
|
|
|
self.printERROR(_("User") + " " + str(userName) + " " +\
|
|
|
|
|
_("not found ..."))
|
|
|
|
|
flagFalse = True
|
|
|
|
|
break
|
|
|
|
|
if flagFalse:
|
|
|
|
|
return False
|
|
|
|
|
foundUsersLdap = self.searchUsersInGroupLdap(users, groupName,
|
|
|
|
|
ldapObj, clVars)
|
|
|
|
|
foundUsersGroup = self.searchUsersInGroupGroup(users, groupName)
|
|
|
|
|
foundUsers = []
|
|
|
|
|
if foundUsersLdap and foundUsersGroup:
|
|
|
|
|
foundUsers = unicList(foundUsersLdap + foundUsersGroup)
|
|
|
|
|
elif foundUsersLdap:
|
|
|
|
|
foundUsers = foundUsersLdap
|
|
|
|
|
elif foundUsersGroup:
|
|
|
|
|
foundUsers = foundUsersGroup
|
|
|
|
|
addUsers = []
|
|
|
|
|
for user in users:
|
|
|
|
|
if not(user in foundUsers):
|
|
|
|
|
addUsers.append(user)
|
|
|
|
|
modAttrs = []
|
|
|
|
|
for userName in addUsers:
|
|
|
|
|
modAttrs.append((ldap.MOD_ADD, 'memberUid', userName))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
try:
|
|
|
|
|
ldapObj.conLdap.modify_s("cn=%s,ou=Groups,%s"\
|
|
|
|
|
%(groupName,clVars.Get("soft_ldap_base")), modAttrs)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def addGroupLdapServer(self, groupName, options, clVars=False):
|
|
|
|
|
"""Добавляет группу пользователей LDAP"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
|
|
|
|
|
# прервать если была неудачная попытка установить новые параметры
|
|
|
|
|
# или были опция вывода на печать
|
|
|
|
|
#if not self.processOptionsForDatavars(options,clVars):
|
|
|
|
|
#return ""
|
|
|
|
|
clVars.Set("soft_ldap_group_name",groupName)
|
|
|
|
|
|
|
|
|
|
#gid = clVars.Get("soft_ldap_group_id")
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
|
|
|
|
|
if self.searchGroupGroupName(groupName):
|
|
|
|
|
self.printERROR(_("group name found in /etc/group ..."))
|
|
|
|
|
return False
|
|
|
|
|
if self.searchLdapGroupName(groupName, ldapObj, clVars):
|
|
|
|
|
self.printERROR(_("group name found in LDAP ..."))
|
|
|
|
|
return False
|
|
|
|
|
# номер группы
|
|
|
|
|
#if not gid:
|
|
|
|
|
gid = str(self.getMaxGid(ldapObj, clVars))
|
|
|
|
|
#clVars.Write("soft_ldap_group_id","1000")
|
|
|
|
|
#gid = str(gid)
|
|
|
|
|
if options.has_key('g'):
|
|
|
|
|
gid = options['g']
|
|
|
|
|
try:
|
|
|
|
|
int(gid)
|
|
|
|
|
except:
|
|
|
|
|
self.printERROR(_("gid not number ..."))
|
|
|
|
|
return False
|
|
|
|
|
if self.searchGroupGid(gid):
|
|
|
|
|
self.printERROR(_("gid found in /etc/group ..."))
|
|
|
|
|
return False
|
|
|
|
|
if self.searchLdapGid(gid, ldapObj, clVars):
|
|
|
|
|
self.printERROR(_("gid found in LDAP ..."))
|
|
|
|
|
return False
|
|
|
|
|
clVars.Set("soft_ldap_group_id", gid)
|
|
|
|
|
|
|
|
|
|
gecos = "CDS group"
|
|
|
|
|
# Коментарий к группе
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
gecos = options['c']
|
|
|
|
|
clVars.Set("soft_ldap_group_desc",gecos)
|
|
|
|
|
|
|
|
|
|
ldifFile = "/usr/lib/calculate/calculate-server/ldif/ldap_group.ldif"
|
|
|
|
|
userLdif = self.createLdif(ldifFile, clVars)
|
|
|
|
|
if not userLdif:
|
|
|
|
|
print self.getError()
|
|
|
|
|
return False
|
|
|
|
|
if not ldapObj.getError():
|
|
|
|
|
ldapObj.ldapAdd(userLdif)
|
|
|
|
|
if ldapObj.getError():
|
|
|
|
|
print _("LDAP Error") + ": " + ldapObj.getError()
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('p'):
|
|
|
|
|
sys.stdout.write(gid)
|
|
|
|
|
else:
|
|
|
|
|
self.printSUCCESS(_("Add group ..."))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def delGroupLdapServer(self, groupName, options, clVars=False,
|
|
|
|
|
orgUnit="ou=Groups"):
|
|
|
|
|
"""Удаляет группу пользователей LDAP"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
|
|
|
|
|
#gid = clVars.Get("soft_ldap_group_id")
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
|
|
|
|
|
res = self.searchLdapGroupName(groupName, ldapObj, clVars)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(_("Group") + " " + groupName + " "+\
|
|
|
|
|
_("not found in LDAP ..."))
|
|
|
|
|
return False
|
|
|
|
|
groupId = res[0][0][1]['gidNumber'][0]
|
|
|
|
|
if self.searchLdapUserPrimGroup(groupId, ldapObj, clVars):
|
|
|
|
|
self.printERROR(_("cannot remove user's primary group") + ".")
|
|
|
|
|
return False
|
|
|
|
|
deleteDN = "cn=%s,%s,%s"\
|
|
|
|
|
%(groupName,orgUnit,clVars.Get("soft_ldap_base"))
|
|
|
|
|
# Удаление группы
|
|
|
|
|
try:
|
|
|
|
|
ldapObj.conLdap.delete_s(deleteDN)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Group") + " " + groupName + " " + _("deleted") +\
|
|
|
|
|
" ...")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def searchLdapUser(self, userName, ldapObj, clVars, orgUnit="ou=Users"):
|
|
|
|
|
"""Находит пользователя сервиса LDAP"""
|
|
|
|
|
baseDN = "%s,%s"%(orgUnit,clVars.Get("soft_ldap_base"))
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "uid=%s" %(userName)
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchLdapUserPrimGroup(self, groupId, ldapObj, clVars):
|
|
|
|
|
"""Находит пользователей с первичной группой groupId"""
|
|
|
|
|
baseDN = "%s,%s"%("ou=Users",clVars.Get("soft_ldap_base"))
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "gidNumber=%s" %(groupId)
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def searchSambaUser(self, userName, ldapObj, clVars):
|
|
|
|
|
"""Находит пользователя сервиса LDAP"""
|
|
|
|
|
baseDN = "ou=Users,%s"\
|
|
|
|
|
% clVars.Get("soft_ldap_base")
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "uid=%s" %(userName)
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
if resSearch:
|
|
|
|
|
resSearch = resSearch[0][0][1]
|
|
|
|
|
if resSearch.has_key("sambaSID"):
|
|
|
|
|
return resSearch
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def searchUidPasswd(self, userId):
|
|
|
|
|
"""Находит пользователя по его идентефикатору из /etc/passwd"""
|
|
|
|
|
filePasswd = "/etc/passwd"
|
|
|
|
|
if os.path.exists(filePasswd):
|
|
|
|
|
FD = open(filePasswd)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
userIds = []
|
|
|
|
|
for line in lines:
|
|
|
|
|
userIds.append(line.split(":")[2])
|
|
|
|
|
if userId in userIds:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def searchUidLdap(self, userId, ldapObj, clVars):
|
|
|
|
|
"""Находит пользователя по его идентефикатору из LDAP"""
|
|
|
|
|
baseDN = "ou=Users,%s"\
|
|
|
|
|
% clVars.Get("soft_ldap_base")
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "uid=*"
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
uids = []
|
|
|
|
|
if resSearch:
|
|
|
|
|
for scope in resSearch:
|
|
|
|
|
if scope[0][1].has_key('uidNumber'):
|
|
|
|
|
uid = scope[0][1]['uidNumber'][0]
|
|
|
|
|
uids.append(uid)
|
|
|
|
|
if userId in uids:
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def searchLdapGroupName(self, groupName, ldapObj, clVars):
|
|
|
|
|
"""Находит группу сервиса LDAP по её имени"""
|
|
|
|
|
baseDN = "ou=Groups,%s"\
|
|
|
|
|
% clVars.Get("soft_ldap_base")
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "cn=%s" %(groupName)
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchUsersInGroupLdap(self, usersNames, groupName, ldapObj, clVars):
|
|
|
|
|
"""Ищет спиcок пользователей в группе, ищет в LDAP
|
|
|
|
|
|
|
|
|
|
В случае успеха выводит список найденных пользователей
|
|
|
|
|
если нет группы False
|
|
|
|
|
если ничего не найдено пустой список
|
|
|
|
|
"""
|
|
|
|
|
res = self.searchLdapGroupName(groupName, ldapObj, clVars)
|
|
|
|
|
if not res:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
findUsers = []
|
|
|
|
|
if res[0][0][1].has_key('memberUid'):
|
|
|
|
|
usersInGroup = res[0][0][1]['memberUid']
|
|
|
|
|
for userName in usersNames:
|
|
|
|
|
if userName in usersInGroup:
|
|
|
|
|
findUsers.append(userName)
|
|
|
|
|
return findUsers
|
|
|
|
|
|
|
|
|
|
def searchUsersInGroupGroup(self, usersNames, groupName):
|
|
|
|
|
"""Ищет спиcок пользователей в группе, ищет в /etc/groups
|
|
|
|
|
|
|
|
|
|
В случае успеха выводит список найденных пользователей
|
|
|
|
|
если нет группы False
|
|
|
|
|
если ничего не найдено пустой список
|
|
|
|
|
"""
|
|
|
|
|
res = self.searchGroupGroupName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
findUsers = []
|
|
|
|
|
res = res.rstrip()
|
|
|
|
|
usersInGroup = res.split(':')[3]
|
|
|
|
|
if not usersInGroup:
|
|
|
|
|
return findUsers
|
|
|
|
|
usersInGroup = usersInGroup.split(',')
|
|
|
|
|
for userName in usersNames:
|
|
|
|
|
if userName in usersInGroup:
|
|
|
|
|
findUsers.append(userName)
|
|
|
|
|
return findUsers
|
|
|
|
|
|
|
|
|
|
def searchLdapGid(self, groupId, ldapObj, clVars):
|
|
|
|
|
"""Находит группу сервиса LDAP по ёе id"""
|
|
|
|
|
baseDN = "ou=Groups,%s"\
|
|
|
|
|
% clVars.Get("soft_ldap_base")
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "gidNumber=%s" %(str(groupId))
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchLdapMemberGid(self, userName, ldapObj, clVars):
|
|
|
|
|
"""Находит группу сервиса LDAP по ёе id"""
|
|
|
|
|
baseDN = "ou=Groups,%s"\
|
|
|
|
|
% clVars.Get("soft_ldap_base")
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "memberUid=%s" %(userName)
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
return resSearch
|
|
|
|
|
|
|
|
|
|
def searchGroupsGroups(self, userGroups, printError=True):
|
|
|
|
|
"""Ищет список групп из списка userGroups в /etc/group
|
|
|
|
|
|
|
|
|
|
Список групп может состоять из чисел или названий групп
|
|
|
|
|
Возвращает список имен групп
|
|
|
|
|
"""
|
|
|
|
|
userGroupNames = []
|
|
|
|
|
flagInt = True
|
|
|
|
|
for gid in userGroups:
|
|
|
|
|
try:
|
|
|
|
|
int(gid)
|
|
|
|
|
except:
|
|
|
|
|
flagInt = False
|
|
|
|
|
break
|
|
|
|
|
flagError = False
|
|
|
|
|
if flagInt:
|
|
|
|
|
for gidNumber in userGroups:
|
|
|
|
|
res = self.searchGroupGid(gidNumber)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
userGroupNames.append(res.split(':')[0])
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(_("Group number") + " " + str(gidNumber) +\
|
|
|
|
|
" " + _("not found in /etc/group") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
for groupName in userGroups:
|
|
|
|
|
res = self.searchGroupGroupName(groupName)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(_("Group name") + " " + str(groupName) +\
|
|
|
|
|
" " + _("not found in /etc/group") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
userGroupNames = userGroups
|
|
|
|
|
return userGroupNames
|
|
|
|
|
|
|
|
|
|
def searchGroupsLdap(self, userGroups, ldapObj, clVars, printError=True):
|
|
|
|
|
"""Ищет список групп из списка userGroups в LDAP
|
|
|
|
|
|
|
|
|
|
Список групп может состоять из чисел или названий групп
|
|
|
|
|
Возвращает список имен групп
|
|
|
|
|
"""
|
|
|
|
|
userGroupNames = []
|
|
|
|
|
flagInt = True
|
|
|
|
|
for gid in userGroups:
|
|
|
|
|
try:
|
|
|
|
|
int(gid)
|
|
|
|
|
except:
|
|
|
|
|
flagInt = False
|
|
|
|
|
break
|
|
|
|
|
flagError = False
|
|
|
|
|
if flagInt:
|
|
|
|
|
for gidNumber in userGroups:
|
|
|
|
|
res = self.searchLdapGid(gidNumber, ldapObj, clVars)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
userGroupNames.append(res[0][0][1]['cn'][0])
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(_("Group number") + " " + str(gidNumber) +\
|
|
|
|
|
" " + _("not found in LDAP") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
for groupName in userGroups:
|
|
|
|
|
res = self.searchLdapGroupName(groupName, ldapObj, clVars)
|
|
|
|
|
if not res:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
if printError:
|
|
|
|
|
self.printERROR(_("Group name") + " " + str(groupName) +\
|
|
|
|
|
" " + _("not found in LDAP") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
userGroupNames = userGroups
|
|
|
|
|
return userGroupNames
|
|
|
|
|
|
|
|
|
|
def searchGroupGid(self, groupId):
|
|
|
|
|
"""Ищет gid в /etc/group"""
|
|
|
|
|
gId = int(groupId)
|
|
|
|
|
fileGroup = "/etc/group"
|
|
|
|
|
if os.path.exists(fileGroup):
|
|
|
|
|
FD = open(fileGroup)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
res = ""
|
|
|
|
|
for line in lines:
|
|
|
|
|
gid = int(line.split(":")[2])
|
|
|
|
|
if gid == gId:
|
|
|
|
|
res = line
|
|
|
|
|
break
|
|
|
|
|
return res
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def searchGroupGroupName(self, groupName):
|
|
|
|
|
"""Ищет имя группы в /etc/group"""
|
|
|
|
|
fileGroup = "/etc/group"
|
|
|
|
|
if os.path.exists(fileGroup):
|
|
|
|
|
FD = open(fileGroup)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
res = ""
|
|
|
|
|
for line in lines:
|
|
|
|
|
gName = line.split(":")[0]
|
|
|
|
|
if gName == groupName:
|
|
|
|
|
res = line
|
|
|
|
|
break
|
|
|
|
|
return res
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def searchPasswdUser(self, userName):
|
|
|
|
|
"""Ищет пользователей в /etc/passwd"""
|
|
|
|
|
filePasswd = "/etc/passwd"
|
|
|
|
|
if os.path.exists(filePasswd):
|
|
|
|
|
FD = open(filePasswd)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
lineUser = ""
|
|
|
|
|
for line in lines:
|
|
|
|
|
if userName == line.split(":")[0]:
|
|
|
|
|
lineUser = line
|
|
|
|
|
break
|
|
|
|
|
if lineUser:
|
|
|
|
|
return lineUser
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getUidMin(self):
|
|
|
|
|
"""Получаем начальный UID пользователя"""
|
|
|
|
|
fileLogin = "/etc/login.defs"
|
|
|
|
|
fileAdduser = "/etc/adduser.conf"
|
|
|
|
|
uidMin = 1000
|
|
|
|
|
if os.path.exists(fileLogin):
|
|
|
|
|
FD = open(fileLogin)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if "UID_MIN" in line and not "#" in line:
|
|
|
|
|
s = re.compile("\s+")
|
|
|
|
|
uidMin = int(s.split(line)[1])
|
|
|
|
|
break
|
|
|
|
|
elif os.path.exists(fileAdduser):
|
|
|
|
|
FD = open(fileLogin)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if "FIRST_UID" in line and not "#" in line:
|
|
|
|
|
uidMin = int(line.split('=')[1])
|
|
|
|
|
break
|
|
|
|
|
return uidMin
|
|
|
|
|
|
|
|
|
|
def chownR(self, directory, uid, gid):
|
|
|
|
|
"""изменяет владельца и группу
|
|
|
|
|
|
|
|
|
|
для всех файлов и директорий внутри directory
|
|
|
|
|
"""
|
|
|
|
|
scanObjs = fileObj.scanDirs([directory])
|
|
|
|
|
# меняем владельца домашней директории
|
|
|
|
|
os.chown(directory, uid,gid)
|
|
|
|
|
# Меняем владельца директорий
|
|
|
|
|
for dirCh in scanObjs[0].dirs:
|
|
|
|
|
os.chown(dirCh, uid,gid)
|
|
|
|
|
# Меняем владельца файлов
|
|
|
|
|
for fileCh in scanObjs[0].files:
|
|
|
|
|
os.chown(fileCh, uid,gid)
|
|
|
|
|
# Меняем владельца ссылок
|
|
|
|
|
for linkCh in scanObjs[0].links:
|
|
|
|
|
os.lchown(linkCh[1], uid, gid)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def createHomeDir(self, userName, homeDir, ldapObj, clVars):
|
|
|
|
|
"""Создаем домашнюю директорию пользователя
|
|
|
|
|
|
|
|
|
|
создание происходит после создания пользователя
|
|
|
|
|
"""
|
|
|
|
|
skelDir = "/etc/skel"
|
|
|
|
|
resLdap = self.searchLdapUser(userName, ldapObj, clVars)
|
|
|
|
|
if resLdap:
|
|
|
|
|
uid = int(resLdap[0][0][1]['uidNumber'][0])
|
|
|
|
|
gid = int(resLdap[0][0][1]['gidNumber'][0])
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
if not os.path.exists(homeDir):
|
|
|
|
|
# Создаем домашнюю директорию
|
|
|
|
|
os.makedirs(homeDir)
|
|
|
|
|
# Файловый объект
|
|
|
|
|
fileObj = cl_profile._file()
|
|
|
|
|
# Сканируем скелетную директорию
|
|
|
|
|
scanObjs = fileObj.scanDirs([skelDir])
|
|
|
|
|
if not scanObjs:
|
|
|
|
|
return True
|
|
|
|
|
for dirCreate in scanObjs[0].dirs:
|
|
|
|
|
#создаем в домашней директории директории из /etc/skel
|
|
|
|
|
fileObj.createDir(skelDir, dirCreate, homeDir)
|
|
|
|
|
dirName = homeDir + dirCreate.split(skelDir)[1]
|
|
|
|
|
os.chown(dirName, uid,gid)
|
|
|
|
|
for fileCopy in scanObjs[0].files:
|
|
|
|
|
oldFile = homeDir + fileCopy.split(skelDir)[1]
|
|
|
|
|
#копируем файлы
|
|
|
|
|
fileObj.openFiles(fileCopy, oldFile)
|
|
|
|
|
fileObj.saveOldFile()
|
|
|
|
|
fileObj.oldProfile = False
|
|
|
|
|
fileObj.closeFiles()
|
|
|
|
|
os.chown(oldFile, uid,gid)
|
|
|
|
|
for linkCreate in scanObjs[0].links:
|
|
|
|
|
#копируем ссылки
|
|
|
|
|
dst = homeDir + linkCreate[1].split(skelDir)[1]
|
|
|
|
|
srcHomeList = linkCreate[0].split(skelDir)
|
|
|
|
|
if len(srcHomeList)>1:
|
|
|
|
|
src = homeDir + srcHomeList[1]
|
|
|
|
|
else:
|
|
|
|
|
src = linkCreate[0]
|
|
|
|
|
os.symlink(src,dst)
|
|
|
|
|
#Изменение прав на ссылки
|
|
|
|
|
os.lchown(dst, uid, gid)
|
|
|
|
|
os.chmod(homeDir, 0700)
|
|
|
|
|
os.chown(homeDir, uid,gid)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def removeHomeDir(self, homeDir):
|
|
|
|
|
"""Удаление домашней директории пользователя"""
|
|
|
|
|
if os.path.exists(homeDir):
|
|
|
|
|
self.execProg("rm -rf %s" %homeDir)
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getUidMax(self):
|
|
|
|
|
"""Получаем конечный UID пользователя"""
|
|
|
|
|
fileLogin = "/etc/login.defs"
|
|
|
|
|
fileAdduser = "/etc/adduser.conf"
|
|
|
|
|
uidMax = 29999
|
|
|
|
|
if os.path.exists(fileLogin):
|
|
|
|
|
FD = open(fileLogin)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if "UID_MAX" in line and not "#" in line:
|
|
|
|
|
s = re.compile("\s+")
|
|
|
|
|
uidMax = int(s.split(line)[1])
|
|
|
|
|
break
|
|
|
|
|
elif os.path.exists(fileAdduser):
|
|
|
|
|
FD = open(fileLogin)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
if "LAST_UID" in line and not "#" in line:
|
|
|
|
|
uidMax = int(line.split('=')[1])
|
|
|
|
|
break
|
|
|
|
|
return uidMax
|
|
|
|
|
|
|
|
|
|
def getMaxUidPasswd(self):
|
|
|
|
|
"""Получаем максимальный добавленный id из /etc/passwd"""
|
|
|
|
|
filePasswd = "/etc/passwd"
|
|
|
|
|
uidMax = self.getUidMax()
|
|
|
|
|
uidMin = self.getUidMin()
|
|
|
|
|
uids = []
|
|
|
|
|
uids.append(0)
|
|
|
|
|
if os.path.exists(filePasswd):
|
|
|
|
|
FD = open(filePasswd)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
uid = int(line.split(":")[2])
|
|
|
|
|
if uid<=uidMax and uid>=uidMin:
|
|
|
|
|
uids.append(uid)
|
|
|
|
|
return max(uids)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getMaxGidGroup(self):
|
|
|
|
|
"""Получаем максимальный добавленный gid из /etc/group"""
|
|
|
|
|
fileGroup = "/etc/group"
|
|
|
|
|
gidMax = self.getUidMax()
|
|
|
|
|
gidMin = self.getUidMin()
|
|
|
|
|
gids = []
|
|
|
|
|
gids.append(0)
|
|
|
|
|
if os.path.exists(fileGroup):
|
|
|
|
|
FD = open(fileGroup)
|
|
|
|
|
lines = FD.readlines()
|
|
|
|
|
FD.close()
|
|
|
|
|
for line in lines:
|
|
|
|
|
gid = int(line.split(":")[2])
|
|
|
|
|
if gid<=gidMax and gid>=gidMin:
|
|
|
|
|
gids.append(gid)
|
|
|
|
|
return max(gids)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getMaxGidLdap(self, ldapObj, clVars):
|
|
|
|
|
"""Находит максимальный добавленный gid в LDAP"""
|
|
|
|
|
baseDN = "ou=Groups,%s"\
|
|
|
|
|
% clVars.Get("soft_ldap_base")
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
searchFilter = "cn=*"
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
gidMax = self.getUidMax()
|
|
|
|
|
gidMin = self.getUidMin()
|
|
|
|
|
gids = []
|
|
|
|
|
gids.append(0)
|
|
|
|
|
if resSearch:
|
|
|
|
|
for scope in resSearch:
|
|
|
|
|
if scope[0][1].has_key('gidNumber'):
|
|
|
|
|
# Пропускаем группы компьютеров
|
|
|
|
|
if scope[0][1].has_key('description') and\
|
|
|
|
|
scope[0][1]['description'][0] == "Computer group":
|
|
|
|
|
continue
|
|
|
|
|
gid = int(scope[0][1]['gidNumber'][0])
|
|
|
|
|
if gid<=gidMax and gid>=gidMin:
|
|
|
|
|
gids.append(gid)
|
|
|
|
|
return max(gids)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getMaxUidLdap(self, ldapObj, clVars, orgUnit="ou=Users"):
|
|
|
|
|
"""Находит максимальный добавленный id в LDAP"""
|
|
|
|
|
baseDN = "%s,%s"\
|
|
|
|
|
% (orgUnit,clVars.Get("soft_ldap_base"))
|
|
|
|
|
#searchScope = ldap.SCOPE_SUBTREE
|
|
|
|
|
searchScope = ldap.SCOPE_ONELEVEL
|
|
|
|
|
#searchFilter = "(&(!(uid=*$))(uid=*))"
|
|
|
|
|
searchFilter = "uid=*"
|
|
|
|
|
retrieveAttributes = None
|
|
|
|
|
resSearch = ldapObj.ldapSearch(baseDN, searchScope,
|
|
|
|
|
searchFilter, retrieveAttributes)
|
|
|
|
|
uidMax = self.getUidMax()
|
|
|
|
|
uidMin = self.getUidMin()
|
|
|
|
|
uids = []
|
|
|
|
|
uids.append(0)
|
|
|
|
|
if resSearch:
|
|
|
|
|
for scope in resSearch:
|
|
|
|
|
if scope[0][1].has_key('uidNumber'):
|
|
|
|
|
uid = int(scope[0][1]['uidNumber'][0])
|
|
|
|
|
if uid<=uidMax and uid>=uidMin:
|
|
|
|
|
uids.append(uid)
|
|
|
|
|
return max(uids)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def getMaxUid(self, ldapObj, clVars):
|
|
|
|
|
"""Находит максимальный id +1"""
|
|
|
|
|
uidMax = self.getUidMax()
|
|
|
|
|
uidMin = self.getUidMin()
|
|
|
|
|
uidMaxLdap = self.getMaxUidLdap(ldapObj, clVars)
|
|
|
|
|
uidMaxPasswd = self.getMaxUidPasswd()
|
|
|
|
|
if uidMaxLdap > uidMaxPasswd:
|
|
|
|
|
uidMax = uidMaxLdap
|
|
|
|
|
else:
|
|
|
|
|
uidMax = uidMaxPasswd
|
|
|
|
|
if uidMax == 0:
|
|
|
|
|
return uidMin
|
|
|
|
|
else:
|
|
|
|
|
return uidMax+1
|
|
|
|
|
|
|
|
|
|
def getMaxGid(self, ldapObj, clVars):
|
|
|
|
|
"""Находит максимальный gid +1"""
|
|
|
|
|
gidMax = self.getUidMax()
|
|
|
|
|
gidMin = self.getUidMin()
|
|
|
|
|
gidMaxLdap = self.getMaxGidLdap(ldapObj, clVars)
|
|
|
|
|
gidMaxGroup = self.getMaxGidGroup()
|
|
|
|
|
if gidMaxLdap > gidMaxGroup:
|
|
|
|
|
gidMax = gidMaxLdap
|
|
|
|
|
else:
|
|
|
|
|
gidMax = gidMaxGroup
|
|
|
|
|
if gidMax == 0:
|
|
|
|
|
return gidMin
|
|
|
|
|
else:
|
|
|
|
|
return gidMax+1
|
|
|
|
|
|
|
|
|
|
def delUserGroupLdap(self, users, groupName, ldapObj, clVars):
|
|
|
|
|
"""Удаление пользователей из списка из группы LDAP"""
|
|
|
|
|
res = self.searchLdapGroupName(groupName, ldapObj, clVars)
|
|
|
|
|
if not res :
|
|
|
|
|
self.printERROR(_("group name not found in LDAP") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if not res[0][0][1].has_key("memberUid"):
|
|
|
|
|
self.printERROR(_("Member list empty in group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
memberUsers = res[0][0][1]["memberUid"]
|
|
|
|
|
flagError =False
|
|
|
|
|
for user in users:
|
|
|
|
|
if not user in memberUsers:
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
self.printERROR(_("User") + " " +str(user)+ " " +\
|
|
|
|
|
_("not found in group") +" "+ str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
modAttrs = []
|
|
|
|
|
for userName in users:
|
|
|
|
|
modAttrs.append((ldap.MOD_DELETE, 'memberUid', userName))
|
|
|
|
|
try:
|
|
|
|
|
ldapObj.conLdap.modify_s("cn=%s,%s,%s"\
|
|
|
|
|
%(groupName,"ou=Groups",clVars.Get("soft_ldap_base")),
|
|
|
|
|
modAttrs)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modGroupLdapServer(self, groupName, options, clVars=False):
|
|
|
|
|
"""Модифицирует настройки группы пользователей LDAP"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
if not self.searchLdapGroupName(groupName, ldapObj, clVars):
|
|
|
|
|
self.printERROR(_("group name not found in LDAP ..."))
|
|
|
|
|
return False
|
|
|
|
|
# Добавляем список пользователей в группу
|
|
|
|
|
if options.has_key('m'):
|
|
|
|
|
# добавляемые пользователи в группу
|
|
|
|
|
users = options['m'].split(',')
|
|
|
|
|
res = self.addUserGroupLdap(users, groupName, ldapObj, clVars)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Append list users to a group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Not append list users to a group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем список пользователей из группы
|
|
|
|
|
if options.has_key('x'):
|
|
|
|
|
# удаляемые пользователи из группы
|
|
|
|
|
users = options['x'].split(',')
|
|
|
|
|
res = self.delUserGroupLdap(users, groupName, ldapObj, clVars)
|
|
|
|
|
if res:
|
|
|
|
|
self.printSUCCESS(_("Deleted list users to a group") + " " +\
|
|
|
|
|
str(groupName) + " ...")
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Not delete list users to a group") +\
|
|
|
|
|
" " + str(groupName) + " ...")
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modUserSambaServer(self, userName, options, clVars=False):
|
|
|
|
|
"""Модифицирует настройки пользователя samba в LDAP"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
res = self.searchLdapUser(userName, ldapObj, clVars)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(_("User") + " " + str(userName) + " " +\
|
|
|
|
|
_("not found in LDAP") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('P') or options.has_key('p'):
|
|
|
|
|
pwDialog = [_("New SMB password"),
|
|
|
|
|
_("Retype new SMB password")]
|
|
|
|
|
userPwd = self.modUserLdapServer(userName, options, clVars,
|
|
|
|
|
'passwd',pwDialog)
|
|
|
|
|
if not userPwd:
|
|
|
|
|
return False
|
|
|
|
|
textLine = self.execProg("smbpasswd -s %s" %(userName),
|
|
|
|
|
"%s\n%s\n" %(userPwd,userPwd))
|
|
|
|
|
if not ("" in str(textLine)):
|
|
|
|
|
self.printERROR(_("Not modify samba user password") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Modify samba user password") + " ...")
|
|
|
|
|
else:
|
|
|
|
|
if not self.modUserLdapServer(userName, options, clVars):
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def modUserLdapServer(self, userName, options, clVars=False ,optOut=False,
|
|
|
|
|
pwDialog=False):
|
|
|
|
|
"""Модифицирует настройки пользователя LDAP в LDAP"""
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
res = self.searchLdapUser(userName, ldapObj, clVars)
|
|
|
|
|
if not res:
|
|
|
|
|
self.printERROR(_("User") + " " + str(userName) + " " +\
|
|
|
|
|
_("not found in LDAP") + " ...")
|
|
|
|
|
return False
|
|
|
|
|
#uid = res[0][0][1]['uidNumber'][0]
|
|
|
|
|
#gid = res[0][0][1]['gidNumber'][0]
|
|
|
|
|
#homeDir = res[0][0][1]['homeDirectory']
|
|
|
|
|
# Новые группы в которые входит пользователь
|
|
|
|
|
if options.has_key('G'):
|
|
|
|
|
userGroups = options['G'].split(',')
|
|
|
|
|
#список имен добавляемых групп
|
|
|
|
|
userGroupNames = self.searchGroupsLdap(userGroups,
|
|
|
|
|
ldapObj, clVars)
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
# Удаляем пользователя из групп в которые он входит
|
|
|
|
|
if not self.delUserInGroup(userName, ldapObj, clVars):
|
|
|
|
|
return False
|
|
|
|
|
flagError = False
|
|
|
|
|
for group in userGroupNames:
|
|
|
|
|
if not self.addUserGroupLdap([userName],
|
|
|
|
|
group, ldapObj, clVars):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Replace list of supplementary group") +\
|
|
|
|
|
" ...")
|
|
|
|
|
# Добавляем группы в которые входит пользователь
|
|
|
|
|
if options.has_key('a'):
|
|
|
|
|
userGroups = options['a'].split(',')
|
|
|
|
|
#список имен добавляемых групп
|
|
|
|
|
userGroupNames = self.searchGroupsLdap(userGroups,
|
|
|
|
|
ldapObj, clVars)
|
|
|
|
|
if not userGroupNames:
|
|
|
|
|
return False
|
|
|
|
|
flagError = False
|
|
|
|
|
for group in userGroupNames:
|
|
|
|
|
if not self.addUserGroupLdap([userName],
|
|
|
|
|
group, ldapObj, clVars):
|
|
|
|
|
flagError = True
|
|
|
|
|
break
|
|
|
|
|
if flagError:
|
|
|
|
|
return False
|
|
|
|
|
self.printSUCCESS(_("Append list of supplementary group") +\
|
|
|
|
|
" ...")
|
|
|
|
|
# Изменяемые аттрибуты пользователя
|
|
|
|
|
modAttrs = []
|
|
|
|
|
# Изменяем коментарий к пользователю
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
comment = options['c']
|
|
|
|
|
if res[0][0][1].has_key('displayName'):
|
|
|
|
|
modAttr += [(ldap.MOD_REPLACE, 'displayName', comment),
|
|
|
|
|
(ldap.MOD_REPLACE, 'gecos', comment),
|
|
|
|
|
(ldap.MOD_REPLACE, 'cn', comment)]
|
|
|
|
|
else:
|
|
|
|
|
modAttrs += [(ldap.MOD_REPLACE, 'gecos', comment),
|
|
|
|
|
(ldap.MOD_REPLACE, 'cn', comment)]
|
|
|
|
|
# Изменяем оболочку пользователя
|
|
|
|
|
if options.has_key('s'):
|
|
|
|
|
shell = options['s']
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'loginShell', shell))
|
|
|
|
|
# Изменяем пароль пользователя
|
|
|
|
|
if options.has_key('P'):
|
|
|
|
|
pwdA = sys.stdin.readline().rstrip()
|
|
|
|
|
pwdB = sys.stdin.readline().rstrip()
|
|
|
|
|
elif options.has_key('p'):
|
|
|
|
|
if not pwDialog:
|
|
|
|
|
pwDialog = [_("New password"),
|
|
|
|
|
_("Retype new password")]
|
|
|
|
|
pwdA = getpass.getpass(pwDialog[0]+":")
|
|
|
|
|
pwdB = getpass.getpass(pwDialog[1]+":")
|
|
|
|
|
if options.has_key('P') or options.has_key('p'):
|
|
|
|
|
if not (pwdA == pwdB):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("password incorrect")+ ": " + _("try again"))
|
|
|
|
|
return False
|
|
|
|
|
userPwd = pwdA
|
|
|
|
|
if res[0][0][1].has_key('userPassword'):
|
|
|
|
|
userPwdHash =\
|
|
|
|
|
self.execProg("slappasswd -s %s -h %s"\
|
|
|
|
|
%(userPwd, self.userCrypt))
|
|
|
|
|
modAttrs.append((ldap.MOD_REPLACE, 'userPassword',
|
|
|
|
|
userPwdHash))
|
|
|
|
|
if modAttrs:
|
|
|
|
|
try:
|
|
|
|
|
ldapObj.conLdap.modify_s("uid=%s,%s,%s"\
|
|
|
|
|
%(userName,"ou=Users",clVars.Get("soft_ldap_base")),
|
|
|
|
|
modAttrs)
|
|
|
|
|
except ldap.LDAPError, e:
|
|
|
|
|
self.printERROR(e[0]['desc'])
|
|
|
|
|
return False
|
|
|
|
|
if options.has_key('c'):
|
|
|
|
|
self.printSUCCESS(_("Modify comment") + " ...")
|
|
|
|
|
if options.has_key('s'):
|
|
|
|
|
self.printSUCCESS(_("Modify shell") + " ...")
|
|
|
|
|
if options.has_key('P') or options.has_key('p'):
|
|
|
|
|
self.printSUCCESS(_("Modify LDAP user password") + " ...")
|
|
|
|
|
if optOut and optOut =='passwd':
|
|
|
|
|
return userPwd
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def addUserSambaServer(self, userName, options, clVars=False):
|
|
|
|
|
"""Добавляет LDAP пользователя в LDAP-сервер"""
|
|
|
|
|
#print self.getUidMax()
|
|
|
|
|
#print self.getMaxUidPasswd()
|
|
|
|
|
#return False
|
|
|
|
|
if not clVars:
|
|
|
|
|
clVars = cl_base.DataVars()
|
|
|
|
|
clVars.flServer()
|
|
|
|
|
clVars.flIniFile()
|
|
|
|
|
# прервать если была неудачная попытка установить новые параметры
|
|
|
|
|
# или были опция вывода на печать
|
|
|
|
|
#if not options['s']:
|
|
|
|
|
#if not self.processOptionsForDatavars(options,clVars):
|
|
|
|
|
#return ""
|
|
|
|
|
ldapParser = iniLdapParser()
|
|
|
|
|
adminDn = ldapParser.getVar("admin","DN")
|
|
|
|
|
adminPw = ldapParser.getVar("admin","PASS")
|
|
|
|
|
ldapObj = ldapFunction(adminDn, adminPw)
|
|
|
|
|
# Добавление машины samba
|
|
|
|
|
if options.has_key('w'):
|
|
|
|
|
if self.addMashineSambaServer(userName, options, clVars):
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
#self.addUserGroupLdap(['root1','test1','test2'],
|
|
|
|
|
#'guest', ldapObj, clVars)
|
|
|
|
|
#print self.getMaxGid(ldapObj, clVars)
|
|
|
|
|
#print self.searchUsersInGroupGroup(['root','bin'], 'bin')
|
|
|
|
|
#return False
|
|
|
|
|
resSearch = self.searchLdapUser(userName, ldapObj, clVars)
|
|
|
|
|
if not resSearch:
|
|
|
|
|
resSearch = self.searchPasswdUser(userName)
|
|
|
|
|
if self.searchSambaUser(userName, ldapObj, clVars):
|
|
|
|
|
self.printERROR(_("SMB user exists"))
|
|
|
|
|
return False
|
|
|
|
|
#пароль пользователя
|
|
|
|
|
userPwd = ""
|
|
|
|
|
#диалог ввода пароля
|
|
|
|
|
pwDialog = [_("New SMB password"),
|
|
|
|
|
_("Retype new SMB password")]
|
|
|
|
|
if not resSearch:
|
|
|
|
|
# Добавим пользователя LDAP
|
|
|
|
|
userPwd = self.addUserLdapServer(userName, options,
|
|
|
|
|
clVars, 'passwd', pwDialog)
|
|
|
|
|
if not userPwd:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
pwdA = getpass.getpass(pwDialog[0]+":")
|
|
|
|
|
pwdB = getpass.getpass(pwDialog[1]+":")
|
|
|
|
|
if not (pwdA == pwdB):
|
|
|
|
|
self.printERROR (_("ERROR") + ": " +\
|
|
|
|
|
_("password incorrect")+ ": " + _("try again"))
|
|
|
|
|
return False
|
|
|
|
|
userPwd = pwdA
|
|
|
|
|
textLine = self.execProg("smbpasswd -a -s %s" %(userName),
|
|
|
|
|
"%s\n%s\n" %(userPwd,userPwd))
|
|
|
|
|
if "Added" in str(textLine):
|
|
|
|
|
self.printSUCCESS(_("Add user in samba service ..."))
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
self.printERROR(_("Not add user ..."))
|
|
|
|
|
return False
|