Add change password

master3.3
parent a0dbb48224
commit 739f97cbd3

@ -151,16 +151,6 @@ class RsyncProgressBar:
class ldapData(ldapUser):
"""LDAP methods"""
def addDN(self, *arg):
"""
Append text DN elements
"""
DNs = []
for dn in arg:
if dn:
DNs.append(dn)
return ','.join(DNs)
def getReplDN(self):
"""
Get from LDAP last domain server
@ -317,6 +307,7 @@ class Client(commandServer, encrypt):
mountRemote - mount remote domain resource
delDomain - remove workstation from domain
addDomain - add workstation to domain
changePasswd - change password on server
"""
# object for user data in LDAP
@ -2246,105 +2237,45 @@ class Client(commandServer, encrypt):
self.restartDBus()
return True
def updateEnvFiles(self):
"""Апдейт env файлов до версии 2.2"""
previousVersion = self.clVars.Get("os_remote_client")
flagUpdate = False
if not previousVersion:
# Апдейт
envFile="/var/calculate/calculate.env"
remoteHost = self.getInfoService("client", "cl_remote_host",
envFile=envFile)
remotePw = self.getInfoService("client", "cl_remote_pw",
envFile=envFile)
if remoteHost and remotePw:
self.clVars.Write("cl_remote_host", remoteHost, True, "local")
self.clVars.Write("cl_remote_pw", remotePw, True, "local")
envFile="/etc/calculate/calculate.env"
previousVersion = self.getInfoService("client", "os_remote_client",
envFile=envFile)
workHost = self.getInfoService("client", "os_remote_auth",
envFile=envFile)
if previousVersion and workHost:
self.clVars.Write("os_remote_client", previousVersion, True)
if workHost != "local":
self.clVars.Write("os_remote_auth", workHost, True)
self.printOK(_("Env files updated") + " ...")
flagUpdate = True
return flagUpdate
def setUserPasswordToServer(self):
"""Установка пароля пользователя на сервере"""
# Проверяем на root
if self.isRoot(False):
@safetyWrapper(native_errors=(TemplatesError,ClientError),
man_int=__("Manually interrupted"))
def clientPasswd(self,dv):
"""
Change user password on server
"""
self.initVars(dv)
try:
self.uid = int(self.clVars.Get('ur_uid'))
self.gid = int(self.clVars.Get('ur_gid'))
except ValueError as e:
raise ClientError(_("Failed to determnate UID and GID"))
self.sync = self.clVars.Get('cl_client_sync') == 'on'
self.userName = self.clVars.Get("ur_login")
self.homeDir = self.clVars.Get('ur_home_path')
self.domain = self.clVars.Get("cl_remote_host")
# check on root
if self.uid == 0:
self.printERROR(_("The user is root"))
self.printWARNING(\
_("The program can be executed by 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 the domain"))
self.printWARNING(_("Use passwd"))
return False
count = 2
# Получаем старый пароль пользователя
curPassword = self.getUserPassword(_("Enter the current password"))
if not curPassword:
self.printERROR(_("The current password is empty"))
for i in range(count):
count -= 1
# Получаем старый пароль пользователя
curPassword = self.getUserPassword(
_("Enter the current password"))
if curPassword:
break
self.printERROR(_("The current password is empty"))
if not curPassword:
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)
for i in range(count):
# Получаем старый пароль пользователя
curPassword = self.getUserPassword(
_("Enter the current password"))
if not curPassword:
self.printERROR(_("The current password is empty"))
continue
# Проверяем в LDAP сервере текущий пароль пользователя
ret, err = self.checkUserPwdLDAP(server, userDN, curPassword)
if ret:
break
self.printERROR(err)
if not ret:
return False
password = self.getUserPwd({"p":""}, "p", False)
if password is False:
for i in range(2):
password = self.getUserPwd({"p":""}, "p", False)
if password:
break
if password is False:
_("The program can be executed for a non-root user only"))
return False
# Переменные для записи в env файл
password = self.clVars.Get('ur_user_new_pw')
curPassword = self.clVars.Get('ur_user_pw')
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
raise ClientError(_("Failed to change password"))
# ~/.calculate/server.env
fileConfig = os.path.join(os.environ["HOME"], self.configFileServer)
if not self.setServerCommand(["passwd_samba"], varsConfig, fileConfig):
return False
self.printOK(_("%s's password changed")%os.environ["USER"] + \
" ...")
self.printWARNING(_("The password will be changed when you log "
fileConfig = os.path.join(self.homeDir, self.configFileServer)
if not self.setServerCommand(["passwd_samba"], varsConfig, fileConfig,
self.uid,self.gid):
raise ClientError(_("Failed to change password"))
self.printSUCCESS(_("%s's password changed")%
self.clVars.Get('ur_login'))
self.printSUCCESS(_("The password will be changed when you log "
"out from the X session"))
return True

@ -1,159 +0,0 @@
#-*- 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_client import client, __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] domain")
# Коментарии к использованию программы
COMMENT_EXAMPLES = _("Add settings for connecting to "
"domain server.calculate.ru")
# Пример использования программы
EXAMPLES = _("%prog server.calculate.ru")
# Описание программы (что делает программа)
DESCRIPTION = _("Changes settings for connecting to the domain")
# Опции командной строки
CMD_OPTIONS = [{'shortOption':"r",
'help':_("remove the settings for connecting to the domain")},
{'longOption':"mount",
'help':_("mount the [remote] domain resource")},
{'longOption':"set"},
{'longOption':"install",
'help':_("install the package")},
{'longOption':"uninstall",
'help':_("uninstall the package")}]
class client_cmd(share_cmd):
def __init__(self):
# Объект опций командной строки
setpos = \
filter(lambda x:x[1].get('longOption')=="set",
enumerate(CMD_OPTIONS))[0][0]
CMD_OPTIONS[setpos] = opt.variable_set[0]
self.optobj = opt(\
package=__app__,
version=__version__,
usage=USAGE,
examples=EXAMPLES,
comment_examples=COMMENT_EXAMPLES,
description=DESCRIPTION,
option_list=CMD_OPTIONS + opt.variable_view+opt.color_control,
check_values=self.checkOpts)
# Создаем объект логики
self.logicObj = client()
# Создаем переменные
self.logicObj.createClVars()
# Названия несовместимых опций
self.optionsNamesIncompatible = ["r", "mount", "install", "uninstall"]
# Названия опций несовмесимых с именем домена
self.optionsNamesNotDomain = self.optionsNamesIncompatible
def getOptionsNotDomain(self, optObj):
"""Получаем опции несовместимые с именем домена"""
retList = []
for nameOpt in self.optionsNamesNotDomain:
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):
"""Проверка опций командной строки"""
optionsNotDomain = self.getOptionsNotDomain(optObj)
if not args:
options = optionsNotDomain + [optObj.color, optObj.v,
optObj.filter, optObj.xml]
if not filter(lambda x: x, options):
errMsg = _("no such argument")+":"+" %s" %USAGE.split(" ")[-1]
self.optobj.error(errMsg)
return False
elif len(filter(lambda x: x, optionsNotDomain))>1:
errMsg = _("incompatible options")+":"+" %s"\
%self.getStringIncompatibleOptions()
self.optobj.error(errMsg)
return False
elif filter(lambda x: x, optionsNotDomain):
errMsg = _("unnecessary argument")+":"+" %s" %USAGE.split(" ")[-1]
self.optobj.error(errMsg)
return False
if len(args)>1:
errMsg = _("incorrect argument") + ":" + " %s" %" ".join(args)
self.optobj.error(errMsg)
return False
if not optObj.v:
if optObj.filter:
errMsg = _("incorrect option") + ":" + " %s" %"--filter" +\
": " + _("used with option '-v'")
self.optobj.error(errMsg)
return False
if optObj.xml:
errMsg = _("incorrect option") + ":" + " %s" %"--xml" +\
": " + _("used with option '-v'")
self.optobj.error(errMsg)
return False
return optObj, args
def addDomain(self, domainName):
"""Ввод в домен"""
if domainName:
return self.logicObj.addDomain(domainName)
else:
self.printERROR(_("No domain name found as argument"))
return False
def delDomain(self):
"""Вывод из домена"""
return self.logicObj.delDomain()
def mountRemote(self):
"""Монтирование remote и домашней директории если компьютер в домене
а так-же ввод в домен если найдено имя хоста и пароль для подключения
"""
return self.logicObj.mountRemote()
def install(self):
"""Инсталяция программы"""
return self.logicObj.installProg()
def updateEnvFiles(self):
"""Апдейт env файлов до новой версии"""
return self.logicObj.updateEnvFiles()
def uninstall(self):
"""Удаление программы"""
return self.logicObj.uninstallProg()

@ -1,87 +0,0 @@
#-*- 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_client import client, __app__, __version__
from cl_opt import opt
import sys
from cl_share_cmd import share_cmd
from cl_print import color_print
# Перевод сообщений для программы
from cl_lang import lang
lang().setLanguage(sys.modules[__name__])
# Использование программы
USAGE = _("%prog [options]")
# Описание программы (что делает программа)
DESCRIPTION = _("Change the user password")
# Коментарии к использованию программы
COMMENT_EXAMPLES = _("change the user password for Samba and Unix services")
# Пример использования программы
EXAMPLES = _("%prog")
class passwd_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=opt.variable_control+opt.color_control,
check_values=self.checkOpts)
# Создаем объект логики
self.logicObj = client()
# Создаем переменные
self.logicObj.createClVars()
def checkOpts(self, optObj, args):
"""Проверка опций командной строки"""
if args:
errMsg = _("invalid argument") + ":" + " %s" %" ".join(args)
self.optobj.error(errMsg)
return False
if not optObj.v:
if optObj.filter:
errMsg = _("incorrect option") + ":" + " %s" %"--filter" +\
": " + _("used with option '-v'")
self.optobj.error(errMsg)
return False
if optObj.xml:
errMsg = _("incorrect option") + ":" + " %s" %"--xml" +\
": " + _("used with option '-v'")
self.optobj.error(errMsg)
return False
return optObj, args
def setUserPasswordToServer(self):
"""Изменение пароля пользователя на сервере"""
try:
res = self.logicObj.setUserPasswordToServer()
except KeyboardInterrupt:
sys.stdout.write("\b\b\n")
color_print().printERROR(_("Manually interrupted"))
return False
except EOFError:
sys.stdout.write("\n")
color_print().printERROR(_("Manually interrupted"))
return False
return res

@ -47,6 +47,16 @@ class ClientInfo(ClassSerializer):
CheckOnly = Boolean
CheckAll = Boolean
class ClientPasswdInfo(ClassSerializer):
"""Parameters for method install"""
ur_login = String
ur_user_pw = String
ur_user_new_pw = String
Default = Array(String)
CheckOnly = Boolean
CheckAll = Boolean
class SyncInfo(ClassSerializer):
"""Parameters for method install"""
ur_login = String
@ -106,7 +116,7 @@ class Wsdl:
"""
cl-client-sync-login
"""
@rpc(Integer, ClientInfo, _returns = Array(ReturnedMessage))
@rpc(Integer, SyncInfo, _returns = Array(ReturnedMessage))
@core_method(category=__('Client'),title=__('Domain user login'),
image='applications-other',
gui=True,command='cl-client-sync-login',
@ -141,7 +151,7 @@ class Wsdl:
"""
cl-client-sync-logout
"""
@rpc(Integer, ClientInfo, _returns = Array(ReturnedMessage))
@rpc(Integer, SyncInfo, _returns = Array(ReturnedMessage))
@core_method(category=__('Client'),title=__('Domain user logout'),
image='applications-other',
gui=True,command='cl-client-sync-logout',
@ -174,36 +184,36 @@ class Wsdl:
return view
"""
cl-client-sync-test
cl-passwd
"""
@rpc(Integer, ClientInfo, _returns = Array(ReturnedMessage))
@core_method(category=__('Client'),title=__('Test'),
@rpc(Integer, ClientPasswdInfo, _returns = Array(ReturnedMessage))
@core_method(category=__('Client'),title=__('Change password'),
image='applications-other',
gui=True,command='cl-client-sync-test',
rights=['domainuser'])
def clienttest(self, sid, info):
return self.callMethod(sid,info,method_name="clienttest",
gui=True,command='cl-passwd',
rights=['password'],user=True)
def clientpasswd(self, sid, info):
return self.callMethod(sid,info,method_name="clientpasswd",
logicClass=Client,
method="clienttest")
method="clientPasswd")
def clienttest_vars(self,dv=None):
def clientpasswd_vars(self,dv=None):
if not dv:
dv = DataVarsClient()
dv.importClient()
dv.flIniFile()
dv.Set('cl_action','logout',True)
dv.Set('cl_action','passwd',True)
dv.addGroup(None,
normal=('ur_login','cl_client_sync'),
next_label=_("Configure"))
normal=('ur_login','ur_user_pw','ur_user_new_pw'),
next_label=_("Change password"))
return dv
@rpc(Integer, ViewParams,_returns = ViewInfo)
def clienttest_view (self, sid, params):
dv = self.get_cache(sid,"clienttest","vars")
def clientpasswd_view (self, sid, params):
dv = self.get_cache(sid,"clientpasswd","vars")
if not dv:
dv = self.clienttest_vars()
dv = self.clientpasswd_vars()
else:
dv.processRefresh()
view = ViewInfo(dv,viewparams=params)
self.set_cache(sid, 'clienttest', "vars",dv,smart=False)
self.set_cache(sid, 'clientpasswd', "vars",dv,smart=False)
return view

@ -5,6 +5,9 @@ from calculate.lib.datavars import Variable,VariableError,ReadonlyVariable
from calculate.lib.utils.files import readLinesFile
from calculate.lib.utils.common import getValueFromCmdLine
from calculate.lib.utils.ip import isOpenPort
import ldap
from calculate.lib.cl_ldap import ldapUser
from calculate.lib.variables.user import LdapHelper
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_client3',sys.modules[__name__])
@ -163,3 +166,59 @@ class VariableClClientMountSet(Variable):
def init(self):
self.label = _("Only mount the domain resource")
self.help = _("only mount the [remote] domain resource")
class VariableUrUserPw(Variable,LdapHelper):
"""
Current user password
"""
type = "need-onepassword"
opt = ["--old-password"]
metavalue = "OLDPASSWORD"
value = ""
untrusted = True
def init(self):
self.label = _("Current password")
self.help = _("current user password")
def checkUserPwdLDAP(self, server, userDN, password):
"""Проверка пароля Unix пользователя на сервере"""
ldapInit = ldap.initialize("ldap://%s"%server)
errMessage = ""
try:
ldapInit.bind_s(userDN, password)
except ldap.INVALID_CREDENTIALS:
raise VariableError(_("Wrong password"))
except ldap.LDAPError, e:
errMessage = e[0]['desc']
raise VariableError(errMessage)
return True
def check(self,value):
if not value:
raise VariableError(_("Empty password"))
server = self.Get('cl_remote_host')
ldapObj = self.getLdapUserObject()
if ldapObj:
usersDN = ldapObj.getUsersDN()
userDN = ldapObj.addDN("uid=%s"%self.Get('ur_login'),
usersDN)
self.checkUserPwdLDAP(server,userDN,value)
class VariableUrUserNewPw(Variable):
"""
New user password
"""
type = "need-password"
opt = ["--new-password"]
metavalue = "NEWPASSWORD"
value = ""
untrusted = True
def init(self):
self.label = _("New password")
self.help = _("new user password")
def check(self,value):
if not value:
raise VariableError(_("Empty password"))

Loading…
Cancel
Save