|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /proc/21573/root/usr/share/system-config-users/ |
Upload File : |
## userWindow.py - event handling code for userconf's user window
## 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 gtk
import string
import libuser
import mainWindow
import messageDialog
import userGroupCheck
import userGroupFind
##
## 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 userWindow:
def __init__(self, parent, userStore, group_clist, xml, selinuxEnabled):
self.parent = parent
self.userStore = userStore
self.group_clist = group_clist
self.userWin = xml.get_widget('newUserWindow')
self.userWin.connect("delete-event", self.on_userWin_cancel_button_clicked)
self.userWin.set_icon(mainWindow.iconPixbuf)
self.userWinUserName = xml.get_widget('newUserNameEntry')
self.userWinFullName = xml.get_widget('newFullNameEntry')
self.userWinPassword = xml.get_widget('newPasswordEntry')
self.userWinConfirm = xml.get_widget('newConfirmEntry')
self.userWinHomeDir = xml.get_widget('newHomeDirEntry')
self.loginShellCombo = xml.get_widget('newLoginShellCombo')
self.loginShellCombo.entry.set_property('editable', False)
self.selinuxCombo = xml.get_widget("selinuxCombo")
self.selinuxCombo.entry.set_property('editable', False)
self.selinuxLabel = xml.get_widget("selinuxLabel")
self.newGroupCheck = xml.get_widget('newGroupCheck')
self.passwordLabel = xml.get_widget('passwordLabel')
self.homeDirHbox = xml.get_widget('homeDirHbox')
self.homeDirCheck = xml.get_widget('homeDirCheck')
self.uidCheckButton = xml.get_widget('uidCheckButton')
self.uidBox = xml.get_widget('uidBox')
self.uidSpinButton = xml.get_widget('uidSpinButton')
self.uidSpinButton.set_range(0, pow(2, 32))
self.uidSpinButton.set_value(500)
if not selinuxEnabled:
self.selinuxCombo.set_sensitive(False)
self.selinuxLabel.set_sensitive(False)
self.selinuxRoleDict = { _("User"): "user_r", _("Staff") : "staff_r",
_("System Administrator") : "sysadm_r"}
roles = self.selinuxRoleDict.keys()
roles.sort()
self.selinuxCombo.set_popdown_strings(roles)
self.selinuxCombo.list.select_item(2)
self.shells = self.parent.ADMIN.getUserShells()
self.shells.sort()
self.loginShellCombo.set_popdown_strings(self.shells)
default = '/bin/bash'
if default in self.shells:
self.loginShellCombo.list.select_item(self.shells.index(default))
xml.signal_connect("on_userWin_cancel_button_clicked", self.on_userWin_cancel_button_clicked)
xml.signal_connect("on_userWin_ok_button_clicked", self.on_userWin_ok_button_clicked)
xml.signal_connect("on_newUserNameEntry_focus_out_event", self.on_newUserNameEntry_focus_out_event)
xml.signal_connect("on_uidCheckButton_toggled", self.on_uidCheckButton_toggled)
#--function to reset the entry widgets in the user screen
def userWinReset(self):
self.userWinUserName.grab_focus()
self.userWinUserName.set_text("")
self.userWinFullName.set_text("")
self.userWinPassword.set_text("")
self.userWinConfirm.set_text("")
self.userWinHomeDir.set_text("")
self.newGroupCheck.set_active(True)
self.uidCheckButton.set_active(False)
self.homeDirCheck.set_active(True)
try:
#Hack to work around what I suspect is a gtk bug
self.uidSpinButton.set_value(500)
except:
pass
default = '/bin/bash'
if default in self.shells:
self.loginShellCombo.list.select_item(self.shells.index(default))
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 newUserWin(self, filter):
self.filter = filter
self.userWinReset()
self.userWin.show_all()
#Hide SELinux widgets for now
self.selinuxCombo.hide()
self.selinuxLabel.hide()
def hideWin(self):
self.userWin.hide()
def getUserName(self):
name = self.userWinUserName.get_text()
return name
def getFullName(self):
return self.userWinFullName.get_text()
#--------Event handlers for user window-----#
def on_homeDirCheck_toggled(self, *args):
self.homeDirHbox.set_sensitive(self.homeDirCheck.get_active())
def on_newUserNameEntry_focus_out_event(self, *args):
name = self.userWinUserName.get_text()
self.userWinHomeDir.set_text("/home/%s" % name)
def on_uidCheckButton_toggled(self, *args):
self.uidBox.set_sensitive(self.uidCheckButton.get_active())
def on_userWin_cancel_button_clicked(self, *args):
self.userWinReset()
self.userWin.hide()
return True
def on_userWin_ok_button_clicked(self, *args):
self.busy()
userName = self.userWinUserName.get_text()
fullName = self.userWinFullName.get_text()
pw = self.userWinPassword.get_text ()
confirm = self.userWinConfirm.get_text ()
homeDir = self.userWinHomeDir.get_text()
#Check for ascii-only strings
if not userGroupCheck.isUsernameOk(userName, self.userWinUserName):
self.ready()
self.userWinUserName.grab_focus()
return
if not userGroupCheck.isNameOk(fullName, self.userWinFullName):
self.ready()
self.userWinFullName.grab_focus()
return
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
if not userGroupCheck.isHomedirOk(homeDir, self.userWinHomeDir):
self.ready()
self.userWinHomeDir.grab_focus()
self.on_newUserNameEntry_focus_out_event()
return
if userName == "":
#The user name is blank, so complain
messageDialog.show_message_dialog(_("Please specify a user name"))
self.ready()
self.userWinUserName.grab_focus()
return
user = self.parent.ADMIN.lookupUserByName(userName)
if user != None:
#This user already exists, so complain
messageDialog.show_message_dialog(_("An account with username '%s' already exists.") %userName)
self.ready()
self.userWinUserName.set_text("")
self.userWinUserName.grab_focus()
return
if pw == confirm and len (pw) >= 6:
#If the passwords match, go on
pass
else:
#The passwords don't match, so complain
if not pw and not confirm:
messageDialog.show_message_dialog(_("Please enter a password for the user."))
self.ready()
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.userWinPassword.set_text("")
self.userWinConfirm.set_text("")
self.userWinPassword.grab_focus()
return
else:
messageDialog.show_message_dialog(_("The passwords do not match."))
self.ready()
self.userWinPassword.set_text("")
self.userWinConfirm.set_text("")
self.userWinPassword.grab_focus()
return
userEnt = self.parent.ADMIN.initUser(userName)
# workaround bug with purely numerical names in ADMIN.initUser ()
userEnt.set (libuser.USERNAME, userName)
userEnt.set(libuser.GECOS, [fullName])
# Don't set if there are defaults
if not len (userEnt.get (libuser.SHADOWMIN)):
userEnt.set(libuser.SHADOWMIN, '0')
if not len (userEnt.get (libuser.SHADOWMAX)):
userEnt.set(libuser.SHADOWMAX, '99999')
if self.homeDirCheck.get_active():
userEnt.set(libuser.HOMEDIRECTORY, [homeDir])
else:
userEnt.set(libuser.HOMEDIRECTORY, [""])
userEnt.set(libuser.LOGINSHELL, [self.loginShellCombo.entry.get_text()])
if self.uidCheckButton.get_active():
uidNumber = int(self.uidSpinButton.get_value())
else:
uidNumber = None
gidNumber = None
gidDuplicate = False
try:
uidNumber, gidNumber = userGroupFind.find_uid_gid (self.parent.ADMIN, self.parent.preferences, uidNumber = uidNumber, gidNumber = gidNumber)
except userGroupFind.DuplicateUidNumberError, ue:
# This uid already exists, so complain
messageDialog.show_message_dialog(_("The uid %s is already in use.") % ue.uidNumber)
self.ready()
self.uidSpinButton.grab_focus()
return
except userGroupFind.DuplicateGidNumberError, ge:
gidDuplicate = True
gidNumber = ge.gidNumber
# A group with this gid already exists. Handle this a little further down.
if self.uidCheckButton.get_active() and uidNumber < 500:
# They want a UID < 500. Warn the user, but allow it if they insist
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO,
(_("Creating a user with a UID less than 500 is not recommended. "
"Are you sure you want to do this?")))
dlg.set_position(gtk.WIN_POS_CENTER)
dlg.set_modal(True)
dlg.set_icon(mainWindow.iconPixbuf)
result = dlg.run()
dlg.destroy()
if result == gtk.RESPONSE_YES:
pass
else:
self.ready()
return
userEnt.set(libuser.UIDNUMBER, [uidNumber])
if self.newGroupCheck.get_active(): #Create new group
group = self.parent.ADMIN.lookupGroupByName(userName)
if group != None or gidDuplicate:
# A group with this name or gid already exists. Ask them what they want to do.
dlg = gtk.Dialog()
dlg.set_modal(True)
dlg.set_icon(mainWindow.iconPixbuf)
dlg.add_button(gtk.STOCK_CANCEL, 0)
dlg.add_button(gtk.STOCK_OK, 1)
dlg.set_border_width(4)
dlg.vbox.set_spacing(4)
if gidDuplicate:
label = gtk.Label(_("A group with this gid already exists. What would you like to do?"))
else:
label = gtk.Label(_("A group with this name already exists. What would you like to do?"))
label.set_line_wrap(True)
dlg.vbox.pack_start(label)
self.existingRadio = gtk.RadioButton(None, (_("Add to the existing group")))
self.usersRadio = gtk.RadioButton(self.existingRadio, (_("Add to the 'users' group")))
self.existingRadio.set_border_width(6)
self.usersRadio.set_border_width(6)
dlg.vbox.pack_start(self.existingRadio)
dlg.vbox.pack_start(self.usersRadio)
dlg.show_all()
result = dlg.run()
dlg.destroy()
if result == 1:
#The clicked Ok, so do what they want
if self.existingRadio.get_active():
#Add the user to the existing group
if gidDuplicate:
cn = [userName, self.parent.ADMIN.lookupGroupById (gidNumber)]
else:
cn = group.get(libuser.GROUPNAME)[0]
#gidNumber = group.get(libuser.GIDNUMBER)[0]
userEnt.set(libuser.GIDNUMBER, [gidNumber])
self.userWinReset()
self.userWin.hide()
else:
#Add the user to the 'users' group
self.addToUsersGroup(userEnt, userName)
self.userWinReset()
self.userWin.hide()
else:
#They clicked Cancel, so do nothing
self.ready()
return
else:
#No group currently exists with this name, so we can create one
groupEnt = self.parent.ADMIN.initGroup(userName)
# workaround bug with purely numerical names in ADMIN.initGroup ()
groupEnt.set (libuser.GROUPNAME, userName)
groupEnt.set (libuser.GIDNUMBER, gidNumber)
cn = groupEnt.get(libuser.GROUPNAME)[0]
userEnt.set(libuser.GIDNUMBER, [gidNumber])
members = groupEnt.get(libuser.MEMBERNAME)
if not members:
members = []
memberlist = string.join(members, ", ")
self.parent.ADMIN.addGroup(groupEnt)
self.parent.refresh_users_and_groups(cn)
self.userWinReset()
self.userWin.hide()
else:
#Add user to group 'users'
self.addToUsersGroup(userEnt, userName)
self.userWin.hide()
if self.homeDirCheck.get_active():
#Create a home directory for the user
self.parent.ADMIN.addUser(userEnt)
else:
#Do not create a home directory for the user
self.parent.ADMIN.addUser(userEnt)
homeDir = ""
self.parent.ADMIN.setpassUser(userEnt, pw, 0)
self.parent.refresh_users_and_groups([userName, 'users'])
self.ready()
def addToUsersGroup(self, userEnt, userName):
groupEnt = self.parent.ADMIN.lookupGroupByName('users')
if groupEnt == None:
#The 'users' doesn't exist. Let's create one
groupEnt = self.parent.ADMIN.initGroup('users')
groupEnt.set(libuser.GIDNUMBER, "100")
self.parent.ADMIN.addGroup(groupEnt)
cn = groupEnt.get(libuser.GROUPNAME)[0]
# try to get a name to associate with the user's primary gid,
# and attempt to minimize lookups by caching answers
try:
gidNumber = groupEnt.get(libuser.GIDNUMBER)[0]
except:
#Uh-oh. It looks like /etc/group and /etc/gshadow are out of sync. Give up and quit.
messageDialog.show_message_dialog(_("The system group database cannot be read. This problem is most likely caused by a mismatch in /etc/group and /etc/gshadow. The program will exit now."))
import os
os._exit(0)
userEnt.set(libuser.GIDNUMBER, [gidNumber])
members = groupEnt.get(libuser.MEMBERNAME)
if not members:
members = []
members.append(userName)
groupEnt.set(libuser.MEMBERNAME, members)
self.parent.ADMIN.modifyGroup(groupEnt)