Back to index

system-config-printer  1.3.9+20120706
pysmb.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 
00003 ## system-config-printer
00004 ## CUPS backend
00005  
00006 ## Copyright (C) 2002, 2003, 2006, 2007, 2008, 2010 Red Hat, Inc.
00007 ## Authors:
00008 ##  Tim Waugh <twaugh@redhat.com>
00009  
00010 ## This program is free software; you can redistribute it and/or modify
00011 ## it under the terms of the GNU General Public License as published by
00012 ## the Free Software Foundation; either version 2 of the License, or
00013 ## (at your option) any later version.
00014  
00015 ## This program is distributed in the hope that it will be useful,
00016 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 ## GNU General Public License for more details.
00019  
00020 ## You should have received a copy of the GNU General Public License
00021 ## along with this program; if not, write to the Free Software
00022 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023 
00024 import errno
00025 from gettext import gettext as _
00026 import gobject
00027 import gtk
00028 import os
00029 import pwd
00030 import smbc
00031 from debug import *
00032 
00033 class _None(RuntimeError):
00034     pass
00035 
00036 try:
00037     NoEntryError = smbc.NoEntryError
00038     PermissionError = smbc.PermissionError
00039     ExistsError = smbc.ExistsError
00040     NotEmptyError = smbc.NotEmptyError
00041     TimedOutError = smbc.TimedOutError
00042     NoSpaceError = smbc.NoSpaceError
00043 except AttributeError:
00044     NoEntryError = PermissionError = ExistsError = _None
00045     NotEmptyError = TimedOutError = NoSpaceError = _None
00046 
00047 class AuthContext:
00048     def __init__ (self, parent=None, workgroup='', user='', passwd=''):
00049         self.passes = 0
00050         self.has_failed = False
00051         self.auth_called = False
00052         self.tried_guest = False
00053         self.cancel = False
00054         self.use_user = user
00055         self.use_password = passwd
00056         self.use_workgroup = workgroup
00057         self.dialog_shown = False
00058         self.parent = parent
00059 
00060     def perform_authentication (self):
00061         self.passes += 1
00062         if self.passes == 1:
00063             return 1
00064 
00065         if not self.has_failed:
00066             return 0
00067 
00068         debugprint ("pysmb: authentication pass: %d" % self.passes)
00069         if not self.auth_called:
00070             debugprint ("pysmb: auth callback not called?!")
00071             self.cancel = True
00072             return 0
00073 
00074         self.has_failed = False
00075         if self.auth_called and not self.tried_guest:
00076             self.use_user = 'guest'
00077             self.use_password = ''
00078             self.tried_guest = True
00079             debugprint ("pysmb: try auth as guest")
00080             return 1
00081 
00082         self.auth_called = False
00083 
00084         if self.dialog_shown:
00085             d = gtk.MessageDialog (self.parent,
00086                                    gtk.DIALOG_MODAL |
00087                                    gtk.DIALOG_DESTROY_WITH_PARENT,
00088                                    gtk.MESSAGE_ERROR,
00089                                    gtk.BUTTONS_CLOSE)
00090             d.set_title (_("Not authorized"))
00091             d.set_markup ('<span weight="bold" size="larger">' +
00092                           _("Not authorized") + '</span>\n\n' +
00093                           _("The password may be incorrect."))
00094             d.run ()
00095             d.destroy ()
00096 
00097         # After that, prompt
00098         d = gtk.Dialog (_("Authentication"), self.parent,
00099                         gtk.DIALOG_MODAL | gtk.DIALOG_NO_SEPARATOR,
00100                         (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
00101                          gtk.STOCK_OK, gtk.RESPONSE_OK))
00102         d.set_default_response (gtk.RESPONSE_OK)
00103         d.set_border_width (6)
00104         d.set_resizable (False)
00105         hbox = gtk.HBox (False, 12)
00106         hbox.set_border_width (6)
00107         image = gtk.Image ()
00108         image.set_from_stock (gtk.STOCK_DIALOG_AUTHENTICATION,
00109                               gtk.ICON_SIZE_DIALOG)
00110         hbox.pack_start (image, False, False, 0)
00111         vbox = gtk.VBox (False, 12)
00112         label = gtk.Label ('<span weight="bold" size="larger">' +
00113                            _("You must log in to access %s.") % self.for_server +
00114                            '</span>')
00115         label.set_use_markup (True)
00116         label.set_alignment (0, 0)
00117         label.set_line_wrap (True)
00118         vbox.pack_start (label, False, False, 0)
00119 
00120         table = gtk.Table (3, 2)
00121         table.set_row_spacings (6)
00122         table.set_col_spacings (6)
00123         table.attach (gtk.Label (_("Username:")), 0, 1, 0, 1, 0, 0)
00124         username_entry = gtk.Entry ()
00125         table.attach (username_entry, 1, 2, 0, 1, 0, 0)
00126         table.attach (gtk.Label (_("Domain:")), 0, 1, 1, 2, 0, 0)
00127         domain_entry = gtk.Entry ()
00128         table.attach (domain_entry, 1, 2, 1, 2, 0, 0)
00129         table.attach (gtk.Label (_("Password:")), 0, 1, 2, 3, 0, 0)
00130         password_entry = gtk.Entry ()
00131         password_entry.set_activates_default (True)
00132         password_entry.set_visibility (False)
00133         table.attach (password_entry, 1, 2, 2, 3, 0, 0)
00134         vbox.pack_start (table, False, False, 0)
00135         hbox.pack_start (vbox, False, False, 0)
00136         d.vbox.pack_start (hbox)
00137         self.dialog_shown = True
00138         d.show_all ()
00139         d.show_now ()
00140 
00141         if self.use_user == 'guest':
00142             self.use_user = pwd.getpwuid (os.getuid ())[0]
00143             debugprint ("pysmb: try as %s" % self.use_user)
00144         username_entry.set_text (self.use_user)
00145         domain_entry.set_text (self.use_workgroup)
00146 
00147         d.set_keep_above (True)
00148         gtk.gdk.pointer_grab (d.window, True)
00149         gtk.gdk.keyboard_grab (d.window, True)
00150         response = d.run ()
00151         gtk.gdk.keyboard_ungrab ()
00152         gtk.gdk.pointer_ungrab ()
00153 
00154         if response == gtk.RESPONSE_CANCEL:
00155             self.cancel = True
00156             d.destroy ()
00157             return -1
00158 
00159         self.use_user = username_entry.get_text ()
00160         self.use_password = password_entry.get_text ()
00161         self.use_workgroup = domain_entry.get_text ()
00162         d.destroy ()
00163         return 1
00164 
00165     def initial_authentication (self):
00166         try:
00167             context = smbc.Context ()
00168             self.use_workgroup = context.workgroup
00169         except:
00170             pass
00171 
00172     def failed (self, exc=None):
00173         self.has_failed = True
00174         debugprint ("pysmb: operation failed: %s" % repr (exc))
00175 
00176         if exc:
00177             if (self.cancel or
00178                 (type (exc) in [NoEntryError, ExistsError, NotEmptyError,
00179                                 TimedOutError, NoSpaceError]) or
00180                 (type (exc) == RuntimeError and
00181                  not (exc.args[0] in [errno.EACCES, errno.EPERM]))):
00182                     raise exc
00183 
00184     def callback (self, server, share, workgroup, user, password):
00185         debugprint ("pysmb: got password callback")
00186         self.auth_called = True
00187         self.for_server = server
00188         self.for_share = share
00189         if self.passes == 1:
00190             self.initial_authentication ()
00191 
00192         if self.use_user:
00193             if self.use_workgroup:
00194                 workgroup = self.use_workgroup
00195 
00196             return (workgroup, self.use_user, self.use_password)
00197 
00198         user = ''
00199         password = ''
00200         return (workgroup, user, password)