Merge master

master3.3
commit 89353f34a0

@ -26,6 +26,8 @@ else
fi
fi
/sbin/modprobe ecryptfs
if [[ "`ps axeo command | grep 'xdm/xdm --logout' | grep -v grep | \
sed -n -r 's/.* USER=([^ ]+) .*/\1/p'`" == "$USER" ]];
then

@ -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

@ -0,0 +1,5 @@
#!/bin/bash
keyctl unlink $( keyctl request user $USER )
umount -l /home/$USER
exit 0

@ -15,7 +15,7 @@
# limitations under the License.
__app__ = 'calculate-desktop'
__version__ = '3.1.4'
__version__ = '3.1.6'
import os
import sys

@ -22,17 +22,25 @@ 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)
from calculate.lib.utils.common import getpathenv
getRunCommands,STDOUT,childMounts)
from calculate.lib.utils.common import (getpathenv,appendProgramToEnvFile,
removeProgramToEnvFile,mountEcryptfs,
CommonError, isBootstrapDataOnly)
from calculate.core.server.func import safetyWrapper
from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate
setLocalTranslate('cl_desktop3',sys.modules[__name__])
__ = getLazyLocalTranslate(_)
from itertools import ifilter
import tarfile
import tempfile
import shutil
class DesktopError(Exception):
@ -50,7 +58,66 @@ 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 ecrypted data"))
except CommonError as e:
raise DesktopError(_("Failed to mount ecrypted data")+": \"%s\""%str(e))
else:
tf = None
try:
# если профиль содержит только данные от бутстрапа core
if isBootstrapDataOnly(userDir):
if childMounts(userDir):
raise DesktopError(
_("Failed to create encrypt user profile")+":"+
_("User home directory contains mount points"))
# поместить данные во временный tarfile
calculateName = ".calculate"
calculatePath = path.join(userDir,calculateName)
tf = tempfile.TemporaryFile()
with tarfile.open(fileobj=tf,mode='w:') as tarf:
tarf.add(calculatePath,calculateName)
tf.flush()
tf.seek(0)
# удалить эти данные
shutil.rmtree(calculatePath)
# создать шифрованные данные
e = process('/usr/bin/ecryptfs-setup-private','-u',userName,
'-b','-l',userPwd,stderr=STDOUT)
if e.failed():
raise DesktopError(e.read())
# если были данные от бутстрапа, то распаковать их
if tf:
with tarfile.open(fileobj=tf,mode='r:') as tarf:
tarf.extractall(userDir)
except Exception as e:
if tf:
tf.seek(0)
bakArchName = path.join(userDir,".calculate.tar.bz2")
with open(bakArchName,'w') as f:
f.write(tf.read())
raise DesktopError(str(e)+
_("Failed to create encrypt user profile"))
finally:
if tf:
tf.close()
def createUserDir(self, userName, uid, gid, userDir, mode=0700):
"""
Create user directory with need uid and gid
"""
@ -117,44 +184,36 @@ class Desktop:
"""
Creating user profile and userdir
"""
self.initVars(datavars)
#uid = os.getuid()
#try:
# realUserName = pwd.getpwuid(uid).pw_name
#except:
# realUserName = ""
#userName = self.clVars.Get("ur_login")
#uidGid = False
#if self.clVars.isModuleInstalled("client"):
# # domain host
# domain = self.clVars.Get("client.cl_remote_host")
# # authorized in domain or local
# hostAuth = self.clVars.Get("client.os_remote_auth")
#else:
# domain = ""
# hostAuth = ""
#uid = self.clVars.Get('ur_uid')
#gid = self.clVars.Get('ur_gid')
#if not uid or not gid:
# raise DesktopError(_("Failed to determine the user UID"))
#uid,gid = int(uid),int(gid)
self.homeDir = self.clVars.Get('ur_home_path')
rootPath = self.clVars.Get('cl_root_path')
# real path to home dir
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(userName,uid,gid,self.homeDir)
self.endTask()
if (self.clVars.Get('ur_home_crypt_set') == 'on' and
self.clVars.Get('install.cl_autologin') != userName):
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')
#self.homeDir = self.clVars.Get('ur_home_path')
#rootPath = self.clVars.Get('cl_root_path')
## real path to home dir
#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)
## 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"))
#return True
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()
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):
"""
@ -219,15 +278,15 @@ class Desktop:
where='cl_desktop_online_user',eq=urLogin,limit=1)
session = self.clVars.Get('cl_desktop_xsession')
if session == 'xfce':
logoutCommand = "org.xfce.SessionManager " \
logoutCommand = "/usr/bin/qdbus org.xfce.SessionManager " \
"/org/xfce/SessionManager Logout False False"
elif session == 'kde':
logoutCommand = "org.kde.ksmserver /KSMServer logout 0 0 0"
logoutCommand = "/usr/bin/kquitapp ksmserver"
elif session == 'gnome':
logoutCommand = "org.gnome.SessionManager " \
logoutCommand = "/usr/bin/qdbus org.gnome.SessionManager " \
"/org/gnome/SessionManager Logout 1"
else:
raise DesktopError(_("Unable detect X session"))
raise DesktopError(_("Unable to detect the X session"))
if process("su",urLogin,"-c",
("DISPLAY=:%s /usr/bin/qdbus "%display)+logoutCommand).failed():
raise DesktopError(_("Unable send logout command"))

@ -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 <stdio.h>
// для пароля
#include <sys/types.h>
// для strcpy strlen
#include <string.h>
// для работы с ключами
#include <keyutils.h>
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;
};

@ -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

@ -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.utils','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})

Loading…
Cancel
Save