Viewing file: userProperties.py (25.26 KB) -rwxr-xr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
## userProperties.py - event handling code for userconf's user properties ## Copyright (C) 2001-2003 Red Hat, Inc. ## Copyright (C) 2001-2003 Brent Fox <bfox@redhat.com>
## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version.
## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
## Author: Brent Fox
import exceptions import gtk import gobject import time import string import math import types import locale import rhpl.iconv import libuser import mainWindow import messageDialog import userGroupCheck
import warnings warnings.filterwarnings("ignore", "", DeprecationWarning, __name__)
## ## I18N ## from rhpl.translate import _, N_ import rhpl.translate as translate domain = "system-config-users" translate.textdomain (domain) gtk.glade.bindtextdomain(domain)
busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
class userProperties: def __init__(self, parent, user_clist, group_clist, xml, selinuxEnabled): self.parent = parent self.user_clist = user_clist self.group_clist = group_clist self.primaryGroupList = []
self.userWin = xml.get_widget('userProperties') self.userWin.connect("delete-event", self.on_cancel_button_clicked) self.userWin.set_icon(mainWindow.iconPixbuf) self.userWinUserName = xml.get_widget('userNameEntry') self.userWinFullName = xml.get_widget('fullNameEntry') self.userWinPassword = xml.get_widget('passwordEntry') self.userWinConfirm = xml.get_widget('confirmEntry') self.userWinHomeDir = xml.get_widget('homeDirEntry') self.loginShellCombo = xml.get_widget('loginShellCombo') self.loginShellCombo.entry.set_property('editable', False) self.selinuxPropCombo = xml.get_widget("selinuxPropCombo") self.selinuxPropCombo.entry.set_property('editable', False) self.selinuxPropLabel = xml.get_widget("selinuxPropLabel") self.userNotebook = xml.get_widget('userNotebook') self.lastChangedLabel = xml.get_widget('lastChangedLabel')
self.accountLockCheck = xml.get_widget('accountLockCheck') self.accountExpireCheck = xml.get_widget('accountExpireCheck') self.accountMonthEntry = xml.get_widget('accountMonthEntry') self.accountDayEntry = xml.get_widget('accountDayEntry') self.accountYearEntry = xml.get_widget('accountYearEntry') self.accountHSep = xml.get_widget('accountHSep') self.accountHBox = xml.get_widget('newAccountHBox') self.pwExpireCheck = xml.get_widget('pwExpireCheck') self.pwExpireTable = xml.get_widget('pwExpireTable') self.pwAllowEntry = xml.get_widget('pwAllowEntry') self.pwRequireEntry = xml.get_widget('pwRequireEntry') self.pwWarnEntry = xml.get_widget('pwWarnEntry') self.pwInactiveEntry = xml.get_widget('pwInactiveEntry') self.groupVBox = xml.get_widget('userPropGroupVBox')
if not selinuxEnabled: self.selinuxPropCombo.set_sensitive(False) self.selinuxPropLabel.set_sensitive(False)
self.selinuxRoleDict = { _("User"): "user_r", _("Staff") : "staff_r", _("System Administrator") : "sysadm_r"} roles = self.selinuxRoleDict.keys() roles.sort() self.selinuxPropCombo.set_popdown_strings(roles)
self.groupStore = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING) self.groupTreeView = gtk.TreeView(self.groupStore) self.groupTreeView.set_property("headers-visible", False)
self.checkboxrenderer = gtk.CellRendererToggle() self.checkboxrenderer.connect("toggled", self.toggled_item) col = gtk.TreeViewColumn(None, self.checkboxrenderer, active=0) self.groupTreeView.append_column(col) col = gtk.TreeViewColumn(None, gtk.CellRendererText(), text=1) self.groupTreeView.append_column(col)
self.groupChecklistSW = gtk.ScrolledWindow() self.groupChecklistSW = gtk.ScrolledWindow() self.groupChecklistSW.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) self.groupChecklistSW.set_shadow_type(gtk.SHADOW_IN) self.groupChecklistSW.add(self.groupTreeView) self.groupVBox.pack_start(self.groupChecklistSW, True)
self.shells = self.parent.ADMIN.getUserShells() self.shells.sort() self.loginShellCombo.set_popdown_strings(self.shells)
self.groupHBox = gtk.HBox(False, 5) self.primaryGroupCombo = gtk.Combo() self.primaryGroupCombo.entry.set_property('editable', False) self.groupHBox.pack_start(gtk.Label(_("Primary Group:")), False) self.groupHBox.pack_start(self.primaryGroupCombo, True) self.groupVBox.pack_start(self.groupHBox, False)
xml.signal_connect("on_cancel_button_clicked", self.on_cancel_button_clicked) xml.signal_connect("on_ok_button_clicked", self.on_ok_button_clicked) xml.signal_connect("on_accountExpireCheck_toggled", self.on_accountExpireCheck_toggled) xml.signal_connect("on_pwExpireCheck_toggled", self.on_pwExpireCheck_toggled) xml.signal_connect("on_accountLockCheck_toggled", self.on_accountLockCheck_toggled)
def busy(self): self.userWin.set_sensitive(False) self.userWin.window.set_cursor(busy_cursor)
def ready(self): self.userWin.window.set_cursor(ready_cursor) self.userWin.set_sensitive(True)
def userWinReset(self): self.userNotebook.set_current_page(0) self.userWinUserName.set_text('') self.userWinFullName.set_text('') self.userWinPassword.set_text('') self.userWinConfirm.set_text('') self.userWinHomeDir.set_text('') self.groupStore.clear()
self.accountLockCheck.set_active(False) self.on_accountLockCheck_toggled() self.accountExpireCheck.set_active(False) self.accountMonthEntry.set_text("") self.accountDayEntry.set_text("") self.accountYearEntry.set_text("") self.pwExpireCheck.set_active(False) self.pwAllowEntry.set_text('0') self.pwRequireEntry.set_text('0') self.pwWarnEntry.set_text('0') self.pwInactiveEntry.set_text('0') def showUserProperties(self, userEnt): self.userEnt = userEnt self.userWinReset()
uid = self.userEnt.get(libuser.USERNAME)[0] uidNumber = self.userEnt.get(libuser.UIDNUMBER)[0] if uidNumber == 0: #Don't allow root account to be locked self.accountLockCheck.set_sensitive(False) else: self.accountLockCheck.set_sensitive(True) self.on_accountLockCheck_toggled()
fn = self.userEnt.get(libuser.GECOS)[0] #Convert the user fullName into unicode so pygtk2 doesn't truncate strings fn = unicode (fn, 'utf-8') hd = self.userEnt.get(libuser.HOMEDIRECTORY)[0] shell = self.userEnt.get(libuser.LOGINSHELL)[0]
self.userWinUserName.set_text(uid) if uid == "root": #Don't allow root uid to be changed self.userWinUserName.set_sensitive(False)
self.userWinFullName.set_text(fn) self.userWinPassword.set_text(' ') self.userWinConfirm.set_text(' ') self.userWinHomeDir.set_text(hd)
if shell not in self.shells: self.shells.append(shell) self.shells.sort() self.loginShellCombo.set_popdown_strings(self.shells) self.loginShellCombo.list.select_item(self.shells.index(shell))
lastChange = self.userEnt.get(libuser.SHADOWLASTCHANGE) if lastChange: daysSinceEpoch = lastChange[0] secondsPerDay = 24 * 60 * 60 secondsSinceEpoch = int(daysSinceEpoch) * int(secondsPerDay) age = time.strftime("%c", time.gmtime(secondsSinceEpoch)) converter = rhpl.iconv.open("utf-8", locale.nl_langinfo (locale.CODESET)) age = converter.iconv(age) self.lastChangedLabel.set_text(age)
if "shadow" in self.userEnt.modules(): expire = self.userEnt.get(libuser.SHADOWEXPIRE) min = self.userEnt.get(libuser.SHADOWMIN) max = self.userEnt.get(libuser.SHADOWMAX) warning = self.userEnt.get(libuser.SHADOWWARNING) inactive = self.userEnt.get(libuser.SHADOWINACTIVE)
if expire: try: if int(expire[0]) != -1: self.accountExpireCheck.set_active(True) days = int(self.userEnt.get(libuser.SHADOWEXPIRE)[0] + 1) tmp = days * int(secondsPerDay) age = time.localtime(tmp) year = str(age[0]) month = str(age[1]) day = str(age[2]) self.accountMonthEntry.set_text(month) self.accountDayEntry.set_text(day) self.accountYearEntry.set_text(year) except: self.accountExpireCheck.set_active(False)
if int(min[0]) == 0 and int(max[0]) == 99999 and int(warning[0]) == 7 and int(inactive[0]) == -1: self.pwExpireCheck.set_active(False) else: self.pwExpireCheck.set_active(True) self.pwAllowEntry.set_text(str(min[0])) self.pwRequireEntry.set_text(str(max[0])) self.pwWarnEntry.set_text(str(warning[0])) self.pwInactiveEntry.set_text(str(inactive[0]))
if self.parent.ADMIN.userIsLocked(self.userEnt) == 1: self.accountLockCheck.set_active(True)
self.fill_groups_list(self.userEnt) self.set_default_group(self.userEnt) self.userWin.show_all()
#Hide SELinux widgets for now self.selinuxPropCombo.hide() self.selinuxPropLabel.hide()
if "shadow" not in self.userEnt.modules(): #hide the account expiration and password expiration widgets if shadow passwords are not enabled self.accountExpireCheck.hide() self.accountHBox.hide() self.accountHSep.hide() self.userNotebook.get_nth_page(2).hide()
def on_cancel_button_clicked(self, *args): self.userWinReset() self.userWin.hide() return True
def on_ok_button_clicked(self, *args): self.busy() #The logic here is kind of complicated, but I'll try to explain uid = self.userWinUserName.get_text() userName = self.userEnt.get(libuser.USERNAME)[0] gecos = self.userWinFullName.get_text() pw = self.userWinPassword.get_text() confirm = self.userWinConfirm.get_text()
#Check for UTF-8-only strings if not userGroupCheck.isUsernameOk(uid, self.userWinUserName): self.ready() self.userWinUserName.grab_focus() return
if not userGroupCheck.isNameOk(gecos, self.userWinFullName): self.ready() self.userWinFullName.grab_focus() return
hd = self.userWinHomeDir.get_text() shell = self.loginShellCombo.entry.get_text() primaryGroup = self.userEnt.get(libuser.GIDNUMBER)[0]
if pw == confirm == ' ': pass elif pw == confirm and len (pw) >= 6: #Check for ascii-only strings if not userGroupCheck.isPasswordOk(pw, self.userWinPassword): self.ready() self.userWinPassword.grab_focus() return
if not userGroupCheck.isPasswordOk(confirm, self.userWinConfirm): self.ready() self.userWinConfirm.grab_focus() return
self.parent.ADMIN.setpassUser(self.userEnt, pw, 0) else: if not pw and not confirm: messageDialog.show_message_dialog(_("Please enter a password for the user.")) self.ready() self.userNotebook.set_current_page(0) self.userWinPassword.set_text("") self.userWinConfirm.set_text("") self.userWinPassword.grab_focus() return elif len (pw) < 6: messageDialog.show_message_dialog(_("The password is too short. Please " "use at least 6 characters.")) self.ready() self.userNotebook.set_current_page(0) self.userWinPassword.set_text("") self.userWinConfirm.set_text("") self.userWinPassword.grab_focus() return else: messageDialog.show_message_dialog(_("Passwords do not match."))
self.ready() self.userNotebook.set_current_page(0) self.userWinPassword.set_text("") self.userWinConfirm.set_text("") self.userWinPassword.grab_focus() return
if not userGroupCheck.isHomedirOk(hd, self.userWinHomeDir): self.ready() self.userWinHomeDir.set_text(self.userEnt.get(libuser.HOMEDIRECTORY)[0]) self.userWinHomeDir.grab_focus() return
self.userEnt.set(libuser.USERNAME, uid) self.userEnt.set(libuser.GECOS, gecos) self.userEnt.set(libuser.HOMEDIRECTORY, hd) self.userEnt.set(libuser.LOGINSHELL, shell)
group_list = [] need_refresh = [uid] members = []
#Let's iterate through the groupStore and see what groups are selected iter = self.groupStore.get_iter_root() while iter: val = self.groupStore.get_value(iter, 0) group = self.groupStore.get_value(iter, 1)
try: groupEnt = self.parent.group_dict[group] except: groupEnt = self.parent.ADMIN.lookupGroupByName(group) gid = groupEnt.get(libuser.GIDNUMBER)[0] members = groupEnt.get(libuser.MEMBERNAME) if not members: members = [] elif uid != userName and userName in members: # username has changed, remove references to old name members.remove (userName) groupEnt.set (libuser.MEMBERNAME, members) self.parent.ADMIN.modifyGroup (groupEnt) need_refresh.append(group)
if val: try: index = members.index(uid) except: index = -1
if index == -1: # the user is not in the group, but should be need_refresh.append(group) if primaryGroup != gid: members.append(uid) groupEnt.set(libuser.MEMBERNAME, members) self.parent.ADMIN.modifyGroup(groupEnt) else: try: index = members.index(uid) except: index = -1 if index >= 0: # the user is not supposed to be in the group, but is need_refresh.append(group) members.remove(uid) groupEnt.set(libuser.MEMBERNAME, members) self.parent.ADMIN.modifyGroup(groupEnt)
iter = self.groupStore.iter_next(iter)
if self.primaryGroupCombo.entry.get_text() == "": messageDialog.show_message_dialog(_("Please select at least one group for the user."))
self.ready() self.userNotebook.set_current_page(3) return else: primaryGroupEnt = self.parent.ADMIN.lookupGroupByName(self.primaryGroupCombo.entry.get_text()) if primaryGroupEnt == None: primaryGroupId = int(self.primaryGroupCombo.entry.get_text()) else: primaryGroupId = primaryGroupEnt.get(libuser.GIDNUMBER)[0] self.userEnt.set(libuser.GIDNUMBER, [primaryGroupId]) if self.accountExpireCheck.get_active(): year = string.strip(self.accountYearEntry.get_text()) month = string.strip(self.accountMonthEntry.get_text()) day = string.strip(self.accountDayEntry.get_text())
if month == "": messageDialog.show_message_dialog(_("Please specify the month that the password will expire.")) self.ready() self.userNotebook.set_current_page(1) self.accountMonthEntry.set_text("") self.accountMonthEntry.grab_focus() return
if day == "": messageDialog.show_message_dialog(_("Please specify the day that the password will expire.")) self.ready() self.userNotebook.set_current_page(1) self.accountDayEntry.set_text("") self.accountDayEntry.grab_focus() return if year == "": messageDialog.show_message_dialog(_("Please specify the year that the password will expire.")) self.ready() self.userNotebook.set_current_page(1) self.accountYearEntry.set_text("") self.accountYearEntry.grab_focus() return
year = int(year) month = int(month) day = int(day)
timetuple = [ year, month, day, 1, 1, 1, 1, 1, 1] try: tmp = time.mktime(timetuple) except: #mktime will throw an OverflowError if the year is too big. messageDialog.show_message_dialog(_("The year is out of range. Please select a different year.")) self.ready() self.userNotebook.set_current_page(1) self.accountYearEntry.set_text("") self.accountYearEntry.grab_focus() return seconds = 24 * 60 * 60 daysTillExpire = tmp / seconds fraction, integer = math.modf(daysTillExpire)
if fraction == 0.0: daysTillExpire = str(int(tmp/seconds)-1) else: daysTillExpire = str(int(tmp/seconds))
self.userEnt.set(libuser.SHADOWEXPIRE, daysTillExpire) else: self.userEnt.set(libuser.SHADOWEXPIRE, "-1")
if self.pwExpireCheck.get_active(): allowed = string.strip(self.pwAllowEntry.get_text()) required = string.strip(self.pwRequireEntry.get_text()) warning = string.strip(self.pwWarnEntry.get_text()) inactive = string.strip(self.pwInactiveEntry.get_text())
if allowed == "": messageDialog.show_message_dialog(_("Please specify the number of days before " "changing the password is allowed.")) self.ready() self.userNotebook.set_current_page(2) self.pwAllowEntry.set_text("") self.pwAllowEntry.grab_focus() return
if required == "": messageDialog.show_message_dialog(_("Please specify the number of days before " "changing the password is required.")) self.ready() self.userNotebook.set_current_page(2) self.pwRequireEntry.set_text("") self.pwRequireEntry.grab_focus() return
if warning == "": messageDialog.show_message_dialog(_("Please specify the number of days to warn the user before " "changing the password is required.")) self.ready() self.userNotebook.set_current_page(2) self.pwWarnEntry.set_text("") self.pwWarnEntry.grab_focus() return
if inactive == "": messageDialog.show_message_dialog(_("Please specify the number of days until the user " "account becomes inactive after password has expired.")) self.ready() self.userNotebook.set_current_page(2) self.pwInactiveEntry.set_text("") self.pwInactiveEntry.grab_focus() return
self.userEnt.set(libuser.SHADOWMIN, allowed) self.userEnt.set(libuser.SHADOWMAX, required) self.userEnt.set(libuser.SHADOWWARNING, warning) self.userEnt.set(libuser.SHADOWINACTIVE, inactive) else: self.userEnt.set(libuser.SHADOWMIN, '0') self.userEnt.set(libuser.SHADOWMAX, '99999') self.userEnt.set(libuser.SHADOWWARNING, '7') self.userEnt.set(libuser.SHADOWINACTIVE, '-1')
self.parent.ADMIN.modifyUser(self.userEnt)
if self.accountLockCheck.get_active(): if self.parent.ADMIN.userIsLocked(self.userEnt) == 0: self.parent.ADMIN.lockUser(self.userEnt) else: if self.parent.ADMIN.userIsLocked(self.userEnt) == 1: self.parent.ADMIN.unlockUser(self.userEnt)
self.parent.refresh_users_and_groups(need_refresh) self.userWinReset() self.userWin.hide() self.ready()
def on_accountExpireCheck_toggled(self, *args): self.accountHBox.set_sensitive(self.accountExpireCheck.get_active())
def on_pwExpireCheck_toggled(self, *args): self.pwExpireTable.set_sensitive(self.pwExpireCheck.get_active())
def on_accountLockCheck_toggled(self, *args): isLocked = self.accountLockCheck.get_active () self.userWinPassword.set_sensitive (not isLocked) self.userWinConfirm.set_sensitive (not isLocked)
def toggled_item(self, data, row): #Store the current selection temporarily. Otherwise, calling set_popdown_strings will erase it tempName = self.primaryGroupCombo.entry.get_text() iter = self.groupStore.get_iter(int(row)) val = self.groupStore.get_value(iter, 0) group = self.groupStore.get_value(iter, 1) self.groupStore.set_value(iter, 0, not val)
if self.primaryGroupList == [""]: self.primaryGroupList = [] if val == 0: if group not in self.primaryGroupList: self.primaryGroupList.append(group) elif val ==1: if group in self.primaryGroupList: self.primaryGroupList.remove(group) if self.primaryGroupList == []: self.primaryGroupList.append("")
#Sort the list before pushing it into the combo widget self.primaryGroupList.sort() #Push the list into the combo widget self.primaryGroupCombo.set_popdown_strings(self.primaryGroupList)
if tempName in self.primaryGroupList: #If the tempName is still in the list, preserve the current setting self.primaryGroupCombo.entry.set_text(tempName) else: #The tempName is no longer in the list, so select the first choice in the list self.primaryGroupCombo.entry.set_text(self.primaryGroupList[0])
def fill_groups_list (self, userEnt): self.groups = self.parent.ADMIN.enumerateGroups() self.groups.sort() row = 0 uid = userEnt.get(libuser.USERNAME)[0] usergroups = self.parent.ADMIN.enumerateGroupsByUser(uid) self.primaryGroupList = []
for group in self.groups: if group in usergroups: iter = self.groupStore.append() self.groupStore.set_value(iter, 0, True) self.groupStore.set_value(iter, 1, group) self.primaryGroupList.append(group) else: iter = self.groupStore.append() self.groupStore.set_value(iter, 0, False) self.groupStore.set_value(iter, 1, group)
def set_default_group (self, userEnt): primaryGroupId = userEnt.get(libuser.GIDNUMBER)[0] primaryGroupEnt = self.parent.ADMIN.lookupGroupById(primaryGroupId) if primaryGroupEnt == None: primaryGroupName = str(primaryGroupId) self.primaryGroupCombo.list.unselect_all() self.primaryGroupList.append(primaryGroupName) self.primaryGroupCombo.set_popdown_strings(self.primaryGroupList) self.primaryGroupCombo.entry.set_text(primaryGroupName) else: self.primaryGroupCombo.set_popdown_strings(self.primaryGroupList) primaryGroupName = primaryGroupEnt.get(libuser.GROUPNAME)[0] index = self.primaryGroupList.index(primaryGroupName) self.primaryGroupCombo.list.select_item(index)
|