cluster-webmin/0040775000567100000120000000000010121450511013472 5ustar jcameronwheelcluster-webmin/lang/0040775000567100000120000000000010116530203014414 5ustar jcameronwheelcluster-webmin/lang/en0100664000567100000120000002515410116530203014745 0ustar jcameronwheelindex_title=Cluster Webmin Servers index_hosts=Managed Servers index_nohosts=No Webmin servers have been registered for management. index_add=Add server index_gadd=Add servers in group index_edit=Edit module index_tedit=Edit theme index_refresh=Refresh user, group and module lists index_modules=Modules and Themes index_users=Webmin Users and Groups index_installmsg=Select the location to install a new module or theme from .. index_local=From local file index_uploaded=From uploaded file index_ftp=From ftp or http URL index_installok=Install Now index_return=servers list index_down=Each server should re-download module index_version=Webmin $1 index_nodeps=Ignore module dependencies when installing index_grant2=Grant access only to users and groups : index_grant1=Grant access to all Webmin users index_euser=Edit user: index_cuser=Add User index_egroup=Edit group: index_cgroup=Add Group index_euseracl=Edit ACL for index_egroupacl=Edit ACL for index_inmod=in index_gacl=Global ACL index_sync=Synchronize index_upgrade=Upgrade Webmin index_updesc=Select a source for the Webmin package to use to upgrade all managed servers .. index_installon=Install on index_upgradeon=Servers to upgrade this_server=this server add_title=Add Servers add_msg=Adding $1 .. add_gmsg=Adding servers in group $1 .. add_err=Failed to add server add_gerr=Failed to add group add_echeck=Server $1 does not have the Webmin configuration module add_echeck2=Server $1 does not have the Webmin Users module add_eversion=Server $1 is not running Webmin version $2 or above. add_ok=Added $1 with $2 modules, $3 themes, $4 users and $5 groups. refresh_title=Refresh Module and User Lists refresh_header=Re-requesting module, user and group lists from all servers .. refresh_1=Refreshed $1 (added $2 , removed $3). refresh_2=Refreshed $1 (added $2). refresh_3=Refreshed $1 (removed $2). refresh_4=Refreshed $1 (no module changes). refresh_u1=Added $1 users. refresh_u2=Removed $1 users. refresh_g1=Added $1 groups. refresh_g2=Removed $1 groups. refresh_done=.. done refresh_del=Removed $1 from server list refresh_failed=Failed to refresh $1 : $2 host_title=Managed Server host_header=Managed Webmin server details host_name=Host name host_type=Server type host_delete=Remove from managed list host_installed=Installed Packages host_os=OS and version host_version=Webmin version host_count=Modules installed host_tcount=Themes installed host_header_m=Installed Webmin modules host_header_t=Installed Webmin themes host_header_u=Webmin users host_header_g=Webmin groups edit_title_mod=Edit Module edit_title_theme=Edit Theme edit_header_mod=Webmin module details from $1 edit_header_theme=Webmin theme details from $1 edit_desc=Description edit_cat=Category edit_dir=Directory edit_deps=Depends upon edit_nodeps=Nothing edit_ondeps=Depended upon by edit_uninst_mod=Uninstall module from: edit_uninst_theme=Uninstall theme from: edit_all=All servers edit_ver=Version edit_nover=None available edit_os=Supported systems edit_osall=All operating systems edit_hosts=Installed on Servers edit_codes=From test $1 edit_acl=Edit ACL for edit_uacl=User $1 on $2 edit_gacl=Group $1 on $2 install_err=Failed to install module install_title=Install Module install_elocal=No local file given install_elocal2='$1' does not exist install_eupload=Your browser does not support file uploads install_eurl=Incomprehensible URL '$1' install_ecomp=File is compressed, but the $1 command was not found on your system install_egzip=File is gzipped, but the $1 command was not found on your system install_ecmd=Not a valid module file : $1 install_einfo=Module $1 is missing a module.info file install_enone=File does not appear to contain any modules install_header=Installing $1 on all hosts .. install_header5=Installing $1 on $2 .. install_header4=Installing $1 on members of $2 .. install_header3=Installing $1 on hosts that do not have it .. do_failed=Failed to install on $1 : $2 do_success_mod=Installed module $2 on $1 do_success_theme=Installed theme $2 on $1 do_done=.. done delete_err=Failed to delete module $1 delete_epack=The module $1 does not exist delete_title=Delete Module delete_rusure_mod=Are you sure you want to delete the module $1 from all servers ? $2 kB of files will be deleted forever. delete_rusure_theme=Are you sure you want to delete the theme $1 from all servers ? $2 kB of files will be deleted forever. delete_rusure2_mod=Are you sure you want to delete the module $1 from $3 ? $2 kB of files will be deleted forever. delete_rusure2_theme=Are you sure you want to delete the theme $1 from $3 ? $2 kB of files will be deleted forever. delete_ok=Delete delete_error=Failed to delete from $1 : $2 delete_success=Deleted from $1. delete_done=.. done delete_header_mod=Deleting module $1 .. delete_header_theme=Deleting theme $1 .. delete_edepends=Module(s) $1 depend upon it. delete_egone=Module no longer exists delete_esuccess=Successfully deleted from $1 : $2 delete_acls=Remove from users and reset access control settings? user_title1=Create Webmin User user_header1=New Webmin user details user_name=Username user_group=Member of group user_nogroup=<None> user_pass=Password user_set=Set to user_unix=Unix authentication user_lock=No password accepted user_lang=Language user_theme=Personal theme user_default=Server default user_themedef=Default Webmin theme user_ips=IP access control user_allips=Allow from all addresses user_allow=Only allow from listed addresses user_deny=Deny from listed addresses user_mods=Modules user_sall=Select all user_snone=Select none user_sinvert=Invert selection user_err1=Failed to create user user_ename='$1' is not a valid username user_etaken=The username '$1' is already in use user_ecolon=Passwords cannot contain the : character user_doing=Creating user $1 on all hosts .. user_doing3=Creating user $1 on hosts that do not have it .. user_doing4=Creating user $1 on members of $2 .. user_doing5=Creating user $1 on host $2 .. user_doing2=Updating user $1 on all hosts .. user_success=Created user on $1 user_success2=Updated user on $1 user_failed=Failed to create user on $1 : $2 user_failed2=Failed to update user on $1 : $2 user_done=.. done user_egroup=Group does not exist on server user_groupmods=(In addition to modules from group) user_title2=Edit Webmin User user_header2=User details from $1 user_leave=Leave unchanged user_modsel=Only selected modules.. user_modadd=Add selected modules.. user_moddel=Remove selected modules.. user_mleave=Leave unchanged ($1 modules) user_nogroup2=No group user_allow2=Allowing user_deny2=Denying user_allowall=No access control user_hosts=User Exists on Servers user_acl=Edit ACL for user_aclh=$1 on $2 user_aclhg=Global ACL on $1 user_return=user details user_servers=Server(s) to create on user_all=<all hosts> user_donthave=<hosts that don't have it> user_ofgroup=Members of $1 udelete_title=Delete User udelete_doing=Deleting user $1 from all hosts .. udelete_success=Successfully deleted from $1 udelete_failed=Failed to delete from $1 : $2 udelete_done=.. done group_title1=Create Group group_header1=New Webmin group details group_name=Group name group_err1=Failed to create group group_ename='$1' is not a valid group name group_etaken=The group name '$1' is already in use group_doing=Creating group $1 on all hosts .. group_doing3=Creating group $1 on hosts that do not have it .. group_doing4=Creating group $1 on members of $2 .. group_doing5=Creating group $1 on host $2 .. group_doing2=Updating group $1 on all hosts .. group_success=Created group on $1 group_failed=Failed to create group on $1 : $2 group_done=.. done group_title2=Edit Group group_header2=Webmin group details from $1 group_group=Parent group group_mems=Members on server group_mods=Modules for members group_groupmods=(In addition to modules from parent group) group_hosts=Group Exists on Servers group_egroup=Parent group does not exist on server group_success2=Updated group on $1 group_failed2=Failed to update ground on $1 : $2 group_return=group details group_nomems=No members group_servers=Server(s) to create on gdelete_title=Delete Group gdelete_desc=Are you sure you want to delete the group $1 and its member users $2 from all hosts ? gdelete_ok=Delete Group gdelete_doing=Deleting group $1 from all hosts .. gdelete_success=Successfully deleted from $1 gdelete_failed=Failed to delete from $1 : $2 gdelete_done=.. done gdelete_esub=This group has subgroups $1, and so cannot be deleted. acl_title=Module Access Control acl_title2=For user $1 in $2 on $3 acl_title3=For group $1 in $2 on $3 acl_title2_ga=Global ACL for user $1 on $3 acl_title3_ga=Global ACL for group $1 on $3 acl_options=$1 access control options from $2 acl_optionsg=Global access control options from $1 acl_config=Can edit module configuration? acl_raw=Raw ACL file entries acl_efound=Failed to edit ACL : $1 does not have access to $2 on any server acl_save1=Save on all hosts acl_save2=Save only on $1 acl_err=Failed to save access control acl_doing=Setting access control for $1 on all hosts .. acl_doing2=Setting access control for $1 on $2 .. acl_success=Successfully set access control on $1 acl_failed=Failed to set access control on $1 : $2 acl_done=.. done sync_title=Synchronize Servers sync_desc=This form allows you to create Webmin users and groups on servers that do not currently have them, in order to bring accounts into sync across all servers in your cluster. sync_hosts=Servers to synchronize sync_hall=All servers sync_hsel=Selected .. sync_users=Users to create sync_uall=All missing users sync_unone=No users sync_usel=Only users sync_unot=All except users sync_groups=Groups to create sync_gall=All missing groups sync_gnone=No groups sync_gsel=Only groups sync_gnot=All except groups sync_ok=Create Users and Groups sync_on=Synchronizing $1 .. sync_insync=Users and groups are in sync. sync_ucreate=Adding Webmin user $1 .. sync_gcreate=Adding Webmin group $1 .. sync_acl=Copying ACL files for $1 .. sync_test=Only show what would be done? sync_restart=Re-starting Webmin .. upgrade_title=Upgrade Webmin upgrade_header=Upgrading Webmin on all hosts .. upgrade_header2=Upgrading Webmin on $1 .. upgrade_header3=Upgrading Webmin on hosts running a version older than $1 .. upgrade_header4=Upgrading Webmin on members of $1 .. upgrade_emode=The install type of this host ($1) differs from the type of package selected ($2) upgrade_mode_=tar.gz upgrade_mode_rpm=RPM upgrade_mode_solaris-pkg=Solaris package upgrade_mode_gentoo=Gentoo package upgrade_mode_debian=Debian package upgrade_mode_caldera=Caldera RPM upgrade_ok=Successfully upgraded Webmin $1 package on $2 upgrade_failed=Failed to install on $1 : $2 upgrade_done=.. done upgrade_efast=Only servers using fast RPC mode can be upgraded upgrade_ereconn=Failed to re-connect to Webmin after upgrade! : $1 cluster-webmin/lang/ca0100644000567100000120000002621210115717247014736 0ustar jcameronwheelindex_title=Servidors de Cluster Webmin index_hosts=Servidors gestionats index_nohosts=No s'ha registrat cap servidor Webmin per a la seva gesti. index_add=Afegeix servidor index_gadd=Afegeix servidors al grup index_edit=Edita el mdul index_tedit=Edita el tema index_refresh=Refresca l'usuari, el grup i les llistes de mduls index_modules=Mduls i Temes index_users=Usuaris i Grups Webmin index_installmsg=Selecciona la ubicaci a partir de la qual s'installar un nou mdul o tema... index_local=Des d'un fitxer local index_uploaded=Des d'un fitxer pujat index_ftp=Per FTP o URL HTTP index_installok=Installa'l ara index_return=a la llista de servidors index_down=Cada servidor ha de redescarregar el mdul index_version=Webmin $1 index_nodeps=Ignora les dependncies del mdul en installar-lo index_grant2=Concedeix accs noms als usuaris i grups: index_grant1=Concedeix accs a tots els usuaris de Webmin index_euser=Edita index_cuser=Afegeix Usuari index_egroup=Edita index_cgroup=Afegeix Grup index_euseracl=Edita index_egroupacl=Edita index_inmod=a index_gacl=ACL Global index_sync=Sincronitza index_upgrade=Actualitza Webmin index_updesc=Selecciona una font del paquet Webmin per actualitzar tots els servidors gestionats... index_installon=Installa a index_all=<tots els hosts> index_donthave=<hosts que no el tenen> index_group=Membres de $1 index_upgradeon=Servidors per actualitzar this_server=aquest servidor add_title=Addici de Servidors add_msg=Afegint $1... add_gmsg=Afegint servidors al grup $1 .. add_err=No he pogut afegir el servidor add_gerr=No he pogut afegir el grup add_echeck=El servidor $1 no t el mdul de configuraci de Webmin add_echeck2=El servidor $1 no t el mdul d'Usuaris de Webmin add_eversion=El servidor $1 no est executant Webmin versi $2. add_ok=He afegit $1 amb $2 mduls, $3 temes, $4 usuaris i $5 grups. refresh_title=Refresc de Mdul i Llistes d'Usuaris refresh_header=Tornant a demanar les llistes de mduls, usuaris i grups de tots els servidors... refresh_1=He refrescat $1 ($2 afegit(s), $3 eliminat(s)). refresh_2=He refrescat $1 ($2 afegit(s)). refresh_3=He refrescat $1 ($2 eliminat(s)). refresh_4=He refrescat $1 (sense canvis al mdul). refresh_u1=He afegit $1 usuaris. refresh_u2=He eliminat $1 usuaris. refresh_g1=He afegit $1 grups. refresh_g2=He eliminat $1 grups. refresh_done=...fet refresh_del=He eliminat $1 de la llista de servidors refresh_failed=No he pogut refrescar $1: $2 host_title=Servidor Gestionat host_header=Detalls del servidor Webmin gestionat host_name=Nom del host host_type=Tipus de servidor host_delete=Treu-lo de la llista de gesti host_installed=Paquets Installats host_os=SO i versi host_version=Versi Webmin host_count=Mduls installats host_tcount=Temes installats host_header_m=Mduls Webmin installats host_header_t=Temes Webmin installats host_header_u=Usuaris Webmin host_header_g=Grups Webmin edit_title_mod=Edici de Mdul edit_title_theme=Edici de Tema edit_header_mod=Detalls del mdul Webmin de: $1 edit_header_theme=Detalls del tema Webmin de: $1 edit_desc=Descripci edit_cat=Categoria edit_dir=Directori edit_deps=Depn de edit_nodeps=Res edit_ondeps=En depn edit_uninst_mod=Desinstalla el mdul de: edit_uninst_theme=Desinstalla el tema de: edit_all=Tots els servidors edit_ver=Versi edit_nover=Cap de disponible edit_os=Sistemes suportats edit_osall=Tots els sistemes operatius edit_hosts=Installat als Servidors edit_codes=Del test $1 edit_acl=Edita edit_uacl=ACL de l'usuari $1 de $2 edit_gacl=ACL del grup $1 de $2 install_err=No he pogut installar el mdul install_title=Installaci de Mdul install_elocal=No has donat cap fitxer local install_elocal2='$1' no existeix install_eupload=El teu navegador no suporta puges de fitxers install_eurl=URL '$1' incomprensible install_ecomp=El fitxer est comprimit, per no s'ha trobat l'ordre $1 al sistema install_egzip=El fitxer est comprimita mb gzip, per no s'ha trobat l'ordre $1 al sistema install_ecmd=No s un fitxer de mdul vlid: $1 install_einfo=Al mdul $1 li falta un fitxer module.info install_enone=No sembla que el fitxer contingui cap mdul install_header=Installant $1 a tots els hosts... install_header2=Installant $1 a $2 .. install_header4=Installant $1 als membres de $2 .. install_header3=Installant $1 als hosts que no el tenen... do_failed=No he pogut installar sobre $1: $2 do_success_mod=He installat el mdul $2 a $1 do_success_theme=He installat el tema $2 a $1 do_done=...fet delete_err=No he pogut suprimir el mdul $1 delete_epack=El mdul $1 no existeix delete_title=Supressi de Mdul delete_rusure_mod=Segur que vols suprimir el mdul $1 de tots els servidors? S'esborraran $2 Kb de fitxers per sempre. delete_rusure_theme=Segur que vols suprimir el tema $1 de tots els servidors? S'esborraran $2 Kb de fitxers per sempre. delete_rusure2_mod=Segur que vols suprimir el mdul $1 de $3? S'esborraran $2 Kb de fitxers per sempre. delete_rusure2_theme=Segur que vols suprimir el tema $1 de $3? S'esborraran $2 Kb de fitxers per sempre. delete_ok=Suprimeix delete_error=No he pogut suprimir de $1: $2 delete_success=Suprimit de $1. delete_done=...fet delete_header_mod=Suprimint el mdul $1... delete_header_theme=Suprimint el tema $1... delete_edepends=El(s) mdul(s) $1 en depenen. delete_egone=El mdul ja no existeix delete_esuccess=He suprimit amb xit de $1: $2 delete_acls=Elimina dels usuaris i reinicia els valors de control d'accs user_title1=Creaci d'Usuari Webmin user_header1=Detalls del nou usuari Webmin user_name=Usuari user_group=Membre del grup user_nogroup=<Cap> user_pass=Contrasenya user_set=Estableix a user_unix=Autenticaci Unix user_lock=No s'accepta cap contrasenya user_lang=Idioma user_theme=Tema personal user_default=Valor per defecte del servidor user_themedef=Tema de Webmin per defecte user_ips=Control d'accs IP user_all=Permet des de totes les adreces user_allow=Permet noms des de les adreces llistades user_deny=Denega des de les adreces llistades user_mods=Mduls user_sall=Seleccciona'ls tots user_snone=No en seleccionis cap user_sinvert=Inverteix la selecci user_err1=No he pogut crear l'usuari user_ename='$1' no s un nom d'usuari vlid user_etaken=El nom d'usuari '$1' ja est en s user_ecolon=Les contrasenyes no poden contenir el carcter ':' user_doing=Creant l'usuari $1 a tots els hosts... user_doing2=Actualitzant l'usuari $1 a tots els hosts... user_success=He creat l'usuari on $1 user_success2=He actualitzat l'usuari a $1 user_failed=No he pogut crear l'usuari a $1: $2 user_failed2=No he pogut actualitzar l'usuari a $1: $2 user_done=...fet user_egroup=No existeix el grup al servidor user_groupmods=(A ms a ms dels mduls del grup) user_title2=Edici d'Usuari Webmin user_header2=Detalls de l'usuari de $1 user_leave=Deixa-ho tal com est user_modsel=Noms els mduls seleccionats... user_modadd=Afegeix els mduls seleccionats... user_moddel=Elimina els mduls seleccionats... user_mleave=Deixa-ho tal com est ($1 mduls) user_nogroup2=Sense grup user_allow2=Permetent user_deny2=Denegant user_allowall=Sense control d'accs user_hosts=L'Usuari Existeix als Servidors user_acl=Edita l'ACL de user_aclh=$1 a $2 user_aclhg=ACL global a $1 user_return=als detalls de l'usuari udelete_title=Supressi d'usuari udelete_doing=Suprimint l'usuari $1 de tots els hosts... udelete_success=Esborrat de $1 amb xit udelete_failed=No he pogut suprimir de $1: $2 udelete_done=...fet group_title1=Creaci de Grup group_header1=Detalls del nou grup Webmin group_name=Nom del grup group_err1=No he pogut crear el grup group_ename='$1' no s un nom de grup vlid group_etaken=El nom del grup '$1' ja est en s group_doing=Creant el grup $1 a tots els hosts... group_success=He creat el grup a $1 group_failed=No he pogut crear el grup a $1: $2 group_done=...fet group_title2=Edici de Grup group_header2=Detalls del grup Webmin de $1 group_group=Grup pare group_mems=Membres al servidor group_mods=Mduls dels membres group_groupmods=(A ms a ms dels mduls del grup pare) group_hosts=El Grup Existeix als Servidors group_egroup=El grup pare no existeix al servidor group_success2=He actualitzat el grup a $1 group_failed2=No he pogut actualitzar el grup a $1 :$2 group_doing2=Actualitzant el grup $1 a tots els hosts... group_return=als detalls del grup group_nomems=No hi ha cap membre gdelete_title=Supressi de Grup gdelete_desc=Segur que vols suprimir el grup $1 i els seus usuaris membres $2 de tots els hosts? gdelete_ok=Suprimeix el Grup gdelete_doing=Suprimint el grup $1 de tots els hosts... gdelete_success=He suprimit amb xit de $1 gdelete_failed=NO he pogut suprimir de $1: $2 gdelete_done=...fet gdelete_esub=Aquest grup t els subgrups $1, a per tant no es pot suprimir. acl_title=Control d'Accs al Mdul acl_title2=De l'usuari $1 de $2 a $3 acl_title3=Del grup $1 de $2 a $3 acl_title2_ga=ACL global de l'usuari $1 a $3 acl_title3_ga=ACL global ACL del grup $1 a $3 acl_options=Opcions de control d'accs $1 de $2 acl_optionsg=Opcions globals de control d'accs de $1 acl_config=Pot editar la configuraci del mdul acl_raw=Entrades del fitxer d'ACL pelada acl_efound=No he pogut editar l'ACL: $1 no t accs a $2 a cap servidor acl_save1=Desa a tots els hosts acl_save2=Desa noms a $1 acl_err=No he pogut desar el control d'accs acl_doing=Establint el control d'accs de $1 a tots els hosts... acl_doing2=Establint el control d'accs de $1 a $2 .. acl_success=He establert amb xit el control d'accs a $1 acl_failed=No he pogut establir el control d'accs a $1: $2 acl_done=...fet sync_title=Sincronitzaci de Servidors sync_desc=Aquest formulari permet crear usuaris i grups Webmin als servidors que actualment no els tenen, per tal de sincronitzar els comptes a travs de tots els servidors del cluster. sync_hosts=Servidors to sincronitzar sync_hall=Tots els servidors sync_hsel=Seleccionats... sync_users=Usuaris a crear sync_uall=Tots els usuaris que falten sync_unone=Cap usuari sync_usel=Noms els usuaris sync_unot=Tots excepte els usuaris sync_groups=Grups a crear sync_gall=Tots els grups que falten sync_gnone=Cap grup sync_gsel=Noms els grups sync_gnot=Tots escepte els grups sync_ok=Crea Usuaris i Grups sync_on=Sincronitzant $1... sync_insync=Els usuaris i els grups estan sincronitzats. sync_ucreate=Afegint l'usuari Webmin $1... sync_gcreate=Afegint el grup Webmin $1... sync_acl=Copiant els fitxers ACL de $1... sync_test=Mostra noms el que es faria sync_restart=Reiniciant Webmin... upgrade_title=Actualitzaci de Webmin upgrade_header=Actualitzant Webmin a tots els hosts... upgrade_header2=Actualitzant Webmin a $1... upgrade_header3=Actualitzant Webmin als hosts que tenen una versi ms antiga de la $1... upgrade_header4=Actualitzant Webmin als membres de $1... upgrade_emode=El tipus d'installaci d'aquest host ($1) s diferent del tipus de paquet seleccionat ($2) upgrade_mode_=tar.gz upgrade_mode_rpm=RPM upgrade_mode_solaris-pkg=Paquet Solaris upgrade_mode_gentoo=Paquet Gentoo upgrade_mode_debian=Paquet Debian upgrade_mode_caldera=ROM de Caldera upgrade_ok=He actualitzat correctament el paquet $1 de Webmin a $2 upgrade_failed=No he pogut installar a on $1: $2 upgrade_done=...fet upgrade_efast=Noms espoden actualitzar els servidors que utilitzen el mode RPC rpid upgrade_ereconn=No he pogut reconnectar amb Webmin desprs de l'actualitzaci!: $1 cluster-webmin/lang/es0100664000567100000120000002214110067401523014752 0ustar jcameronwheelindex_title=Servidores Webmin de Clster index_hosts=Servidores Gestionados index_nohosts=No se han registrado servidores de Webmin para gestin. index_add=Aadir Servidor index_gadd=Aadir servidores en grupo index_edit=Editar mdulo index_tedit=Editar tema index_refresh=Refrescar servidores index_modules=Mdulos y Temas index_users=Usuarios y Grupos de Webmin index_installmsg=Selecciona la localizacin desde donde instalar un nuevo mdulo o tema... index_local=Desde archivo local index_uploaded=Desde archivo cargado index_ftp=Desde ftp o URL http index_installok=Instalar Ahora index_return=lista de servidores index_down=Cada servidor debera de volver a descargar el mdulo index_version=Webmin $1 index_nodeps=Ignorar dependencias del mdulo al instalar index_grant2=Garantizar slo acceso a usuarios y grupos: index_grant1=Garantizar acceso a todos los usuarios de Webmin index_euser=Editar usuario: index_cuser=Aadir usuario index_egroup=Editar grupo: index_cgroup=Aadir grupo index_euseracl=Editar ACL para index_egroupacl=Editar ACL para index_inmod=en index_gacl=ACL Global this_server=este servidor add_title=Aadir Servidores add_msg=Aadiendo $1 add_gmsg=Aadiendo servidores en grupo $1... add_err=No pude aadir servidor add_gerr=No pude aadir grupo add_echeck=El servidor $1 no tiene el mdulo de configuracin de Webmin add_echeck2=El servidor $1 no tiene el mdulo de Usuarios de Webmin add_eversion=El servidor $1 no est ejecutando la versin $2 o superior de Webmin. add_ok=Aadido $1 con $2 mdulos, $3 temas, $4 usuarios y $5 grupos. refresh_title=Refrescar Listas de Mdulos y Usuarios refresh_header=Volviendo a requerir listas de mdulos, usuarios y grupos de todos los servidores... refresh_1=Refrescado $1 (aadido $2, quitado $3). refresh_2=Refrescado $1 (aadido $2). refresh_3=Refrescado $1 (quitado $2). refresh_4=Refrescado $1 (sin cambio de mdulos). refresh_u1=Aadidos $1 usuarios. refresh_u2=Quitados $1 usuarios. refresh_g1=Aadidos $1 grupos. refresh_g2=Quitados $1 grupos. refresh_done=... hecho refresh_del=Quitado $1 de la lista de servidores refresh_failed=No pude refrescar $1: $2 host_title=Servidor Gestionado host_header=Detalles de servidor de Webmin gestionado host_name=Nombre de mquina host_type=Tipo de servidor host_delete=Quitado de lista gestionada host_installed=Paquetes Instalados host_os=SO y versin host_version=Versin de Webmin host_count=Modulos instalados host_tcount=Temas instalados host_header_m=Mdulos de Webmin instalados host_header_t=Temas de Webmin instalados host_header_u=Usuarios de Webmin host_header_g=Grupos de Webmin edit_title_mod=Editar Mdulo edit_title_theme=Editar Tema edit_header_mod=Detalles de mdulo de Webmin desde $1 edit_header_theme=Detalles de tema de Webmin desde $1 edit_desc=Descripcin edit_cat=Categora edit_dir=Directorio edit_deps=Depende de edit_nodeps=Nada edit_ondeps=Dependido de edit_uninst_mod=Desinstalar mdulo desde: edit_uninst_theme=Desinstalar tema desde: edit_all=Todos los servidores edit_ver=Versin edit_nover=Ninguno disponible edit_os=Sistemas soportados edit_osall=Todos los sistemas operativos edit_hosts=Instalado en Servidores edit_codes=Desde prueba $1 edit_acl=Editar ACL para edit_uacl=Usuario $1 en $2 edit_gacl=Grupo $1 en $2 install_err=No pude instalar mdulo install_title=Instalar Mdulo install_elocal=No se ha digitado archivo local install_elocal2='$1' no existe install_eupload=Tu navegador no soporta carga de archivos install_eurl=URL incomprensible '$1' install_ecomp=El archivo est comprimido, pero el comando $1 no fue hallado en tu sistema install_egzip=El archivo est comprimido mediante gzip, pero el comando $1 no fue hallado en tu sistema install_ecmd=No es un archivo de mdulo vlido: $1 install_einfo=Al mdulo $1 le falta el archivo module.info install_enone=El archivo no parece que contenga mdulo alguno install_header=Instalando $1 en todas las mquinas... do_failed=No pude instalar en $1: $2 do_success_mod=Instalado mdulo $2 en $1 do_success_theme=Instalado tema $2 en $1 do_done=... hecho delete_err=No pude borrar mdulo $1 delete_epack=El mdulo $1 no existe delete_title=Borrar Mdulo delete_rusure_mod=Ests seguro de querer borrar el mdulo $1 de todos los servidores?. $2 kB de archivos se borrarn para siempre. delete_rusure_theme=Ests seguro de querer borrar el tema $1 de todos los servidores?, $2 kB de archivos se borrarn para siempre. delete_rusure2_mod=Ests seguro de querer borrar el mdulo $1 desde $3?. $2 kB de archivos se borrarn para siempre. delete_rusure2_theme=Ests seguro de querer borrar el tema $1 desde $3?. $2 kB de archivos se borrarn para siempre. delete_ok=Borrar delete_error=No pude borrar desde $1: $2 delete_success=Borrado desde $1. delete_done=... hecho delete_header_mod=Borrando mdulo $1... delete_header_theme=Borrando tema $1... delete_edepends=El mdulo $1 depende de l. delete_egone=El mdulo ya no existe delete_error=No pude borrar desde $1: $2 delete_esuccess=Borrado con xisto desde $1: $2 delete_acls=Quitar de usuarios y limpiar valores de control de acceso? user_title1=Crear Usuario de Webmin user_header1=Detalles de nuevo usuario de Webmin user_name=Nombre de usuario user_group=miembro de grupo user_nogroup=<Ninguno> user_pass=Clave de acceso user_set=Poner a user_unix=Autenticacin Unix user_lock=No se ha aceptado clave de acceso user_lang=Lenguage user_theme=Tema personal user_default=Por defecto de Servidor user_themedef=Tema por defecto de Webmin user_ips=Control de acceso a IP user_all=Permitir de todas las direcciones user_allow=Slo permitir desde direcciones listadas user_deny=Denegar desde direcciones listadas user_mods=Mdulos user_sall=Seleccionar todos user_snone=No seleccionar nunguno user_sinvert=Invertir seleccin user_err1=No pude crear usuario user_ename='$1' no es un nombre de usuario vlido user_etaken=El nombre de usuario '$1' ya est en uso user_ecolon=Las claves de acceso no pueden contener el carcter ':' user_doing=Creando usuario $1 en todas las mquinas... user_doing2=Actualizando usuario $1 en todas las mquinas user_success=Creado el usuario en $1 user_success2=Actualizado el usuario en $1 user_failed=No pude crear usuario en $1: $2 user_failed2=No pude actualizar usuario en $1: $2 user_done=... hecho user_egroup=El grupo no existe el el servidor user_groupmods=(Adems de los mdulos desde grupo) user_title2=Editar Usuario de Webmin user_header2=Detalles de usuario desde $1 user_leave=Dejar sin cambiar user_modsel=Slo los mdulo seleccionados... user_modadd=Aadir mdulos seleccionados... user_moddel=Quitar mdulos seleccionados... user_mleave=Dejar sin cambiar ($1 mdulos) user_nogroup2=Sin grupo user_allow2=Permitiendo user_deny2=Denegando user_allowall=Sin control de acceso user_hosts=Usuario Existente en Servidores user_acl=Editar ACL para user_aclh=$1 en $2 user_aclhg=ACL global en $1 user_return=detalles de usuario udelete_title=Borrar Usuario udelete_doing=Borrando usuario $1 de todas las mquinas... udelete_success=Borrado con xisto desde $1 udelete_failed=No pude borrar desde $1: $2 udelete_done=... hecho group_title1=Crear Grupo group_header1=Detalles de nuevo grupo de Webmin group_name=Nombre de grupo group_err1=No pude crear grupo group_ename='$1' no es un nombre de grupo vlido group_etaken=El nombre de grupo '$1' ya est en uso group_doing=Creando grupo $1 en todas las mquinas... group_success=Creado grupo en $1 group_failed=No pude crear grupo en $1: $2 group_done=... hecho group_title2=Editar Grupo group_header2=Detalles de grupo de Webmin desde $1 group_group=Grupo padre group_mems=Miembros en servidor group_mods=Mdulos para miembros group_groupmods=(Adems de los mdulos del grupo padre) group_hosts=Grupos Existentes en Servidores group_egroup=El grupo padre no existe en servidor group_success2=Actualizado grupo en $1 group_failed2=No pude actualizar grupo en $1: $2 group_doing2=Actualizando grupo $1 en todas las mquinas... group_return=detalles de grupo group_nomems=Sin miembros gdelete_title=Borrar Grupo gdelete_desc=Ests seguro de querer borrar el grupo $1 y sus usuarios miembros $2 de todas las mquinas? gdelete_ok=Borrar Grupo gdelete_doing=Borrando grupo $1 de todas las mquinas... gdelete_success=Borrado con xito desde $1 gdelete_failed=No pude borrar desde $1: $2 gdelete_done=... hecho gdelete_esub=Este grupo tiene subgrupos $1 y, por ello, no puede ser borrado. acl_title=Control de Acceso a Mdulo acl_title2=Para usuario $1 en $2 sobre $3 acl_title3=para grupo $1 en $2 sobre $3 acl_title2_ga=ACL global para usuario $1 sobre $3 acl_title3_ga=ACL global para grupo $1 sobre $3 acl_options=opciones de control de acceso $1 desde $2 acl_optionsg=opciones de control de acceso globales desde $1 acl_config=Puedo editar la configuracin del mdulo? acl_raw=Entradas de archivo sin bfer de ACL acl_efound=No pude editar ACL: $1 no tiene acceso a $2 en cualquier servidor acl_save1=Salvar en todas las mquinas acl_save2=Salvar slo en $1 acl_err=No pude salvar control de acceso acl_doing=Poniendo control de acceso para $1 en todas las mquinas... acl_doing2=Poniendo control de acceso para $1 en $2... acl_success=Puesto control de acceso con xito en $1 acl_failed=No pude poner control de acceso en $1: $2 acl_done=... hecho cluster-webmin/images/0040775000567100000120000000000007635467614014773 5ustar jcameronwheelcluster-webmin/images/icon.gif0100644000567100000120000000442507504305113016366 0ustar jcameronwheelGIF89a00ʾںʶ¾º¾ºƾƾƾ¶ººƾ²ڒ~vrzxrjbVNNrnn򲲮^VRbZTvvvrrr^ZX2.+&¶¾RNN*.**&&&"""¾f^Z򂂂   ***zzz^^\  F>; ¦JJJ ƾ " ZRN~fff666NNNʾ *&&nfbZZZ  >>>ƺֶ f^^ZNNBBB~|~~~־*""NFDϲ.&!"b^^:2.6.*VRRޒnnn "222VVVªFFF&""B>>溶! ,00H` *T8Ç.$Pċ hȱł`G9xR xPeJY|! F  4H̚ p5Җ:H"FzHjyJ0qRX@F E Bt8AyA /$Pc[[DA 3A#lHD ->`} Ç,p$!QB)bd#HTly Jb,1p:݋L<8`E'OD2J*V\'QYD ZR8PD[pх_c耄 +8TCYGFЇgkцXȠ/OD+G GAg taǕw|rT;D 6X_"qx zG~\ ` 6 AH!WZ!U@ 7TA0,yH""Lq4B#m<vX`$u_$O!$o%Xr &dc 'xr#',d —9H }f 1 )r1vvQA^AǕ'̐ha#wRPP& r,b' p .aGBvt"[JP>Lp/?L"C/KjB'\0a\IIQl +*W”7 S2\ "XR )4r vBnj³$ A `2z [$ ~,3`4̕\*_i30B,$-xAWGV 3WMHcLOSԌm'TS,RfM"q8`CK~b 3R6vl# q C,B! d"$! rA* E!n8B ( @,(PeUT29|!Qcj BOϘB0f @&,A!h!J$B~û6 ND8bh)gI !ac}HEH 0a W]|"BhsCd` Xn! 7WC|q OE! E': HA @ɢBD`J$#:IrNr* >XʳG H:,f.\&8 U u\pCͤ$F1^3I E(&A=Pp qxT\5  @Ӟ9 WFJҒ%]CT4$@5 .+P  |F7v` ZۊЋv +@ui89@ `##!U- 5 ˢ;$`^,K+2V!c@/RLV!Bay@^ -l_2)鱤--;cluster-webmin/images/.xvpics/0040755000567100000120000000000007477302754016360 5ustar jcameronwheelcluster-webmin/images/.xvpics/icon.gif0100664000567100000120000000450207504305113017756 0ustar jcameronwheelP7 332 #IMGINFO:48x48 RGB (2325 bytes) #END_OF_COMMENTS 48 48 255 ڶ۶ڶ۶ڶ(IHFH)IHJHۺֺۺֺ ۶ֺ۶ @ڷֺ@`ڻ۶@ @@ ׺@ֶ׺ڻڷκڶ۶ַ׺ֶڷڶ׺ֶֺֺڶ۶׺׻߶mmmirڒr۷۶۶hnmhND֖λַHImIIH!ֻڶ۶ۺ۶ڷڶֻq% Iַl׻ۻ׻۵߶H (ֺrmiHJIIINI $!MڶmII `۶ڒH$! Ei(% `)ֺn  %߶IH! `۶׺ڒ  ۵I% $`m۶ $mqE$j@$ֶ $In( r`۶ַD $$!ߍm% `۵Һֶ׺)  InH!MI$d۶۶m$ (MimE@mqD $qiI (`M߲ڒ )i$%$I)m۶ E$% %rEmۺ׺ $!$ )Dnһ$%$%$  )mڶֻqE $ N qnڷ۶H rںHII۶۶ֺ׺ۍ$$% I@۶۶I % $@۶֖LjlJIm@۶ֺڶ۶۶造۶耠۶@ֻ۶۶۶۶$IIIHII%Iڻ(III$IIIIH۶۶ڶ۶ڶڷ۶ۺۺڶۺ۶ڶ۶ֶ۶ڻ۶ڻ۷۶׶ۺ׺ۺ۶ڷ۶ڷֻڷֻڷڷڶڷڶ۶׺۶۶۶ڷ۶ڷ۶۶ڷ۶ڷڷcluster-webmin/images/smallicon.gif0100664000567100000120000000242107777121255017432 0ustar jcameronwheelGIF87a yspSNN\X D@? 뿵ƿ 곲摌  sr ת‘)! ki' GGG2//  777555fszyPPOba؃965γ33 wpn @~~njhсޭVPM~~~zzzZVTľvvv fff|wu```}Žӣmki|{{ſwwvH?>ff 硠}}ooJIIź$ eeumi,u 9ǼZp Bv0 p "bC ! `nj_  'S )rByL4Dl(PٍZ\ y6fL@jR"KDZ>Zd:0ڑ&%0ю;[OMU`ɬ9txi"(DD`z@9(23"$cs&PYW2lfh#5@2 ,#.!A"9Q-$L P2O D RtQN'1@d<# Q62Q<S <"4[!L8 y ;L@B 5E6]u$ $C&3Y&W~@Z:6Y/;cluster-webmin/refresh.cgi0100775000567100000120000000706110115014347015626 0ustar jcameronwheel#!/usr/local/bin/perl # refresh.cgi # Reload the list of modules from all managed hosts require './cluster-webmin-lib.pl'; &ui_print_header(undef, $text{'refresh_title'}, ""); $| = 1; # Setup error handler for down hosts sub ref_error { $ref_error_msg = join("", @_); } &remote_error_setup(\&ref_error); print "$text{'refresh_header'}

\n"; @hosts = &list_webmin_hosts(); @servers = &list_servers(); $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); if ($s) { # Refresh the list &remote_foreign_require($s->{'host'}, "webmin", "webmin-lib.pl"); if ($ref_error_msg) { # Host is down .. print $wh &serialise_variable($ref_error_msg); exit; } &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); local $gconfig = &remote_foreign_config($s->{'host'}, undef); foreach $g ('os_type', 'os_version', 'real_os_type', 'real_os_version') { $h->{$g} = $gconfig->{$g}; } $h->{'version'} = &remote_foreign_call($s->{'host'}, "webmin", "get_webmin_version"); # Refresh modules and themes local @old = map { $_->{'dir'} } ( @{$h->{'modules'}}, @{$h->{'themes'}} ); undef($h->{'modules'}); local @mods = &remote_foreign_call($s->{'host'}, "webmin", "get_all_module_infos", 1); @mods = grep { !$_->{'clone'} } @mods; local @themes = &remote_foreign_call($s->{'host'}, "webmin", "list_themes"); local @added; foreach $m (@mods, @themes) { $idx = &indexof($m->{'dir'}, @old); if ($idx < 0) { push(@added, $m->{'dir'}); } else { splice(@old, $idx, 1); } } $h->{'modules'} = \@mods; $h->{'themes'} = \@themes; # Refresh users and groups local @users = &remote_foreign_call($s->{'host'}, "acl", "list_users"); local $ud = scalar(@users) - scalar(@{$h->{'users'}}); $h->{'users'} = \@users; local @groups = &remote_foreign_call($s->{'host'}, "acl", "list_groups"); local $gd = scalar(@groups) - scalar(@{$h->{'groups'}}); $h->{'groups'} = \@groups; &save_webmin_host($h); $rv = [ \@added, \@old, $ud, $gd ]; } else { # remove from managed list &delete_webmin_host($h); $rv = undef; } print $wh &serialise_variable($rv); close($wh); exit; } close($wh); $p++; } # Read back results $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); if ($rv && ref($rv)) { @added = @{$rv->[0]}; @old = @{$rv->[1]}; if (@added && @old) { print &text('refresh_1', $d, join(" ", @added),join(" ", @old)),"\n"; } elsif (@added) { print &text('refresh_2', $d, join(" ", @added)),"\n"; } elsif (@old) { print &text('refresh_3', $d, join(" ", @old)),"\n"; } else { print &text('refresh_4', $d),"\n"; } if ($rv->[2] > 0) { print &text('refresh_u1', $rv->[2]),"\n"; } elsif ($rv->[2] < 0) { print &text('refresh_u2', -$rv->[2]),"\n"; } if ($rv->[3] > 0) { print &text('refresh_g1', $rv->[3]),"\n"; } elsif ($rv->[3] < 0) { print &text('refresh_g2', -$rv->[3]),"\n"; } print "
\n"; } elsif ($rv) { print &text('refresh_failed', $d, $rv),"
\n"; } else { print &text('refresh_del', $h->{'id'}),"
\n"; } $p++; } print "

$text{'refresh_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/module.info0100664000567100000120000000051110121700731015630 0ustar jcameronwheelname=Cluster Webmin desc=Cluster Webmin Servers category=cluster depends=webmin servers desc_ca=Servidors de Cluster Webmin desc_es=Servidores de Clster de Webmin desc_de=Cluster - Webmin-Server longdesc=Install and manage modules, themes, users, groups and access control settings across multiple Webmin servers. version=1.161 cluster-webmin/edit_host.cgi0100775000567100000120000000717110115014275016154 0ustar jcameronwheel#!/usr/local/bin/perl # edit_host.cgi # Show details of a managed host, and all the modules on it require './cluster-webmin-lib.pl'; &ReadParse(); &ui_print_header(undef, $text{'host_title'}, ""); @hosts = &list_webmin_hosts(); ($host) = grep { $_->{'id'} eq $in{'id'} } @hosts; $server = &foreign_call("servers", "get_server", $in{'id'}); @modules = @{$host->{'modules'}}; @themes = @{$host->{'themes'}}; @users = @{$host->{'users'}}; @groups = @{$host->{'groups'}}; # Show host details print "

\n"; print "\n"; print "\n"; print "\n"; print "
$text{'host_header'}
\n"; print "\n"; if ($server->{'id'}) { printf "\n", $server->{'id'}, $server->{'desc'} ? "$server->{'desc'} ($server->{'host'}:$server->{'port'})" : "$server->{'host'}:$server->{'port'}"; } else { print "\n"; } if ($server->{'id'}) { print "\n"; } print "\n"; print "\n"; printf "\n", scalar(@modules); print "\n"; printf "\n", scalar(@themes); print "\n"; print "\n"; print "\n"; printf "\n", $host->{'version'}; print "
$text{'host_name'}%s$text{'this_server'}$text{'host_type'} \n"; foreach $t (@servers::server_types) { print $t->[1] if ($t->[0] eq $server->{'type'}); } print "
$text{'host_count'}%d$text{'host_tcount'}%d
$text{'host_os'}$host->{'real_os_type'} $host->{'real_os_version'}$text{'host_version'}%s

\n"; print "
\n"; # Show table of modules and themes print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'host_header_m'}
\n"; $i = 0; foreach $m (sort { $a->{'desc'} cmp $b->{'desc'} } @modules) { print "\n" if ($i%3 == 0); print "\n"; print "\n" if ($i%3 == 2); $i++; } if (@themes) { $i = 0; print "
",$m->{'desc'},"
$text{'host_header_t'}
\n"; foreach $t (sort { $a->{'desc'} cmp $b->{'desc'} } @themes) { print "\n" if ($i%3 == 0); print "\n"; print "\n" if ($i%3 == 2); $i++; } } print "
",$t->{'desc'},"

\n"; # Show table of users and groups print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'host_header_u'}
\n"; $i = 0; foreach $u (@users) { print "\n" if ($i%4 == 0); print "\n"; print "\n" if ($i%4 == 3); $i++; } if ($i%4) { while($i++%4) { print "\n"; } print "\n"; } if (@groups) { $i = 0; print "
$u->{'name'}
$text{'host_header_g'}
\n"; foreach $g (@groups) { print "\n" if ($i%4 == 0); print "\n"; print "\n" if ($i%4 == 3); $i++; } if ($i%4) { while($i++%4) { print "\n"; } print "\n"; } } print "
$g->{'name'}

\n"; &ui_print_footer("", $text{'index_return'}); cluster-webmin/help/0040775000567100000120000000000007620554611014442 5ustar jcameronwheelcluster-webmin/help/intro.ca.html0100644000567100000120000000320610067401515017032 0ustar jcameronwheel
Servidors de Cluster Webmin
Aquest mdul permet gestionar mduls, temes, usuaris i grups a travs de mltiples servidors Webmin des d'una sola interfcie. Combina les funcions de la Configuraci i Usuaris de Webmin amb la capacitat de portar a terme accions (com ara installar un tema o crear un usuari) a ms d'un servidor alhora.

La part de dalt de la pgina principal sota la capalera Servidors gestionats llista altres servidors Webmin els mduls i usuaris dels quals estan gestionats per aquest mdul. Per afegir un mdul a aquesta llista, primer l'has d'afegir al mdul de Servidors Webmin amb un usuari i contrasenya especificats per entrar al Webmin d'aquest servidor. Llavors, pots seleccionar el servidor de la llista del costat del bot Afegeix servidor.

Quan s'afegeix un servidor, es comprovar que est executant una versi de Webmin suportada (0.985 o ms nova) i que te installats els mduls necessaris. Llavors, es posaran al cau local les llistes de tots als mduls, temes, usuaris i grup del servidor.

Aix que hi hagi noms una icona sota els Servidors gestionats, podrs utilitzar els botons sota Usuaris i Grups Webmin per editar, crear o establir ACLs sobre els usuaris i grups de qualsevol servidor. Els usuaris i grups que cres es crearan a tots els servidors gestionats, per aquells que ja existeixin, siguin editats o suprimits, noms es canviaran als servidors on ja existeixin.

Al peu de la pgina, sota Mduls i Temes, hi ha els botons per editar mduls i temes installats a qualsevol servidor gestionat, i un formulari per installar un mdul o un tema nou a tots els servidors,


cluster-webmin/help/intro.html0100664000567100000120000000306407510241640016454 0ustar jcameronwheel
Cluster Webmin Servers
This module allows you to manage modules, themes, users and groups across multiple Webmin servers from one interface. It combines functions from the Webmin Configuration and Webmin Users modules with the ability to carry out actions (such as installing a theme or creating a user) on multiple servers at once.

The top part of the main page under the Managed Servers heading lists other Webmin servers whose modules and users are being managed by this module. To add a server to this list, you must first add it to the Webmin Servers module, with a username and password specified to login to Webmin on that server. You can then select the server from the list next to the Add Server button.

When a server is added, it will be checked to make sure it is running a supported version of Webmin (0.985 or later) and that it has the necessary modules installed. Lists of all modules, themes, users and groups from the server will then be downloaded and cached locally.

Once there is at least once icon under Managed Servers, you can use the buttons under Webmin Users and Groups to edit, create or set ACLs on users and groups on any server. Users and groups that you create will be created on all managed servers, but those that already exist that are edited or deleted will only be changed on the servers they already exist on.

At the bottom of the page under Modules and Themes are buttons for editing modules and themes installed on any managed server, and a form for installing a new module or theme on all servers.


cluster-webmin/cluster-webmin-lib.pl0100664000567100000120000001473210115014111017532 0ustar jcameronwheel# cluster-webmin-lib.pl # Common functions for managing webmin installs across a cluster do '../web-lib.pl'; &init_config(); require '../ui-lib.pl'; &foreign_require("servers", "servers-lib.pl"); # list_webmin_hosts() # Returns a list of all hosts whose webmin modules are being managed sub list_webmin_hosts { local $hdir = "$module_config_directory/hosts"; opendir(DIR, $hdir); local ($h, @rv); foreach $h (readdir(DIR)) { next if ($h eq "." || $h eq ".." || !-d "$hdir/$h"); local %host = ( 'id', $h ); local $f; opendir(MDIR, "$hdir/$h"); foreach $f (readdir(MDIR)) { if ($f =~ /^(\S+)\.mod$/) { local %mod; &read_file("$hdir/$h/$f", \%mod); push(@{$host{'modules'}}, \%mod); } elsif ($f =~ /^(\S+)\.theme$/) { local %theme; &read_file("$hdir/$h/$f", \%theme); push(@{$host{'themes'}}, \%theme); } elsif ($f =~ /^(\S+)\.user$/) { local %user; &read_file("$hdir/$h/$f", \%user); $user{'modules'} = [ split(/\s+/, $user{'modules'}) ]; $user{'ownmods'} = [ split(/\s+/, $user{'ownmods'}) ]; push(@{$host{'users'}}, \%user); } elsif ($f =~ /^(\S+)\.group$/) { local %group; &read_file("$hdir/$h/$f", \%group); $group{'modules'} = [ split(/\s+/, $group{'modules'}) ]; $group{'ownmods'} = [ split(/\s+/, $group{'ownmods'}) ]; $group{'members'} = [ split(/\s+/, $group{'members'}) ]; push(@{$host{'groups'}}, \%group); } elsif ($f eq "webmin") { &read_file("$hdir/$h/$f", \%host); } } closedir(MDIR); push(@rv, \%host); } closedir(DIR); return @rv; } # save_webmin_host(&host) sub save_webmin_host { local $hdir = "$module_config_directory/hosts"; local %oldfile; mkdir($hdir, 0700); if (-d "$hdir/$_[0]->{'id'}") { opendir(DIR, "$hdir/$_[0]->{'id'}"); map { $oldfile{$_}++ } readdir(DIR); closedir(DIR); } else { mkdir("$hdir/$_[0]->{'id'}", 0700); } local $m; foreach $m (@{$_[0]->{'modules'}}) { &write_file("$hdir/$_[0]->{'id'}/$m->{'dir'}.mod", $m); delete($oldfile{"$m->{'dir'}.mod"}); } foreach $m (@{$_[0]->{'themes'}}) { &write_file("$hdir/$_[0]->{'id'}/$m->{'dir'}.theme", $m); delete($oldfile{"$m->{'dir'}.theme"}); } foreach $m (@{$_[0]->{'users'}}) { local %u = %$m; $u{'modules'} = join(" ", @{$u{'modules'}}); $u{'ownmods'} = join(" ", @{$u{'ownmods'}}); &write_file("$hdir/$_[0]->{'id'}/$u{'name'}.user", \%u); delete($oldfile{"$u{'name'}.user"}); } foreach $m (@{$_[0]->{'groups'}}) { local %g = %$m; $g{'modules'} = join(" ", @{$g{'modules'}}); $g{'ownmods'} = join(" ", @{$g{'ownmods'}}); $g{'members'} = join(" ", @{$g{'members'}}); &write_file("$hdir/$_[0]->{'id'}/$g{'name'}.group", \%g); delete($oldfile{"$g{'name'}.group"}); } local %webmin = %{$_[0]}; delete($webmin{'modules'}); delete($webmin{'themes'}); delete($webmin{'users'}); delete($webmin{'groups'}); delete($webmin{'id'}); &write_file("$hdir/$_[0]->{'id'}/webmin", \%webmin); delete($oldfile{"webmin"}); unlink(map { "$hdir/$_[0]->{'id'}/$_" } keys %oldfile); } # delete_webmin_host(&host) sub delete_webmin_host { system("rm -rf '$module_config_directory/hosts/$_[0]->{'id'}'"); } # list_servers() # Returns a list of all servers from the webmin servers module that can be # managed, plus this server sub list_servers { local @servers = &servers::list_servers(); return ( &servers::this_server(), grep { $_->{'user'} } @servers ); } # server_name(&server) sub server_name { return $_[0]->{'desc'} ? $_[0]->{'desc'} : $_[0]->{'host'}; } # all_modules(&hosts) sub all_modules { local (%done, $u, %descc); local @uniq = grep { !$done{$_->{'dir'}}++ } map { @{$_->{'modules'}} } @{$_[0]}; map { $descc{$_->{'desc'}}++ } @uniq; foreach $u (@uniq) { $u->{'desc'} .= " ($u->{'dir'})" if ($descc{$u->{'desc'}} > 1); } return sort { $a->{'desc'} cmp $b->{'desc'} } @uniq; } # all_themes(&hosts) sub all_themes { local %done; return sort { $a->{'desc'} cmp $b->{'desc'} } grep { !$done{$_->{'dir'}}++ } map { @{$_->{'themes'}} } @{$_[0]}; } # all_groups(&hosts) sub all_groups { local %done; return sort { $a->{'name'} cmp $b->{'name'} } grep { !$done{$_->{'name'}}++ } map { @{$_->{'groups'}} } @{$_[0]}; } # all_users(&hosts) sub all_users { local %done; return sort { $a->{'name'} cmp $b->{'name'} } grep { !$done{$_->{'name'}}++ } map { @{$_->{'users'}} } @{$_[0]}; } # create_on_input(desc) sub create_on_input { local @hosts = &list_webmin_hosts(); local @servers = &list_servers(); if ($_[0]) { print " $_[0]\n"; print "\n"; } print "\n"; if ($_[0]) { print " \n"; } } # create_on_parse(prefix, &already, name) sub create_on_parse { local @hosts = &list_webmin_hosts(); local @servers = &list_servers(); if ($in{'server'} == -2) { # Check who has it already local %already = map { $_->{'id'}, 1 } @{$_[1]}; @hosts = grep { !$already{$_->{'id'}} } @hosts; print "",&text($_[0].'3', $_[2]),"

\n"; } elsif ($in{'server'} =~ /^group_(.*)/) { # Install on members of some group local ($group) = grep { $_->{'name'} eq $1 } &servers::list_all_groups(\@servers); @hosts = grep { local $hid = $_->{'id'}; local ($s) = grep { $_->{'id'} == $hid } @servers; &indexof($s->{'host'}, @{$group->{'members'}}) >= 0 } @hosts; print "",&text($_[0].'4', $_[2], $group->{'name'}), "

\n"; } elsif ($in{'server'} != -1) { # Just install on one host @hosts = grep { $_->{'id'} == $in{'server'} } @hosts; local ($s) = grep { $_->{'id'} == $hosts[0]->{'id'} } @servers; print "",&text($_[0].'5', $_[2], &server_name($s)),"

\n"; } else { # Installing on every host print "",&text($_[0], join(" ", @names)),"

\n"; } return @hosts; } 1; cluster-webmin/index.cgi0100775000567100000120000001725410121450452015302 0ustar jcameronwheel#!/usr/local/bin/perl # index.cgi # Display hosts on which webmin modules are being managed, a list of # installed modules and a form for installing new ones # XXX upgrading the entire of webmin require './cluster-webmin-lib.pl'; &ui_print_header(undef, $text{'index_title'}, "", "intro", 1, 1); # Display hosts on which modules will be installed print "

$text{'index_hosts'}

\n"; @servers = &list_servers(); @hosts = &list_webmin_hosts(); if ($config{'sort_mode'} == 1) { @hosts = sort { my ($as) = grep { $_->{'id'} == $a->{'id'} } @servers; my ($bs) = grep { $_->{'id'} == $b->{'id'} } @servers; lc($as->{'host'}) cmp lc($bs->{'host'}) } @hosts; } elsif ($config{'sort_mode'} == 2) { @hosts = sort { my ($as) = grep { $_->{'id'} == $a->{'id'} } @servers; my ($bs) = grep { $_->{'id'} == $b->{'id'} } @servers; lc(&server_name($as)) cmp lc(&server_name($bs)) }@hosts; } $formno = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; next if (!$s); push(@titles, &server_name($s)."
". &text('index_version', $h->{'version'})); push(@links, "edit_host.cgi?id=$h->{'id'}"); push(@icons, "$gconfig{'webprefix'}/servers/images/$s->{'type'}.gif"); $gothost{$h->{'id'}}++; } if (@links) { &icons_table(\@links, \@titles, \@icons); } else { print "$text{'index_nohosts'}

\n"; } # Build common selectors @wgroups = &all_groups(\@hosts); $modsel2 = $modsel = "\n"; $modsel2 .= "\n"; $themesel = "\n"; $usersel = "\n"; $groupsel = "\n"; print "\n"; @addservers = grep { !$gothost{$_->{'id'}} } @servers; if (@addservers) { print "\n"; $formno++; } else { print "\n"; } @groups = &servers::list_all_groups(\@servers); if (@groups) { print "\n"; $formno++; } else { print "\n"; } print "
\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "
\n"; if (@hosts) { # Display user search forms and new user buttons print "


\n"; print "

$text{'index_users'}

\n"; print "\n"; print "\n"; $formno++; print "\n"; $formno++; print "\n"; $formno++; if (@wgroups) { print "\n"; $formno++; print "\n"; $formno++; } else { print "\n"; } print "\n"; $formno++; print "\n"; $formno++; print "\n"; $formno++; print "
\n"; print "\n"; print $usersel; print "
\n"; print "\n"; print $usersel; print "$text{'index_inmod'}\n"; print $modsel2; print "
\n"; print "\n"; print "
\n"; print "\n"; print $groupsel; print "
\n"; print "\n"; print $groupsel; print "$text{'index_inmod'}\n"; print $modsel2; print "
\n"; print "\n"; print "
\n"; print "\n"; print "
\n"; print "\n"; print "
\n"; # Display modules lists and new module form print "
\n"; print "

$text{'index_modules'}

\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print $modsel; print "\n"; print $themesel; print "
\n"; $formno++; print "
\n"; print "$text{'index_installmsg'}

\n"; print " $text{'index_local'}\n"; print "\n"; print &file_chooser_button("local", 0, $formno); print "
\n"; print " $text{'index_uploaded'}\n"; print "
\n"; print " $text{'index_ftp'}\n"; print "
\n"; print " " x 5," ", "$text{'index_down'}

\n"; print " ", "$text{'index_grant2'}\n"; print "
\n"; print " ", "$text{'index_grant1'}

\n"; print " ", "$text{'index_nodeps'}

\n"; print "$text{'index_installon'}\n"; &create_on_input(); print "

\n"; print "\n"; print "

\n"; $formno++; # Display upgrade form &foreign_require("webmin", "webmin-lib.pl"); print "
\n"; print "

$text{'index_upgrade'}

\n"; print "$text{'index_updesc'}

\n"; # what kind of install is the local system? if (open(MODE, "$root_directory/install-type")) { chop($mode = ); close(MODE); } else { if ($root_directory eq "/usr/libexec/webmin") { $mode = "rpm"; } elsif ($root_directory eq "/opt/webmin") { $mode = "solaris-pkg"; } else { $mode = undef; } } print "

\n"; print "\n"; print " $text{'index_local'}\n"; print "\n"; print &file_chooser_button("file", 0, $formno),"
\n"; print " $text{'index_uploaded'}\n"; print "
\n"; print " $text{'index_ftp'}\n"; print "
\n"; if ($in{'mode'} eq 'rpm' || !$in{'mode'}) { print " $webmin::text{'upgrade_ftp'}
\n"; } print "

\n"; printf " %s
\n", $webmin::text{'upgrade_sig'}; print " ", "$webmin::text{'upgrade_delete'}
\n"; print "$text{'index_upgradeon'}\n"; &create_on_input(); print "\n"; print "

\n"; $formno++; } &ui_print_footer("/", $text{'index'}); cluster-webmin/add.cgi0100775000567100000120000000476510115014207014723 0ustar jcameronwheel#!/usr/local/bin/perl # add.cgi # Add or update a server or group from the webmin servers module require './cluster-webmin-lib.pl'; &ReadParse(); @servers = &list_servers(); if ($in{'add'}) { # Add a single host @add = grep { $_->{'id'} eq $in{'server'} } @servers; &error_setup($text{'add_err'}); $msg = &text('add_msg', &server_name($add[0])); } else { # Add all from a group ($group) = grep { $_->{'name'} eq $in{'group'} } &servers::list_all_groups(\@servers); foreach $m (@{$group->{'members'}}) { push(@add, grep { $_->{'host'} eq $m } @servers); } &error_setup($text{'add_gerr'}); $msg = &text('add_gmsg', $in{'group'}); } &ui_print_header(undef, $text{'add_title'}, ""); print "$msg

\n"; # Setup error handler for down hosts sub add_error { $add_error_msg = join("", @_); } &remote_error_setup(\&add_error); # Get the modules and themes for each host foreach $s (@add) { $add_error_msg = undef; local $host = { 'id' => $s->{'id'} }; local $webmin = &remote_foreign_check($s->{'host'}, "webmin"); if ($add_error_msg) { print "$add_error_msg

\n"; next; } if (!$webmin) { print &text('add_echeck', $s->{'host'}),"

\n"; next; } local $acl = &remote_foreign_check($s->{'host'}, "acl"); if (!$acl) { print &text('add_echeck2', $s->{'host'}),"

\n"; next; } &remote_foreign_require($s->{'host'}, "webmin", "webmin-lib.pl"); &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); $host->{'version'} = &remote_foreign_call($s->{'host'}, "webmin", "get_webmin_version"); if ($host->{'version'} < 0.985) { print &text('add_eversion', $s->{'host'}, 0.985),"

\n"; next; } local $gconfig = &remote_foreign_config($s->{'host'}, undef); foreach $g ('os_type', 'os_version', 'real_os_type', 'real_os_version') { $host->{$g} = $gconfig->{$g}; } local @mods = &remote_foreign_call($s->{'host'}, "webmin", "get_all_module_infos", 1); @mods = grep { !$_->{'clone'} } @mods; $host->{'modules'} = \@mods; local @themes = &remote_foreign_call($s->{'host'}, "webmin", "list_themes"); $host->{'themes'} = \@themes; local @users = &remote_foreign_call($s->{'host'}, "acl", "list_users"); $host->{'users'} = \@users; local @groups = &remote_foreign_call($s->{'host'}, "acl","list_groups"); $host->{'groups'} = \@groups; &save_webmin_host($host); print &text('add_ok', &server_name($s), scalar(@mods), scalar(@themes), scalar(@users), scalar(@groups)),"

\n"; } &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/install.cgi0100775000567100000120000001641610115014342015635 0ustar jcameronwheel#!/usr/local/bin/perl # install.cgi # Download and install webmin module or theme on multiple hosts require './cluster-webmin-lib.pl'; if ($ENV{REQUEST_METHOD} eq "POST") { &ReadParseMime(); } else { &ReadParse(); $no_upload = 1; } &error_setup($text{'install_err'}); if ($in{source} == 2) { &ui_print_unbuffered_header(undef, $text{'install_title'}, ""); } else { &ui_print_header(undef, $text{'install_title'}, ""); } if ($in{source} == 0) { # installing from local file (or maybe directory) if (!$in{'local'}) { &download_error($text{'install_elocal'}); } if (!-r $in{'local'}) { &download_error(&text('install_elocal2', $in{'local'})); } $source = $in{'local'}; $pfile = $in{'local'}; $need_unlink = 0; } elsif ($in{source} == 1) { # installing from upload .. store file in temp location if ($no_upload) { &download_error($text{'install_eupload'}); } $in{'upload_filename'} =~ /([^\/\\]+$)/; $pfile = &tempname("$1"); open(PFILE, "> $pfile"); print PFILE $in{'upload'}; close(PFILE); $source = $in{'upload_filename'}; $need_unlink = 1; } elsif ($in{source} == 2) { # installing from URL.. store downloaded file in temp location $in{'url'} =~ /\/([^\/]+)\/*$/; $pfile = &tempname("$1"); $progress_callback_url = $in{'url'}; if ($in{'url'} =~ /^(http|https):\/\/([^\/]+)(\/.*)$/) { # Make a HTTP request $ssl = $1 eq 'https'; $host = $2; $page = $3; $port = $ssl ? 443 : 80; if ($host =~ /^(.*):(\d+)$/) { $host = $1; $port = $2; } &http_download($host, $port, $page, $pfile, \$error, \&progress_callback, $ssl); } elsif ($in{'url'} =~ /^ftp:\/\/([^\/]+)(:21)?(\/.*)$/) { $host = $1; $file = $3; &ftp_download($host, $file, $pfile, \$error, \&progress_callback); } else { &download_error(&text('install_eurl', $in{'url'})); } &download_error($error) if ($error); $source = $in{'url'}; $need_unlink = 1; } $grant = $in{'grant'} ? undef : [ split(/\s+/, $in{'grantto'}) ]; # Check validity open(MFILE, $pfile); read(MFILE, $two, 2); close(MFILE); if ($two eq "\037\235") { # Unix compressed &has_command("uncompress") || &download_error(&text('install_ecomp', "uncompress")); $cmd = "uncompress -c '$pfile' | tar tf -"; } elsif ($two eq "\037\213") { # Gzipped &has_command("gunzip") || &download_error(&text('install_egzip', "gunzip")); $cmd = "gunzip -c '$pfile' | tar tf -"; } else { # Just a tar file $cmd = "tar tf '$pfile'"; } $tar = `$cmd 2>&1`; $? && &download_error(&text('install_ecmd', "$tar")); foreach $f (split(/\n/, $tar)) { if ($f =~ /^\.\/([^\/]+)\/(.*)$/ || $f =~ /^([^\/]+)\/(.*)$/) { $mods{$1}++; $hasfile{$1,$2}++; } } foreach $m (keys %mods) { $hasfile{$m,"module.info"} || $hasfile{$m,"theme.info"} || &download_error(&text('install_einfo', "$m")); } if (!%mods) { &download_error($text{'install_enone'}); } # Setup error handler for down hosts sub inst_error { $inst_error_msg = join("", @_); } &remote_error_setup(\&inst_error); # Work out which hosts have the module, and which to install on @hosts = &list_webmin_hosts(); @servers = &list_servers(); foreach $h (@hosts) { local $gotall = 1; foreach $m (keys %mods) { local ($alr) = grep { $_->{'dir'} eq $m } (@{$h->{'modules'}}, @{$h->{'themes'}}); $gotall = 0 if (!$alr); } push(@gothosts, $h) if ($gotall); } @hosts = &create_on_parse("install_header", \@gothosts, join(" ", keys %mods)); # Run the install $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); select($wh); $| = 1; select(STDOUT); if (!fork()) { # Do the install in a subprocess close($rh); &remote_foreign_require($s->{'host'}, "webmin", "webmin-lib.pl"); if ($inst_error_msg) { # Failed to contact host .. print $wh &serialise_variable($inst_error_msg); exit; } &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); local $rfile; local $host_need_unlink = 1; if (!$s->{'id'}) { # This host, so we already have the file $rfile = $pfile; $host_need_unlink = 0; } elsif ($in{'source'} == 0) { # Is the file the same on remote? (like if we have NFS) local @st = stat($pfile); local $rst = &remote_eval($s->{'host'}, "webmin", "[ stat('$pfile') ]"); local @rst = @$rst; if (@st && @rst && $st[7] == $rst[7] && $st[9] == $rst[9]) { # File is the same! No need to download $rfile = $pfile; $host_need_unlink = 0; } else { # Need to copy the file across :( $rfile = &remote_write( $s->{'host'}, $pfile); } } elsif ($in{'source'} == 2 && $in{'down'}) { # Ask the remote server to download the file $rfile = &remote_foreign_call($s->{'host'}, "webmin", "tempname"); if ($in{'url'} =~ /^ftp/) { &remote_foreign_call($s->{'host'}, "webmin", "ftp_download", $host, $file, $rfile); } else { &remote_foreign_call($s->{'host'}, "webmin", "http_download", $host, $port, $page, $rfile, undef, undef, $ssl); } } else { # Need to copy the file across :( $rfile = &remote_write($s->{'host'}, $pfile); } # Do the install .. local $rv = &remote_foreign_call($s->{'host'}, "webmin", "install_webmin_module", $rfile, $host_need_unlink, $in{'nodeps'}, $grant); if (ref($rv)) { # It worked .. get all the module infos local @mods; foreach $m (@{$rv->[1]}) { $m =~ s/^.*\///; local %info = &remote_foreign_call( $s->{'host'}, "webmin", "get_module_info", $m); if (!%info) { # Must have been a theme %info = &remote_foreign_call( $s->{'host'}, "webmin", "get_theme_info", $m); $info{'theme'} = 1; } push(@mods, \%info); } print $wh &serialise_variable(\@mods); # Re-request all users, groups, modules and themes # from the server $h->{'modules'} = [ grep { !$_->{'clone'} } &remote_foreign_call($s->{'host'}, "webmin", "get_all_module_infos", 1) ]; $h->{'themes'} = [ &remote_foreign_call($s->{'host'}, "webmin", "list_themes") ]; $h->{'users'} = [ &remote_foreign_call($s->{'host'}, "acl", "list_users") ]; $h->{'groups'} = [ &remote_foreign_call($s->{'host'}, "acl", "list_groups") ]; &save_webmin_host($h); } else { print $wh &serialise_variable($rv); } close($wh); exit; } close($wh); $p++; } # Get back all the results $p = 0; foreach $h (@hosts) { local $rh = "READ$p"; local $line = <$rh>; close($rh); local $rv = &unserialise_variable($line); local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); if (!$line) { print &text('do_failed', $d, "Unknown reason"),"
\n"; } elsif (!ref($rv)) { print &text('do_failed', $d, $rv),"
\n"; } else { # List the modules installed, and add to lists foreach $m (@$rv) { if ($m->{'theme'}) { print &text('do_success_theme', $d, "$m->{'desc'}"), "
\n"; } else { print &text('do_success_mod', $d, "$m->{'desc'}"), "
\n"; } } } $p++; } unlink($pfile) if ($need_unlink); print "

$text{'do_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); sub download_error { unlink($pfile) if ($need_unlink); print "
$whatfailed : $_[0]

\n"; &ui_print_footer("", $text{'index_return'}); exit; } cluster-webmin/edit_mod.cgi0100775000567100000120000001471710115014300015747 0ustar jcameronwheel#!/usr/local/bin/perl # edit_mod.cgi # Display details of a module or theme require './cluster-webmin-lib.pl'; &ReadParse(); $type = $in{'tedit'} || !$in{'mod'} ? 'theme' : 'mod'; $name = $in{$type}; &ui_print_header(undef, $text{"edit_title_$type"}, ""); # Find all hosts with the module or theme @hosts = &list_webmin_hosts(); @servers = &list_servers(); foreach $h (@hosts) { foreach $m ($type eq 'theme' ? @{$h->{'themes'}} : @{$h->{'modules'}}) { if ($m->{'dir'} eq $name) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; push(@got, $s); push(@goth, $h); $mod = $m if (!$mod); if (!$checkon && ($s->{'id'} == $in{'host'} || !$s->{'id'} && !defined($in{'host'}))) { $checkon = $s; $checkonh = $h; } } } } # Get the details from this host, or the first in the list if (!$checkon) { $checkonh = $goth[0]; $checkon = $got[0]; } #&remote_foreign_require($checkon->{'host'}, "software", "software-lib.pl"); #@pinfo = &remote_foreign_call($checkon->{'host'}, "software", "package_info", # $in{'package'}); # Show module/theme details print "\n"; print "\n"; print "
",&text("edit_header_$type", &server_name($checkon)), "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; if ($type eq 'mod') { # Show details of module foreach $m (@{$checkonh->{'modules'}}) { $modmap{$m->{'dir'}} = $m; foreach $d (split(/\s+/, $m->{'depends'})) { push(@{$ondeps{$d}}, $m); } } &read_file("$config_directory/webmin.catnames", \%catnames); print "\n"; $c = $mod->{'category'}; print "\n"; print "\n"; if ($checkon->{'id'}) { print "\n"; } else { print "\n"; } # Show operating systems print "\n"; print "\n"; # Show which modules this module depends upon local @deps = grep { !/^[0-9\.]+$/ } split(/\s+/, $mod->{'depends'}); local @pdeps = split(/\s+/, $mod->{'perldepends'}); print "\n"; print "\n"; # Show which other modules depend on this one print "\n"; print "\n"; } else { # Show details of theme } print "
$text{'edit_desc'}",$mod->{'desc'},"$text{'edit_ver'}",$mod->{'version'} ? $mod->{'version'} : $text{'edit_nover'},"
$text{'edit_cat'}",$catname{$c} ? $catname{$c} : $text{"category_$c"} ? $text{"category_$c"} : $text{"category_"},"$text{'edit_dir'}{'dir'}/'>$mod->{'dir'}
$mod->{'dir'}", "
$text{'edit_os'}\n"; $oss = $mod->{'os_support'}; if (!$oss) { print $text{'edit_osall'}; } else { open(OSLIST, "$root_directory/os_list.txt"); while() { chop; if (/^([^\t]+)\t+([^\t]+)\t+(\S+)\t+(\S+)\t*(.*)$/) { $osname{$3} = $1 if (!$osname{$3}); } } close(OSLIST); while(1) { local ($os, $ver, $codes); if ($oss =~ /^([^\/\s]+)\/([^\{\s]+)\{([^\}]*)\}\s*(.*)$/) { $os = $1; $ver = $2; $codes = $3; $oss = $4; } elsif ($oss =~ /^([^\/\s]+)\/([^\/\s]+)\s*(.*)$/) { $os = $1; $ver = $2; $oss = $3; } elsif ($oss =~ /^([^\{\s]+)\{([^\}]*)\}\s*(.*)$/) { $os = $1; $codes = $2; $oss = $3; } elsif ($oss =~ /^\{([^\}]*)\}\s*(.*)$/) { $codes = $1; $oss = $2; } elsif ($oss =~ /^(\S+)\s*(.*)$/) { $os = $1; $oss = $2; } else { last; } print " , \n" if ($doneone++); $osn = $osname{$os} ? $osname{$os} : $os; $osn =~ s/\s/ /g; if ($ver) { print "$osn $ver"; } elsif ($os) { print "$osn"; } if ($codes) { $codes =~ s/\s/ /g; if ($os) { print " (",&text('edit_codes', "$codes"),")"; } else { print &text('edit_codes', "$codes"); } } } } print "
$text{'edit_deps'}\n"; if (@deps || @pdeps) { foreach $d (@deps) { local $mm = $modmap{$d}; print $mm->{'desc'}," ($mm->{'dir'})
\n"; } foreach $d (@pdeps) { print &text('edit_pdep', "$d"),"
\n"; } } else { print "$text{'edit_nodeps'}\n"; } print "
$text{'edit_ondeps'}\n"; if ($ondeps{$mod->{'dir'}}) { foreach $d (@{$ondeps{$mod->{'dir'}}}) { print $d->{'desc'}," ($d->{'dir'})
\n"; } } else { print "$text{'edit_nodeps'}\n"; } print "

\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; if ($type eq 'mod') { # Show user/group ACL selector print "\n"; print "\n"; print "{'id'}\">\n"; print "\n"; } print "
\n"; print "
\n"; print "
\n"; # Show hosts with the module or theme print "


\n"; print "

$text{'edit_hosts'}

\n"; @icons = map { "/servers/images/$_->{'type'}.gif" } @got; @links = map { "edit_host.cgi?id=$_->{'id'}" } @got; @titles = map { &server_name($_) } @got; &icons_table(\@links, \@titles, \@icons); &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/delete_host.cgi0100775000567100000120000000037610115014176016471 0ustar jcameronwheel#!/usr/local/bin/perl # delete_host.cgi # Remove a managed host from the list require './cluster-webmin-lib.pl'; &ReadParse(); @hosts = &list_webmin_hosts(); ($host) = grep { $_->{'id'} == $in{'id'} } @hosts; &delete_webmin_host($host); &redirect(""); cluster-webmin/delete_mod.cgi0100775000567100000120000001026710115014232016264 0ustar jcameronwheel#!/usr/local/bin/perl # delete_mod.cgi # Delete a module from one or all servers, after asking for confirmation require './cluster-webmin-lib.pl'; &ReadParse(); @servers = &list_servers(); @hosts = &list_webmin_hosts(); if ($in{'server'} < 0) { # Find servers that have the module or theme foreach $h (@hosts) { foreach $m (@{$h->{'modules'}}, @{$h->{'themes'}}) { if ($m->{'dir'} eq $in{'mod'}) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; push(@got, $s); $gotmap{$s} = $h; $best = $s if (!$s->{'id'}); last; } } } $s = $best ? $best : $got[0]; } else { ($s) = grep { $_->{'id'} == $in{'server'} } @servers; ($h) = grep { $_->{'id'} == $in{'server'} } @hosts; @got = ( $s ); $gotmap{$s} = $h; } $h = $gotmap{$s}; foreach $m ($in{'type'} eq 'mod' ? @{$h->{'modules'}} : @{$h->{'themes'}}) { $info = $m if ($m->{'dir'} eq $in{'mod'}); } # Setup error handler for down hosts sub del_error { $del_error_msg = join("", @_); } &remote_error_setup(\&del_error); &remote_foreign_require($s->{'host'}, "webmin", "webmin-lib.pl"); &ui_print_header(undef, $text{'delete_title'}, ""); if ($in{'sure'}) { # do the deletion in separate processes print "
",&text("delete_header_$in{'type'}", $info->{'desc'}),"

\n"; $p = 0; foreach $g (@got) { local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); local $h = $gotmap{$g}; # Check for any dependencies on this host foreach $m (@{$h->{'modules'}}) { foreach $d (split(/\s+/, $m->{'depends'})) { push(@{$ondeps{$d}}, $m); } } if ($ondeps{$in{'mod'}}) { print $wh &serialise_variable([ 0, &text('delete_edepends', join(", ", map { $_->{'desc'} } @{$ondeps{$in{'mod'}}})) ]); exit; } # Delete the module &remote_foreign_require($g->{'host'}, "webmin", "webmin-lib.pl") if ($s ne $g); &remote_foreign_require($g->{'host'}, "acl", "acl-lib.pl"); local $desc = &remote_foreign_call($g->{'host'}, "webmin", "delete_webmin_module", $in{'mod'}, $in{'acls'}); if ($del_error_msg) { print $wh &serialise_variable([ 0, $del_error_msg ]); } elsif ($desc) { print $wh &serialise_variable([ 1, $desc ]); } else { print $wh &serialise_variable([ 0, $text{'delete_egone'} ]); } # Re-request all users and groups from the server local @newmods = grep { $_->{'dir'} ne $in{'mod'} } @{$h->{'modules'}}; local @newthemes = grep { $_->{'dir'} ne $in{'mod'} } @{$h->{'themes'}}; $h->{'modules'} = \@newmods; $h->{'themes'} = \@newthemes; $h->{'users'} = [ &remote_foreign_call($g->{'host'}, "acl", "list_users") ]; $h->{'groups'} = [ &remote_foreign_call($g->{'host'}, "acl", "list_groups") ]; &save_webmin_host($h); close($wh); exit; } close($wh); $p++; } # Read back the results $p = 0; foreach $g (@got) { local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); local $d = &server_name($g); if (!$rv->[0]) { print &text('delete_error', $d, $rv->[1]),"
\n"; } else { print &text('delete_success', $d, $rv->[1]),"
\n"; } $p++; } print "

$text{'delete_done'}

\n"; } else { # Ask if the user is sure.. $rroot = &remote_eval($s->{'host'}, "webmin", '$root_directory'); $sz = &remote_foreign_call($s->{'host'}, "webmin", "disk_usage_kb", "$rroot/$in{'mod'}"); print "

\n"; if ($in{'server'} < 0) { print &text("delete_rusure_$in{'type'}", "$info->{'desc'}", $sz),"

\n"; } else { print &text("delete_rusure2_$in{'type'}", "$info->{'desc'}", $sz, &server_name($s)),"

\n"; } print "

\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print " $text{'delete_acls'}\n"; print "
\n"; } &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/create_group.cgi0100775000567100000120000000616510115014212016642 0ustar jcameronwheel#!/usr/local/bin/perl # create_group.cgi # Create a new Webmin group across multiple servers require './cluster-webmin-lib.pl'; &ReadParse(); &error_setup($text{'group_err1'}); @hosts = &list_webmin_hosts(); # Validate inputs $in{'name'} =~ /^[A-z0-9\-\_\.]+$/ || &error(&text('user_ename', $in{'name'})); # Setup error handler for down hosts sub group_error { $group_error_msg = join("", @_); } &remote_error_setup(\&group_error); # Work out which hosts to create on &ui_print_header(undef, $text{'group_title1'}, ""); foreach $h (@hosts) { local ($alr) = grep { $_->{'name'} eq $in{'name'} } @{$h->{'groups'}}; push(@already, $h) if ($alr); } @hosts = &create_on_parse('group_doing', \@already, $in{'name'}); foreach $h (@hosts) { foreach $ug (@{$h->{'users'}}, @{$h->{'groups'}}) { $taken{$ug->{'name'}}++; } } $taken{$in{'name'}} && &error(&text('user_etaken', $in{'name'})); @servers = &list_servers(); $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); if ($group_error_msg) { # Host is down print $wh &serialise_variable([ 0, $group_error_msg ]); exit; } # Create the group local %newgrp = ( 'name', $in{'name'} ); local @mods = ( split(/\0/, $in{'mods1'}), split(/\0/, $in{'mods2'}), split(/\0/, $in{'mods3'}) ); if ($in{'group'}) { # Add group to the chosen group ($group) = grep { $_->{'name'} eq $in{'group'} } @{$h->{'groups'}}; if (!$group) { # Doesn't exist on this server print $wh &serialise_variable( [ 0, $text{'user_egroup'} ]); exit; } push(@{$group->{'members'}}, $newgrp{'name'}); &remote_foreign_call($s->{'host'}, "acl", "modify_group", $group->{'name'}, $group); # Add modules from group local @ownmods; foreach $m (@mods) { push(@ownmods, $m) if (&indexof($m, @{$group->{'modules'}}) < 0); } @mods = &unique(@mods, @{$group->{'modules'}}); $newgrp{'ownmods'} = \@ownmods; # Copy ACL files for group &remote_foreign_call($s->{'host'}, "acl", "copy_acl_files", $group->{'name'}, $newgrp{'name'}, [ @{$group->{'modules'}}, "" ]); } $newgrp{'modules'} = \@mods; &remote_foreign_call($s->{'host'}, "acl", "create_group", \%newgrp); push(@{$h->{'groups'}}, \%newgrp); &save_webmin_host($h); # Restart the remote webmin print $wh &serialise_variable([ 1 ]); &remote_foreign_call($s->{'host'}, "acl", "restart_miniserv"); exit; } close($wh); $p++; } # Read back the results $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); if ($rv && $rv->[0] == 1) { # It worked print &text('group_success', $d),"
\n"; } else { # Something went wrong print &text('group_failed', $d, $rv->[1]),"
\n"; } $p++; } print "

$text{'group_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/user_form.cgi0100775000567100000120000001057110116530042016165 0ustar jcameronwheel#!/usr/local/bin/perl # user_form.cgi # Display a form for adding a new webmin user to all servers require './cluster-webmin-lib.pl'; &ui_print_header(undef, $text{'user_title1'}, ""); @hosts = &list_webmin_hosts(); @mods = &all_modules(\@hosts); @themes = &all_themes(\@hosts); @wgroups = &all_groups(\@hosts); print "

\n"; print "\n"; print "\n"; print "
$text{'user_header1'}
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; $mp = int((scalar(@mods)+2)/3); print "\n"; &create_on_input($text{'user_servers'}); print "
$text{'user_name'}$text{'user_group'}
$text{'user_pass'} \n"; print "
$text{'user_lang'} \n"; print "$text{'user_theme'} \n"; print "
$text{'user_ips'}\n"; print "\n"; print "\n"; print "
", "$text{'user_allips'}
\n"; print " $text{'user_allow'}
\n"; print " $text{'user_deny'}
$text{'user_mods'}
", "$text{'user_groupmods'}
\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "$text{'user_sall'} \n"; print "$text{'user_snone'} \n"; print "$text{'user_sinvert'}
\n"; print "

\n"; print "
\n"; &ui_print_footer("", $text{'index_return'}); cluster-webmin/create_user.cgi0100775000567100000120000000761210115014215016465 0ustar jcameronwheel#!/usr/local/bin/perl # create_user.cgi # Create a new Webmin user across multiple servers require './cluster-webmin-lib.pl'; &ReadParse(); &error_setup($text{'user_err1'}); @hosts = &list_webmin_hosts(); # Validate inputs $in{'name'} =~ /^[A-z0-9\-\_\.]+$/ || &error(&text('user_ename', $in{'name'})); $in{'pass_def'} == 0 && $in{'pass'} =~ /:/ && &error($text{'user_ecolon'}); if ($in{'ipmode'} > 0) { @ips = split(/\s+/, $in{'ips'}); } # Setup error handler for down hosts sub user_error { $user_error_msg = join("", @_); } &remote_error_setup(\&user_error); # Work out which hosts to create on &ui_print_header(undef, $text{'user_title1'}, ""); foreach $h (@hosts) { local ($alr) = grep { $_->{'name'} eq $in{'name'} } @{$h->{'users'}}; push(@already, $h) if ($alr); } @hosts = &create_on_parse('user_doing', \@already, $in{'name'}); foreach $h (@hosts) { foreach $ug (@{$h->{'users'}}, @{$h->{'groups'}}) { $taken{$ug->{'name'}}++; } } $taken{$in{'name'}} && &error(&text('user_etaken', $in{'name'})); # Create the user on all servers #print "",&text('user_doing', $in{'name'}),"

\n"; @servers = &list_servers(); $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); if ($user_error_msg) { # Host is down print $wh &serialise_variable([ 0, $user_error_msg ]); exit; } # Create the user local %user = ( 'name', $in{'name'} ); if ($in{'lang'}) { $user{'lang'} = $in{'lang'}; } if ($in{'theme'}) { $user{'theme'} = $in{'theme'} eq 'webmin' ? undef : $in{'theme'}; } if ($in{'ipmode'} == 1) { $user{'allow'} = join(" ", @ips); } elsif ($in{'ipmode'} == 2) { $user{'deny'} = join(" ", @ips); } if ($in{'pass_def'} == 0) { $salt = chr(int(rand(26))+65).chr(int(rand(26))+65); $user{'pass'} = crypt($in{'pass'}, $salt); } elsif ($in{'pass_def'} == 3) { $user{'pass'} = 'x'; } elsif ($in{'pass_def'} == 4) { $user{'pass'} = '*LK*'; } $user{'sync'} = 0; local @mods = ( split(/\0/, $in{'mods1'}), split(/\0/, $in{'mods2'}), split(/\0/, $in{'mods3'}) ); if ($in{'group'}) { # Add user to the chosen group ($group) = grep { $_->{'name'} eq $in{'group'} } @{$h->{'groups'}}; if (!$group) { # Doesn't exist on this server print $wh &serialise_variable( [ 0, $text{'user_egroup'} ]); exit; } push(@{$group->{'members'}}, $user{'name'}); &remote_foreign_call($s->{'host'}, "acl", "modify_group", $group->{'name'}, $group); # Add modules from group local @ownmods; foreach $m (@mods) { push(@ownmods, $m) if (&indexof($m, @{$group->{'modules'}}) < 0); } @mods = &unique(@mods, @{$group->{'modules'}}); $user{'ownmods'} = \@ownmods; # Copy ACL files for group &remote_foreign_call($s->{'host'}, "acl", "copy_acl_files", $group->{'name'}, $user{'name'}, [ @{$group->{'modules'}}, "" ]); } $user{'modules'} = \@mods; &remote_foreign_call($s->{'host'}, "acl", "create_user", \%user); push(@{$h->{'users'}}, \%user); &save_webmin_host($h); # Restart the remote webmin print $wh &serialise_variable([ 1 ]); &remote_foreign_call($s->{'host'}, "acl", "restart_miniserv"); exit; } close($wh); $p++; } # Read back the results $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); if ($rv && $rv->[0] == 1) { # It worked print &text('user_success', $d),"
\n"; } else { # Something went wrong print &text('user_failed', $d, $rv->[1]),"
\n"; } $p++; } print "

$text{'user_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/config.info0100644000567100000120000000010107541470754015626 0ustar jcameronwheelsort_mode=Sort hosts by,1,1-Hostname,0-Order added,2-Description cluster-webmin/edit_acl.cgi0100775000567100000120000001030310115014266015725 0ustar jcameronwheel#!/usr/local/bin/perl # edit_acl.cgi # Display a form for editing the ACL for some module for some user or group require './cluster-webmin-lib.pl'; &ReadParse(); # Get hosts and module details @hosts = &list_webmin_hosts(); if ($in{'whohost'} =~ /^(\d+),(\S*)$/) { # Coming from the module page, so know which host to look at ($host) = grep { $_->{'id'} == $1 } @hosts; local ($u) = grep { $_->{'name'} eq $2 } @{$host->{'users'}}; local ($g) = grep { $_->{'name'} eq $2 } @{$host->{'groups'}}; $user = $u if ($u); $group = $g if ($g); ($mod) = grep { $_->{'dir'} eq $in{'mod'} } @{$host->{'modules'}}; } elsif ($in{'modhost'} =~ /^(\d+),(\S*)$/) { # Coming from the user or group page, so know which host to look at ($host) = grep { $_->{'id'} == $1 } @hosts; ($mod) = grep { $_->{'dir'} eq $2 } @{$host->{'modules'}}; if ($in{'user'}) { ($user) = grep { $_->{'name'} eq $in{'user'} } @{$host->{'users'}}; } else { ($group) = grep { $_->{'name'} eq $in{'group'} } @{$host->{'groups'}}; } } else { # Find a host that has the user and module foreach $h (sort { $a->{'id'} <=> $b->{'id'} } @hosts) { local ($m) = grep { $_->{'dir'} eq $in{'mod'} } @{$h->{'modules'}}; if ($in{'user'}) { local ($u) = grep { $_->{'name'} eq $in{'user'} } @{$h->{'users'}}; if ($u && (&indexof($in{'mod'}, @{$u->{'modules'}}) >= 0 || !$in{'mod'})) { $user = $u; $host = $h; $mod = $m; last; } } else { local ($g) = grep { $_->{'name'} eq $in{'group'} } @{$h->{'groups'}}; if ($g && (&indexof($in{'mod'}, @{$g->{'modules'}}) >= 0 || !$in{'mod'})) { $group = $g; $host = $h; $mod = $m; last; } } } $host || &error(&text('acl_efound', $in{'user'} ? $in{'user'} : $in{'group'}, $in{'mod'})); } $who = $user ? $user->{'name'} : $group->{'name'}; @servers = &list_servers(); ($serv) = grep { $_->{'id'} == $host->{'id'} } @servers; $d = &server_name($serv); $ga = "_ga" if (!$mod->{'dir'}); $desc = &text($user ? 'acl_title2'.$ga : 'acl_title3'.$ga, "$who", "$mod->{'desc'}", "$d"); &ui_print_header($desc, $text{'acl_title'}, ""); # Get the host's ACL options &remote_foreign_require($serv->{'host'}, "acl", "acl-lib.pl"); $aref = &remote_eval($serv->{'host'}, "acl", "\%rv = &get_module_acl('$who', '$mod->{'dir'}'); \\%rv"); %access = %$aref; # Display the editor form from this host print "

\n"; print "\n"; print "\n"; if ($in{'group'}) { print "\n"; } else { print "\n"; } print "\n"; print "\n"; print "
", $mod->{'dir'} ? &text('acl_options', $mod->{'desc'}, &server_name($serv)) : &text('acl_optionsg', &server_name($serv)), "
\n"; if ($mod->{'dir'}) { print "\n", $access{'noconfig'} ? "checked" : ""; print "\n"; } if (!-d "$root_directory/$mod->{'dir'}") { # This server doesn't have the module .. use text editor print "\n" if ($mod->{'dir'}); print "\n"; } elsif (-r "$root_directory/$mod->{'dir'}/acl_security.pl") { print "\n" if ($mod->{'dir'}); &foreign_require($mod->{'dir'}, "acl_security.pl"); &foreign_call($mod->{'dir'}, "acl_security_form", \%access); } print "
$text{'acl_config'} \n"; printf " $text{'yes'}\n", $access{'noconfig'} ? "" : "checked"; printf " $text{'no'}

$text{'acl_raw'}
\n"; print "

\n"; print "\n"; print "\n"; print "
\n"; &ui_print_footer("", $text{'index_return'}); cluster-webmin/config0100664000567100000120000000001407503274273014675 0ustar jcameronwheelsort_mode=0 cluster-webmin/edit_user.cgi0100775000567100000120000002077110116530032016151 0ustar jcameronwheel#!/usr/local/bin/perl # edit_user.cgi # Display details of an existing user for changing require './cluster-webmin-lib.pl'; &ReadParse(); &ui_print_header(undef, $text{'user_title2'}, ""); @hosts = &list_webmin_hosts(); @mods = &all_modules(\@hosts); @themes = &all_themes(\@hosts); @wgroups = &all_groups(\@hosts); @servers = &list_servers(); if ($in{'host'} ne '') { ($host) = grep { $_->{'id'} == $in{'host'} } @hosts; ($user) = grep { $_->{'name'} eq $in{'user'} } @{$host->{'users'}}; } else { foreach $h (@hosts) { local ($u) = grep { $_->{'name'} eq $in{'user'} } @{$h->{'users'}}; if ($u) { $host = $h; $user = $u; last; } } } ($serv) = grep { $_->{'id'} == $host->{'id'} } @servers; foreach $h (@hosts) { local ($u) = grep { $_->{'name'} eq $in{'user'} } @{$h->{'users'}}; if ($u) { push(@got, grep { $_->{'id'} == $h->{'id'} } @servers); } } print "
\n"; print "\n"; print "{'id'}\">\n"; print "\n"; print "\n"; print "
",&text('user_header2', &server_name($serv)), "
\n"; print "\n"; printf "\n", $user->{'name'}; foreach $g (@{$host->{'groups'}}) { if (&indexof($user->{'name'}, @{$g->{'members'}}) >= 0) { $group = $g; last; } } print "\n"; print "\n"; @langs = &list_languages(); %langdesc = map { $_->{'lang'}, $_->{'desc'} } @langs; print "\n"; %themedesc = map { $_->{'dir'}, $_->{'desc'} } @themes; print "\n"; print "\n"; print "\n"; $mp = int((scalar(@mods)+2)/3); @umods = $group ? @{$user->{'ownmods'}} : @{$user->{'modules'}}; map { $umods{$_}++ } @umods; print "\n"; print "
$text{'user_name'}
$text{'user_group'} \n"; printf " %s (%s)\n", $text{'user_leave'}, $group ? $group->{'name'} : $text{'user_nogroup2'}; printf " %s\n", $text{'user_set'}; print "
$text{'user_pass'} \n"; print "
$text{'user_lang'} \n"; printf " %s (%s)\n", $text{'user_leave'}, $user->{'lang'} ? $langdesc{$user->{'lang'}} : $text{'user_default'}; printf " %s\n", $text{'user_set'}; print "
$text{'user_theme'} \n"; printf " %s (%s)\n", $text{'user_leave'}, $user->{'theme'} ? $themedesc{$user->{'theme'}} : !defined($user->{'theme'}) ? $text{'user_default'} : $text{'user_themedef'}; printf " %s\n", $text{'user_set'}; print "
$text{'user_ips'}\n"; print " $text{'user_leave'}\n"; if ($user->{'allow'}) { print "($text{'user_allow2'} $user->{'allow'})\n"; } elsif ($user->{'deny'}) { print "($text{'user_deny2'} $user->{'deny'})\n"; } else { print "($text{'user_allowall'})\n"; } print "\n"; print "\n"; print "
\n"; print " $text{'user_allips'}
\n"; print " $text{'user_allow'}
\n"; print " $text{'user_deny'}
$text{'user_mods'}
", "$text{'user_groupmods'}
\n"; print " ", &text('user_mleave', scalar(@umods)),"
\n"; print " $text{'user_modsel'}\n"; print " $text{'user_modadd'}\n"; print " $text{'user_moddel'}\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "$text{'user_sall'} \n"; print "$text{'user_snone'} \n"; print "$text{'user_sinvert'}
\n"; print "
\n"; print "\n"; print "\n"; %mdesc = map { $_->{'dir'}, $_->{'desc'} } @mods; foreach $h (@hosts) { local %ingroup; foreach $g (@{$h->{'groups'}}) { map { $ingroup{$_}++ } @{$g->{'members'}}; } local ($u) = grep { $_->{'name'} eq $in{'user'} } @{$h->{'users'}}; next if (!$u); local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); $sel .= "\n"; } print "\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "
\n"; # Show hosts with the user print "
\n"; print "

$text{'user_hosts'}

\n"; @icons = map { "/servers/images/$_->{'type'}.gif" } @got; @links = map { "edit_host.cgi?id=$_->{'id'}" } @got; @titles = map { &server_name($_) } @got; &icons_table(\@links, \@titles, \@icons); &ui_print_footer("", $text{'index_return'}); cluster-webmin/delete_user.cgi0100775000567100000120000000423710115014236016467 0ustar jcameronwheel#!/usr/local/bin/perl # delete_user.cgi # Delete a webmin user across all servers require './cluster-webmin-lib.pl'; &ReadParse(); &ui_print_header(undef, $text{'udelete_title'}, ""); print "",&text('udelete_doing', $in{'user'}),"

\n"; # Setup error handler for down hosts sub user_error { $user_error_msg = join("", @_); } &remote_error_setup(\&user_error); # Delete the user on all servers that have him foreach $h (&list_webmin_hosts()) { foreach $u (@{$h->{'users'}}) { if ($u->{'name'} eq $in{'user'}) { push(@hosts, $h); last; } } } @servers = &list_servers(); $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); if ($user_error_msg) { # Host is down print $wh &serialise_variable([ 0, $user_error_msg ]); exit; } # Delete the user &remote_foreign_call($s->{'host'}, "acl", "delete_user", $in{'user'}); $h->{'users'} = [ grep { $_->{'name'} ne $in{'user'} } @{$h->{'users'}} ]; # Remove from any groups foreach $g (@{$h->{'groups'}}) { local @mems = @{$g->{'members'}}; local $i = &indexof($in{'user'}, @mems); if ($i >= 0) { splice(@mems, $i, 1); $g->{'members'} = \@mems; &remote_foreign_call($s->{'host'}, "acl", "modify_group", $g->{'name'}, $g); } } &save_webmin_host($h); # Restart the remote webmin print $wh &serialise_variable([ 1 ]); &remote_foreign_call($s->{'host'}, "acl", "restart_miniserv"); exit; } close($wh); $p++; } # Read back the results $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); if ($rv && $rv->[0] == 1) { # It worked print &text('udelete_success', $d),"
\n"; } else { # Something went wrong print &text('udelete_failed', $d, $rv->[1]),"
\n"; } $p++; } print "

$text{'udelete_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/delete_group.cgi0100775000567100000120000000634710115014227016651 0ustar jcameronwheel#!/usr/local/bin/perl # delete_group.cgi # Delete a webmin group across all servers require './cluster-webmin-lib.pl'; &ReadParse(); &ui_print_header(undef, $text{'gdelete_title'}, ""); # Find groups and members on all hosts foreach $h (&list_webmin_hosts()) { foreach $g (@{$h->{'groups'}}) { if ($g->{'name'} eq $in{'group'}) { push(@hosts, $h); push(@mems, @{$g->{'members'}}); foreach $m (@{$g->{'members'}}) { $onhost{$h,$m}++; ($mg) = grep { $_->{'name'} eq $m } @{$h->{'groups'}}; push(@subs, $mg->{'name'}) if ($mg); } last; } } } @mems = &unique(@mems); if (@subs) { print &text('gdelete_esub', "".join(" ", &unique(@subs)).""),"

\n"; &ui_print_footer("", $text{'index_return'}); exit; } if (!$in{'confirm'} && @mems) { # Ask if the user really wants to delete the group and members print "

\n"; print "\n"; print &text('gdelete_desc', "$in{'group'}", "".join(" ", @mems).""),"

\n"; print "\n"; print "

\n"; &ui_print_footer("", $text{'index_return'}); exit; } print "",&text('gdelete_doing', $in{'group'}),"

\n"; # Setup error handler for down hosts sub group_error { $group_error_msg = join("", @_); } &remote_error_setup(\&group_error); @servers = &list_servers(); $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); if ($group_error_msg) { # Host is down print $wh &serialise_variable([ 0, $group_error_msg ]); exit; } # Delete the group &remote_foreign_call($s->{'host'}, "acl", "delete_group", $in{'group'}); $h->{'groups'} = [ grep { $_->{'name'} ne $in{'group'} } @{$h->{'groups'}} ]; # Remove from any groups foreach $g (@{$h->{'groups'}}) { local @mems = @{$g->{'members'}}; local $i = &indexof($in{'group'}, @mems); if ($i >= 0) { splice(@mems, $i, 1); $g->{'members'} = \@mems; &remote_foreign_call($s->{'host'}, "acl", "modify_group", $g->{'name'}, $g); } } # Delete any members foreach $u (grep { $onhost{$h,$_} } @mems) { &remote_foreign_call($s->{'host'}, "acl", "delete_user", $u); $h->{'users'} = [ grep { $_->{'name'} ne $u } @{$h->{'users'}} ]; } &save_webmin_host($h); # Restart the remote webmin print $wh &serialise_variable([ 1 ]); &remote_foreign_call($s->{'host'}, "acl", "restart_miniserv"); exit; } close($wh); $p++; } # Read back the results $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); if ($rv && $rv->[0] == 1) { # It worked print &text('gdelete_success', $d),"
\n"; } else { # Something went wrong print &text('gdelete_failed', $d, $rv->[1]),"
\n"; } $p++; } print "

$text{'gdelete_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/save_user.cgi0100775000567100000120000001211410115014361016153 0ustar jcameronwheel#!/usr/local/bin/perl # save_user.cgi # Update a webmin user on all servers require './cluster-webmin-lib.pl'; &ReadParse(); &ui_print_header(undef, $text{'user_title2'}, ""); print "",&text('user_doing2', $in{'old'}),"

\n"; @allhosts = &list_webmin_hosts(); foreach $h (@allhosts) { foreach $ug (@{$h->{'users'}}, @{$h->{'groups'}}) { $taken{$ug->{'name'}}++; } } # Validate inputs $in{'name'} =~ /^[A-z0-9\-\_\.]+$/ || &error(&text('user_ename', $in{'name'})); $in{'name'} ne $in{'old'} && $taken{$in{'name'}} && &error(&text('user_etaken', $in{'name'})); $in{'pass_def'} == 0 && $in{'pass'} =~ /:/ && &error($text{'user_ecolon'}); if ($in{'ipmode'} > 0) { @ips = split(/\s+/, $in{'ips'}); } # Setup error handler for down hosts sub user_error { $user_error_msg = join("", @_); } &remote_error_setup(\&user_error); # Update the user on all servers that have him foreach $h (@allhosts) { foreach $u (@{$h->{'users'}}) { if ($u->{'name'} eq $in{'old'}) { push(@hosts, $h); last; } } } @servers = &list_servers(); $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); if ($user_error_msg) { # Host is down print $wh &serialise_variable([ 0, $user_error_msg ]); exit; } # Update the user ($user) = grep { $_->{'name'} eq $in{'old'} } @{$h->{'users'}}; $user->{'name'} = $in{'name'}; if (!$in{'lang_def'}) { $user->{'lang'} = $in{'lang'} ? $in{'lang'} : undef; } if (!$in{'theme_def'}) { if ($in{'theme'} eq 'webmin') { delete($user->{'theme'}); } else { $user->{'theme'} = $in{'theme'}; } } if ($in{'ipmode'} == 0) { delete($user->{'allow'}); delete($user->{'deny'}); } elsif ($in{'ipmode'} == 1) { $user->{'allow'} = join(" ", @ips); delete($user->{'deny'}); } elsif ($in{'ipmode'} == 2) { delete($user->{'allow'}); $user->{'deny'} = join(" ", @ips); } if ($in{'pass_def'} == 0) { $salt = chr(int(rand(26))+65).chr(int(rand(26))+65); $user->{'pass'} = crypt($in{'pass'}, $salt); $user->{'sync'} = 0; } elsif ($in{'pass_def'} == 3) { $user->{'pass'} = 'x'; $user->{'sync'} = 0; } elsif ($in{'pass_def'} == 4) { $user->{'pass'} = '*LK*'; $user->{'sync'} = 0; } # Work out which modules the user has local @selmods = ( split(/\0/, $in{'mods1'}), split(/\0/, $in{'mods2'}), split(/\0/, $in{'mods3'}) ); local @mods = @{$user->{'modules'}}; if ($in{'mods_def'} == 2) { @mods = @selmods; } elsif ($in{'mods_def'} == 3) { @mods = &unique(@mods, @selmods); } elsif ($in{'mods_def'} == 0) { @mods = grep { &indexof($_, @selmods) < 0 } @mods; } # Update old and new groups foreach $g (@{$h->{'groups'}}) { if (&indexof($in{'old'}, @{$g->{'members'}}) >= 0) { $oldgroup = $g; } } if ($in{'group_def'}) { $group = $oldgroup; } else { ($group) = grep { $_->{'name'} eq $in{'group'} } @{$h->{'groups'}}; if (!$group && $in{'group'}) { print $wh &serialise_variable( [ 0, $text{'user_egroup'} ]); exit; } } if (($group ? $group->{'name'} : '') ne ($oldgroup ? $oldgroup->{'name'} : '')) { # Group has changed - update the member lists if ($oldgroup) { $oldgroup->{'members'} = [ grep { $_ ne $in{'old'} } @{$oldgroup->{'members'}} ]; &remote_foreign_call($s->{'host'}, "acl", "modify_group", $oldgroup->{'name'}, $oldgroup); } if ($group) { push(@{$group->{'members'}}, $in{'name'}); &remote_foreign_call($s->{'host'}, "acl", "modify_group", $group->{'name'}, $group); } } if ($oldgroup) { # Remove modules from the old group @mods = grep { &indexof($_, @{$oldgroup->{'modules'}}) < 0 } @mods; } @ownmods = ( ); if ($group) { # Add modules from new group foreach $m (@mods) { push(@ownmods, $m) if (&indexof($m, @{$group->{'modules'}}) < 0); } @mods = &unique(@mods, @{$group->{'modules'}}); &remote_foreign_call($s->{'host'}, "acl", "copy_acl_files", $group->{'name'}, $in{'old'}, [ @{$group->{'modules'}}, "" ]); } $user->{'modules'} = \@mods; $user->{'ownmods'} = \@ownmods; &remote_foreign_call($s->{'host'}, "acl", "modify_user", $in{'old'}, $user); &save_webmin_host($h); # Restart the remote webmin print $wh &serialise_variable([ 1 ]); &remote_foreign_call($s->{'host'}, "acl", "restart_miniserv"); exit; } close($wh); $p++; } # Read back the results $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); if ($rv && $rv->[0] == 1) { # It worked print &text('user_success2', $d),"
\n"; } else { # Something went wrong print &text('user_failed2', $d, $rv->[1]),"
\n"; } $p++; } print "

$text{'user_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/group_form.cgi0100775000567100000120000000577010115014307016350 0ustar jcameronwheel#!/usr/local/bin/perl # group_form.cgi # Display a form for adding a new webmin group to all servers require './cluster-webmin-lib.pl'; &ui_print_header(undef, $text{'user_title1'}, ""); @hosts = &list_webmin_hosts(); @mods = &all_modules(\@hosts); @wgroups = &all_groups(\@hosts); print "

\n"; print "\n"; print "\n"; print "
$text{'group_header1'}
\n"; print "\n"; print "\n"; print "\n"; print "\n"; $mp = int((scalar(@mods)+2)/3); print "\n"; &create_on_input($text{'group_servers'}); print "
$text{'group_name'}$text{'user_group'}
$text{'user_mods'}
", "$text{'user_groupmods'}
\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "$text{'user_sall'} \n"; print "$text{'user_snone'} \n"; print "$text{'user_sinvert'}
\n"; print "

\n"; print "
\n"; &ui_print_footer("", $text{'index_return'}); cluster-webmin/edit_group.cgi0100775000567100000120000001445710115014272016335 0ustar jcameronwheel#!/usr/local/bin/perl # edit_group.cgi # Display an existing Webmin group for editing require './cluster-webmin-lib.pl'; &ReadParse(); &ui_print_header(undef, $text{'group_title2'}, ""); @hosts = &list_webmin_hosts(); @mods = &all_modules(\@hosts); @wgroups = &all_groups(\@hosts); @servers = &list_servers(); if ($in{'host'} ne '') { ($host) = grep { $_->{'id'} == $in{'host'} } @hosts; ($edgrp) = grep { $_->{'name'} eq $in{'group'} } @{$host->{'groups'}}; } else { foreach $h (@hosts) { local ($g) =grep { $_->{'name'} eq $in{'group'} } @{$h->{'groups'}}; if ($g) { $host = $h; $edgrp = $g; last; } } } ($serv) = grep { $_->{'id'} == $host->{'id'} } @servers; foreach $h (@hosts) { local ($g) = grep { $_->{'name'} eq $in{'group'} } @{$h->{'groups'}}; if ($g) { push(@got, grep { $_->{'id'} == $h->{'id'} } @servers); } } print "
\n"; print "\n"; print "{'id'}\">\n"; print "\n"; print "\n"; print "
",&text('group_header2', &server_name($serv)), "
\n"; print "\n"; printf "\n", $edgrp->{'name'}; @gm = @{$edgrp->{'members'}}; print "\n"; print "\n"; foreach $g (@{$host->{'groups'}}) { if (&indexof($edgrp->{'name'}, @{$g->{'members'}}) >= 0) { $group = $g; last; } } print "\n"; $mp = int((scalar(@mods)+2)/3); @umods = $group ? @{$edgrp->{'ownmods'}} : @{$edgrp->{'modules'}}; map { $umods{$_}++ } @umods; print "\n"; print "
$text{'group_name'}
$text{'group_mems'}",@gm ? join(" ", @gm) : $text{'group_nomems'},"
$text{'group_group'} \n"; printf " %s (%s)\n", $text{'user_leave'}, $group ? $group->{'name'} : $text{'user_nogroup2'}; printf " %s\n", $text{'user_set'}; print "
$text{'group_mods'}
", "$text{'group_groupmods'}
\n"; print " ", &text('user_mleave', scalar(@umods)),"
\n"; print " $text{'user_modsel'}\n"; print " $text{'user_modadd'}\n"; print " $text{'user_moddel'}\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "$text{'user_sall'} \n"; print "$text{'user_snone'} \n"; print "$text{'user_sinvert'}
\n"; print "
\n"; print "\n"; print "\n"; %mdesc = map { $_->{'dir'}, $_->{'desc'} } @mods; foreach $h (@hosts) { local %ingroup; foreach $g (@{$h->{'groups'}}) { map { $ingroup{$_}++ } @{$g->{'members'}}; } local ($g) = grep { $_->{'name'} eq $in{'group'} } @{$h->{'groups'}}; next if (!$g); local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); $sel .= "\n"; } print "\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "
\n"; # Show hosts with the group print "
\n"; print "

$text{'group_hosts'}

\n"; @icons = map { "/servers/images/$_->{'type'}.gif" } @got; @links = map { "edit_host.cgi?id=$_->{'id'}" } @got; @titles = map { &server_name($_) } @got; &icons_table(\@links, \@titles, \@icons); &ui_print_footer("", $text{'index_return'}); cluster-webmin/config.info.ca0100644000567100000120000000012210067401515016175 0ustar jcameronwheelsort_mode=Ordena els hosts per,1,1-Nom de host,0-Ordre d'introducci,2-Descripci cluster-webmin/save_group.cgi0100775000567100000120000001105710115014356016342 0ustar jcameronwheel#!/usr/local/bin/perl # save_group.cgi # Update a webmin group on all servers require './cluster-webmin-lib.pl'; &ReadParse(); &ui_print_header(undef, $text{'group_title2'}, ""); print "",&text('group_doing2', $in{'old'}),"

\n"; @allhosts = &list_webmin_hosts(); foreach $h (@allhosts) { foreach $ug (@{$h->{'users'}}, @{$h->{'groups'}}) { $taken{$ug->{'name'}}++; } } # Validate inputs $in{'name'} =~ /^[A-z0-9\-\_\.]+$/ || &error(&text('group_ename', $in{'name'})); $in{'name'} ne $in{'old'} && $taken{$in{'name'}} && &error(&text('group_etaken', $in{'name'})); # Setup error handler for down hosts sub group_error { $group_error_msg = join("", @_); } &remote_error_setup(\&group_error); # Update the group on all servers that have it foreach $h (@allhosts) { foreach $g (@{$h->{'groups'}}) { if ($g->{'name'} eq $in{'old'}) { push(@hosts, $h); last; } } } @servers = &list_servers(); $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); if ($group_error_msg) { # Host is down print $wh &serialise_variable([ 0, $group_error_msg ]); exit; } # Update the user ($edgrp) = grep { $_->{'name'} eq $in{'old'} } @{$h->{'groups'}}; $edgrp->{'name'} = $in{'name'}; # Work out which modules the group has local @selmods = ( split(/\0/, $in{'mods1'}), split(/\0/, $in{'mods2'}), split(/\0/, $in{'mods3'}) ); local @mods = @{$edgrp->{'modules'}}; if ($in{'mods_def'} == 2) { @mods = @selmods; } elsif ($in{'mods_def'} == 3) { @mods = &unique(@mods, @selmods); } elsif ($in{'mods_def'} == 0) { @mods = grep { &indexof($_, @selmods) < 0 } @mods; } # Update old and new parent groups foreach $g (@{$h->{'groups'}}) { if (&indexof($in{'old'}, @{$g->{'members'}}) >= 0) { $oldgroup = $g; } } if ($in{'group_def'}) { $group = $oldgroup; } else { ($group) = grep { $_->{'name'} eq $in{'group'} } @{$h->{'groups'}}; if (!$group && $in{'group'}) { print $wh &serialise_variable( [ 0, $text{'group_egroup'} ]); exit; } } if (($group ? $group->{'name'} : '') ne ($oldgroup ? $oldgroup->{'name'} : '')) { # Parent group has changed - update the member lists if ($oldgroup) { $oldgroup->{'members'} = [ grep { $_ ne $in{'old'} } @{$oldgroup->{'members'}} ]; &remote_foreign_call($s->{'host'}, "acl", "modify_group", $oldgroup->{'name'}, $oldgroup); } if ($group) { push(@{$group->{'members'}}, $in{'name'}); &remote_foreign_call($s->{'host'}, "acl", "modify_group", $group->{'name'}, $group); } } if ($oldgroup) { # Remove modules from the old group @mods = grep { &indexof($_, @{$oldgroup->{'modules'}}) < 0 } @mods; } @ownmods = ( ); if ($group) { # Add modules from new group foreach $m (@mods) { push(@ownmods, $m) if (&indexof($m, @{$group->{'modules'}}) < 0); } @mods = &unique(@mods, @{$group->{'modules'}}); &remote_foreign_call($s->{'host'}, "acl", "copy_acl_files", $group->{'name'}, $in{'old'}, [ @{$group->{'modules'}}, "" ]); } $edgrp->{'modules'} = \@mods; $edgrp->{'ownmods'} = \@ownmods; &remote_foreign_call($s->{'host'}, "acl", "modify_group", $in{'old'}, $edgrp); # Recursively update all member users and groups &remote_foreign_call($s->{'host'}, "acl", "update_members", $h->{'users'}, $h->{'groups'}, $edgrp->{'modules'}, $edgrp->{'members'}); @freshusers = &remote_foreign_call($s->{'host'}, "acl", "list_users"); $h->{'users'} = \@freshusers; @freshgroups = &remote_foreign_call($s->{'host'}, "acl", "list_groups"); $h->{'groups'} = \@freshgroups; &save_webmin_host($h); # Restart the remote webmin print $wh &serialise_variable([ 1 ]); &remote_foreign_call($s->{'host'}, "acl", "restart_miniserv"); exit; } close($wh); $p++; } # Read back the results $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); if ($rv && $rv->[0] == 1) { # It worked print &text('group_success2', $d),"
\n"; } else { # Something went wrong print &text('group_failed2', $d, $rv->[1]),"
\n"; } $p++; } print "

$text{'group_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); cluster-webmin/save_acl.cgi0100775000567100000120000000661310115014352015743 0ustar jcameronwheel#!/usr/local/bin/perl # save_acl.cgi # Save the ACL for a module for a user or group require './cluster-webmin-lib.pl'; &ReadParse(); $who = $in{'_acl_user'} ? $in{'_acl_user'} : $in{'_acl_group'}; # Validate and parse inputs &error_setup($text{'acl_err'}); $maccess{'noconfig'} = $in{'noconfig'}; if (-r "../$in{'_acl_mod'}/acl_security.pl") { &foreign_require($in{'_acl_mod'}, "acl_security.pl"); if ($in{'_acl_mod'}) { eval "\%$in{'_acl_mod'}::in = \%in"; } else { %global::in = %in; } &foreign_call($in{'_acl_mod'}, "acl_security_save", \%maccess, \%in); } # Setup error handler for down hosts sub user_error { $user_error_msg = join("", @_); } &remote_error_setup(\&user_error); # Write out on all hosts, or just one host &ui_print_header(undef, $text{'acl_title'}, ""); @allhosts = &list_webmin_hosts(); @servers = &list_servers(); if ($in{'all'}) { # Doing on all hosts that the user has the module on foreach $h (@allhosts) { local $w; if ($in{'_acl_user'}) { ($w) = grep { $_->{'name'} eq $in{'_acl_user'} } @{$h->{'users'}}; } else { ($w) = grep { $_->{'name'} eq $in{'_acl_group'} } @{$h->{'groups'}}; } next if (!$w); local %ingroup; foreach $g (@{$h->{'groups'}}) { map { $ingroup{$_}++ } @{$g->{'members'}}; } local @m = $ingroup{$w->{'name'}} ? @{$w->{'ownmods'}} : @{$w->{'modules'}}; push(@hosts, $h) if (&indexof($in{'_acl_mod'}, @m) >= 0 || !$in{'_acl_mod'}); } print "",&text('acl_doing', $who),"

\n"; } else { # Doing on just one host @hosts = grep { $_->{'id'} == $in{'_acl_host'} } @allhosts; local ($s) = grep { $_->{'id'} == $hosts[0]->{'id'} } @servers; print "",&text('acl_doing2', $who, &server_name($s)),"

\n"; } $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); if (!fork()) { close($rh); &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); if ($user_error_msg) { # Host is down print $wh &serialise_variable([ 0, $user_error_msg ]); exit; } # Save the .acl file local $cd = &remote_eval($s->{'host'}, "acl", '$config_directory'); &remote_foreign_call($s->{'host'}, "acl", "write_file", "$cd/$in{'_acl_mod'}/$who.acl", \%maccess); # Recursively update the ACL for all member users and groups if ($in{'_acl_group'}) { local ($group) = grep { $_->{'name'} eq $in{'_acl_group'} } @{$h->{'groups'}}; &remote_foreign_call($s->{'host'}, "acl", "set_acl_files", $h->{'users'}, $h->{'groups'}, $in{'_acl_mod'}, $group->{'members'}, \%maccess); } print $wh &serialise_variable([ 1 ]); exit; } close($wh); $p++; } # Read back the results $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); local $rh = "READ$p"; local $line = <$rh>; local $rv = &unserialise_variable($line); close($rh); if ($rv && $rv->[0] == 1) { # It worked print &text('acl_success', $d),"
\n"; } else { # Something went wrong print &text('acl_failed', $d, $rv->[1]),"
\n"; } $p++; } print "

$text{'acl_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}, $in{'_acl_user'} ? ( "edit_user.cgi?user=$in{'_acl_user'}&host=$in{'_acl_host'}", $text{'user_return'} ) : ( "edit_group.cgi?group=$in{'_acl_group'}&host=$in{'_acl_host'}", $text{'group_return'} )); cluster-webmin/config.info.es0100644000567100000120000000007510067401523016227 0ustar jcameronwheelsort_mode=Clasificar mquinas por,1,1-Nombre,0-Orden aadido cluster-webmin/config.info.de0100664000567100000120000000007410067670022016213 0ustar jcameronwheelsort_mode=Sortiere Hosts nach,1,1-Hostname,0-wie hinzugefgtcluster-webmin/sync_form.cgi0100775000567100000120000000427410115014367016174 0ustar jcameronwheel#!/usr/local/bin/perl # sync_form.cgi # Display a form for creating some or all missing users and groups on # some or all servers require './cluster-webmin-lib.pl'; &ui_print_header(undef, $text{'sync_title'}, ""); print "$text{'sync_desc'}

\n"; print "

\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'sync_hosts'} \n"; print " ", "$text{'sync_hall'}\n"; print " ", "$text{'sync_hsel'}
\n"; print "
$text{'sync_users'} \n"; print " ", "$text{'sync_uall'}  \n"; print " ", "$text{'sync_unone'}
\n"; print " ", "$text{'sync_usel'}\n"; print "
\n"; print " ", "$text{'sync_unot'}\n"; print "
\n"; print "
$text{'sync_groups'} \n"; print " ", "$text{'sync_gall'}  \n"; print " ", "$text{'sync_gnone'}
\n"; print " ", "$text{'sync_gsel'}\n"; print "
\n"; print " ", "$text{'sync_gnot'}\n"; print "
\n"; print "
$text{'sync_test'} $text{'yes'}\n"; print " $text{'no'}
\n"; print "
\n"; &ui_print_footer("", $text{'index_return'}); cluster-webmin/sync.cgi0100775000567100000120000001006510115014364015141 0ustar jcameronwheel#!/usr/local/bin/perl # sync.cgi # Create missing users and groups on servers require './cluster-webmin-lib.pl'; &ReadParse(); @hosts = &list_webmin_hosts(); @servers = &list_servers(); &ui_print_header(undef, $text{'sync_title'}, ""); if ($in{'hosts_mode'} == 0) { # Limit to selected hosts map { $host{$_}++ } split(/\0/, $in{'hosts'}); @phosts = grep { $host{$_->{'id'}} } @hosts; } else { @phosts = @hosts; } # Build lists of all users and group foreach $h (@hosts) { local ($serv) = grep { $_->{'id'} == $h->{'id'} } @servers; foreach $u (@{$h->{'users'}}) { if (!$doneuser{$u->{'name'}}++) { push(@ulist, $u); $u->{'source'} = $serv; } } foreach $g (@{$h->{'groups'}}) { if (!$donegroup{$g->{'name'}}++) { push(@glist, $g); $g->{'source'} = $serv; } } } # Find users and groups to sync if ($in{'users_mode'} == 1) { @usync = @ulist; } elsif ($in{'users_mode'} == 2) { map { $usel{$_}++ } split(/\s+/, $in{'usel'}); @usync = grep { $usel{$_->{'name'}} } @ulist; } elsif ($in{'users_mode'} == 3) { map { $unot{$_}++ } split(/\s+/, $in{'unot'}); @usync = grep { !$unot{$_->{'name'}} } @ulist; } if ($in{'groups_mode'} == 1) { @gsync = @glist; } elsif ($in{'groups_mode'} == 2) { map { $gsel{$_}++ } split(/\s+/, $in{'gsel'}); @gsync = grep { $gsel{$_->{'name'}} } @glist; } elsif ($in{'groups_mode'} == 3) { map { $gnot{$_}++ } split(/\s+/, $in{'gnot'}); @gsync = grep { !$gnot{$_->{'name'}} } @glist; } # Setup error handler for down hosts sub add_error { $add_error_msg = join("", @_); } &remote_error_setup(\&add_error); # Sync on chosen hosts foreach $host (@phosts) { $add_error_msg = undef; local ($serv) = grep { $_->{'id'} == $host->{'id'} } @servers; print "",&text('sync_on', &server_name($serv)),"

\n"; print "

    \n"; # Find missing users and groups local (%usync, %gsync); map { $usync{$_->{'name'}}++ } @{$host->{'users'}}; map { $gsync{$_->{'name'}}++ } @{$host->{'groups'}}; local @uneed = grep { !$usync{$_->{'name'}} } @usync; local @gneed = grep { !$gsync{$_->{'name'}} } @gsync; if (@uneed || @gneed) { &remote_foreign_require($serv->{'host'}, "acl", "acl-lib.pl"); $done_require{$serv->{'host'}}++; if ($add_error_msg) { # Host is down! print "$add_error_msg

    \n"; print "

\n"; next; } # Create missing users foreach $u (@uneed) { # Create the user print &text('sync_ucreate', $u->{'name'}),"
\n"; if (!$in{'test'}) { &remote_foreign_call($serv->{'host'}, "acl", "create_user", $u); push(@{$host->{'users'}}, $u); } print "$text{'refresh_done'}

\n"; print &text('sync_acl', $u->{'name'}),"
\n"; ©_acls_for($u, $serv); print "$text{'refresh_done'}

\n"; } # Create missing groups foreach $g (@gneed) { print &text('sync_gcreate', $g->{'group'}),"
\n"; if (!$in{'test'}) { &remote_foreign_call($serv->{'host'}, "acl", "create_group", $g); push(@{$host->{'groups'}}, $g); } print "$text{'refresh_done'}

\n"; print &text('sync_acl', $g->{'name'}),"
\n"; ©_acls_for($g, $serv); print "$text{'refresh_done'}

\n"; } # Restart webmin print "$text{'sync_restart'}
\n"; if (!$in{'test'}) { &remote_foreign_call($serv->{'host'}, "acl", "restart_miniserv"); } print "$text{'refresh_done'}

\n"; # Update in local list &save_webmin_host($host); } else { print "$text{'sync_insync'}

\n"; } print "\n"; } &webmin_log("sync", undef, undef, \%in); &ui_print_footer("", $text{'index_return'}); # copy_acls_for(&user|&group, &server) # Copy all .acl files from the server on which a user or group does exist # to the given server sub copy_acls_for { local $source = $_[0]->{'source'}; &remote_foreign_require($source->{'host'}, "acl", "acl-lib.pl") if (!$done_require{$source->{'host'}}++); foreach $m (@{$_[0]->{'modules'}}) { local %acl = &remote_foreign_call($source->{'host'}, "acl", "get_module_acl", $_[0]->{'name'},$m); if (%acl) { &remote_foreign_call($_[1]->{'host'}, "acl", "save_module_acl", \%acl, $_[0]->{'name'}, $m); } } } cluster-webmin/CHANGELOG0100664000567100000120000000022110115216625014705 0ustar jcameronwheel---- Changes since 1.150 ---- Added the ability to create Webmin users and groups on one or several servers, rather than on all servers at once. cluster-webmin/upgrade.cgi0100775000567100000120000003261410115014403015612 0ustar jcameronwheel#!/usr/local/bin/perl # upgrade.cgi # Download webmin and upgrade all managed servers of compatible types require './cluster-webmin-lib.pl'; &foreign_require("proc", "proc-lib.pl"); &foreign_require("webmin", "webmin-lib.pl"); &foreign_require("webmin", "gnupg-lib.pl"); &ReadParseMime(); &ui_print_unbuffered_header(undef, $text{'upgrade_title'}, ""); # Save this CGI from being killed by the upgrade $SIG{'TERM'} = 'IGNORE'; if ($in{'source'} == 0) { # from local file &error_setup(&webmin::text('upgrade_err1', $in{'file'})); $file = $in{'file'}; if (!(-r $file)) { &inst_error($webmin::text{'upgrade_efile'}); } } elsif ($in{'source'} == 1) { # from uploaded file &error_setup($webmin::text{'upgrade_err2'}); $file = &tempname(); $need_unlink = 1; if ($no_upload) { &inst_error($webmin::text{'upgrade_ebrowser'}); } open(MOD, ">$file"); print MOD $in{'upload'}; close(MOD); } elsif ($in{'source'} == 2) { # find latest version at www.webmin.com by looking at index page &error_setup($webmin::text{'upgrade_err3'}); $file = &tempname(); &http_download($webmin::update_host, $webmin::update_port, '/', $file, \$error); $error && &inst_error($error); open(FILE, $file); while() { if (/webmin-([0-9\.]+)\.tar\.gz/) { $site_version = $1; last; } } close(FILE); unlink($file); if ($in{'mode'} eq 'rpm') { $progress_callback_url = "http://$webmin::update_host/download/rpm/webmin-$site_version-1.noarch.rpm"; &http_download($webmin::update_host, $webmin::update_port, "/download/rpm/webmin-$site_version-1.noarch.rpm", $file, \$error, \&progress_callback); } else { $progress_callback_url = "http://$webmin::update_host/download/webmin-$site_version.tar.gz"; &http_download($webmin::update_host, $webmin::update_port, "/download/webmin-$site_version.tar.gz", $file, \$error, \&progress_callback); } $error && &inst_error($error); $need_unlink = 1; } elsif ($in{'source'} == 5) { # Download from some URL &error_setup(&webmin::text('upgrade_err5', $in{'url'})); $file = &tempname(); $progress_callback_url = $in{'url'}; if ($in{'url'} =~ /^(http|https):\/\/([^\/]+)(\/.*)$/) { $ssl = $1 eq 'https'; $host = $2; $page = $3; $port = $ssl ? 443 : 80; if ($host =~ /^(.*):(\d+)$/) { $host = $1; $port = $2; } &http_download($host, $port, $page, $file, \$error, \&progress_callback, $ssl); } elsif ($in{'url'} =~ /^ftp:\/\/([^\/]+)(:21)?\/(.*)$/) { $host = $1; $ffile = $3; &ftp_download($host, $ffile, $file, \$error, \&progress_callback); } else { &inst_error($webmin::text{'upgrade_eurl'}); } $need_unlink = 1; $error && &inst_error($error); } # Import the signature for RPM if (&has_command("rpm")) { system("rpm --import $root_directory/webmin/jcameron-key.asc >/dev/null 2>&1"); } # Work out what kind of file we have (RPM or tar.gz) if (`rpm -qp $file 2>&1` =~ /(^|\n)webmin-(\d+\.\d+)/) { # Looks like a webmin RPM $mode = "rpm"; $version = $2; } else { # Check if it is a webmin tar.gz file open(TAR, "gunzip -c $file | tar tf - 2>&1 |"); while() { s/\r|\n//g; if (/^webmin-([0-9\.]+)\//) { $version = $1; } if (/^usermin-([0-9\.]+)\//) { $usermin_version = $1; } if (/^[^\/]+\/(\S+)$/) { $hasfile{$1}++; } if (/^(webmin-([0-9\.]+)\/[^\/]+)$/) { push(@topfiles, $1); } elsif (/^webmin-[0-9\.]+\/([^\/]+)\//) { $intar{$1}++; } } close(TAR); if ($usermin_version) { &inst_error(&webmin::text('upgrade_eusermin',$usermin_version)); } if (!$version) { if ($hasfile{'module.info'}) { &inst_error(&webmin::text('upgrade_emod', 'index.cgi')); } else { &inst_error($webmin::text{'upgrade_etar'}); } } $mode = ""; } # Check the signature if possible and if requested if ($in{'sig'}) { # Check the package signature ($ec, $emsg) = &webmin::gnupg_setup(); if (!$ec) { if ($mode eq 'rpm') { # Use rpm's gpg signature verification system("rpm --import $webmin::module_root_directory/jcameron-key.asc >/dev/null 2>&1"); local $out = `rpm --checksig $file 2>&1`; if ($?) { $ec = 3; $emsg = &webmin::text('upgrade_echecksig', "

$out
"); } } else { # Do a manual signature check if ($in{'source'} == 2) { # Download the key for this tar.gz local ($sigtemp, $sigerror); &http_download($webmin::update_host, $webmin::update_port, "/download/sigs/webmin-$version.tar.gz-sig.asc", \$sigtemp, \$sigerror); if ($sigerror) { $ec = 4; $emsg = &webmin::text( 'upgrade_edownsig', $sigerror); } else { local $data = `cat $file`; local ($vc, $vmsg) = &webmin::verify_data( $data, $sigtemp); if ($vc > 1) { $ec = 3; $emsg = &webmin::text( "upgrade_everify$vc", &html_escape($vmsg)); } } } else { $emsg = $webmin::text{'upgrade_nosig'}; } } } # Tell the user about any GnuPG error if ($ec) { &inst_error($emsg); } elsif ($emsg) { print "$emsg

\n"; } else { print "$webmin::text{'upgrade_sigok'}

\n"; } } else { print "$webmin::text{'upgrade_nocheck'}

\n"; } # gunzip the file if needed open(FILE, $file); read(FILE, $two, 2); close(FILE); if ($two eq "\037\213") { if (!&has_command("gunzip")) { &inst_error($webmin::text{'upgrade_egunzip'}); } $newfile = &tempname(); $out = `gunzip -c $file 2>&1 >$newfile`; if ($?) { unlink($newfile); &inst_error(&webmin::text('upgrade_egzip', "$out")); } unlink($file) if ($need_unlink); $need_unlink = 1; $file = $newfile; } # Setup error handler for down hosts sub inst_error { $inst_error_msg = join("", @_); } &remote_error_setup(\&inst_error); # Build list of selected hosts @hosts = &list_webmin_hosts(); @servers = &list_servers(); if ($in{'server'} == -2) { # Upgrade servers know to run older versions? @hosts = grep { $_->{'version'} < $version } @hosts; print "",&text('upgrade_header3', $version),"

\n"; } elsif ($in{'server'} =~ /^group_(.*)/) { # Upgrade members of some group local ($group) = grep { $_->{'name'} eq $1 } &servers::list_all_groups(\@servers); @hosts = grep { local $hid = $_->{'id'}; local ($s) = grep { $_->{'id'} == $hid } @servers; &indexof($s->{'host'}, @{$group->{'members'}}) >= 0 } @hosts; print "",&text('upgrade_header4', $group->{'name'}),"

\n"; } elsif ($in{'server'} != -1) { # Upgrade one host @hosts = grep { $_->{'id'} == $in{'server'} } @hosts; local ($s) = grep { $_->{'id'} == $hosts[0]->{'id'} } @servers; print "",&text('upgrade_header2', &server_name($s)),"

\n"; } else { # Upgrading every host print "

",&text('upgrade_header'),"

\n"; } # Run the install $p = 0; foreach $h (@hosts) { local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local ($rh = "READ$p", $wh = "WRITE$p"); pipe($rh, $wh); select($wh); $| = 1; select(STDOUT); if (!fork()) { # Do the install in a subprocess close($rh); if (!$s->{'fast'} && $s->{'id'} != 0) { print $wh &serialise_variable($text{'upgrade_efast'}); exit; } &remote_foreign_require($s->{'host'}, "webmin","webmin-lib.pl"); if ($inst_error_msg) { # Failed to contact host .. print $wh &serialise_variable($inst_error_msg); exit; } # Check the remote host's version local $rver = &remote_foreign_call($s->{'host'}, "webmin", "get_webmin_version"); if ($version == $rver) { print $wh &serialise_variable( &webmin::text('upgrade_elatest', $version)); exit; } elsif ($version <= $rver) { print $wh &serialise_variable( &webmin::text('upgrade_eversion', $version)); exit; } # Check the install type on the remote host local $rmode = &remote_eval($s->{'host'}, "webmin", "chop(\$m = `cat \$root_directory/install-type`); \$m"); if ($rmode ne $mode) { print $wh &serialise_variable( &text('upgrade_emode', $text{'upgrade_mode_'.$rmode}, $text{'upgrade_mode_'.$mode})); exit; } # Get the file to the server somehow local $rfile; local $host_need_unlink = 1; if (!$s->{'id'}) { # This host, so we already have the file $rfile = $file; $host_need_unlink = 0; } elsif ($in{'source'} == 0) { # Is the file the same on remote? (like if we have NFS) local @st = stat($file); local $rst = &remote_eval($s->{'host'}, "webmin", "[ stat('$file') ]"); local @rst = @$rst; if (@st && @rst && $st[7] == $rst[7] && $st[9] == $rst[9]) { # File is the same! No need to download $rfile = $file; $host_need_unlink = 0; } else { # Need to copy the file across :( $rfile = &remote_write( $s->{'host'}, $file); } } else { # Need to copy the file across :( $rfile = &remote_write($s->{'host'}, $file); } # Do the install .. if ($mode eq "rpm") { # Can just run RPM command # XXX doesn't actually check output! &remote_eval($s->{'host'}, "webmin", "system(\"rpm --import \$root_directory/webmin/jcameron-key.asc >/dev/null 2>&1\")"); ($out, $ex) = &remote_eval($s->{'host'}, "webmin", "\$out = `rpm -U --ignoreos --ignorearch '$rfile' >/dev/null 2>&1 {'host'}, "webmin", "unlink('$rfile')") if ($host_need_unlink); if ($ex) { print $wh &serialise_variable( "

$out
"); exit; } } else { # Get the original install directory local $rdir = &remote_eval($s->{'host'}, "webmin", "chop(\$d = `cat \$config_directory/install-dir`); \$d"); if ($rdir) { # Extract tar.gz in temporary location first $extract = &remote_foreign_call($s->{'host'}, "webmin", "tempname"); &remote_eval($s->{'host'}, "webmin", "mkdir('$extract', 0755)"); } else { # Extract next to original dir $oldroot = &remote_eval($s->{'host'}, "webmin", "\$root_directory"); $extract = "$oldroot/.."; } # Actually unpack the tar file local ($out, $ex) = &remote_eval($s->{'host'}, "webmin", "\$out = `cd '$extract' ; tar xf '$rfile' 2>&1 >/dev/null`; (\$out, \$?)"); if ($ex) { print $wh &serialise_variable( "
$out
"); exit; } # Delete the original tar.gz &remote_eval($s->{'host'}, "webmin", "unlink('$rfile')") if ($host_need_unlink); # Run setup.sh in the extracted directory $setup = $rdir ? "./setup.sh '$rdir'" : "./setup.sh"; ($out, $ex) = &remote_eval($s->{'host'}, "webmin", "\$SIG{'TERM'} = 'IGNORE'; \$ENV{'config_dir'} = \$config_directory; \$ENV{'webmin_upgrade'} = 1; \$ENV{'autothird'} = 1; \$out = `(cd $extract/webmin-$version && $setup) &1 | tee /tmp/.webmin/webmin-setup.out`; (\$out, \$?)"); if ($ex || $out !~ /success/i) { print $wh &serialise_variable( "
$out
"); exit; } if ($rdir) { # Can delete the temporary source directory &remote_eval($s->{'host'}, "webmin", "system(\"rm -rf \'$extract\'\")"); } elsif ($in{'delete'}) { # Can delete the old root directory &remote_eval($s->{'host'}, "webmin", "system(\"rm -rf \'$oldroot\'\")"); } } # Force an RPC re-connect to new version &remote_finished(); &remote_foreign_require($s->{'host'}, "webmin","webmin-lib.pl"); if ($inst_error_msg) { # Failed to contact host .. print $wh &serialise_variable( &text('upgrade_ereconn', $inst_error_msg)); exit; } &remote_foreign_require($s->{'host'}, "acl", "acl-lib.pl"); # Update local version number and module lists $h->{'version'} = $version; local @mods = &remote_foreign_call($s->{'host'}, "webmin", "get_all_module_infos", 1); @mods = grep { !$_->{'clone'} } @mods; $h->{'modules'} = \@mods; local @themes = &remote_foreign_call($s->{'host'}, "webmin", "list_themes"); $h->{'themes'} = \@themes; local @users = &remote_foreign_call($s->{'host'}, "acl", "list_users"); $h->{'users'} = \@users; local @groups = &remote_foreign_call($s->{'host'}, "acl", "list_groups"); $h->{'groups'} = \@groups; &save_webmin_host($h); print $wh &serialise_variable(""); close($wh); exit; } close($wh); $p++; } # Get back all the results $p = 0; foreach $h (@hosts) { local $rh = "READ$p"; local $line = <$rh>; close($rh); local $rv = &unserialise_variable($line); local ($s) = grep { $_->{'id'} == $h->{'id'} } @servers; local $d = &server_name($s); if (!$line) { print &text('upgrade_failed', $d, "Unknown reason"),"
\n"; } elsif ($rv) { print &text('upgrade_failed', $d, $rv),"
\n"; } else { print &text('upgrade_ok', $text{'upgrade_mode_'.$mode}, $d),"
\n"; } $p++; } unlink($file) if ($need_unlink); print "

$text{'upgrade_done'}

\n"; &remote_finished(); &ui_print_footer("", $text{'index_return'}); sub inst_error { unlink($file) if ($need_unlink); print "
$whatfailed : $_[0]

\n"; &ui_print_footer("", $text{'index_return'}); exit; }