diff options
-rw-r--r-- | FS/FS/Conf.pm | 38 | ||||
-rwxr-xr-x | FS/FS/addr_block.pm | 2 | ||||
-rw-r--r-- | FS/FS/part_export.pm | 58 | ||||
-rw-r--r-- | FS/FS/part_export/domain_shellcommands.pm | 56 | ||||
-rw-r--r-- | FS/FS/part_export/forward_shellcommands.pm | 110 | ||||
-rw-r--r-- | FS/FS/svc_domain.pm | 59 | ||||
-rw-r--r-- | FS/FS/svc_forward.pm | 192 | ||||
-rw-r--r-- | FS/MANIFEST | 2 | ||||
-rw-r--r-- | FS/t/part_export-forward_shellcommands.t | 5 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | htetc/handler.pl | 27 | ||||
-rw-r--r-- | htetc/handler.pl-1.0x | 161 | ||||
-rw-r--r-- | httemplate/config/config-view.cgi | 4 | ||||
-rw-r--r-- | httemplate/config/config.cgi | 4 | ||||
-rw-r--r-- | httemplate/docs/install.html | 25 | ||||
-rw-r--r-- | httemplate/edit/part_export.cgi | 2 | ||||
-rw-r--r-- | httemplate/edit/part_router_field.cgi | 7 | ||||
-rw-r--r-- | httemplate/edit/process/generic.cgi | 5 | ||||
-rw-r--r-- | httemplate/edit/process/router.cgi | 3 | ||||
-rwxr-xr-x | httemplate/edit/router.cgi | 4 | ||||
-rwxr-xr-x | httemplate/search/cust_main.cgi | 2 | ||||
-rwxr-xr-x | httemplate/view/svc_acct.cgi | 2 |
22 files changed, 433 insertions, 340 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 5681dde38..84b3c26ed 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -228,8 +228,8 @@ httemplate/docs/config.html { 'key' => 'apacheip', - 'section' => 'apache', - 'description' => 'The current IP address to assign to new virtual hosts', + 'section' => 'deprecated', + 'description' => '<b>DEPRECATED</b>, add an <i>apache</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be the current IP address to assign to new virtual hosts', 'type' => 'text', }, @@ -242,8 +242,8 @@ httemplate/docs/config.html { 'key' => 'apachemachines', - 'section' => 'apache', - 'description' => 'Your Apache machines, one per line. This enables export of `/etc/apache/vhosts.conf\', which can be included in your Apache configuration via the <a href="http://www.apache.org/docs/mod/core.html#include">Include</a> directive.', + 'section' => 'deprecated', + 'description' => '<b>DEPRECATED</b>, add an <i>apache</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be Apache machines, one per line. This enables export of `/etc/apache/vhosts.conf\', which can be included in your Apache configuration via the <a href="http://www.apache.org/docs/mod/core.html#include">Include</a> directive.', 'type' => 'textarea', }, @@ -374,16 +374,16 @@ httemplate/docs/config.html }, { - 'key' => 'excludeaddr', - 'section' => 'deprecated', - 'description' => 'Addresses to exclude from assignment, one per line.', + 'key' => 'exclude_ip_addr', + 'section' => '', + 'description' => 'Exclude these from the list of available broadband service IP addresses. (One per line)', 'type' => 'textarea', }, { 'key' => 'erpcdmachines', - 'section' => '', - 'description' => 'Your ERPCD authenticaion machines, one per line. This enables export of `/usr/annex/acp_passwd\' and `/usr/annex/acp_dialup\'', + 'section' => 'deprecated', + 'description' => '<b>DEPRECATED</b>, ERPCD is no longer supported. Used to be ERPCD authenticaion machines, one per line. This enables export of `/usr/annex/acp_passwd\' and `/usr/annex/acp_dialup\'', 'type' => 'textarea', }, @@ -418,21 +418,21 @@ httemplate/docs/config.html { 'key' => 'icradius_mysqldest', 'section' => 'deprecated', - 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead. Used to be the destination directory for the MySQL databases, on the ICRADIUS/FreeRADIUS machines. Defaults to "/usr/local/var/".', + 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be the destination directory for the MySQL databases, on the ICRADIUS/FreeRADIUS machines. Defaults to "/usr/local/var/".', 'type' => 'text', }, { 'key' => 'icradius_mysqlsource', 'section' => 'deprecated', - 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead. Used to be the source directory for for the MySQL radcheck table files, on the Freeside machine. Defaults to "/usr/local/var/freeside".', + 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be the source directory for for the MySQL radcheck table files, on the Freeside machine. Defaults to "/usr/local/var/freeside".', 'type' => 'text', }, { 'key' => 'icradius_secrets', 'section' => 'deprecated', - 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead. This option used to specify a database for ICRADIUS/FreeRADIUS export. Three lines: DBI data source, username and password.', + 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead. This option used to specify a database for ICRADIUS/FreeRADIUS export. Three lines: DBI data source, username and password.', 'type' => 'textarea', }, @@ -576,22 +576,22 @@ httemplate/docs/config.html { 'key' => 'sendmailconfigpath', - 'section' => 'mail', - 'description' => 'Sendmail configuration file path. Defaults to `/etc\'. Many newer distributions use `/etc/mail\'.', + 'section' => 'deprecated', + 'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be sendmail configuration file path. Defaults to `/etc\'. Many newer distributions use `/etc/mail\'.', 'type' => 'text', }, { 'key' => 'sendmailmachines', - 'section' => 'mail', - 'description' => 'Your sendmail machines, one per line. This enables export of `/etc/virtusertable\' and `/etc/sendmail.cw\'.', + 'section' => 'deprecated', + 'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be sendmail machines, one per line. This enables export of `/etc/virtusertable\' and `/etc/sendmail.cw\'.', 'type' => 'textarea', }, { 'key' => 'sendmailrestart', - 'section' => 'mail', - 'description' => 'If defined, the command which is run on sendmail machines after files are copied.', + 'section' => 'deprecated', + 'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead. Used to define the command which is run on sendmail machines after files are copied.', 'type' => 'text', }, @@ -818,7 +818,7 @@ httemplate/docs/config.html { 'key' => 'vpopmailmachines', 'section' => 'deprecated', - 'description' => '<b>DEPRECATED</b>, add a <i>cp</i> <a href="../browse/part_export.cgi">export</a> instead. This option used to contain your vpopmail pop toasters, one per line. Each line is of the form "machinename vpopdir vpopuid vpopgid". For example: <code>poptoaster.domain.tld /home/vpopmail 508 508</code> Note: vpopuid and vpopgid are values taken from the vpopmail machine\'s /etc/passwd', + 'description' => '<b>DEPRECATED</b>, add a <i>vpopmail</i> <a href="../browse/part_export.cgi">export</a> instead. This option used to contain your vpopmail pop toasters, one per line. Each line is of the form "machinename vpopdir vpopuid vpopgid". For example: <code>poptoaster.domain.tld /home/vpopmail 508 508</code> Note: vpopuid and vpopgid are values taken from the vpopmail machine\'s /etc/passwd', 'type' => 'textarea', }, diff --git a/FS/FS/addr_block.pm b/FS/FS/addr_block.pm index c9305f6af..af4e5fb79 100755 --- a/FS/FS/addr_block.pm +++ b/FS/FS/addr_block.pm @@ -174,7 +174,7 @@ sub next_free_addr { my $self = shift; my $conf = new FS::Conf; - my @excludeaddr = $conf->config('excludeaddr'); + my @excludeaddr = $conf->config('exclude_ip_addr'); my @used = ( map { $_->NetAddr->addr } diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index 4471d6e00..8370b3f9e 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -718,18 +718,30 @@ tie my %vpopmail_options, 'Tie::IxHash', ; tie my %bind_options, 'Tie::IxHash', - #'machine' => { label=>'named machine' }, - 'named_conf' => { label => 'named.conf location', - default=> '/etc/bind/named.conf' }, - 'zonepath' => { label => 'path to zone files', - default=> '/etc/bind/', }, + #'machine' => { label=>'named machine' }, + 'named_conf' => { label => 'named.conf location', + default=> '/etc/bind/named.conf' }, + 'zonepath' => { label => 'path to zone files', + default=> '/etc/bind/', }, + 'bind_release' => { label => 'ISC BIND Release', + type => 'select', + options => [qw(BIND8 BIND9)], + default => 'BIND8' }, + 'bind9_minttl' => { label => 'The minttl required by bind9 and RFC1035.', + default => '1D' }, ; tie my %bind_slave_options, 'Tie::IxHash', - #'machine' => { label=> 'Slave machine' }, - 'master' => { label=> 'Master IP address(s) (semicolon-separated)' }, - 'named_conf' => { label => 'named.conf location', - default => '/etc/bind/named.conf' }, + #'machine' => { label=> 'Slave machine' }, + 'master' => { label=> 'Master IP address(s) (semicolon-separated)' }, + 'named_conf' => { label => 'named.conf location', + default => '/etc/bind/named.conf' }, + 'bind_release' => { label => 'ISC BIND Release', + type => 'select', + options => [qw(BIND8 BIND9)], + default => 'BIND8' }, + 'bind9_minttl' => { label => 'The minttl required by bind9 and RFC1035.', + default => '1D' }, ; tie my %http_options, 'Tie::IxHash', @@ -815,6 +827,18 @@ tie my %ldap_options, 'Tie::IxHash', 'radius' => { label=>'Export RADIUS attributes', type=>'checkbox', }, ; +tie my %forward_shellcommands_options, 'Tie::IxHash', + 'user' => { lable=>'Remote username', default=>'root' }, + 'useradd' => { label=>'Insert command', + default=>'', + }, + 'userdel' => { label=>'Delete command', + default=>'', + }, + 'usermod' => { label=>'Modify command', + default=>'', + }, +; #export names cannot have dashes... %exports = ( @@ -848,13 +872,13 @@ tie my %ldap_options, 'Tie::IxHash', 'desc' => 'Real-time export via remote SSH (i.e. useradd, userdel, etc.)', 'options' => \%shellcommands_options, 'nodomain' => 'Y', - 'notes' => 'Run remote commands via SSH. Usernames are considered unique (also see shellcommands_withdomain). You probably want this if the commands you are running will not accept a domain as a parameter. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="Linux/NetBSD" onClick=\'this.form.useradd.value = "useradd -c $finger -d $dir -m -s $shell -u $uid -p $crypt_password $username"; this.form.useradd_stdin.value = ""; this.form.userdel.value = "userdel -r $username"; this.form.userdel_stdin.value=""; this.form.usermod.value = "usermod -c $new_finger -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username"; this.form.usermod_stdin.value = "";\'><LI><INPUT TYPE="button" VALUE="FreeBSD" onClick=\'this.form.useradd.value = "pw useradd $username -d $dir -m -s $shell -u $uid -g $gid -c $finger -h 0"; this.form.useradd_stdin.value = "$_password\n"; this.form.userdel.value = "pw userdel $username -r"; this.form.userdel_stdin.value=""; this.form.usermod.value = "pw usermod $old_username -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -c $new_finger -h 0"; this.form.usermod_stdin.value = "$new__password\n";\'><LI><INPUT TYPE="button" VALUE="Just maintain directories (use with sysvshell or bsdshell)" onClick=\'this.form.useradd.value = "cp -pr /etc/skel $dir; chown -R $uid.$gid $dir"; this.form.useradd_stdin.value = ""; this.form.usermod.value = "[ -d $old_dir ] && mv $old_dir $new_dir || ( chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; find . -depth -print | cpio -pdm $new_dir; chmod u-t $new_dir; chown -R $uid.$gid $new_dir; rm -rf $old_dir )"; this.form.usermod_stdin.value = ""; this.form.userdel.value = "rm -rf $dir"; this.form.userdel_stdin.value="";\'></UL>', + 'notes' => 'Run remote commands via SSH. Usernames are considered unique (also see shellcommands_withdomain). You probably want this if the commands you are running will not accept a domain as a parameter. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="Linux/NetBSD" onClick=\'this.form.useradd.value = "useradd -c $finger -d $dir -m -s $shell -u $uid -p $crypt_password $username"; this.form.useradd_stdin.value = ""; this.form.userdel.value = "userdel -r $username"; this.form.userdel_stdin.value=""; this.form.usermod.value = "usermod -c $new_finger -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username"; this.form.usermod_stdin.value = "";\'><LI><INPUT TYPE="button" VALUE="FreeBSD" onClick=\'this.form.useradd.value = "pw useradd $username -d $dir -m -s $shell -u $uid -g $gid -c $finger -h 0"; this.form.useradd_stdin.value = "$_password\n"; this.form.userdel.value = "pw userdel $username -r"; this.form.userdel_stdin.value=""; this.form.usermod.value = "pw usermod $old_username -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -c $new_finger -h 0"; this.form.usermod_stdin.value = "$new__password\n";\'><LI><INPUT TYPE="button" VALUE="Just maintain directories (use with sysvshell or bsdshell)" onClick=\'this.form.useradd.value = "cp -pr /etc/skel $dir; chown -R $uid.$gid $dir"; this.form.useradd_stdin.value = ""; this.form.usermod.value = "[ -d $old_dir ] && mv $old_dir $new_dir || ( chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; find . -depth -print | cpio -pdm $new_dir; chmod u-t $new_dir; chown -R $new_uid.$new_gid $new_dir; rm -rf $old_dir )"; this.form.usermod_stdin.value = ""; this.form.userdel.value = "rm -rf $dir"; this.form.userdel_stdin.value="";\'></UL>The following variables are available for interpolation (prefixed with new_ or old_ for replace operations): <UL><LI><code>$username</code><LI><code>$_password</code><LI><code>$quoted_password</code> - unencrypted password quoted for the shell<LI><code>$crypt_password</code> - encrypted password<LI><code>$uid</code><LI><code>$gid</code><LI><code>$finger</code> - GECOS, already quoted for the shell (do not add additional quotes)<LI><code>$dir</code> - home directory<LI><code>$shell</code><LI><code>$quota</code><LI>All other fields in <a href="../docs/schema.html#svc_acct">svc_acct</a> are also available.</UL>', }, 'shellcommands_withdomain' => { 'desc' => 'Real-time export via remote SSH.', 'options' => \%shellcommands_withdomain_options, - 'notes' => 'Run remote commands via SSH. username@domain (rather than just usernames) are considered unique (also see shellcommands). You probably want this if the commands you are running will accept a domain as a parameter, and will allow the same username with different domains. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.', + 'notes' => 'Run remote commands via SSH. username@domain (rather than just usernames) are considered unique (also see shellcommands). You probably want this if the commands you are running will accept a domain as a parameter, and will allow the same username with different domains. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$username</code><LI><code>$domain</code><LI><code>$_password</code><LI><code>$quoted_password</code> - unencrypted password quoted for the shell<LI><code>$crypt_password</code> - encrypted password<LI><code>$uid</code><LI><code>$gid</code><LI><code>$finger</code> - GECOS, already quoted for the shell (do not add additional quotes)<LI><code>$dir</code> - home directory<LI><code>$shell</code><LI><code>$quota</code><LI>All other fields in <a href="../docs/schema.html#svc_acct">svc_acct</a> are also available.</UL>', }, 'ldap' => { @@ -873,7 +897,7 @@ tie my %ldap_options, 'Tie::IxHash', 'sqlmail' => { 'desc' => 'Real-time export to SQL-backed mail server', 'options' => \%sqlmail_options, - 'nodomain' => 'N', + 'nodomain' => '', 'notes' => 'Database schema can be made to work with Courier IMAP and Exim. Others could work but are untested. (...extended description from pc-intouch?...)', }, @@ -935,7 +959,7 @@ tie my %ldap_options, 'Tie::IxHash', 'domain_shellcommands' => { 'desc' => 'Run remote commands via SSH, for domains.', 'options' => \%domain_shellcommands_options, - 'notes' => 'Run remote commands via SSH, for domains. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.', + 'notes' => 'Run remote commands via SSH, for domains. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="qmail catchall .qmail-domain-default maintenance" onClick=\'this.form.useradd.value = "[ \"$uid\" -a \"$gid\" -a \"$dir\" -a \"$qdomain\" ] && [ -e $dir/.qmail-$qdomain-default ] || { touch $dir/.qmail-$qdomain-default; chown $uid:$gid $dir/.qmail-$qdomain-default; }"; this.form.userdel.value = ""; this.form.usermod.value = "";\'></UL>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$domain</code><LI><code>$qdomain</code> - domain with periods replaced by colons<LI><code>$uid</code> - of catchall account<LI><code>$gid</code> - of catchall account<LI><code>$dir</code> - home directory of catchall account<LI>All other fields in <a href="../docs/schema.html#svc_domain">svc_domain</a> are also available.</UL>', }, @@ -948,13 +972,19 @@ tie my %ldap_options, 'Tie::IxHash', #'nodomain' => 'Y', 'notes' => 'Database schema can be made to work with Courier IMAP and Exim. Others could work but are untested. (...extended description from pc-intouch?...)', }, + + 'forward_shellcommands' => { + 'desc' => 'Run remote commands via SSH, for forwards', + 'options' => \%forward_shellcommands_options, + 'notes' => 'Run remote commands via SSH, for forwards. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="text vpopmail maintenance" onClick=\'this.form.useradd.value = "[ -d /home/vpopmail/domains/$domain/$username ] && { echo \"$destination\" > /home/vpopmail/domains/$domain/$username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$domain/$username/.qmail; }"; this.form.userdel.value = "rm /home/vpopmail/domains/$domain/$username/.qmail"; this.form.usermod.value = "mv /home/vpopmail/domains/$old_domain/$old_username/.qmail /home/vpopmail/domains/$new_domain/$new_username; [ \"$old_destination\" != \"$new_destination\" ] && { echo \"$new_destination\" > /home/vpopmail/domains/$new_domain/$new_username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$new_domain/$new_username/.qmail; }";\'></UL>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$username</code><LI><code>$domain</code><LI><code>$destination</code> - forward destination<LI>All other fields in <a href="../docs/schema.html#svc_forward">svc_forward</a> are also available.</UL>', + }, }, 'svc_www' => { 'www_shellcommands' => { 'desc' => 'Run remote commands via SSH, for virtual web sites.', 'options' => \%www_shellcommands_options, - 'notes' => 'Run remote commands via SSH, for virtual web sites. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.', + 'notes' => 'Run remote commands via SSH, for virtual web sites. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$zone</code><LI><code>$username</code><LI><code>$homedir</code><LI>All other fields in <a href="../docs/schema.html#svc_www">svc_www</a> are also available.</UL>', }, 'apache' => { diff --git a/FS/FS/part_export/domain_shellcommands.pm b/FS/FS/part_export/domain_shellcommands.pm index 5b3cd5d79..0edbab0dd 100644 --- a/FS/FS/part_export/domain_shellcommands.pm +++ b/FS/FS/part_export/domain_shellcommands.pm @@ -28,17 +28,15 @@ sub _export_command { no strict 'refs'; ${$_} = $svc_domain->getfield($_) foreach $svc_domain->fields; } + ( $qdomain = $domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES -# my $domain_record = $svc_www->domain_record; # or die ? -# my $zone = $domain_record->reczone; # or die ? -# unless ( $zone =~ /\.$/ ) { -# my $svc_domain = $domain_record->svc_domain; # or die ? -# $zone .= '.'. $svc_domain->domain; -# } - -# my $svc_acct = $svc_www->svc_acct; # or die ? -# my $username = $svc_acct->username; -# my $homedir = $svc_acct->dir; # or die ? + if ( $svc_domain->catchall ) { + no strict 'refs'; + my $svc_acct = $svc_domain->catchall_svc_acct; + ${$_} = $svc_acct->getfield($_) foreach qw(uid gid dir); + } else { + ${$_} = '' foreach qw(uid gid dir); + } #done setting variables for the command @@ -60,27 +58,23 @@ sub _export_replace { ${"old_$_"} = $old->getfield($_) foreach $old->fields; ${"new_$_"} = $new->getfield($_) foreach $new->fields; } -# my $old_domain_record = $old->domain_record; # or die ? -# my $old_zone = $old_domain_record->reczone; # or die ? -# unless ( $old_zone =~ /\.$/ ) { -# my $old_svc_domain = $old_domain_record->svc_domain; # or die ? -# $old_zone .= '.'. $old_svc_domain->domain; -# } -# -# my $old_svc_acct = $old->svc_acct; # or die ? -# my $old_username = $old_svc_acct->username; -# my $old_homedir = $old_svc_acct->dir; # or die ? -# -# my $new_domain_record = $new->domain_record; # or die ? -# my $new_zone = $new_domain_record->reczone; # or die ? -# unless ( $new_zone =~ /\.$/ ) { -# my $new_svc_domain = $new_domain_record->svc_domain; # or die ? -# $new_zone .= '.'. $new_svc_domain->domain; -# } - -# my $new_svc_acct = $new->svc_acct; # or die ? -# my $new_username = $new_svc_acct->username; -# my $new_homedir = $new_svc_acct->dir; # or die ? + ( $old_qdomain = $old_domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES + ( $new_qdomain = $new_domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES + + if ( $old->catchall ) { + no strict 'refs'; + my $svc_acct = $old->catchall_svc_acct; + ${"old_$_"} = $svc_acct->getfield($_) foreach qw(uid gid dir); + } else { + ${"old_$_"} = '' foreach qw(uid gid dir); + } + if ( $new->catchall ) { + no strict 'refs'; + my $svc_acct = $new->catchall_svc_acct; + ${"new_$_"} = $svc_acct->getfield($_) foreach qw(uid gid dir); + } else { + ${"new_$_"} = '' foreach qw(uid gid dir); + } #done setting variables for the command diff --git a/FS/FS/part_export/forward_shellcommands.pm b/FS/FS/part_export/forward_shellcommands.pm new file mode 100644 index 000000000..43d558a69 --- /dev/null +++ b/FS/FS/part_export/forward_shellcommands.pm @@ -0,0 +1,110 @@ +package FS::part_export::forward_shellcommands; + +use strict; +use vars qw(@ISA); +use FS::part_export; + +@ISA = qw(FS::part_export); + +sub rebless { shift; } + +sub _export_insert { + my($self) = shift; + $self->_export_command('useradd', @_); +} + +sub _export_delete { + my($self) = shift; + $self->_export_command('userdel', @_); +} + +sub _export_command { + my ( $self, $action, $svc_forward ) = (shift, shift, shift); + my $command = $self->option($action); + + #set variable for the command + no strict 'vars'; + { + no strict 'refs'; + ${$_} = $svc_forward->getfield($_) foreach $svc_forward->fields; + } + + my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } ); + $username = $svc_acct->username; + $domain = $svc_acct->domain; + if ($self->dstsvc) { + $destination = $self->dstsvc_acct->email; + } else { + $destination = $self->dst; + } + + #done setting variables for the command + + $self->shellcommands_queue( $svc_forward->svcnum, + user => $self->option('user')||'root', + host => $self->machine, + command => eval(qq("$command")), + ); +} + +sub _export_replace { + my( $self, $new, $old ) = (shift, shift, shift); + my $command = $self->option('usermod'); + + #set variable for the command + no strict 'vars'; + { + no strict 'refs'; + ${"old_$_"} = $old->getfield($_) foreach $old->fields; + ${"new_$_"} = $new->getfield($_) foreach $new->fields; + } + + my $old_svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } ); + $old_username = $old_svc_acct->username; + $old_domain = $old_svc_acct->domain; + if ($self->dstsvc) { + $old_destination = $self->dstsvc_acct->email; + } else { + $old_destination = $self->dst; + } + + my $new_svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } ); + $new_username = $new_svc_acct->username; + $new_domain = $new_svc_acct->domain; + if ($self->dstsvc) { + $new_destination = $self->dstsvc_acct->email; + } else { + $new_destination = $self->dst; + } + + #done setting variables for the command + + $self->shellcommands_queue( $new->svcnum, + user => $self->option('user')||'root', + host => $self->machine, + command => eval(qq("$command")), + ); +} + +#a good idea to queue anything that could fail or take any time +sub shellcommands_queue { + my( $self, $svcnum ) = (shift, shift); + my $queue = new FS::queue { + 'svcnum' => $svcnum, + 'job' => "FS::part_export::forward_shellcommands::ssh_cmd", + }; + $queue->insert( @_ ); +} + +sub ssh_cmd { #subroutine, not method + use Net::SSH '0.07'; + &Net::SSH::ssh_cmd( { @_ } ); +} + +#sub shellcommands_insert { #subroutine, not method +#} +#sub shellcommands_replace { #subroutine, not method +#} +#sub shellcommands_delete { #subroutine, not method +#} + diff --git a/FS/FS/svc_domain.pm b/FS/FS/svc_domain.pm index 3941d6eff..81edc337e 100644 --- a/FS/FS/svc_domain.pm +++ b/FS/FS/svc_domain.pm @@ -3,14 +3,13 @@ package FS::svc_domain; use strict; use vars qw( @ISA $whois_hack $conf $smtpmachine @defaultrecords $soadefaultttl $soaemail $soaexpire $soamachine - $soarefresh $soaretry $qshellmachine $nossh_hack + $soarefresh $soaretry ); use Carp; use Mail::Internet 1.44; use Mail::Header; use Date::Format; use Net::Whois 1.0; -use Net::SSH; use FS::Record qw(fields qsearch qsearchs dbh); use FS::Conf; use FS::svc_Common; @@ -37,9 +36,6 @@ $FS::UID::callback{'FS::domain'} = sub { $soarefresh = $conf->config('soarefresh'); $soaretry = $conf->config('soaretry'); - $qshellmachine = $conf->exists('qmailmachines') - ? $conf->config('shellmachine') - : ''; }; =head1 NAME @@ -120,21 +116,6 @@ If any records are defined in the I<defaultrecords> configuration file, appropriate records are added to the domain_record table (see L<FS::domain_record>). -If a machine is defined in the I<shellmachine> configuration value, the -I<qmailmachines> configuration file exists, and the I<catchall> field points -to an an account with a home directory (see L<FS::svc_acct>), the command: - - [ -e $dir/.qmail-$qdomain-defualt ] || { - touch $dir/.qmail-$qdomain-default; - chown $uid:$gid $dir/.qmail-$qdomain-default; - } - -is executed on shellmachine via ssh (see L<dot-qmail/"EXTENSION ADDRESSES">). -This behaviour can be supressed by setting $FS::svc_domain::nossh_hack true. - -a machine is defined -in the - =cut sub insert { @@ -211,28 +192,6 @@ sub insert { $dbh->commit or die $dbh->errstr if $oldAutoCommit; - if ( $qshellmachine && $self->catchall && ! $nossh_hack ) { - - my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->catchall } ) - or warn "WARNING: inserted unknown catchall: ". $self->catchall; - if ( $svc_acct && $svc_acct->dir ) { - my $qdomain = $self->domain; - $qdomain =~ s/\./:/g; #see manpage for 'dot-qmail': EXTENSION ADDRESSES - my ( $uid, $gid, $dir ) = ( - $svc_acct->uid, - $svc_acct->gid, - $svc_acct->dir, - ); - - my $queue = new FS::queue { - 'svcnum' => $self->svcnum, - 'job' => 'Net::SSH::ssh_cmd', - }; - $error = $queue->insert("root\@$qshellmachine", "[ -e $dir/.qmail-$qdomain-default ] || { touch $dir/.qmail-$qdomain-default; chown $uid:$gid $dir/.qmail-$qdomain-default; }" ); - - } - } - ''; #no error } @@ -411,6 +370,15 @@ sub domain_record { } +sub catchall_svc_acct { + my $self = shift; + if ( $self->catchall ) { + qsearchs( 'svc_acct', { 'svcnum' => $self->catchall } ); + } else { + ''; + } +} + =item whois Returns the Net::Whois::Domain object (see L<Net::Whois>) for this domain, or @@ -449,8 +417,6 @@ sub submit_internic { =head1 BUGS -All BIND/DNS fields should be included (and exported). - Delete doesn't send a registration template. All registries should be supported. @@ -462,9 +428,8 @@ The $recref stuff in sub check should be cleaned up. =head1 SEE ALSO L<FS::svc_Common>, L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>, -L<FS::part_svc>, L<FS::cust_pkg>, L<Net::Whois>, L<ssh>, -L<dot-qmail>, schema.html from the base documentation, config.html from the -base documentation. +L<FS::part_svc>, L<FS::cust_pkg>, L<Net::Whois>, schema.html from the base +documentation, config.html from the base documentation. =cut diff --git a/FS/FS/svc_forward.pm b/FS/FS/svc_forward.pm index 1c5b5c40d..2b1fb9225 100644 --- a/FS/FS/svc_forward.pm +++ b/FS/FS/svc_forward.pm @@ -1,9 +1,7 @@ package FS::svc_forward; use strict; -use vars qw( @ISA $nossh_hack $conf $shellmachine @qmailmachines - @vpopmailmachines ); -use Net::SSH qw(ssh); +use vars qw( @ISA ); use FS::Conf; use FS::Record qw( fields qsearch qsearchs dbh ); use FS::svc_Common; @@ -13,21 +11,6 @@ use FS::svc_domain; @ISA = qw( FS::svc_Common ); -#ask FS::UID to run this stuff for us later -$FS::UID::callback{'FS::svc_forward'} = sub { - $conf = new FS::Conf; - if ( $conf->exists('qmailmachines') ) { - $shellmachine = $conf->config('shellmachine') - } else { - $shellmachine = ''; - } - if ( $conf->exists('vpopmailmachines') ) { - @vpopmailmachines = $conf->config('vpopmailmachines'); - } else { - @vpopmailmachines = (); - } -}; - =head1 NAME FS::svc_forward - Object methods for svc_forward records @@ -91,17 +74,6 @@ the error, otherwise returns false. The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be defined. An FS::cust_svc record will be created and inserted. -If the configuration value (see L<FS::Conf>) vpopmailmachines exists, then -the command: - - [ -d $vpopdir/domains/$domain/$source ] && { - echo "$destination" >> $vpopdir/domains/$domain/$username/.$qmail - chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.$qmail - } - -is executed on each vpopmailmachine via ssh (see the vpopmail documentation). -This behaviour can be supressed by setting $FS::svc_forward::nossh_hack true. - =cut sub insert { @@ -128,32 +100,6 @@ sub insert { return $error; } - my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } ); - my $username = $svc_acct->username; - my $domain = $svc_acct->domain; - my $destination; - if ($self->dstsvc) { - $destination = $self->dstsvc_acct->email; - } else { - $destination = $self->dst; - } - - foreach my $vpopmailmachine ( @vpopmailmachines ) { - my($machine, $vpopdir, $vpopuid, $vpopgid) = split(/\s+/, $vpopmailmachine); - my $queue = new FS::queue { - 'svcnum' => $self->svcnum, - 'job' => 'Net::SSH::ssh_cmd', - }; - # should be neater - my $error = $queue->insert("root\@$machine","[ -d $vpopdir/domains/$domain/$username ] && { echo \"$destination\" >> $vpopdir/domains/$domain/$username/.qmail; chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.qmail; }") - unless $nossh_hack; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - - } - $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; #no error @@ -166,19 +112,6 @@ returns the error, otherwise returns false. The corresponding FS::cust_svc record will be deleted as well. -If the configuration value vpopmailmachines exists, then the command: - - { sed -e '/^$destination/d' < - $vpopdir/domains/$srcdomain/$srcusername/.qmail > - $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp; - mv $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp - $vpopdir/domains/$srcdomain/$srcusername/.qmail; - chown $vpopuid.$vpopgid $vpopdir/domains/$srcdomain/$srcusername/.qmail; } - - -is executed on each vpopmailmachine via ssh. This behaviour can be supressed -by setting $FS::svc_forward_nossh_hack true. - =cut sub delete { @@ -201,37 +134,6 @@ sub delete { return $error; } - my $svc_acct = $self->srcsvc_acct; - my $username = $svc_acct->username; - my $domain = $svc_acct->domain; - my $destination; - if ($self->dstsvc) { - $destination = $self->dstsvc_acct->email; - } else { - $destination = $self->dst; - } - foreach my $vpopmailmachine ( @vpopmailmachines ) { - my($machine, $vpopdir, $vpopuid, $vpopgid) = - split(/\s+/, $vpopmailmachine); - my $queue = new FS::queue { 'job' => 'Net::SSH::ssh_cmd' }; - # should be neater - my $error = $queue->insert("root\@$machine", - "sed -e '/^$destination/d' " . - "< $vpopdir/domains/$domain/$username/.qmail" . - "> $vpopdir/domains/$domain/$username/.qmail.temp; " . - "mv $vpopdir/domains/$domain/$username/.qmail.temp " . - "$vpopdir/domains/$domain/$username/.qmail; " . - "chown $vpopuid.$vpopgid $vpopdir/domains/$domain/$username/.qmail;" - ) - unless $nossh_hack; - - if ($error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - - } - $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; } @@ -242,29 +144,6 @@ sub delete { Replaces OLD_RECORD with this one in the database. If there is an error, returns the error, otherwise returns false. -If the configuration value vpopmailmachines exists, then the command: - - { sed -e '/^$destination/d' < - $vpopdir/domains/$srcdomain/$srcusername/.qmail > - $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp; - mv $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp - $vpopdir/domains/$srcdomain/$srcusername/.qmail; - chown $vpopuid.$vpopgid $vpopdir/domains/$srcdomain/$srcusername/.qmail; } - - -is executed on each vpopmailmachine via ssh. This behaviour can be supressed -by setting $FS::svc_forward_nossh_hack true. - -Also, if the configuration value vpopmailmachines exists, then the command: - - [ -d $vpopdir/domains/$domain/$source ] && { - echo "$destination" >> $vpopdir/domains/$domain/$username/.$qmail - chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.$qmail - } - -is executed on each vpopmailmachine via ssh. This behaviour can be supressed -by setting $FS::svc_forward_nossh_hack true. - =cut sub replace { @@ -295,66 +174,6 @@ sub replace { return $error; } - my $old_svc_acct = $old->srcsvc_acct; - my $old_username = $old_svc_acct->username; - my $old_domain = $old_svc_acct->domain; - my $destination; - if ($old->dstsvc) { - $destination = $old->dstsvc_acct->email; - } else { - $destination = $old->dst; - } - foreach my $vpopmailmachine ( @vpopmailmachines ) { - my($machine, $vpopdir, $vpopuid, $vpopgid) = - split(/\s+/, $vpopmailmachine); - my $queue = new FS::queue { - 'svcnum' => $new->svcnum, - 'job' => 'Net::SSH::ssh_cmd', - }; - # should be neater - my $error = $queue->insert("root\@$machine", - "sed -e '/^$destination/d' " . - "< $vpopdir/domains/$old_domain/$old_username/.qmail" . - "> $vpopdir/domains/$old_domain/$old_username/.qmail.temp; " . - "mv $vpopdir/domains/$old_domain/$old_username/.qmail.temp " . - "$vpopdir/domains/$old_domain/$old_username/.qmail; " . - "chown $vpopuid.$vpopgid " . - "$vpopdir/domains/$old_domain/$old_username/.qmail;" - ) - unless $nossh_hack; - - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - } - - #false laziness with stuff in insert, should subroutine - my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $new->srcsvc } ); - my $username = $svc_acct->username; - my $domain = $svc_acct->domain; - if ($new->dstsvc) { - $destination = $new->dstsvc_acct->email; - } else { - $destination = $new->dst; - } - - foreach my $vpopmailmachine ( @vpopmailmachines ) { - my($machine, $vpopdir, $vpopuid, $vpopgid) = split(/\s+/, $vpopmailmachine); - my $queue = new FS::queue { - 'svcnum' => $new->svcnum, - 'job' => 'Net::SSH::ssh_cmd', - }; - # should be neater - my $error = $queue->insert("root\@$machine","[ -d $vpopdir/domains/$domain/$username ] && { echo \"$destination\" >> $vpopdir/domains/$domain/$username/.qmail; chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.qmail; }") - unless $nossh_hack; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "queueing job (transaction rolled back): $error"; - } - } - #end subroutinable bits - $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; } @@ -450,19 +269,12 @@ sub dstsvc_acct { =back -=head1 VERSION - -$Id: svc_forward.pm,v 1.12 2002-05-31 17:50:37 ivan Exp $ - =head1 BUGS -The remote commands should be configurable. - =head1 SEE ALSO L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>, -L<FS::svc_acct>, L<FS::svc_domain>, L<Net::SSH>, L<ssh>, L<dot-qmail>, -schema.html from the base documentation. +L<FS::svc_acct>, L<FS::svc_domain>, schema.html from the base documentation. =cut diff --git a/FS/MANIFEST b/FS/MANIFEST index 32a4e4f59..6397cc411 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -73,6 +73,7 @@ FS/part_export/bsdshell.pm FS/part_export/cp.pm FS/part_export/cyrus.pm FS/part_export/domain_shellcommands.pm +FS/part_export/forward_shellcommands.pm FS/part_export/http.pm FS/part_export/infostreet.pm FS/part_export/ldap.pm @@ -155,6 +156,7 @@ t/part_export-bsdshell.t t/part_export-cp.t t/part_export-cyrus.t t/part_export-domain_shellcommands.t +t/part_export-forward_shellcommands.t t/part_export-http.t t/part_export-infostreet.t t/part_export-ldap.t diff --git a/FS/t/part_export-forward_shellcommands.t b/FS/t/part_export-forward_shellcommands.t new file mode 100644 index 000000000..78ca68d10 --- /dev/null +++ b/FS/t/part_export-forward_shellcommands.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_export::forward_shellcommands; +$loaded=1; +print "ok 1\n"; @@ -10,6 +10,8 @@ TEMPLATE = asp #TEMPLATE = mason ASP_GLOBAL = /usr/local/etc/freeside/asp-global +MASON_HANDLER = /usr/local/etc/freeside/handler.pl +MASONDATA = /usr/local/etc/freeside/masondata #deb, others? FREESIDE_DOCUMENT_ROOT = /var/www/freeside @@ -115,6 +117,9 @@ install-docs: docs [ "${TEMPLATE}" = "asp" -a ! -e ${ASP_GLOBAL} ] && mkdir ${ASP_GLOBAL} || true [ "${TEMPLATE}" = "asp" ] && chown -R freeside ${ASP_GLOBAL} || true [ "${TEMPLATE}" = "asp" ] && cp htetc/global.asa ${ASP_GLOBAL} || true + [ "${TEMPLATE}" = "mason" ] && cp htetc/handler.pl ${MASON_HANDLER} || true + [ "${TEMPLATE}" = "mason" -a ! -e ${MASONDATA} ] && mkdir ${MASONDATA} || true + [ "${TEMPLATE}" = "mason" ] && chown -R freeside ${MASONDATA} || true perl-modules: cd FS; \ diff --git a/htetc/handler.pl b/htetc/handler.pl index 768ebffec..9f2a483c2 100644 --- a/htetc/handler.pl +++ b/htetc/handler.pl @@ -28,20 +28,25 @@ use strict; # Create Mason objects # -my $parser = new HTML::Mason::Parser; -my $interp = new HTML::Mason::Interp (parser=>$parser, - comp_root=>'/var/www/masondocs', - data_dir=>'/home/ivan/freeside_current/masondata', - out_mode=>'stream', - ); -my $ah = new HTML::Mason::ApacheHandler ( interp => $interp, - #auto_send_headers => 0, - ); + +#my $parser = new HTML::Mason::Parser; +#my $interp = new HTML::Mason::Interp (parser=>$parser, +# comp_root=>'/var/www/masondocs', +# data_dir=>'/usr/local/etc/freeside/masondata', +# out_mode=>'stream', +# ); +my $ah = new HTML::Mason::ApacheHandler ( + #interp => $interp, + #auto_send_headers => 0, + comp_root=>'/var/www/masonside', + data_dir=>'/usr/local/etc/freeside/masondata', + #out_mode=>'stream', +); # Activate the following if running httpd as root (the normal case). # Resets ownership of all files created by Mason at startup. # -chown (Apache->server->uid, Apache->server->gid, $interp->files_written); +#chown (Apache->server->uid, Apache->server->gid, $interp->files_written); sub handler { @@ -121,7 +126,7 @@ sub handler *CGI::redirect = sub { my( $self, $location ) = @_; - + use vars qw($m); #http://www.masonhq.com/docs/faq/#how_do_i_do_an_external_redirect $m->clear_buffer; # The next two lines are necessary to stop Apache from re-reading diff --git a/htetc/handler.pl-1.0x b/htetc/handler.pl-1.0x new file mode 100644 index 000000000..768ebffec --- /dev/null +++ b/htetc/handler.pl-1.0x @@ -0,0 +1,161 @@ +#!/usr/bin/perl +# +# This is a basic, fairly fuctional Mason handler.pl. +# +# For something a little more involved, check out session_handler.pl + +package HTML::Mason; + +# Bring in main Mason package. +use HTML::Mason; + +# Bring in ApacheHandler, necessary for mod_perl integration. +# Uncomment the second line (and comment the first) to use +# Apache::Request instead of CGI.pm to parse arguments. +use HTML::Mason::ApacheHandler; +# use HTML::Mason::ApacheHandler (args_method=>'mod_perl'); + +# Uncomment the next line if you plan to use the Mason previewer. +#use HTML::Mason::Preview; + +use strict; + +# List of modules that you want to use from components (see Admin +# manual for details) +#{ package HTML::Mason::Commands; +# use CGI; +#} + +# Create Mason objects +# +my $parser = new HTML::Mason::Parser; +my $interp = new HTML::Mason::Interp (parser=>$parser, + comp_root=>'/var/www/masondocs', + data_dir=>'/home/ivan/freeside_current/masondata', + out_mode=>'stream', + ); +my $ah = new HTML::Mason::ApacheHandler ( interp => $interp, + #auto_send_headers => 0, + ); + +# Activate the following if running httpd as root (the normal case). +# Resets ownership of all files created by Mason at startup. +# +chown (Apache->server->uid, Apache->server->gid, $interp->files_written); + +sub handler +{ + my ($r) = @_; + + # If you plan to intermix images in the same directory as + # components, activate the following to prevent Mason from + # evaluating image files as components. + # + #return -1 if $r->content_type && $r->content_type !~ m|^text/|i; + + #rar + { package HTML::Mason::Commands; + use strict; + use vars qw( $cgi $p ); + use CGI; + #use CGI::Carp qw(fatalsToBrowser); + use Date::Format; + use Date::Parse; + use Time::Local; + use Tie::IxHash; + use HTML::Entities; + use IO::Handle; + use IO::File; + use String::Approx qw(amatch); + use Chart::LinesPoints; + use HTML::Widgets::SelectLayers 0.02; + use FS::UID qw(cgisuidsetup dbh getotaker datasrc driver_name); + use FS::Record qw(qsearch qsearchs fields dbdef); + use FS::Conf; + use FS::CGI qw(header menubar popurl table itable ntable idiot eidiot + small_custview myexit http_header); + use FS::Msgcat qw(gettext geterror); + + use FS::agent; + use FS::agent_type; + use FS::domain_record; + use FS::cust_bill; + use FS::cust_bill_pay; + use FS::cust_credit; + use FS::cust_credit_bill; + use FS::cust_main; + use FS::cust_main_county; + use FS::cust_pay; + use FS::cust_pkg; + use FS::cust_refund; + use FS::cust_svc; + use FS::nas; + use FS::part_bill_event; + use FS::part_pkg; + use FS::part_referral; + use FS::part_svc; + use FS::part_svc_router; + use FS::pkg_svc; + use FS::port; + use FS::queue qw(joblisting); + use FS::raddb; + use FS::session; + use FS::svc_acct; + use FS::svc_acct_pop qw(popselector); + use FS::svc_acct_sm; + use FS::svc_domain; + use FS::svc_forward; + use FS::svc_www; + use FS::router; + use FS::part_router_field; + use FS::router_field; + use FS::addr_block; + use FS::part_sb_field; + use FS::sb_field; + use FS::svc_broadband; + use FS::type_pkgs; + use FS::part_export; + use FS::part_export_option; + use FS::export_svc; + use FS::msgcat; + + *CGI::redirect = sub { + my( $self, $location ) = @_; + + #http://www.masonhq.com/docs/faq/#how_do_i_do_an_external_redirect + $m->clear_buffer; + # The next two lines are necessary to stop Apache from re-reading + # POSTed data. + $r->method('GET'); + $r->headers_in->unset('Content-length'); + $r->content_type('text/html'); + #$r->err_header_out('Location' => $location); + $r->header_out('Location' => $location); + $r->header_out('Content-Type' => 'text/html'); + $m->abort(302); + + ''; + }; + + $cgi = new CGI; + &cgisuidsetup($cgi); + #&cgisuidsetup($r); + $p = popurl(2); + } + + $r->content_type('text/html'); + #eorar + + my $headers = $r->headers_out; + $headers->{'Pragma'} = $headers->{'Cache-control'} = 'no-cache'; + #$r->no_cache(1); + $headers->{'Expires'} = '0'; + +# $r->send_http_header; + + my $status = $ah->handle_request($r); + + $status; +} + +1; diff --git a/httemplate/config/config-view.cgi b/httemplate/config/config-view.cgi index bafe5a8e7..9a0006792 100644 --- a/httemplate/config/config-view.cgi +++ b/httemplate/config/config-view.cgi @@ -5,13 +5,13 @@ <% my $conf = new FS::Conf; my @config_items = $conf->config_items; %> <% foreach my $section ( qw(required billing username password UI session - shell mail apache BIND + shell BIND ), '', 'deprecated') { %> <A NAME="<%= $section || 'unclassified' %>"></A> <FONT SIZE="-2"> <% foreach my $nav_section ( qw(required billing username password UI session - shell mail apache BIND + shell BIND ), '', 'deprecated') { %> <% if ( $section eq $nav_section ) { %> diff --git a/httemplate/config/config.cgi b/httemplate/config/config.cgi index fd9a82958..409869e11 100644 --- a/httemplate/config/config.cgi +++ b/httemplate/config/config.cgi @@ -25,13 +25,13 @@ function SafeOnsubmit() { <form name="OneTrueForm" action="config-process.cgi" METHOD="POST" onSubmit="SafeOnsubmit()"> <% foreach my $section ( qw(required billing username password UI session - shell mail apache BIND + shell BIND ), '', 'deprecated') { %> <A NAME="<%= $section || 'unclassified' %>"></A> <FONT SIZE="-2"> <% foreach my $nav_section ( qw(required billing username password UI session - shell mail apache BIND + shell BIND ), '', 'deprecated') { %> <% if ( $section eq $nav_section ) { %> diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html index 51dce4da5..533decb7b 100644 --- a/httemplate/docs/install.html +++ b/httemplate/docs/install.html @@ -13,9 +13,9 @@ Before installing, you need: <li>A <b>transactional</b> database engine <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">supported</a> by Perl's <a href="http://dbi.perl.org">DBI</a>. <ul> <li><a href="http://www.postgresql.org/">PostgreSQL</a> is recommended (v7or later). - <li>MySQL versions before 4.1 do not support standard SQL subqueries and are <b>NOT SUPPORTED</b>. If you are a developer who wishes to contribute MySQL 3.x/4.0 support, see <a href="http://pouncequick.420.am/rt/Ticket/Display.html?id=438">ticket #438</a> in the bug-tracking system and ask on the -devel mailing list. -<!-- <li>MySQL has been reported to work. - <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>. If you want to use MySQL, you <b>must</b> use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a> or <a href="http://www.mysql.com/doc/I/n/InnoDB.html">InnoDB</a>, and set it as the default table type using the <code>--default-table-type=BDB</code> or <code>--default-table-type=InnoDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> or <code>default-table-type=InnoDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>. --> + <li><a href="http://www.mysql.com/">MySQL</a> <b>MINIMUM VERSION 4.1</b> is untested but may work. Versions before 4.1 do not support standard SQL subqueries and are <b>NOT SUPPORTED</b>. If you are a developer who wishes to contribute MySQL 3.x/4.0 support, see <a href="http://pouncequick.420.am/rt/Ticket/Display.html?id=438">ticket #438</a> in the bug-tracking system and ask on the -devel mailing list. +<!-- <li>MySQL has been reported to work. --> + <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>. If you want to use MySQL, you <b>must</b> use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a> or <a href="http://www.mysql.com/doc/I/n/InnoDB.html">InnoDB</a>, and set it as the default table type using the <code>--default-table-type=BDB</code> or <code>--default-table-type=InnoDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> or <code>default-table-type=InnoDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>. </ul> <li>Perl modules (<a href="http://theoryx5.uwinnipeg.ca/CPAN/perl/CPAN.html">CPAN</a> will query, download and build perl modules automatically) <ul> @@ -41,13 +41,13 @@ Before installing, you need: <li><a href="http://search.cpan.org/search?dist=String-Approx">String-Approx</a> <li><a href="http://search.cpan.org/search?dist=Text-Template">Text-Template</a> <li><a href="http://search.cpan.org/search?dist=DBI">DBI</a> - <li><a href="http://search.cpan.org/search?mode=module&query=DBD">DBD for your database engine</a> (<a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> for PostgreSQL<!--, <a href="http://search.cpan.org/search?dist=DBD-mysql">DBD::mysql</a> for MySQL-->) + <li><a href="http://search.cpan.org/search?mode=module&query=DBD">DBD for your database engine</a> (<a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> for PostgreSQL, <a href="http://search.cpan.org/search?dist=DBD-mysql">DBD::mysql</a> for MySQL) <li><a href="http://search.cpan.org/search?dist=DBIx-DataSource">DBIx-DataSource</a> <li><a href="http://search.cpan.org/search?dist=DBIx-DBSchema">DBIx-DBSchema</a> <li><a href="http://search.cpan.org/search?dist=Net-SSH">Net-SSH</a> <li><a href="http://search.cpan.org/search?dist=String-ShellQuote">String-ShellQuote</a> <li><a href="http://search.cpan.org/search?dist=Net-SCP">Net-SCP</a> - <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a> (use version 1.0x - Freeside is not yet compatible with version 1.1x) + <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a> <li><a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a> <li><a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a> <li><a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a> @@ -72,17 +72,16 @@ Enter it again: Shall the new user be allowed to create databases? (y/n) y Shall the new user be allowed to create more new users? (y/n) n CREATE USER</pre> -<!-- <li> with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#User_Account_Management">MySQL</a>: + <li> with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#User_Account_Management">MySQL</a>: <pre> $ mysqladmin -u root password '<i>set_a_root_database_password</i>' $ mysql -u root -p mysql> GRANT SELECT,INSERT,UPDATE,DELETE,INDEX,ALTER,CREATE,DROP on freeside.* TO freeside@localhost IDENTIFIED BY '<i>set_a_freeside_database_password</i>';</pre> ---> </ul> <!-- <li>Unpack the tarball: <pre>gunzip -c fs-x.y.z.tar.gz | tar xvf -</pre>--> <li>Edit the top-level Makefile: <ul> - <li>Set <tt>DATASOURCE</tt> to your <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI data source</a>, for example, <tt>DBI:Pg:dbname=freeside</tt> for PostgresSQL<!-- or <tt>DBI:mysql:freeside</tt> for MySQL-->. See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI manpage</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">manpage for your DBD</a> for the exact syntax of your DBI data source. + <li>Set <tt>DATASOURCE</tt> to your <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI data source</a>, for example, <tt>DBI:Pg:dbname=freeside</tt> for PostgresSQL or <tt>DBI:mysql:freeside</tt> for MySQL. See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI manpage</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">manpage for your DBD</a> for the exact syntax of your DBI data source. <li>Set <tt>DB_PASSWORD</tt> to the freeside database user's password. </ul> <li>Add the freeside database to your database engine: @@ -93,10 +92,9 @@ $ su <pre> $ su freeside $ createdb freeside</pre> -<!-- (with MySQL:) + (with MySQL:) <pre> $ mysqladmin -u freeside -p create freeside </pre> ---> <li>Build and install the Perl modules: <pre> $ make perl-modules @@ -145,11 +143,10 @@ PerlSetVar Debug 2 </pre></font> </ul></td> <td><ul> - <li>(use version 1.0x - Freeside is not yet compatible with version 1.1x) <li>Run <tt>make masondocs</tt> <li>Copy <tt>masondocs/</tt> to your web server's document space. - <li>Copy <tt>htetc/handler.pl</tt> to your web server's configuration directory. - <li>Edit <tt>handler.pl</tt> and set an appropriate <tt>data_dir</tt>, such as <tt>/usr/local/etc/freeside/mason-data</tt> + <li>Copy <tt>htetc/handler.pl</tt> to an appropriate directory (use htetc/handler.pl-1.0x for Mason versions before 1.10). + <li>Edit <tt>handler.pl</tt> and set an appropriate <tt>data_dir</tt>, such as <tt>/usr/local/etc/freeside/masondata</tt> <li>Configure Apache to use the <tt>handler.pl</tt> file and to execute .cgi files using HTML::Mason. For example: <font size="-1"><pre> PerlModule HTML::Mason @@ -159,7 +156,7 @@ AddHandler perl-script .cgi PerlHandler HTML::Mason </Files> <Perl> -require "/usr/local/apache/conf/handler.pl"; +require "/usr/local/etc/freeside/handler.pl"; </Perl> </Directory> </pre></font> diff --git a/httemplate/edit/part_export.cgi b/httemplate/edit/part_export.cgi index 839a114fb..4defbc86f 100644 --- a/httemplate/edit/part_export.cgi +++ b/httemplate/edit/part_export.cgi @@ -60,7 +60,7 @@ my $widget = new HTML::Widgets::SelectLayers( foreach my $select_option ( @{$optinfo->{options}} ) { #if ( ref($select_option) ) { #} else { - $selected = $select_option eq $value ? ' SELECTED' : ''; + my $selected = $select_option eq $value ? ' SELECTED' : ''; $html .= qq!<OPTION VALUE="$select_option"$selected>!. qq!$select_option</OPTION>!; #} diff --git a/httemplate/edit/part_router_field.cgi b/httemplate/edit/part_router_field.cgi index c3e99be2c..02962b1c0 100644 --- a/httemplate/edit/part_router_field.cgi +++ b/httemplate/edit/part_router_field.cgi @@ -21,7 +21,10 @@ if ( $cgi->param('error') ) { my $action = $part_router_field->routerfieldpart ? 'Edit' : 'Add'; my $p1 = popurl(1); -print header("$action Router Extended Field Definition", ''); +print header("$action Router Extended Field Definition", + menubar('Main Menu' => $p, + 'View all Extended Fields' => $p. 'browse/generic.cgi?part_router_field') + ); print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'), "</FONT>" @@ -30,8 +33,6 @@ print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'), <FORM ACTION="<%=$p1%>process/generic.cgi" METHOD=POST> <INPUT TYPE="hidden" NAME="table" VALUE="part_router_field"> -<INPUT TYPE="hidden" NAME="redirect_ok" - VALUE="<%=$p1%>part_router_field.cgi"> <INPUT TYPE="hidden" NAME="routerfieldpart" VALUE="<%= $routerfieldpart%>"> Field #<B><%=$routerfieldpart or "(NEW)"%></B><BR><BR> diff --git a/httemplate/edit/process/generic.cgi b/httemplate/edit/process/generic.cgi index 751987f7a..9c54feb1d 100644 --- a/httemplate/edit/process/generic.cgi +++ b/httemplate/edit/process/generic.cgi @@ -27,6 +27,7 @@ use DBIx::DBSchema::Table; my $error; my $p2 = popurl(2); +my $p3 = popurl(3); my $table = $cgi->param('table'); my $dbdef = dbdef or die "Cannot fetch dbdef!"; @@ -56,7 +57,7 @@ if($pkey_val and (my $old = qsearchs($table, { $pkey, $pkey_val} ))) { } my $redirect_ok = (($cgi->param('redirect_ok')) ? - $cgi->param('redirect_ok') : $p2."view/$table.cgi"); + $cgi->param('redirect_ok') : $p3."browse/generic.cgi?$table"); my $redirect_error = (($cgi->param('redirect_error')) ? $cgi->param('redirect_error') : $cgi->referer()); @@ -64,6 +65,6 @@ if($error) { $cgi->param('error', $error); print $cgi->redirect($redirect_error . '?' . $cgi->query_string); } else { - print $cgi->redirect($redirect_ok . '?' .$pkey_val); + print $cgi->redirect($redirect_ok); } %> diff --git a/httemplate/edit/process/router.cgi b/httemplate/edit/process/router.cgi index c0cb884f0..1b7fc3805 100644 --- a/httemplate/edit/process/router.cgi +++ b/httemplate/edit/process/router.cgi @@ -34,6 +34,7 @@ if($old) { } #else do nothing } else { $error = $new->insert; + $routernum = $new->routernum; } check($error); @@ -95,6 +96,6 @@ foreach($cgi->param) { # Yay, everything worked! $dbh->commit or die $dbh->errstr; -print $cgi->redirect(popurl(3). "edit/router.cgi?$routernum"); +print $cgi->redirect(popurl(3). "browse/router.cgi"); %> diff --git a/httemplate/edit/router.cgi b/httemplate/edit/router.cgi index d2279ff00..b524c6494 100755 --- a/httemplate/edit/router.cgi +++ b/httemplate/edit/router.cgi @@ -32,6 +32,10 @@ if($cgi->param('error')) { Router #<%=$routernum or "(NEW)"%> <BR><BR>Name <INPUT TYPE="text" NAME="routername" SIZE=32 VALUE="<%=$hashref->{routername}%>"> + +<BR><BR> +Custom fields: +<BR> <%=table() %> <% diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi index fe4ec5d05..5b39a09f2 100755 --- a/httemplate/search/cust_main.cgi +++ b/httemplate/search/cust_main.cgi @@ -469,7 +469,7 @@ sub cardsearch { $card =~ /^(\d{13,16})$/ or eidiot "Illegal card number\n"; my($payinfo)=$1; - [ qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'}) + [ qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'}), qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'DCRD'}) ]; } diff --git a/httemplate/view/svc_acct.cgi b/httemplate/view/svc_acct.cgi index f04e47163..599c1d8b9 100755 --- a/httemplate/view/svc_acct.cgi +++ b/httemplate/view/svc_acct.cgi @@ -1,4 +1,4 @@ -<-- mason kludge --> +<!-- mason kludge --> <% my $conf = new FS::Conf; |