Logo Search packages:      
Sourcecode: sadms version File versions  Download package

sadms.py

#!/usr/bin/python
# -*-coding: UTF-8 -*-
# bbou@ac-toulouse.fr
# GPL license
# 30/08/2009 
# sadms.py

import pygtk
pygtk.require("2.0")
from gtk import *
import gtk.glade
import gobject
import pango
import locale
import string
import re
import os
import sys
import gettext

import runner
import remote
import globs
import users
import acls
import shares
import share
import ipcalc

#######################################################################
#     GLOBALS
#######################################################################

APP_NAME = "sadms"

# settings
setting={
      'realm':'',
      'dns':'',
      'kdc':'',
      'domain':'',
      'server':'',
      'hostOu':'',
      'administrator':'',
      'administratorPassword':'',
      'users':'',
      'hostsAllow':'',
      'winsServer':'',
      'userFilter':'$3 >= %LOWID%',
      'userNotFilter':'index($1,\"HOST\")>0',
      'groupFilter':'$3 >= %LOWID%',
      'groupNotFilter':'index($1,\"BUILTIN\")>0',
      'cifsserver':'server',
      'cifsshare':'*',
      'cifsmountpoint':'~/.cifsmount',
      'cifsuser':'*'
}

sysSetting={
      'getGroupMap':'net groupmap list',
      'idmapUidRange':"testparm -sv 2> /dev/null | grep 'idmap uid' | awk '{split($4,range,\"-\");print range[1],range[2]}'",
      'idmapGidRange':"testparm -sv 2> /dev/null | grep 'idmap gid' | awk '{split($4,range,\"-\");print range[1],range[2]}'",
      'service':{'default':'service','debian':'invoke-rc.d','redhat':'service','suse':'service','mandriva':'service'},
      'docs':{'default':'file:///usr/share/doc/sadms-%s/%s',
            'redhat':'file:///usr/share/doc/sadms-%s/%s',
            'debian':'file:///usr/share/doc/sadms/%s',
            'suse':'file:///usr/share/doc/packages/sadms/%s',
            'mandriva':'file:///usr/share/doc/sadms-%s/%s'},
      'browser':{'default':'/usr/bin/firefox',
            'redhat':'/usr/bin/firefox',
            'debian':'/usr/bin/firefox',
            'suse':'/usr/bin/firefox',
            'mandriva':'/usr/bin/mozilla-firefox'},
      'pidof':{'default':'/sbin/pidof %PROCESS%',
            'redhat':'/sbin/pidof %PROCESS%',
            'debian':'/bin/pidof %PROCESS%',
            'suse':'/sbin/pidof %PROCESS%',
            'mandriva':'/sbin/pidof %PROCESS%'},

      'getUsers':"getent passwd | cut -f 1 -d ':' | grep -v '^$' | sort",
      'getGroups':"getent group | cut -f 1 -d ':' | grep -v '^$' | sort",
      'getNetwork':"ip addr show dev eth0 | grep inet | grep -v inet6 | awk '{print $2}'",
      'getDnsDomain':'dnsdomainname',
      'getHost':"hostname | cut -f 1 -d '.'",
      'getPartitions':"cat /etc/fstab | cut -f 1 -d ' ' | grep -v 'none' | grep -v '^$' | sort",
      'getPamServices':"ls /etc/pam.d | grep -v '~'",
      'getKdcUsingDns':"host -t srv _kerberos._tcp.%DNSDOMAIN% | tail -n 1 | grep -v 'not found' | grep -v ';;' | awk '{print $NF}' | sed 's/\..*$//g'",
      'domainStatus':'sh -c \'[ -e /var/lib/sadms/domain ] && cat /var/lib/sadms/domain\'',
      'pamStatus':'sh -c \'[ -e /var/lib/sadms/pam ] && cat /var/lib/sadms/pam\'',
      'getVersion':"cat version | head -n 1",
      'getDistribution':'sh -c \'if [ -f /etc/debian_version ]; then echo "debian"; else if [ -f /etc/SuSE-release ]; then echo "suse"; else if [ -e /etc/mandrake-release -o -e /etc/mandriva-release ]; then echo "mandriva"; else if [ -e /etc/redhat-release ]; then echo "redhat"; else echo "default"; fi; fi; fi; fi\'',
      'getNmb':'sh -c \'if [ -f /etc/init.d/nmb ]; then echo "nmb"; fi\'',
}

serviceSetting={
      'winbindd':{'default':'winbind',
            'redhat':'winbind',
            'debian':'winbind',
            'suse':'winbind',
            'mandriva':'winbind'},
      'smbd':{'default':'smb',
            'redhat':'smb',
            'debian':'smbd',
            'suse':'smb',
            'mandriva':'smb'},
      'nmbd':{'default':'smb',
            'redhat':'smb',
            'debian':'nmbd',
            'suse':'nmb',
            'mandriva':'smb'},
}

#######################################################################
#     Localize
#######################################################################

def getlangs():
      langs = []
      lc, encoding = locale.getdefaultlocale()
      if (lc):
            langs = [lc]
      language = os.environ.get('LANGUAGE', None)
      if (language):
            langs += language.split(":")
      langs += ["en_US"]
      return langs

localepath = os.path.realpath(os.path.dirname(sys.argv[0]))
langs = getlangs()
for module in (gettext, gtk.glade):
      module.bindtextdomain(APP_NAME, localepath)
      module.textdomain(APP_NAME)

translator = gettext.translation(APP_NAME, localepath, languages=langs, fallback = True)
#print langs
#print localepath
#print translator.info()
_ = translator.gettext

#######################################################################
#     StatusBar
#######################################################################

class StatusBar:

      NONE=0
      OK=1
      ERROR=2
      WAIT=3

      pixbufs=[]

      def __init__(self,statusBar,image):
            self.statusBar=statusBar
            self.contextId=self.statusBar.get_context_id('sadms')
            self.statusBar.push(self.contextId,'SADMS')
            self.image=image
            if StatusBar.pixbufs==[]:
                  StatusBar.pixbufs=self.setupImages()

      def setupImages(self):
            imageFile=['grey.png','green.png','red.png','wait.png']
            pixbufs=[]
            for i in range(len(imageFile)):
                        pixbufs.append(gtk.gdk.pixbuf_new_from_file('pixmaps/'+imageFile[i]))
            return pixbufs

      def put(self,message):
            self.statusBar.pop(self.contextId)
            self.statusBar.push(self.contextId,message)
            return

      def run(self,message):
            self.put(message)
            self.putImage(StatusBar.WAIT)
            return

      def success(self):
            self.putImage(StatusBar.OK)
            return

      def fail(self):
            self.putImage(StatusBar.ERROR)
            return

      def putImage(self,i):
            self.image.set_from_pixbuf(StatusBar.pixbufs[i])
            return
      
#######################################################################
#     Console
#######################################################################

class Console:
      
      pixbufs=[]

      def __init__(self,textview,progressBar):
            self.textbuffer=gtk.TextBuffer(None)
            self.stdoutTag=self.textbuffer.create_tag('n',foreground='black')
            self.stderrTag=self.textbuffer.create_tag('e',foreground='red')
            self.stderrTag=self.textbuffer.create_tag('f',foreground='#50506F')
            self.failTag=self.textbuffer.create_tag('F',foreground='white',background='red',scale=1.0,weight=pango.WEIGHT_BOLD)
            self.successTag=self.textbuffer.create_tag('s',foreground='white',background='#008000',scale=1.0,weight=pango.WEIGHT_BOLD)
            self.textview=textview
            self.textview.set_property('editable',False)
            self.textview.set_wrap_mode(gtk.WRAP_NONE)
            self.textview.set_buffer(self.textbuffer)
            self.progressBar=progressBar
            if Console.pixbufs==[]:
                  Console.pixbufs=self.setupImages()
            self.clear()
            return

      def setupImages(self):
            imageFile=['warning.png','critical.png','red.png']
            pixbufs=[]
            for i in range(len(imageFile)):
                        pixbufs.append(gtk.gdk.pixbuf_new_from_file('pixmaps/'+imageFile[i]))
            return pixbufs

      def start(self):
            self.halt=False
            gobject.timeout_add(200,self.progress)
            return

      def progress(self):
            if self.halt:
                  self.progressBar.set_fraction(1.0)
            else:
                  self.progressBar.pulse()
            return not self.halt

      def terminate(self):
            self.halt=True
            return

      def sinkWrite(self,data):
            self.put(data,'n')
            return

      def sinkWriteErr(self,data):
            self.put(data,'e')
            return

      def sinkFail(self,context,stopped,exitstatus):
            if stopped:
                  self.put('[STOP]\n','F')
                  self.put('%s was interrupted\n' % (context.label),'f')
            else: 
                  self.put('[ERROR]\n','F')
                  self.put('returned error code %s\n' % (exitstatus),'f')
                  self.put('command line was <%s>\n' % (context.label),'f')
            return

      def sinkSuccess(self,message):
            self.put('[OK]\n','s')
            return

      def sinkClear(self):
            self.clear()
            return

      def clear(self):
            self.textbuffer.delete(self.textbuffer.get_start_iter(),self.textbuffer.get_end_iter())
            self.textbuffer.insert(self.textbuffer.get_end_iter(),'\n')
            self.endmark=self.textbuffer.create_mark('end',self.textbuffer.get_start_iter(),left_gravity=False)
            self.errendmark=self.textbuffer.create_mark('errend',self.textbuffer.get_end_iter(),left_gravity=False)
            return

      def put(self,text,tagname):
            # output
            try:
                  if tagname in ['e','f','F']:
                        if not re.match('^\s*$',text):
                              if tagname=='e':
                                    pixbufIndex=0
                              else:
                                    pixbufIndex=1
                              self.textbuffer.insert_pixbuf(self.textbuffer.get_iter_at_mark(self.errendmark),Console.pixbufs[pixbufIndex])
                        self.textbuffer.insert_with_tags_by_name(self.textbuffer.get_iter_at_mark(self.errendmark),text,tagname)
                  else:
                        self.textbuffer.insert_with_tags_by_name(self.textbuffer.get_iter_at_mark(self.endmark),text,tagname)
            except:
                  pass
            # scroll
            self.textview.scroll_to_mark(self.errendmark,0,use_align=False)
            return

      def get(self):
            return self.textbuffer.get_text(self.textbuffer.get_start_iter(),self.textbuffer.get_end_iter())

#######################################################################
#     TextViewer
#######################################################################

class TextViewer:

      def __init__(self,dialog,textview):
            self.dialog=dialog
            self.textview=textview
            self.textbuffer=gtk.TextBuffer(None)
            self.endmark=self.textbuffer.create_mark('end',self.textbuffer.get_start_iter(),left_gravity=False)
            self.headerTag=self.textbuffer.create_tag('header',foreground='darkBlue')
            self.bodyTag=self.textbuffer.create_tag('body',foreground='black')
            self.textview.set_property('editable',False)
            self.textview.set_wrap_mode(gtk.WRAP_NONE)
            self.textview.set_buffer(self.textbuffer)
            return

      def set(self,text):
            self.textbuffer.delete(self.textbuffer.get_start_iter(),self.textbuffer.get_end_iter())
            lines=text.splitlines()
            for line in lines:
                  tag='body'
                  if re.match('^[^\s]',line):
                        tag='header'                  
                  i=self.textbuffer.get_end_iter()
                  self.textbuffer.insert_with_tags_by_name(i,line+'\n',tag)
            #self.textview.scroll_to_mark(self.endmark,0,use_align=False)
            return

      # wrappers 
      
      def run(self):
            return self.dialog.run()

      def hide(self):
            self.dialog.hide()
            return

#######################################################################
#     PAMViewer
#######################################################################

class ListView:
      
      def __init__(self,listview):
            self.listview=listview
            return

      def setup(self,columns):      

            types=[t[1] for t in columns]

            # model
            self.model=gtk.ListStore(*types)
            self.listview.set_model(self.model)

            # columns
            for rank,datatype,header,expand,width in columns:
                  column=gtk.TreeViewColumn(header)
                  if datatype==str:
                        column.set_sort_column_id(rank)
                        column.connect('clicked',self.columnClicked,self.listview)
                        cell=gtk.CellRendererText()
                        #cell.set_property('ellipsize',pango.ELLIPSIZE_END)
                        attr='text'
                  if datatype==int:
                        column.set_sort_column_id(rank)
                        column.connect('clicked',self.columnClicked,self.listview)
                        cell=gtk.CellRendererText()
                        attr='text'
                  elif datatype==bool:
                        cell=gtk.CellRendererToggle()
                        cell.set_property('activatable',True)
                        cell.connect('toggled',self.toggle_acl_callback,(rank))
                        attr='active'
                  elif datatype==gtk.gdk.Pixbuf:
                        cell=gtk.CellRendererPixbuf()
                        attr='pixbuf'
                  else:
                        cell=gtk.CellRendererText()
                        attr='text' 
                  column.pack_start(cell,expand)
                  if width!=None:
                        column.set_min_width(width)
                  column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
                  column.set_resizable(True)
                  column.add_attribute(cell,attr,rank)
                  column.set_cell_data_func(cell,self.render)
                  self.listview.append_column(column)

            # header
            self.listview.set_headers_visible(True)
            self.listview.set_headers_clickable(False)
            
            # selection
            self.listview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
            return

      def setupImages(self,imageFile):
            pixbufs=[]
            for i in range(len(imageFile)):
                        pixbufs.append(gtk.gdk.pixbuf_new_from_file('pixmaps/'+imageFile[i]))
            return pixbufs

      # render callback
      def render(self,column,cell,model,i):
            r=model.get_path(i)
            toggle=r[0] % 2 == 0
            if toggle:
                  cell.set_property('cell-background','lightGray')
            else:
                  cell.set_property('cell-background','white')
            return

      # toggle callback
      def toggle_acl_callback(self,cell,r,(c)):
            self.model[r][c]=not self.model[r][c]
            return       
      
      # click column call back
      def columnClicked(self,c,data):     
            pass

      def clear(self):
            self.model.clear()
            return
      
      def getSelection(self):
            selection=self.listview.get_selection()
            (model,pathlist)=selection.get_selected_rows()
            return [model.get_value(model.get_iter(path),ListView.TEXT) for path in pathlist]

class PamView(ListView):

      IMAGE=0
      TYPE=1
      CONTROL=2
      PROG=3
      ARGS=4

      pixbufs=[]

      columns=(
            [IMAGE,gtk.gdk.Pixbuf,'',False,20],
            [TYPE,str,'type',True,80],
            [CONTROL,str,'control',True,90],
            [PROG,str,'prog',True,130],
            [ARGS,str,'args',True,None],
            )

      def __init__(self,listview):
            ListView.__init__(self,listview)
            self.setup(PamView.columns)
      
            # images
            if PamView.pixbufs==[]:
                  PamView.pixbufs=self.setupImages(['keyring.png','authorization.png','lock.png','terminal.png'])
            return

      def getPixbuf(self,index):
            return PamView.pixbufs[index]

      def set(self,items,index):
            type=items[0]
            control=items[1]
            prog=items[2]
            args=items[3]
            self.model.append([self.getPixbuf(index),type,control,prog,args])
            return      

class PamViewer:

      def __init__(self,authview,accountview,passwordview,sessionview,label):
            self.authview=PamView(authview)
            self.accountview=PamView(accountview)
            self.passwordview=PamView(passwordview)
            self.sessionview=PamView(sessionview)
            self.label=label
            self.type2view={'auth':self.authview,'account':self.accountview,'password':self.passwordview,'session':self.sessionview}
            self.type2index={'auth':0,'account':1,'password':2,'session':3}
            return

      def clear(self):
            for v in self.type2view.values():
                  v.clear()

      def set(self,text):
            self.clear()
            lines=text.strip('\n\r ').splitlines()
            lines=[l for l in lines if not re.match('^$',l) and not re.match('^#',l) ]
            for l in lines:
                  fields=l.split()
                  type=fields[0]
                  args=' '.join(fields[1:])
                  if type=='@include':
                        type=fields[1]
                        if not type in ['common-auth','common-account','common-password','common-session']:
                              continue;
                        type=type[7:]
                        self.type2view[type].set(['','','@include',args],self.type2index[type])
                        continue
                  # control can be [name=value name=value .. ]
                  control=fields[1]
                  q=1
                  if control.startswith('['):
                        for q in range(1,len(fields)):
                              if fields[q].endswith(']'):
                                    break
                        control=' '.join(fields[1:q+1])           
                  prog=fields[q+1].replace('/lib/security/$ISA/','')
                  args=' '.join(fields[q+2:])
                  self.type2view[type].set([type,control,prog,args],self.type2index[type])
            return

class PamViewers:

      def __init__(self,label,dialog,authview1,accountview1,passwordview1,sessionview1,label1,authview2,accountview2,passwordview2,sessionview2,label2):
            self.dialog=dialog
            self.label=label
            self.viewer1=PamViewer(authview1,accountview1,passwordview1,sessionview1,label1)
            self.viewer2=PamViewer(authview2,accountview2,passwordview2,sessionview2,label2)
            return

      def setLabels(self,label,label1,label2):
            self.label.set_text(label)
            self.viewer1.label.set_text(label1)
            self.viewer2.label.set_text(label2)
            return

      def clear(self):
            self.viewer1.clear()
            self.viewer2.clear()
            return

      # wrappers 
      
      def run(self):
            return self.dialog.run()

      def hide(self):
            self.dialog.hide()
            return

#######################################################################
#     SADMS
#######################################################################

class Sadms:
      
      pixbufs=[]
      
      ERROR=0
      OK=1
      NONE=2
      
      DNS=0
      REALM=1
      KDC=2
      DOMAIN=3
      SERVER=4
      USERS=5
      HOSTSALLOW=6
      OU=7
      WINS=8
      ADMIN=9
      ADMINPWD=10
      NDATA=11
      ALL=range(NDATA)

      def __init__(self):

            handlers={
                  'on_destroy':                 self.exit,
                  'on_exit_activate':           self.exit,

                  'on_open_activate':           self.load,
                  'on_save_activate':           self.save,
                  'on_saveAs_activate':         self.save,
                  'on_validate_activate':       self.forceValidateData,
                  'on_detect_activate':         self.detectData,

                  'on_precheck_activate':       self.preCheck,
                  'on_postcheck_activate':      self.postCheck,
                  'on_dependencies_activate':   self.dependenciesCheck,
                  'on_install_activate':        self.install,
                  'on_uninstall_activate':      self.uninstall,
                  'on_installKerberos_activate':      self.installKerberos,
                  'on_viewSettings_activate':   self.conf,

                  'on_installPam_activate':     self.installPam,
                  'on_uninstallPam_activate':   self.uninstallPam,
                  'on_viewPamSettings_activate':      self.confPam,
                  'on_viewPamServices_activate':      self.viewPam,

                  'on_diagNetwork_activate':    self.diagNetwork,
                  'on_diagDns_activate':        self.diagDns,
                  'on_diagKerberos_activate':   self.diagKerberos,
                  'on_diagDomain_activate':     self.diagDomain,
                  'on_diagDomainJoin_activate': self.diagDomainJoin,
                  'on_diagNmb_activate':        self.diagNmb,
                  'on_diagSmb_activate':        self.diagSmb,
                  'on_diagAuth_activate':       self.diagAuth,
                  'on_test_activate':           self.test,

                  'on_getUsers_activate':       self.getUsers,
                  'on_getGroups_activate':      self.getGroups,
                  'on_syncClocks_activate':     self.forceSyncClocks,
                  'on_signalDaemons_activate':  self.signalDaemons,
                  'on_startDaemons_activate':   self.startDaemons,
                  'on_stopDaemons_activate':    self.stopDaemons,
                  'on_restartDaemons_activate': self.restartDaemons,
                  'on_statusDaemons_activate':  self.statusDaemons,
                  'on_purge_activate':          self.purge,

                  'on_users_activate':          self.users,
                  'on_shares_activate':         self.shares,      
                  'on_acls_activate':           self.acls,
                  'on_globals_activate':        self.globs,

                  'on_clearOutput_activate':    self.forceClearOutput,
                  'on_saveOutput_activate':     self.saveOutput,
                  'on_monospace_activate':      self.monospace,

                  'on_remote_activate':         self.setRemote,
                  'on_remote_clone_activate':   self.remoteCloneSadms,
                  'on_remote_preinstall_activate':self.remotePreinstallSadms,
                  'on_runRemotely_activate':    self.remoteSadms,

                  'on_version_activate':        self.version,
                  'on_about_activate':          self.about,
                  'on_help_activate':           self.help,
                  'on_docs_activate':           self.docs,
                  #---
                  'on_refreshStatus_clicked':   self.forceRefreshStatus,
                  'on_toggleWinbind_clicked':   self.toggleWinbind,
                  'on_toggleSmb_clicked':       self.toggleSmb,
                  'on_toggleNmb_clicked':       self.toggleNmb,
                  'on_open_clicked':            self.load,
                  'on_saveas_clicked':          self.save,
                  'on_validate_clicked':        self.forceValidateData,
                  'on_detect_clicked':          self.detectData,
                  'on_install_clicked':         self.toggleInstall,
                  'on_installPam_clicked':      self.toggleInstallPam,
                  'on_remote_clicked':          self.setRemote,
                  'on_stop_clicked':            self.stop,
                  'on_help_clicked':            self.help,
            }

            # runner
            self.runner=runner.GtkRunner(host='localhost',user='root',wdir='/opt/sadms')

            self.widgets=gtk.glade.XML('sadms.glade')
            self.widgets.signal_autoconnect(handlers)

            # widgets
            self.window=self['sadms']
            self.aboutDialog=self['aboutDialog']
            self.authDialog=self['authDialog']
            self.connectDialog=self['connectDialog']
            self.remoteDialog=self['remoteDialog']
            self.helpDialog=self['helpDialog']
            
            self.notebook=self['sadmsNotebook']
            self.dataTable=self['dataPage']
            self.domainImage=self['domainImage']
            self.pamImage=self['pamImage']
            self.installButton=self['installButton']
            self.installPamButton=self['installPamButton']
            self.winbindImage=self['winbindImage']
            self.smbImage=self['smbImage']
            self.nmbImage=self['nmbImage']
            self.winbindToggle=self['toggleWinbindButton']
            self.smbToggle=self['toggleSmbButton']
            self.nmbToggle=self['toggleNmbButton']
            self.remoteStatusImage=self['remoteStatusImage']
            self.remoteLabel=self['remoteLabel']
            self.progressBar=self['progressBar']
            self.noSharesMenuitem=self['noSharesMenuitem']
            self.withPamWinbindMenuitem=self['withPamWinbindMenuitem']
            self.withPamMountMenuitem=self['withPamMountMenuitem']
            self.withPamMkhomedirMenuitem=self['withPamMkhomedirMenuitem']
            self.isVerbose=self['verboseMenuitem']
            self.helpView=TextViewer(self.helpDialog,self['helpView'])
            self.pamViewers=PamViewers(self['pamTargetLabel'],self['pamConfDialog'],self['pamAuthView'],self['pamAccountView'],self['pamPasswordView'],self['pamSessionView'],self['pamConfLabel'],self['pam2AuthView'],self['pam2AccountView'],self['pam2PasswordView'],self['pam2SessionView'],self['pamConf2Label'])
            
            # widget wrappers
            self.output=Console(self['console'],self.progressBar)
            self.status=StatusBar(self['statusBar'],self['statusImage'])
            
            # data widgets
            self.realmEntry=self['realmEntry']
            self.dnsEntry=self['dnsEntry']
            self.kdcEntry=self['kdcEntry']
            self.domainEntry=self['domainEntry']
            self.serverEntry=self['serverEntry']
            self.hostOuEntry=self['hostOuEntry']
            self.administratorEntry=self['administratorEntry']
            self.administratorPasswordEntry=self['administratorPasswordEntry']
            self.usersEntry=self['usersEntry']
            self.hostsAllowEntry=self['hostsAllowEntry']
            self.winsServerEntry=self['winsServerEntry']

            # load settings
            settingsFile='./settings.sadms'
            if sys.argv[1:]!=[]:
                  settingsFile=sys.argv[1]
            self.doLoad(settingsFile);
            
            # images
            if Sadms.pixbufs==[]:
                  Sadms.pixbufs=self.setupImages()
            
            self.setupValidateImages()

            # daemons and status
            self.refreshInstallStatus()
            self.refreshDaemons()
            gobject.timeout_add(10000,self.refreshTimerHandler)
            
            self.tabHome()
            return

      # widget access

      def __getitem__(self, key):
            return self.widgets.get_widget(key)

      # exit

      def exit(self,*options):
            self.stop()
            if __name__=="__main__":
                  gtk.main_quit()
            else:
                  self.window.destroy()   
            return

      # image
      
      def setupImages(self):
            imageFile=['red.png','green.png','grey.png']
            pixbufs=[]
            for i in range(len(imageFile)):
                        pixbufs.append(gtk.gdk.pixbuf_new_from_file('pixmaps/'+imageFile[i]))
            return pixbufs

      def setupValidateImages(self):
            self.dataImage=[]
            for i in range(0,Sadms.NDATA):
                  self.dataImage.append(gtk.Image())
                  self.dataImage[i].show()
                  self.dataImage[i].set_from_pixbuf(Sadms.pixbufs[Sadms.NONE])
                  self.dataTable.attach(self.dataImage[i],2,3,i,i+1,0,0,0)
            return

      def resetValidateImages(self):
            for r in range(0,Sadms.NDATA):
                  self.putValidateImage(r,Sadms.NONE)

      def putValidateImage(self,r,v):
            self.dataImage[r].set_from_pixbuf(Sadms.pixbufs[v])
            return

      # tabs
      
      def tabHome(self):
            self.notebook.set_current_page(0)
            return

      def tabData(self):
            self.notebook.set_current_page(1)
            return

      def tabOutput(self):
            self.notebook.set_current_page(2)
            return

      def tabRemote(self):
            self.notebook.set_current_page(3)
            return

      #######################################################################
      #     DATA MANAGEMENT
      #######################################################################

      def forceValidateData(self,*options):
            return self.validateData(Sadms.ALL)

      def validateData(self,checks):
            self.tabData();
            self.status.put(_('validating ...'))
            errors=self.checkData(checks)
            if errors==0:
                  self.status.put(_('ok'))
                  self.status.success()
            else:
                  self.status.put(_('errors'))
                  self.status.fail()
            return errors==0

      def checkData(self,checks):
            self.tabData();
            self.resetValidateImages()

            errors=0

            # dns
            if Sadms.DNS in checks:
                  value=self.dnsEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.DNS,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.DNS,Sadms.ERROR)
                        errors=errors+1
            # realm
            if Sadms.REALM in checks:
                  value=self.realmEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.REALM,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.REALM,Sadms.ERROR)
                        errors=errors+1

            # kdc
            if Sadms.KDC in checks:
                  value=self.kdcEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.KDC,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.KDC,Sadms.ERROR)
                        errors=errors+1

            # domain
            if Sadms.DOMAIN in checks:
                  value=self.domainEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.DOMAIN,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.DOMAIN,Sadms.ERROR)
                        errors=errors+1
            
            # server
            if Sadms.SERVER in checks:
                  value=self.serverEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.SERVER,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.SERVER,Sadms.ERROR)
                        errors=errors+1

            # users
            if Sadms.USERS in checks:
                  value=self.usersEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.USERS,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.USERS,Sadms.ERROR)
                        errors=errors+1

            # hosts allow
            if Sadms.HOSTSALLOW in checks:
                  value=self.hostsAllowEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.HOSTSALLOW,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.HOSTSALLOW,Sadms.ERROR)
                        errors=errors+1

            # host ou
            if Sadms.OU in checks:
                  value=self.hostOuEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.OU,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.OU,Sadms.ERROR)
                        #errors=errors+1
            
            # wins
            if Sadms.WINS in checks:
                  value=self.winsServerEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.WINS,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.WINS,Sadms.ERROR)
                        #errors=errors+1

            # admin
            if Sadms.ADMIN in checks:
                  value=self.administratorEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.ADMIN,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.ADMIN,Sadms.ERROR)
                        errors=errors+1
            
            # admin password
            if Sadms.ADMINPWD in checks:
                  value=self.administratorPasswordEntry.get_text()
                  if value!='':
                        self.putValidateImage(Sadms.ADMINPWD,Sadms.OK)
                  else:
                        self.putValidateImage(Sadms.ADMINPWD,Sadms.ERROR)
                        errors=errors+1
            return errors

      def detectData(self,*options):
            self.tabData();
            self.clearData()
            self.resetValidateImages()

            loc=string.split(locale.getdefaultlocale()[0],'_')[1]

            # clear
            setting['dns']=''
            setting['realm']=''
            setting['kdc']=''
            setting['server']=''
            setting['hostsAllow']=''
            setting['hostOu']=''
            setting['users']=''
            setting['administrator']=''

            # dns domain, realm
            status,output=self.runToString(sysSetting['getDnsDomain'])
            if status:
                  setting['dns']=output
                  setting['realm']=setting['dns'].upper()

            # kdc 
            cl=sysSetting['getKdcUsingDns']
            cl=cl.replace('%DNSDOMAIN%',setting['dns'])
            status,output=self.runToString(cl)
            if status and output!='':
                  setting['kdc']=output
            
            # server
            status,output=self.runToString(sysSetting['getHost'])
            if status:
                  setting['server']=output
            
            # host allow
            status,output=self.runToString(sysSetting['getNetwork'])
            if status and output != '':
                  setting['hostsAllow']=ipcalc.toNet(ipcalc.toBase(output),ipcalc.toMask(output))
            
            # ou
            setting['hostOu']='Computers'
            
            # user container,administrator
            setting['users']='Domain Users'
            if loc=='EN':
                  setting['administrator']='administrator'
                  setting['users']='Domain Users'
            elif loc=='FR':
                  setting['administrator']='administrateur'
                  setting['users']='Utilisa. du domaine'
                  
            # display
            self.dnsEntry.set_text(setting['dns'])
            self.realmEntry.set_text(setting['realm'])
            self.kdcEntry.set_text(setting['kdc'])
            self.serverEntry.set_text(setting['server'])
            self.hostsAllowEntry.set_text(setting['hostsAllow'])
            self.hostOuEntry.set_text(setting['hostOu'])
            self.administratorEntry.set_text(setting['administrator'])
            self.usersEntry.set_text(setting['users'])

            self.validateData([Sadms.DNS,Sadms.REALM,Sadms.KDC,Sadms.SERVER,Sadms.HOSTSALLOW,Sadms.OU,Sadms.USERS,Sadms.ADMIN,Sadms.ADMINPWD])  
            return

      #######################################################################
      #     INPUT DATA IO
      #######################################################################

      def load(self,*options):
            dialog=gtk.FileChooserDialog('Open',None,gtk.FILE_CHOOSER_ACTION_OPEN,(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
            dialog.set_default_response(gtk.RESPONSE_OK)
            dialog.set_current_folder(dialog.get_current_folder()+'/settings')
            fileFilter=gtk.FileFilter()
            fileFilter.set_name('SADMS config files')
            fileFilter.add_mime_type('application/sadms')
            fileFilter.add_pattern('*.sadms')
            dialog.add_filter(fileFilter)
            fileFilter=gtk.FileFilter()
            fileFilter.set_name('All files')
            fileFilter.add_pattern('*')
            dialog.add_filter(fileFilter)
            response = dialog.run()
            if response==gtk.RESPONSE_OK:
                  self.doLoad(dialog.get_filename())
            elif response==gtk.RESPONSE_CANCEL:
                  pass
            dialog.destroy()
            return

      def save(self,*options):
            dialog=gtk.FileChooserDialog('Save as',None,gtk.FILE_CHOOSER_ACTION_SAVE,(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
            dialog.set_default_response(gtk.RESPONSE_OK)
            dialog.set_current_folder(dialog.get_current_folder()+'/settings')
            fileFilter=gtk.FileFilter()
            fileFilter.set_name('SADMS config files')
            fileFilter.add_mime_type('application/sadms')
            fileFilter.add_pattern('*.sadms')
            dialog.add_filter(fileFilter)
            fileFilter=gtk.FileFilter()
            fileFilter.set_name('All files')
            fileFilter.add_pattern('*')
            dialog.add_filter(fileFilter)
            response = dialog.run()
            if response==gtk.RESPONSE_OK:
                  self.doSave(dialog.get_filename())
            elif response==gtk.RESPONSE_CANCEL:
                  pass
            dialog.destroy()
            return

      def loadSettings(self,settingsFile):
            try:
                  f=open(settingsFile,'r')
                  lines=f.readlines()
                  f.close()
                  for l in lines:
                        if l[0]!='#':
                              field=string.split(l[:-1],'=')
                              if len(field) > 1:
                                    setting[field[0]]=field[1]
            except IOError,exceptData:
                  self.status.put(_('io error %s') % (settingsFile))
                  self.status.fail()
                  self.putMessageWarn(_("Could not load: %s\n[%s]") % (settingsFile, exceptData))
            return
            
      def saveSettings(self,settingsFile):
            try:
                  line=['realm='+setting['realm']+'\n',\
                        'dns='+setting['dns']+'\n',\
                        'kdc='+setting['kdc']+'\n',\
                        'domain='+setting['domain']+'\n',\
                        'server='+setting['server']+'\n',\
                        'hostOu='+setting['hostOu']+'\n',\
                        'administrator='+setting['administrator']+'\n',\
                        'administratorPassword='+setting['administratorPassword']+'\n',\
                        'users='+setting['users']+'\n',\
                        'hostsAllow='+setting['hostsAllow']+'\n',\
                        'winsServer='+setting['winsServer']+'\n']
                  f=open(settingsFile,'w')
                  f.writelines(line)
                  f.close()
            except IOError,exceptData:
                  self.status.put(_('io error %s') % (settingsFile))
                  self.status.fail()
                  self.putMessageWarn(_("Could not save: %s\n[%s]") % (settingsFile, exceptData))
            return

      def clearData(self):
            self.tabData();
            self.realmEntry.set_text('')
            self.dnsEntry.set_text('')
            self.kdcEntry.set_text('')
            self.domainEntry.set_text('')
            self.serverEntry.set_text('')
            self.hostOuEntry.set_text('')
            self.administratorEntry.set_text('')
            self.administratorPasswordEntry.set_text('')
            self.usersEntry.set_text('')
            self.hostsAllowEntry.set_text('')
            self.winsServerEntry.set_text('')
            return

      def doLoad(self,settingsFile):
            self.status.put(_('loading ')+settingsFile)
            self.loadSettings(settingsFile)
            self.clearData()
            self.realmEntry.set_text(setting['realm'])
            self.dnsEntry.set_text(setting['dns'])
            self.kdcEntry.set_text(setting['kdc'])
            self.domainEntry.set_text(setting['domain'])
            self.serverEntry.set_text(setting['server'])
            self.hostOuEntry.set_text(setting['hostOu'])
            self.administratorEntry.set_text(setting['administrator'])
            self.administratorPasswordEntry.set_text(setting['administratorPassword'])
            self.usersEntry.set_text(setting['users'])
            self.hostsAllowEntry.set_text(setting['hostsAllow'])
            self.winsServerEntry.set_text(setting['winsServer'])
            return

      def doSave(self,settingsFile):
            if self.validateData(Sadms.ALL)!= 0:
                  self.status.put(_('did not save invalid data'))
                  return
            self.status.put(_('saving ')+settingsFile)
            setting['realm']=self.realmEntry.get_text()
            setting['dns']=self.dnsEntry.get_text()
            setting['kdc']=self.kdcEntry.get_text()
            setting['domain']=self.domainEntry.get_text()
            setting['server']=self.serverEntry.get_text()
            setting['hostOu']=self.hostOuEntry.get_text()
            setting['administrator']=self.administratorEntry.get_text()
            #setting['administratorPassword']=self.administratorPasswordEntry.get_text()
            setting['users']=self.usersEntry.get_text()
            setting['hostsAllow']=self.hostsAllowEntry.get_text()
            setting['winsServer']=self.winsServerEntry.get_text()
            self.saveSettings(settingsFile)
            return

      #######################################################################
      #     DIAGNOSTICS
      #######################################################################

      def diagNetwork(self,*options):
            if not self.validateData([Sadms.DNS,Sadms.DOMAIN,Sadms.KDC,Sadms.SERVER,Sadms.HOSTSALLOW]):
                  return
            value1="'"+self.dnsEntry.get_text()+"'"
            value2="'"+self.domainEntry.get_text()+"'"
            value3="'"+self.kdcEntry.get_text()+"'"
            value4="'"+self.serverEntry.get_text()+"'"
            value5="'"+self.hostsAllowEntry.get_text()+"'"
            value6="'"+self.winsServerEntry.get_text()+"'"
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_test-network.sh '+valueVerbose+' '+value1+' '+value2+' '+value3+' '+value4+' '+value5+' '+value6
            self.status.put(_("network test"))
            self.run(cl)
            return

      def diagDns(self,*options):
            if not self.validateData([Sadms.DNS,Sadms.KDC]):
                  return
            value1="'"+self.dnsEntry.get_text()+"'"
            value2="'"+self.kdcEntry.get_text()+"'"
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_test-dns.sh '+valueVerbose+' '+value1+' '+value2
            self.status.put(_("dns test"))
            self.run(cl)
            return

      def diagKerberos(self,*options):
            if not self.validateData([Sadms.DNS,Sadms.REALM,Sadms.KDC,Sadms.ADMIN,Sadms.ADMINPWD]):
                  return
            value1="'"+self.realmEntry.get_text()+"'"
            value2="'"+self.dnsEntry.get_text()+"'"
            value3="'"+self.kdcEntry.get_text()+"'"
            value4="'"+self.administratorEntry.get_text()+"'"
            value5="'"+self.administratorPasswordEntry.get_text()+"'"
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_test-kerberos.sh '+valueVerbose+' '+value1+' '+value2+' '+value3+' '+value4+' '+value5
            self.status.put(_("kerberos test"))
            self.run(cl)
            return

      def diagDomain(self,*options):
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_test-domain.sh '+valueVerbose
            self.status.put(_("domain test"))
            self.run(cl)
            return

      def diagDomainJoin(self,*options):
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_test-domainjoin.sh '+valueVerbose
            self.status.put(_("domain join test"))
            self.run(cl)
            return

      def diagNmb(self,*options):
            if not self.validateData([Sadms.DNS,Sadms.DOMAIN,Sadms.KDC,Sadms.SERVER,Sadms.HOSTSALLOW]):
                  return
            value1="'"+self.dnsEntry.get_text()+"'"
            value2="'"+self.domainEntry.get_text()+"'"
            value3="'"+self.kdcEntry.get_text()+"'"
            value4="'"+self.serverEntry.get_text()+"'"
            value5="'"+self.hostsAllowEntry.get_text()+"'"
            value6="'"+self.winsServerEntry.get_text()+"'"
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_test-nmb.sh '+valueVerbose+' '+value1+' '+value2+' '+value3+' '+value4+' '+value5+' '+value6
            self.status.put(_("nmb test"))
            self.run(cl)
            return

      def diagSmb(self,*options):
            if not self.validateData([Sadms.DOMAIN]):
                  return
            self['connectDialogServerEntry'].set_text(self.serverEntry.get_text())
            self['connectDialogShareEntry'].set_text('data')
            self['connectDialogInfoLabel'].set_text('')
            response=self.connectDialog.run()
            self.connectDialog.hide()
            if response!=gtk.RESPONSE_OK:
                  return
            server=self['connectDialogServerEntry'].get_text()
            share=self['connectDialogShareEntry'].get_text()
            response=self.authDialog.run()
            self.authDialog.hide()
            if response!=gtk.RESPONSE_OK:
                  return
            user=self['authDialogUserEntry'].get_text()
            password=self['authDialogPasswordEntry'].get_text()
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            value1="'"+server+"'"
            value2="'"+share+"'"
            value3="'"+self.domainEntry.get_text()+"'"
            value4="'"+user+"'"
            value5="'"+password+"'"
            cl='./_test-smb.sh '+valueVerbose+' '+value1+' '+value2+' '+value3+' '+value4+' '+value5
            self.status.put(_("smb test"))
            self.run(cl)
            return

      def diagAuth(self,*options):
            if not self.validateData([Sadms.REALM,Sadms.REALM]):
                  return
            response=self.authDialog.run()
            self.authDialog.hide()
            if response==gtk.RESPONSE_OK:
                  user=self['authDialogUserEntry'].get_text()
                  password=self['authDialogPasswordEntry'].get_text()
                  value1="'"+user+"'"
                  value2="'"+password+"'"
                  value3="'"+self.domainEntry.get_text()+"'"
                  value4="'"+self.realmEntry.get_text()+"'"
                  if self.isVerbose.get_active():
                        valueVerbose='-v'
                  else:
                        valueVerbose=''
                  cl='./_test-auth.sh '+valueVerbose+' '+value1+' '+value2+' '+value3+' '+value4
                  self.status.put(_("authentication test"))
                  self.run(cl)
            return

      #######################################################################
      #     UTILS
      #######################################################################

      def preCheck(self,*options):
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            self.run("./_precheck.sh "+valueVerbose)
            return

      def postCheck(self,*options):
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            value1="'"+self.realmEntry.get_text()+"'"
            self.run("./_postcheck.sh "+valueVerbose+" "+value1)
            return
      
      def dependenciesCheck(self,*options):
            self.run("./sadms-deps.py")
            return
      
      def forceSyncClocks(self,*options):
            return self.syncClocks()

      def syncClocks(self):
            value1=self.kdcEntry.get_text()
            if value1=="":
                  self.status.put(_("invalid time server"))
                  return
            value1="'"+value1+"'"
            command='./_sync-clocks.sh '+value1
            self.status.put(_("synchronizing clocks ..."))
            self.run(command)
            self.status.put(_("synchronizing clocks done"))
            return

      def purge(self,*options):
            response=self.putMessageQuestion(_('Purging will result in samba data (notably id map) being lost\nDo you want to continue ?'))
            if response==gtk.RESPONSE_OK:
                  cl='./_purge.sh'
                  self.status.put(_("purging ..."))
                  self.run(cl)
            return

      #######################################################################
      #     DAEMONS
      #######################################################################

      def signalDaemons(self,*options):
            cl='./_signal.sh'
            self.status.put(_("signaling daemons ..."))
            self.run(cl)
            return

      def startDaemons(self,*options):
            cl='./_start.sh'
            self.status.put(_("starting daemons ..."))
            self.run(cl)
            return

      def stopDaemons(self,*options):
            cl='./_stop.sh'
            self.status.put(_("stopping daemons ..."))
            self.run(cl)
            return

      def restartDaemons(self,*options):
            cl='./_restart.sh'
            self.status.put(_("restarting daemons ..."))
            self.run(cl)
            return

      def statusDaemons(self,*options):
            cl='./_status.sh'
            self.status.put(_("status daemons ..."))
            self.run(cl)
            return

      def forceRefreshStatus(self,*options):
            self.refreshInstallStatus()
            self.refreshDaemons()
            return

      def refreshTimerHandler(self):
            self.refreshInstallStatus()
            self.refreshDaemons()
            return True

      def refreshDaemons(self):
            textStart=_("_Start")
            textStop=_("_Stop")

            # winbind
            status=self.getDaemonStatus('winbindd')
            statusImage=gtk.STOCK_NO
            text=textStart
            if status==True:
                  statusImage=gtk.STOCK_YES
                  text=textStop
            elif status==False:
                  statusImage=gtk.STOCK_NO
                  text=textStart
            self.winbindImage.set_from_stock(statusImage,gtk.ICON_SIZE_BUTTON)
            self.winbindToggle.set_label(text)

            # smb
            status=self.getDaemonStatus('smbd')
            statusImage=gtk.STOCK_NO
            text=textStart
            if status==True:
                  statusImage=gtk.STOCK_YES
                  text=textStop
            elif status==False:
                  statusImage=gtk.STOCK_NO
                  text=textStart
            self.smbImage.set_from_stock(statusImage,gtk.ICON_SIZE_BUTTON)
            self.smbToggle.set_label(text)

            # nmb
            status=self.getDaemonStatus('nmbd')
            statusImage=gtk.STOCK_NO
            text=textStart
            if status==True:
                  statusImage=gtk.STOCK_YES
                  text=textStop
            elif status==False:
                  statusImage=gtk.STOCK_NO
                  text=textStart
            self.nmbImage.set_from_stock(statusImage,gtk.ICON_SIZE_BUTTON)
            self.nmbToggle.set_label(text)
            return True

      def toggleWinbind(self,*options):
            self.toggleDaemon('winbindd')
            return

      def toggleSmb(self,*options):
            self.toggleDaemon('smbd')
            return

      def toggleNmb(self,*options):
            self.toggleDaemon('nmbd')
            return

      def toggleDaemon(self,daemon):
            distribution=self.getDistribution()
            status=self.getDaemonStatus(daemon)
            if status:
                  command='stop'
            else:
                  command='start'
            daemon2=serviceSetting[daemon][distribution]
            if daemon=='nmbd':
                  nmb=self.getNmb()
                  if nmb!=None and nmb!='':
                        daemon2=nmb
            cl='%s %s %s' % (sysSetting['service'][distribution],daemon2,command)
            self.runToString(cl)
            self.refreshDaemons()
            return

      #######################################################################
      #     INSTALL
      #######################################################################

      def toggleInstall(self,*options):
            if self.installButton.get_label()==_('Install'):
                  self.install()
            else:
                  self.uninstall()        

      def toggleInstallPam(self,*options):
            if self.installPamButton.get_label()==_('Install PAM'):
                  self.installPam()
            else:
                  self.uninstallPam()           

      def refreshInstallStatus(self):
            # domain
            cl=sysSetting['domainStatus']
            status,output=self.runToString(cl)
            statusImage=gtk.STOCK_CLOSE
            buttonLabel=_('Install')
            if status:
                  output=output.strip()
                  if output=='1':
                        statusImage=gtk.STOCK_YES
                        buttonLabel=_('Uninstall')
                  elif output=='0':
                        statusImage=gtk.STOCK_NO
                        buttonLabel=_('Install')
            self.domainImage.set_from_stock(statusImage,gtk.ICON_SIZE_BUTTON)
            self.installButton.set_label(buttonLabel)

            # pam
            cl=sysSetting['pamStatus']
            status,output=self.runToString(cl)
            statusImage=gtk.STOCK_CLOSE
            buttonLabel=_('Install PAM')
            if status:
                  output=output.strip()
                  if output=='1':
                        statusImage=gtk.STOCK_YES
                        buttonLabel=_('Uninstall PAM')
                  elif output=='0':
                        statusImage=gtk.STOCK_NO
                        buttonLabel=_('Install PAM')
            self.pamImage.set_from_stock(statusImage,gtk.ICON_SIZE_BUTTON)
            self.installPamButton.set_label(buttonLabel)
            return

      #######################################################################
      #     INSTALL DOMAIN
      #######################################################################

      def install(self,*options):
            if not self.validateData(Sadms.ALL):
                  self.status.put(_("invalid data"))
                  return
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            value1="'"+self.realmEntry.get_text()+"'"
            value2="'"+self.dnsEntry.get_text()+"'"
            value3="'"+self.kdcEntry.get_text()+"'"
            value4="'"+self.domainEntry.get_text()+"'"
            value5="'"+self.serverEntry.get_text()+"'"
            value6="'"+self.hostOuEntry.get_text()+"'"
            value7="'"+self.administratorEntry.get_text()+"'"
            value8="'"+self.administratorPasswordEntry.get_text()+"'"
            value9="'"+self.usersEntry.get_text()+"'"
            value10="'"+self.hostsAllowEntry.get_text()+"'"
            value11="'"+self.winsServerEntry.get_text()+"'"
            noSharesSwitch=''
            if self.noSharesMenuitem.get_active():
                  noSharesSwitch='-noshares'          
            cl='./_install.sh '+valueVerbose+' '+noSharesSwitch+' '+value1+' '+value2+' '+value3+' '+value4+' '+value5+' '+value6+' '+value7+' '+value8+' '+value9+' '+value10+' '+value11
            self.status.put(_("installing ..."))
            context=runner.Context()
            context.startTab=self.tabHome
            context.endTab=self.tabHome
            context.atExit=[self.refreshInstallStatus,self.refreshDaemons]
            self.run(cl,context)
            return

      def uninstall(self,*options):
            if not self.validateData([Sadms.ADMIN,Sadms.ADMINPWD]):
                  self.status.put(_("invalid data"))
                  return
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            value1="'"+self.administratorEntry.get_text()+"'"
            value2="'"+self.administratorPasswordEntry.get_text()+"'"
            cl='./_uninstall.sh '+valueVerbose+' '+value1+' '+value2
            self.status.put(_("uninstall"))
            context=runner.Context()
            context.startTab=self.tabHome
            context.endTab=self.tabHome
            context.atExit=[self.refreshInstallStatus,self.refreshDaemons]
            self.run(cl,context)
            return

      def installKerberos(self,*options):
            if not self.validateData([Sadms.DNS,Sadms.REALM,Sadms.KDC,Sadms.ADMIN,Sadms.ADMINPWD]):
                  self.status.put(_("invalid data"))  
                  return
            value1="'"+self.realmEntry.get_text()+"'"
            value2="'"+self.dnsEntry.get_text()+"'"
            value3="'"+self.kdcEntry.get_text()+"'"
            cl='./_install-kerberos.sh '+value1+' '+value2+' '+value3
            self.status.put(_("installing ..."))
            context=runner.Context()
            context.startTab=self.tabHome
            context.endTab=self.tabHome
            self.run(cl,context)
            return

      def conf(self,*options):
            self.run("./_cat-conf.sh")
            return

      #######################################################################
      #     PAM
      #######################################################################

      def installPam(self,*options):
            switchTest=''
            switchWinbind=''
            if self.withPamWinbindMenuitem.get_active():
                  switchWinbind='-w'
            switchMkhomedir=''
            if self.withPamMkhomedirMenuitem.get_active():
                  switchMkhomedir='-h'
            switchMount=''
            value1="''"
            value2="''"
            value3="'"+setting['cifsmountpoint']+"'"
            value4="'"+setting['domain']+"'"
            value5="'"+setting['cifsuser']+"'"
            if self.withPamMountMenuitem.get_active():
                  switchMount='-m'
                  self['connectDialogServerEntry'].set_text(setting['cifsserver'])
                  self['connectDialogShareEntry'].set_text(setting['cifsshare'].replace('%(USER)','*'))
                  self['connectDialogInfoLabel'].set_text('(use * as macro for logged in user)')
                  response=self.connectDialog.run()
                  self.connectDialog.hide()
                  if response!=gtk.RESPONSE_OK:
                        return
                  server=self['connectDialogServerEntry'].get_text()
                  share=self['connectDialogShareEntry'].get_text()
                  if server=='' or share=='':
                        return
                  share=share.replace('*','%(USER)')
                  value1="'"+server+"'"
                  value2="'"+share+"'"
                  value4="'"+self.domainEntry.get_text()+"'"
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_install-pam.sh '+valueVerbose+' '+switchTest+' '+switchWinbind+' '+switchMkhomedir+' '+switchMount+' '+value1+' '+value2+' '+value3+' '+value4+' '+value5
            self.status.put(_("installing PAM ..."))
            context=runner.Context()
            context.startTab=self.tabHome
            context.endTab=self.tabHome
            context.atExit=[self.refreshInstallStatus,self.refreshDaemons]
            if switchTest!='':
                  context.atExit.append(self.pamExit)
            self.run(cl,context)
            return

      def uninstallPam(self,*options):
            switchTest=''
            switchWinbind=''
            if self.withPamWinbindMenuitem.get_active():
                  switchWinbind='-w'
            switchMkhomedir=''
            if self.withPamMkhomedirMenuitem.get_active():
                  switchMkhomedir='-h'
            switchMount=''
            if self.withPamMountMenuitem.get_active():
                  switchMount='-m'
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            value1="'"+setting['cifsmountpoint']+"'"
            cl='./_uninstall-pam.sh '+valueVerbose+' '+switchTest+' '+switchWinbind+' '+switchMkhomedir+' '+switchMount+' '+value1
            self.status.put(_("uninstalling PAM ..."))
            context=runner.Context()
            context.startTab=self.tabHome
            context.endTab=self.tabHome
            context.atExit=[self.refreshInstallStatus,self.refreshDaemons]
            if switchTest!='':
                  context.atExit.append(self.pamExit)
            self.run(cl,context)
            return

      def pamExit(self):
            self.pamViewers.clear()
            self.pamViewers.setLabels('<common system services>','New','Current')   
            cl='./_cat-pammodulesconf.sh -new'
            status,output=self.runToString(cl)
            if status:
                  self.pamViewers.viewer1.set(output)
            cl='./_cat-pammodulesconf.sh'
            status,output=self.runToString(cl)
            if status:
                  self.pamViewers.viewer2.set(output)
            self.pamViewers.run()

            self.pamViewers.clear()
            self.pamViewers.setLabels('samba','New','Current')    
            cl='./_cat-pammodulesconf.sh -new samba'
            status,output=self.runToString(cl)
            if status:
                  self.pamViewers.viewer1.set(output)
            cl='./_cat-pammodulesconf.sh samba'
            status,output=self.runToString(cl)
            if status:
                  self.pamViewers.viewer2.set(output)
            self.pamViewers.run()

            self.pamViewers.hide()
            return

      def viewPam(self,*options):
            self.pamViewers.clear()
            self.pamViewers.setLabels('<common system services> + samba','common','samba')      
            cl='./_cat-pammodulesconf.sh'
            status,output=self.runToString(cl)
            if status:
                  self.pamViewers.viewer1.set(output)
            cl='./_cat-pammodulesconf.sh samba'
            status,output=self.runToString(cl)
            if status:
                  self.pamViewers.viewer2.set(output)
            self.pamViewers.run()
            self.pamViewers.hide()
            return

      def confPam(self,*options):
            cl='./_cat-pamconf.sh'
            self.run(cl)
            return      

      #######################################################################
      #     USERS AND HOMES
      #######################################################################

      def getUsers(self,*options):
            low,high=self.getUidmapRange()
            f=setting["userFilter"]
            f=f.replace('%LOWID%',str(low))
            nf=setting["userNotFilter"]
            value1="'"+f+"'"
            value2="'"+nf+"'"
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_list-users.sh '+valueVerbose+' '+value1+' '+value2
            self.status.put(_("listing users ..."))
            self.run(cl)
            return

      def getGroups(self,*options):
            low,high=self.getGidmapRange()
            f=setting["groupFilter"]
            f=f.replace('%LOWID%',str(low))
            nf=setting["groupNotFilter"]
            value1="'"+f+"'"
            value2="'"+nf+"'"
            if self.isVerbose.get_active():
                  valueVerbose='-v'
            else:
                  valueVerbose=''
            cl='./_list-groups.sh '+valueVerbose+' '+value1+' '+value2
            self.status.put(_("listing groups ..."))
            self.run(cl)
            return

      def getGroupMap(self,*options):
            self.status.put(_("group map"))
            self.run(sysSetting['getGroupMap'])
            return

      #######################################################################
      #     OTHERS
      #######################################################################

      def remoteCloneSadms(self,*options):
            # enforce local op to avoid recursion
            savedRunner=self.runner.get()
            self.runner.setLocal()

            remoteHost,remoteDir,remoteUser=self.getRemoteData()
            if (remoteHost,remoteDir,remoteUser)!=(None,None,None):
                  status=remote.sshDo(remoteHost,remoteUser,remoteDir,'exit')
                  if not status:
                        self.putMessageWarn('SSH connection failed (host unreachable,wrong user,...)\nor required user password (set SSH key authentication)\nor key password (set SSH agent)')
                        return
                  cl="./_clone-sadms.sh '%s' '%s' '%s'" % (remoteHost,remoteUser,remoteDir)
                  self.run(cl)
            self.runner.set(*savedRunner)
            return

      def remotePreinstallSadms(self,*options):
            if not self.runner.runRemote:
                  self.putMessageWarn('Please run in remote mode')
                  self.tabRemote()
                  self.setRemote()
                  return
            self.run('cd pre; ./_preinstall.sh')
            return

      def remoteSadms(self,*options):
            remoteHost,remoteDir,remoteUser=self.getRemoteData()
            if (remoteHost,remoteDir,remoteUser)!=(None,None,None):
                  cl="./_remote-sadms.sh '%s' '%s' '%s'" % (remoteHost,remoteUser,remoteDir)
                  self.run(cl)
            return

      def test(self,*options):
            self.run('./_test.sh')

      def version(self,*options):
            self.run("./_version.sh")
            distribution=self.getDistribution()
            return

      def help(self,*options):
            f=open('./help-procedure','r')
            text0=f.read()
            f.close()
            f=open('./help-pre','r')
            text1=f.read()
            f.close()
            f=open('./help-data','r')
            text2=f.read()
            f.close()
            f=open('./help-pam','r')
            text3=f.read()
            f.close()
            self.helpView.set(text0+text1+text2+text3)
            response=self.helpDialog.run()
            self.helpDialog.hide()
            return

      def docs(self,*options):
            distribution=self.getDistribution()
            browser=sysSetting['browser'][distribution]
            urlbase=sysSetting['docs'][distribution]
            if distribution=="suse" or distribution=="debian":
                  url=urlbase % ('index.html')
            else:
                  url=urlbase % (self.getVersion(),'index.html')
            #print '%s %s' % (browser,url)
            os.spawnv(os.P_NOWAIT,browser,[browser,url])
            return

      def getVersion(self):
            cl=sysSetting['getVersion']
            status,output=self.runToString(cl)
            return output

      def about(self,*options):
            self.aboutDialog.show()
            return

      #######################################################################
      #     MODULES
      #######################################################################

      def users(self,*options):
            m=users.UserManager()
            m.runner=self.runner
            m.refresh()
            return

      def shares(self,*options):
            m=shares.SharesManager()
            m.runner=self.runner
            m.refresh() 
            return

      def acls(self,*options):
            m=acls.AclManager(self.runner)
            return

      def globs(self,*options):
            m=globs.GlobalsManager()
            m.runner=self.runner
            m.refresh()
            return

      #######################################################################
      #     HELPERS
      #######################################################################
      
      def getDistribution(self):
            cl=sysSetting['getDistribution']
            status,output=self.runToString(cl)
            if status:
                  return output.strip('\n\r ')
            return 'default'

      def getNmb(self):
            cl=sysSetting['getNmb']
            status,output=self.runToString(cl)
            if status:
                  return output.strip('\n\r ')
            return None

      def getUidmapRange(self):
            cl=sysSetting["idmapUidRange"]
            status,output=self.runToString(cl)
            if status and output!='':
                  r=output.split()
                  return r[0],r[1]
            return 500,60000

      def getGidmapRange(self):
            cl=sysSetting["idmapGidRange"]
            status,output=self.runToString(cl)
            if status and output!='':
                  r=output.split()
                  return r[0],r[1]
            return 500,60000

      def getDaemonStatus(self,daemon):
            distribution=self.getDistribution()
            cl=sysSetting['pidof'][distribution]
            cl=cl.replace('%PROCESS%',daemon)
            status,output=self.runToString(cl)
            if status:
                  return output.strip('\n\r ')!=''
            return None

      def getRemoteData(self):
            remoteHost=self.runner.remoteHost
            if remoteHost==None:
                  remoteHost='localhost'
            remoteUser=self.runner.remoteUser
            if remoteUser==None:
                  remoteUser='root'
            self['remoteDialogHostEntry'].set_text(remoteHost)
            self['remoteDialogDirEntry'].set_text('/opt/sadms')
            self['remoteDialogUserEntry'].set_text(remoteUser)
            response=self.remoteDialog.run()
            self.remoteDialog.hide()
            if response!=gtk.RESPONSE_OK:
                  return None,None,None
            remoteHost=self['remoteDialogHostEntry'].get_text()
            remoteDir=self['remoteDialogDirEntry'].get_text()
            remoteUser=self['remoteDialogUserEntry'].get_text()
            return remoteHost,remoteDir,remoteUser

      #######################################################################
      #     OUTPUT
      #######################################################################

      def forceClearOutput(self,*options):
            self.output.clear()
            return

      def saveOutput(self,*options):
            dialog=gtk.FileChooserDialog("Save as...",None,gtk.FILE_CHOOSER_ACTION_SAVE,(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN, gtk.RESPONSE_OK))
            dialog.set_default_response(gtk.RESPONSE_OK)
            fileFilter=gtk.FileFilter()
            fileFilter.set_name("SADMS log files")
            fileFilter.add_mime_type("application/log")
            fileFilter.add_pattern("*.log")
            dialog.add_filter(fileFilter)
            fileFilter=gtk.FileFilter()
            fileFilter.set_name("All files")
            fileFilter.add_pattern("*")
            dialog.add_filter(fileFilter)
            response=dialog.run()
            if response==gtk.RESPONSE_OK:
                  filename=dialog.get_filename()
                  self.doSaveOutput(filename)
            elif response==gtk.RESPONSE_CANCEL:
                  pass
            dialog.destroy()
            return

      def doSaveOutput(self,logFile):
            if logFile==None or logFile=="":
                  return
            text=self.output.get()
            try:
                  f=open(logFile,"w")
                  f.write(text)
                  f.close()
            except IOError:
                  print "Could not open ",logFile
            return
      
      def monospace(self,check,*options):
            if check.get_active():
                  self.output.stdoutTag.set_property('family','Monospace')
                  self.output.stderrTag.set_property('family','Monospace')
            else:
                  self.output.stdoutTag.set_property('family','')
                  self.output.stderrTag.set_property('family','')
            return

      # message
      
      def putMessageQuestion(self,message,**options):
            dialog=gtk.MessageDialog(None,gtk.DIALOG_MODAL,gtk.MESSAGE_QUESTION,gtk.BUTTONS_OK_CANCEL,message)
            result=dialog.run()
            dialog.destroy()
            return result
      
      def putMessageWarn(self,message,**options):
            dialog=gtk.MessageDialog(None,gtk.DIALOG_MODAL,gtk.MESSAGE_WARNING,gtk.BUTTONS_CLOSE,message)
            result=dialog.run()
            dialog.destroy()
            return result
      
      #######################################################################
      #     RUN
      #######################################################################
      
      def setRemote(self,*options):
            m=remote.RemoteManager()

            host=self.runner.remoteHost
            if host==None:
                  host='localhost'
            user=self.runner.remoteUser
            if user==None:
                  user='root'
            wdir=self.runner.remoteDir
            if wdir==None:
                  wdir='/opt/sadms'

            m.remoteCheck.set_active(self.runner.runRemote)
            m.hostEntry.set_text(host)
            m.userEntry.set_text(user)
            m.dirEntry.set_text(wdir)
            m.keyPathEntry.set_text('~/.ssh/id_dsa')
            m.refresh()
            response=m.dialog.run()
            m.dialog.hide()
            if response==gtk.RESPONSE_OK:
                  remoteFlag=m.remoteCheck.get_active()
                  host= m.hostEntry.get_text()
                  user=m.userEntry.get_text()
                  wdir=m.dirEntry.get_text()
                  if remoteFlag and m.canRun():
                        self.runner.setRemote(host,user,wdir)
                        self.remoteStatusImage.set_from_pixbuf(Sadms.pixbufs[Sadms.OK])
                  else:
                        self.runner.setLocal(host,user,wdir)
                        self.remoteStatusImage.set_from_pixbuf(Sadms.pixbufs[Sadms.ERROR])
            self.remoteLabel.set_text(self.runner.toString())
            return

      def stop(self,*options):
            pids=self.runner.kill()
            
            # status
            self.status.fail()
            self.status.put(_('killed <%s>') % (','.join([str(p) for p in pids])))
            return

      def run(self,command,context=None):

            # start tab
            if context!=None and hasattr(context,'startTab'):
                  context.startTab()
            else:
                  self.tabOutput()

            # context
            context=self.makeContext(command,context)

            # run
            self.output.clear()
            self.output.start()
            self.status.run(context.label)
            self.runner.run(command,context,self.output,self)
            return

      def runToString(self,command):
            status,output=self.runner.runToString(command)
            return status,output

      def makeContext(self,command,context):
            # reuse context if any
            if context==None:
                  context=runner.Context()

            # obfuscate password in display
            pw=self['administratorPasswordEntry'].get_text()
            if pw!="":
                  context.label=command.replace(pw,'*****')
            else:
                  context.label=command

            return context

      #callback
      def notify(self,context,result):

            # process id
            cl="<"+context.label+">"
            
            # status
            self.status.put(cl+_(" terminated with status ")+str(result))
            if result==0:
                  self.status.success()
            else:
                  self.status.fail()

            # progress
            self.output.terminate()

            # tab
            if result==0 and hasattr(context,'endTab'):
                  context.endTab()
            else:
                  self.tabOutput()
            # atexit
            if hasattr(context,'atExit'):
                  todos=context.atExit
                  for todo in todos:
                        todo()
            return

#######################################################################
#     MAIN
#######################################################################

import sys
import os

if __name__=="__main__":
      e=sys.argv[0]
      e=os.path.realpath(e)
      d=os.path.dirname(e)
      os.chdir(d)
      
      s=Sadms()

      gtk.main()

__author__='Bernard Bou <bou@ac-toulouse.fr>'

Generated by  Doxygen 1.6.0   Back to index