From f4e095fac9543cb8af838be31e12ff9440582e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B0=D0=BC=D0=BE=D1=83=D0=BA=D0=B8=D0=BD=20=D0=90?= =?UTF-8?q?=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9?= Date: Thu, 3 Jun 2010 14:50:20 +0400 Subject: [PATCH] Added cl-passwd utility --- pym/cl_client.py | 136 +++++++++++++++++++++++++++++++++++++++-------- setup.py | 3 +- 2 files changed, 117 insertions(+), 22 deletions(-) diff --git a/pym/cl_client.py b/pym/cl_client.py index a1951d5..25a0ebb 100644 --- a/pym/cl_client.py +++ b/pym/cl_client.py @@ -38,6 +38,7 @@ from client.progressbar import ProgressBar from cl_utils import runOsCommand, getpathenv, getModeFile, removeDir, isMount from _cl_keys import getKey, clearKey from convertenv import convertEnv +from encrypt import encrypt lang().setLanguage(sys.modules[__name__]) @@ -243,7 +244,73 @@ class ldapData(ldapUser): return True return False -class client(share): +class commandServer(color_print): + """Отправка команд на сервер (изменение пароля пользователя на сервере)""" + + def setServerCommand(self, command, varsCommand, fileConfig, + uid=None, gid=None): + """Установить команду для сервера""" + pathConfig = os.path.split(fileConfig)[0] + # Создаем директорию если ее нет + if not os.path.exists(pathConfig): + os.makedirs(pathConfig) + if not uid is None and not gid is None: + os.chown(pathConfig, uid, gid) + objConfig = iniParser(fileConfig) + varsRun = {"run":"on"} + varsRun.update(varsCommand) + if not objConfig.setVar(["command"]+command, varsRun): + self.printERROR(_("Can not write variables in file %s")\ + %fileConfig) + return False + if not uid is None and not gid is None: + os.chown(fileConfig, uid, gid) + return True + + def checkUserPwdLDAP(self, server, userDN, password): + """Проверка пароля Unix пользователя на сервере""" + ldapInit = ldap.initialize("ldap://%s"%server) + errMessage = "" + try: + ldapInit.bind_s(userDN, password) + except ldap.INVALID_CREDENTIALS: + errMessage = _("Password incorrect") + return False, errMessage + except ldap.LDAPError, e: + errMessage = e[0]['desc'] + return False, errMessage + return True, errMessage + + def getUserPwd(self, options, optDialog, optStdIn, pwDialog=False): + """Получить пароль у пользователя + + options - полученные опции командной строки + optDialog - опция командной строки для вывода диалога для получения + пароля + optStdIn - опция командной строки для получения пароля из + стандартного ввода (stdin) + pwDialog - структура для вывода приглашения в режиме диалога + """ + userPwd = "" + if optStdIn and options.has_key(optStdIn): + pwdA = sys.stdin.readline().rstrip() + pwdB = sys.stdin.readline().rstrip() + elif optDialog and options.has_key(optDialog): + if not pwDialog: + pwDialog = [_("New password"), + _("Retype new password")] + pwdA = getpass.getpass(pwDialog[0]+":") + pwdB = getpass.getpass(pwDialog[1]+":") + if (optStdIn and options.has_key(optStdIn)) or\ + (optDialog and options.has_key(optDialog)): + if not pwdA or not (pwdA == pwdB): + self.printERROR (_("ERROR") + ": " +\ + _("passwords do not match")) + return False + userPwd = pwdA + return userPwd + +class client(share, commandServer, encrypt): """Методы работы для подключения пользователя к серверу и синхронизации""" # Объект для поиска пользовательских данных в LDAP ldapDataObj = ldapData() @@ -627,26 +694,6 @@ class client(share): return False return varsConfig - def setServerCommand(self, command, varsCommand, fileConfig, - uid=None, gid=None): - """Установить команду для сервера""" - pathConfig = os.path.split(fileConfig)[0] - # Создаем директорию если ее нет - if not os.path.exists(pathConfig): - os.makedirs(pathConfig) - if not uid is None and not gid is None: - os.chown(pathConfig, uid, gid) - objConfig = iniParser(fileConfig) - varsRun = {"run":"on"} - varsRun.update(varsCommand) - if not objConfig.setVar(["command"]+command, varsRun): - self.printERROR(_("Can not write variables in file %s")\ - %fileConfig) - return False - if not uid is None and not gid is None: - os.chown(fileConfig, uid, gid) - return True - def foundArchFile(self,strCurrentTime,archPathProcess, archPathSuccess, progress=False, remoteServer=False): @@ -1859,3 +1906,50 @@ class client(share): flagUpdate = True return flagUpdate + def setUserPasswordToServer(self): + """Установка пароля пользователя на сервере""" + # Проверяем на root + if self.isRoot(False): + self.printERROR(_("The user is root")) + self.printWARNING(\ + _("The program can be executed from a non-root user only")) + return False + # DNS имя хоста + server = self.ldapDataObj.getHost() + # DN пользователей + usersDN = self.ldapDataObj.getUsersDN() + if not (server and usersDN): + self.printERROR(_("The computer is not in domain")) + self.printWARNING(_("Use passwd")) + return False + # Получаем старый пароль пользователя + curPassword = self.getUserPassword(_("Enter current password")) + if not curPassword: + self.printERROR(_("Current password is empty")) + return False + userDN = self.ldapDataObj.addDN("uid=%s"%os.environ["USER"], usersDN) + # Проверяем в LDAP сервере текущий пароль пользователя + ret, err = self.checkUserPwdLDAP(server, userDN, curPassword) + if not ret: + self.printERROR(err) + return False + password = self.getUserPwd({"p":""}, "p", False) + if password is False: + return False + # Переменные для записи в env файл + varsConfig = {"unix_hash":self.getHashPasswd(password,"ssha"), + "samba_lm_hash":self.getHashPasswd(password,"lm"), + "samba_nt_hash":self.getHashPasswd(password,"nt"), + "samba_nt_hash_old":self.getHashPasswd(curPassword,"nt")} + if filter(lambda x: not x, varsConfig.values()): + return False + # ~/.calculate/server.env + fileConfig = os.path.join(os.environ["HOME"], self.configFileServer) + if not self.setServerCommand(["passwd_samba"], varsConfig, fileConfig): + return False + self.printOK(_("Changed password of user %s")%os.environ["USER"] + \ + " ...") + self.printWARNING(_("Password will be changed when you logout from the \ +X session")) + return True + diff --git a/setup.py b/setup.py index 0a03e06..8a22793 100755 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ from distutils.command.build_scripts import build_scripts from distutils.command.install_scripts import install_scripts -__version__ = "2.2.0" +__version__ = "2.2.0.0" __app__ = "calculate-client" @@ -145,6 +145,7 @@ setup( data_files = data_files, scripts=["./scripts/cl-sync", "./scripts/cl-client", + "./scripts/cl-passwd", "./scripts/install", "./scripts/uninstall"], ext_modules = [Extension('calculate-client.pym._cl_keys',