# -*- coding: utf-8 -*-
###########################################################################
# Copyright (C) 2003 by Wido Depping
# <widod@users.sourceforge.net>
#
# Copyright: See COPYING file that comes with this distribution
#
###########################################################################
import ldap
import os.path
from qt import *
import environment
from plugins.mass_creation_plugin.MassCreationDesign import MassCreationDesign
from base.utils.gui.BrowserWidget import BrowserWidget
from base.backend.ServerList import ServerList
from base.backend.ServerObject import ServerObject
from base.utils.backend.DateHelper import DateHelper
from base.utils.backend.CryptPwGenerator import CryptPwGenerator
from base.utils.gui.BrowserDialog import BrowserDialog
from base.utils.gui.PluginInformation import PluginInformation
from base.backend.LumaConnection import LumaConnection
from plugins.mass_creation_plugin import postProcess,preProcess
from base.backend.SmartDataObject import SmartDataObject
from base.utils.gui.LumaErrorDialog import LumaErrorDialog
class MassCreation(MassCreationDesign):
###############################################################################
def __init__(self,parent = None,name = None,fl = 0):
MassCreationDesign.__init__(self,parent,name,fl)
self.iconPath = os.path.join(environment.lumaInstallationPrefix, "share", "luma", "icons")
self.enableAutomount()
self.dateEdit.setDate(QDate.currentDate())
###############################################################################
def createUsers(self):
if str(self.nodeEdit.text()) == "":
self.createButton.setEnabled(True)
tmpDialog = QMessageBox(self.trUtf8("Incomplete information"),
self.trUtf8("Please select a valid node from a ldap server."),
QMessageBox.Critical,
QMessageBox.Ok,
QMessageBox.NoButton,
QMessageBox.NoButton,
self)
tmpDialog.setIconPixmap(QPixmap(os.path.join(self.iconPath, "warning_big.png")))
tmpDialog.exec_loop()
return
# set gui busy
environment.setBusy(True)
self.createButton.setEnabled(False)
# get data for usernames
userMax = self.prefixMaxBox.value()
userMin = self.prefixMinBox.value()
userCount = userMax - userMin + 1
userPrefix = str(self.prefixEdit.text())
usedNumbers = self.getUsedUidNumbers()
uidNumMin = self.uidNumMinBox.value()
uidNumMax = self.uidNumMaxBox.value()
# list of free uidNumbers to use for our users
freeNumbers = self.getUidNumbers(uidNumMin, uidNumMax, usedNumbers, userCount)
if freeNumbers == None:
environment.setBusy(False)
self.createButton.setEnabled(True)
tmpDialog = QMessageBox(self.trUtf8("Warning"),
self.trUtf8("""There are not enough user ids left! Try increasing the uidNumber range or delete some users from the subtree."""),
QMessageBox.Critical,
QMessageBox.Ok,
QMessageBox.NoButton,
QMessageBox.NoButton,
self)
tmpDialog.setIconPixmap(QPixmap(os.path.join(self.iconPath, "warning_big.png")))
tmpDialog.exec_loop()
return
shadowMax = None
dateHelper = DateHelper()
if self.dateButton.isChecked():
date = self.dateEdit.date()
year = date.year()
month = date.month()
day = date.day()
shadowMax = dateHelper.dateToUnix(year, month, day)
else:
days = self.dayBox.value()
shadowMax = dateHelper.datedurationToUnix(days)
baseHomeDir = str(self.homeEdit.text())
groupId = str(self.gidBox.value())
loginShell = str(self.shellEdit.text())
tmpList = str(self.nodeEdit.text()).split("@")
server = tmpList[-1]
baseDN = tmpList[0]
tmpObject = ServerList()
tmpObject.readServerList()
serverMeta = tmpObject.getServerObject(server)
connectionObject = LumaConnection(serverMeta)
bindSuccess, exceptionObject = connectionObject.bind()
if not bindSuccess:
environment.setBusy(False)
self.createButton.setEnabled(True)
dialog = LumaErrorDialog()
errorMsg = self.trUtf8("Could not bind to server.<br><br>Reason: ")
errorMsg.append(str(exceptionObject))
dialog.setErrorMessage(errorMsg)
dialog.exec_loop()
return
pwGenerator = CryptPwGenerator()
self.passwordEdit.clear()
createResult = True
automountSuccess = True
for x in range(userMin, userMax+1):
environment.updateUI()
userName = userPrefix + str(x)
uidNumber = freeNumbers[0]
del freeNumbers[0]
passwordClear, passwordCrypt = pwGenerator.getRandomPassword()
homeDir = baseHomeDir + "/" + userName
values = {}
# removed 'account' class
values['objectClass'] = ["account", 'posixAccount', 'shadowAccount']
values['uid'] = [userName]
values['uidNumber'] = [str(uidNumber)]
values['cn'] = [userName]
values['userPassword'] = ["{crypt}" + passwordCrypt]
values['loginShell'] = [loginShell]
values['shadowExpire'] = [str(shadowMax)]
values['gidNumber'] = [groupId]
values["homeDirectory"] = [homeDir]
preProcess(serverMeta, values)
tmpDN = 'uid=' + userName + "," + baseDN
dataObject = SmartDataObject((tmpDN, values), serverMeta)
success, exceptionObject = connectionObject.addDataObject(dataObject)
if not success:
createResult = False
break
# create automount entry
if self.enableNFSBox.isChecked():
tmpList = str(self.automountLocationEdit.text()).split(",")
del tmpList[-1]
automountDN = ",".join(tmpList)
dn = "cn=" + values["uid"][0] + "," + automountDN
mountValues = {}
mountValues["objectClass"] = ["automount"]
mountValues["cn"] = [values["uid"][0]]
automountServer = str(self.nfsServerEdit.text())
automountOptions = str(self.nfsArgumentsEdit.text())
automountInfo = automountOptions + " " + automountServer + ":" + values["homeDirectory"][0]
#automountInfo = "-fstype=nfs,rw,quota,soft,intr ciphome.in.tu-clausthal.de:" + values["homeDirectory"][0]
mountValues["automountInformation"] = [automountInfo]
mountValues["description"] = ["Mountpoint of the home directory from user " + values["cn"][0]]
dataObject = SmartDataObject((dn, mountValues), serverMeta)
success, exceptionObject = connectionObject.addDataObject(dataObject)
if not success:
automountSuccess = False
break
postProcess(serverMeta, values)
self.passwordEdit.append(userName + ': ' + passwordClear + "\n")
connectionObject.unbind()
environment.setBusy(False)
self.createButton.setEnabled(True)
if not createResult:
dialog = LumaErrorDialog()
errorMsg = self.trUtf8("Could not create all users.<br><br>Reason: ")
errorMsg.append(str(exceptionObject))
dialog.setErrorMessage(errorMsg)
dialog.exec_loop()
elif not automountSuccess:
dialog = LumaErrorDialog()
errorMsg = self.trUtf8("Could not create all automount information.<br><br>Reason: ")
errorMsg.append(str(exceptionObject))
dialog.setErrorMessage(errorMsg)
dialog.exec_loop()
else:
tmpDialog = QMessageBox(self.trUtf8("Success"),
self.trUtf8("""All users were created successfully."""),
QMessageBox.Critical,
QMessageBox.Ok,
QMessageBox.NoButton,
QMessageBox.NoButton,
self)
tmpDialog.setIconPixmap(QPixmap(os.path.join(self.iconPath, "final.png")))
tmpDialog.exec_loop()
###############################################################################
def browseServer(self):
dialog = BrowserDialog(self)
if dialog.result() == QDialog.Accepted:
self.nodeEdit.setText(dialog.getItemPath())
###############################################################################
def getUsedUidNumbers(self):
baseString = str(self.nodeEdit.text())
tmpList = baseString.split('@')
serverName = tmpList[-1]
ldapObject = tmpList[0]
serverList = ServerList()
serverList.readServerList()
serverMeta = serverList.getServerObject(serverName)
environment.setBusy(True)
connectionObject = LumaConnection(serverMeta)
bindSuccess, exceptionObject = connectionObject.bind()
if not bindSuccess:
environment.setBusy(False)
dialog = LumaErrorDialog()
errorMsg = self.trUtf8("Could not bind to server.<br><br>Reason: ")
errorMsg.append(str(exceptionObject))
dialog.setErrorMessage(errorMsg)
dialog.exec_loop()
return []
success, resultList, exceptionObject = connectionObject.search(ldapObject, ldap.SCOPE_SUBTREE,
"(objectClass=posixAccount)", ["uidNumber"], 0)
connectionObject.unbind()
environment.setBusy(False)
if success:
if resultList == None:
resultList = []
numberList = []
for x in resultList:
number = int(x.getAttributeValue('uidNumber', 0))
numberList.append(number)
return numberList
else:
dialog = LumaErrorDialog()
errorMsg = self.trUtf8("Could not retrieve used userid numbers.<br><br>Reason: ")
errorMsg.append(str(exceptionObject))
dialog.setErrorMessage(errorMsg)
dialog.exec_loop()
return []
###############################################################################
def getUidNumbers(self, uidNumMin, uidNumMax, usedNumbers, userCount):
tmpList = []
for x in range(uidNumMin, uidNumMax + 1):
if len(tmpList) == userCount:
break
if not (x in usedNumbers):
tmpList.append(x)
if len(tmpList) == userCount:
return tmpList
else:
return None
###############################################################################
def browseGroups(self):
result = None
dialog = BrowserDialog(self)
if dialog.result() == QDialog.Accepted:
success, resultList, exceptionObject = dialog.getLdapItem()
if success:
if len(resultList) > 0:
resultItem = resultList[0]
groupId = None
if resultItem.hasAttribute('gidNumber'):
groupId = resultItem.getAttributeValue('gidNumber', 0)
self.gidBox.setValue(int(groupId))
else:
tmpDialog = QMessageBox(self.trUtf8("Wrong entry"),
self.trUtf8("""The selected ldap entry did not contain the attribute 'gidNumber'."""),
QMessageBox.Critical,
QMessageBox.Ok,
QMessageBox.NoButton,
QMessageBox.NoButton,
self)
tmpDialog.setIconPixmap(QPixmap(os.path.join(self.iconPath, "warning_big.png")))
tmpDialog.exec_loop()
# Search result did not contain any items
else:
dialog = LumaErrorDialog(dialog)
errorMsg = self.trUtf8("Could not retrieve selected item.<br><br>Reason: ")
errorMsg.append(str(exceptionObject))
dialog.setErrorMessage(errorMsg)
dialog.exec_loop()
# search operation unsuccessful
else:
dialog = LumaErrorDialog(dialog)
errorMsg = self.trUtf8("Could not retrieve selected item.<br><br>Reason: ")
errorMsg.append(str(exceptionObject))
dialog.setErrorMessage(errorMsg)
dialog.exec_loop()
###############################################################################
def enableAutomount(self):
state = self.enableNFSBox.isChecked()
self.nfsServerEdit.setEnabled(state)
self.nfsArgumentsEdit.setEnabled(state)
self.automountLocationEdit.setEnabled(state)
self.browseAutomountButton.setEnabled(state)
self.automountLabel.setEnabled(state)
self.serverLabel.setEnabled(state)
self.argLabel.setEnabled(state)
self.locationLabel.setEnabled(state)
###############################################################################
def browseAutomount(self):
dialog = BrowserDialog(self)
if dialog.result() == QDialog.Accepted:
self.automountLocationEdit.setText(dialog.getItemPath())
###############################################################################
def enableDateEdit(self):
self.dateEdit.setEnabled(1)
self.dayBox.setEnabled(0)
###############################################################################
def disableDateEdit(self):
self.dateEdit.setEnabled(0)
self.dayBox.setEnabled(1)
|