diff --git a/data/login.d/20desktop b/data/login.d/20desktop index 0d4716f..85c0ecf 100644 --- a/data/login.d/20desktop +++ b/data/login.d/20desktop @@ -22,20 +22,14 @@ then # skip desktop configure if user not domain and it already has home dir # with not /etc/skel contents userHome=`getent passwd $USER | awk -F: '{ print( $6 ); }'` - if [[ "${DOMAIN_USER}" == "on" ]] || - ! [[ -d "${userHome}" ]] || - [[ -z "`ls ${userHome}`" ]] || - diff -uq <(ls -A1 /etc/skel | wc) <(ls -A1 ${userHome} | sort) &>/dev/null + ERRORLOG=`/usr/sbin/cl-desktop --gui-progress $USER 2>&1` + # raise xmessage error if cl-desktop failed + if [ "$?" -gt "0" ]; then - ERRORLOG=`/usr/sbin/cl-desktop --gui-progress $USER 2>&1` - # raise xmessage error if cl-desktop failed - if [ "$?" -gt "0" ]; - then - # write error message to logfile - echo "$ERRORLOG" >> $FILE_LOG - # display error by xmessage - exit 1 - fi + # write error message to logfile + echo "$ERRORLOG" >> $FILE_LOG + # display error by xmessage + exit 1 fi fi exit 0 diff --git a/data/logout.d/98umount b/data/logout.d/98umount new file mode 100644 index 0000000..bf3b074 --- /dev/null +++ b/data/logout.d/98umount @@ -0,0 +1,4 @@ +#!/bin/bash + +umount -l /home/$USER +exit 0 diff --git a/desktop/cl_desktop.py b/desktop/cl_desktop.py index c417f5e..11ca1de 100644 --- a/desktop/cl_desktop.py +++ b/desktop/cl_desktop.py @@ -22,13 +22,16 @@ import pwd import time import traceback +from calculate.desktop._cl_keys import getKey, clearKey from datavars import DataVarsDesktop, DataVars, __version__,__app__ -from calculate.lib.cl_template import Template, ProgressTemplate,TemplatesError +from calculate.lib.cl_template import (Template, ProgressTemplate, + TemplatesError,templateFunction,iniParser) from calculate.lib.utils.files import runOsCommand, isMount,process, \ - getRunCommands + getRunCommands,STDOUT from calculate.lib.utils.common import getpathenv,appendProgramToEnvFile, \ - removeProgramToEnvFile + removeProgramToEnvFile,mountEcryptfs, \ + CommonError from calculate.core.server.func import safetyWrapper from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate @@ -54,7 +57,31 @@ class Desktop: self.clTempl = None self.clVars = None - def createUserDir(self, uid, gid, userDir, mode=0700): + def createCryptDir(self,userName,uid,gud,userDir): + """ + Создать шифрование домашней директории, или подключить существующую + """ + userPwd = getKey(userName) + if not userPwd or userPwd == "XXXXXXXX": + raise DesktopError(_("User password not found")) + ecryptfsPath = path.join('/home/.ecryptfs',userName) + if path.exists(ecryptfsPath): + for d in (".ecryptfs",".Private"): + source,target = path.join(ecryptfsPath,d),path.join(userDir,d) + if not path.lexists(target): + os.symlink(source,target) + try: + if not mountEcryptfs(userName,userPwd,userDir): + raise DesktopError(_("Failed to mount ecrypt")) + except CommonError as e: + raise DesktopError(_("Failed to mount ecrypt")+": \"%s\""%str(e)) + else: + e = process('/usr/bin/ecryptfs-setup-private','-u',userName,'-b','-l',userPwd,stderr=STDOUT) + if e.failed(): + raise DesktopError(e.read()+ + _("Failed to create encrypt user profile")) + + def createUserDir(self, userName, uid, gid, userDir, mode=0700): """ Create user directory with need uid and gid """ @@ -135,7 +162,7 @@ class Desktop: break return ret - @safetyWrapper(native_errors=(TemplatesError,DesktopError), + @safetyWrapper(native_errors=(TemplatesError,DesktopError,CommonError), man_int=__("Configuration manually interrupted"), post_action=umountUserRes) def createHome(self, datavars=None): @@ -171,17 +198,28 @@ class Desktop: self.homeDir = path.join(rootPath, self.homeDir[1:]) if not path.exists(self.homeDir): self.startTask(_("Creating the home directory for %s")%self.homeDir) - self.createUserDir(uid,gid,self.homeDir) + self.createUserDir(userName,uid,gid,self.homeDir) + self.endTask() + if self.clVars.Get('ur_home_crypt_set') == 'on': + self.createCryptDir(userName,uid,gid,self.homeDir) + + domainUser = self.clVars.Get('ur_domain_set') == 'on' + lastTimestamp = templateFunction.getLastElog() + iniEnv = path.join(self.homeDir,'.calculate/ini.env') + userIni = iniParser(iniEnv) + userTimestamp = userIni.getVar('main','elog').encode('utf-8') + + if (domainUser or not path.exists(iniEnv) or + userTimestamp != lastTimestamp): + # action - "user profile configuration" + self.clVars.Set("cl_action", "desktop", True) + # apply user profiles + self.startTask(_("Setting up the user profile"),progress=True) + dirsAndFiles = self.applyTemplatesFromUser() self.endTask() - # action - "user profile configuration" - self.clVars.Set("cl_action", "desktop", True) - # apply user profiles - self.startTask(_("Setting up the user profile"),progress=True) - dirsAndFiles = self.applyTemplatesFromUser() - self.endTask() - if not dirsAndFiles: - raise DesktopError(_("Failed to apply user profile templates")) - self.printSUCCESS(_("User account %s is configured")%userName + " ...") + if not dirsAndFiles: + raise DesktopError(_("Failed to apply user profile templates")) + self.printSUCCESS(_("User account %s is configured")%userName + " ...") return True def getMountUserPaths(self, homeDir=False): diff --git a/desktop/datavars.py b/desktop/datavars.py index 4396367..e091e7a 100644 --- a/desktop/datavars.py +++ b/desktop/datavars.py @@ -15,7 +15,7 @@ # limitations under the License. __app__ = 'calculate-desktop' -__version__ = '3.1.4' +__version__ = '3.1.6' import os import sys diff --git a/lib/cl_keys.c b/lib/cl_keys.c new file mode 100644 index 0000000..f26e992 --- /dev/null +++ b/lib/cl_keys.c @@ -0,0 +1,66 @@ +// Copyright 2007-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. + +#include + +// для пароля +#include + +// для strcpy strlen +#include + +// для работы с ключами +#include + +char* getKey(char *login) +{ + char buffer[255]; + memset(buffer,0,sizeof(buffer)); + int ret; + // ищем номер пользовательского ключа + ret = request_key("user", login, NULL, 0); + if (ret < 0) + { + return ""; + }; + + // Возвращаем значение ключа + ret = keyctl_read(ret, buffer, sizeof(buffer)); + if (ret < 0) + { + return ""; + }; + return buffer; +}; + +int clearKey(char *login) +{ + int ret; + key_serial_t dest; + dest = KEY_SPEC_USER_SESSION_KEYRING; + // ищем номер пользовательского ключа + ret = request_key("user", login, NULL, 0); + if (ret < 0) + { + return 1; + }; + + // удаляем ключ + ret = keyctl_unlink(ret, dest); + if (ret < 0) + { + return 1; + }; + return 0; +}; diff --git a/lib/cl_keys.i b/lib/cl_keys.i new file mode 100644 index 0000000..4143e09 --- /dev/null +++ b/lib/cl_keys.i @@ -0,0 +1,7 @@ +%module cl_keys +%inline %{ +/* Put header files here or function declarations like below */ +extern char* getKey(char*); +extern int clearKey(char*); +%} +%include cl_keys.c \ No newline at end of file diff --git a/setup.py b/setup.py index 7cc5867..4dcfe4c 100755 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ # limitations under the License. __app__ = "calculate-desktop" -__version__ = "3.1.4" +__version__ = "3.1.6" import os import stat @@ -41,7 +41,8 @@ data_files += [('/usr/share/calculate/xdm', ['data/cmd_login', 'data/login.d/20desktop', 'data/login.d/99final'])] + \ [('/usr/share/calculate/xdm/logout.d', - ['data/logout.d/00init'])] + ['data/logout.d/00init', + 'data/logout.d/98umount'])] def __scanDir(scanDir, prefix, replace_dirname, dirData, flagDir=False): """Scan directory""" @@ -105,7 +106,7 @@ class cl_install_data(install_data): setup( name = 'calculate-desktop', - version = "3.0.0_alpha1", + version = "3.1.6", description = "Create and configure user profile", author = "Calculate Ltd.", author_email = "support@calculate.ru", @@ -114,4 +115,8 @@ setup( package_dir = {'calculate.desktop': "desktop"}, packages = ['calculate.desktop','calculate.desktop.variables'], data_files = data_files, + ext_modules = [Extension('calculate.desktop._cl_keys', + library_dirs = ['/usr/lib'], + libraries = ['keyutils'], + sources = ['./lib/cl_keys.i', './lib/cl_keys.c'])], cmdclass={'install_data': cl_install_data})