line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Provision::Unix::Web::Apache; |
2
|
|
|
|
|
|
|
# ABSTRACT: provision web hosting accounts on Apache |
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
55
|
|
5
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
72
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.10'; |
8
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
5
|
use English qw( -no_match_vars ); |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
22
|
|
10
|
1
|
|
|
1
|
|
829
|
use Params::Validate qw( :all ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
670
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
my ( $prov, $util, $web ); |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub new { |
15
|
1
|
|
|
1
|
0
|
3
|
my $class = shift; |
16
|
|
|
|
|
|
|
|
17
|
1
|
|
|
|
|
57
|
my %p = validate( |
18
|
|
|
|
|
|
|
@_, |
19
|
|
|
|
|
|
|
{ prov => { type => OBJECT }, |
20
|
|
|
|
|
|
|
web => { type => OBJECT }, |
21
|
|
|
|
|
|
|
debug => { type => BOOLEAN, optional => 1, default => 1 }, |
22
|
|
|
|
|
|
|
fatal => { type => BOOLEAN, optional => 1, default => 1 }, |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
); |
25
|
|
|
|
|
|
|
|
26
|
1
|
|
|
|
|
10
|
$web = $p{web}; |
27
|
1
|
|
|
|
|
3
|
$prov = $p{prov}; |
28
|
|
|
|
|
|
|
## no critic |
29
|
1
|
|
|
|
|
62
|
eval "require Apache::Admin::Config"; |
30
|
|
|
|
|
|
|
## use critic |
31
|
1
|
50
|
|
|
|
22643
|
if ( $EVAL_ERROR ) { |
32
|
0
|
|
|
|
|
0
|
return $prov->error( 'Apache::Admin::Config not installed', |
33
|
|
|
|
|
|
|
fatal => $p{fatal}, |
34
|
|
|
|
|
|
|
debug => $p{debug}, |
35
|
|
|
|
|
|
|
); |
36
|
|
|
|
|
|
|
}; |
37
|
1
|
|
|
|
|
10
|
$util = $prov->get_util; |
38
|
|
|
|
|
|
|
|
39
|
1
|
|
|
|
|
2
|
my $self = {}; |
40
|
1
|
|
|
|
|
6
|
bless( $self, $class ); |
41
|
|
|
|
|
|
|
|
42
|
1
|
|
|
|
|
21
|
return $self; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub create { |
46
|
|
|
|
|
|
|
|
47
|
1
|
|
|
1
|
1
|
2
|
my $self = shift; |
48
|
|
|
|
|
|
|
|
49
|
1
|
|
|
|
|
38
|
my %p = validate( |
50
|
|
|
|
|
|
|
@_, |
51
|
|
|
|
|
|
|
{ 'request' => { type => HASHREF, optional => 1, }, |
52
|
|
|
|
|
|
|
'prompt' => { type => BOOLEAN, optional => 1, default => 0 }, |
53
|
|
|
|
|
|
|
'test_mode' => { type => BOOLEAN, optional => 1, default => 0 }, |
54
|
|
|
|
|
|
|
'fatal' => { type => SCALAR, optional => 1, default => 1 }, |
55
|
|
|
|
|
|
|
'debug' => { type => SCALAR, optional => 1, default => 1 }, |
56
|
|
|
|
|
|
|
}, |
57
|
|
|
|
|
|
|
); |
58
|
|
|
|
|
|
|
|
59
|
1
|
|
|
|
|
14
|
my $vals = $web->get_vhost_attributes( |
60
|
|
|
|
|
|
|
{ request => $p{request}, |
61
|
|
|
|
|
|
|
prompt => $p{prompt}, |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
); |
64
|
|
|
|
|
|
|
|
65
|
1
|
|
|
|
|
6
|
$prov->audit("apache create"); |
66
|
|
|
|
|
|
|
|
67
|
1
|
50
|
|
|
|
6
|
if ( $self->exists( request => $vals ) ) { |
68
|
0
|
|
|
|
|
0
|
return $prov->error( "that virtual host already exists", ); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# test all the values and make sure we've got enough to form a vhost |
72
|
|
|
|
|
|
|
# minimum needed: vhost servername, ip[:port], documentroot |
73
|
|
|
|
|
|
|
|
74
|
1
|
|
50
|
|
|
7
|
my $ip = $vals->{'ip'} || '*:80'; |
75
|
1
|
|
|
|
|
3
|
my $name = lc( $vals->{'vhost'} ); |
76
|
1
|
|
|
|
|
2
|
my $docroot = $vals->{'documentroot'}; |
77
|
1
|
|
50
|
|
|
6
|
my $home = $vals->{'admin_home'} || "/home"; |
78
|
|
|
|
|
|
|
|
79
|
1
|
50
|
|
|
|
4
|
unless ($docroot) { |
80
|
0
|
0
|
|
|
|
0
|
if ( -d "$home/$name" ) { $docroot = "$home/$name" } |
|
0
|
|
|
|
|
0
|
|
81
|
0
|
0
|
|
|
|
0
|
return $prov->error( |
82
|
|
|
|
|
|
|
"documentroot was not set and could not be determined!", ) |
83
|
|
|
|
|
|
|
unless -d $docroot; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
1
|
50
|
|
1
|
|
6
|
if ( $p{debug} ) { use Data::Dumper; print Dumper($vals); } |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
2298
|
|
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
11
|
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# define the vhost |
89
|
1
|
|
|
|
|
155
|
my @lines = "\n<VirtualHost $ip>"; |
90
|
1
|
|
|
|
|
4
|
push @lines, " ServerName $name"; |
91
|
1
|
|
|
|
|
3
|
push @lines, " DocumentRoot $docroot"; |
92
|
1
|
50
|
|
|
|
6
|
push @lines, " ServerAdmin " . $vals->{'serveradmin'} |
93
|
|
|
|
|
|
|
if $vals->{'serveradmin'}; |
94
|
1
|
50
|
|
|
|
5
|
push @lines, " ServerAlias " . $vals->{'serveralias'} |
95
|
|
|
|
|
|
|
if $vals->{'serveralias'}; |
96
|
1
|
50
|
|
|
|
4
|
if ( $vals->{'cgi'} ) { |
97
|
0
|
0
|
|
|
|
0
|
if ( $vals->{'cgi'} eq "basic" ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
98
|
0
|
|
|
|
|
0
|
push @lines, |
99
|
|
|
|
|
|
|
" ScriptAlias /cgi-bin/ \"/usr/local/www/cgi-bin.basic/"; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
elsif ( $vals->{'cgi'} eq "advanced" ) { |
102
|
0
|
|
|
|
|
0
|
push @lines, |
103
|
|
|
|
|
|
|
" ScriptAlias /cgi-bin/ \"/usr/local/www/cgi-bin.advanced/\""; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
elsif ( $vals->{'cgi'} eq "custom" ) { |
106
|
0
|
|
|
|
|
0
|
push @lines, |
107
|
|
|
|
|
|
|
" ScriptAlias /cgi-bin/ \"" |
108
|
|
|
|
|
|
|
. $vals->{'documentroot'} |
109
|
|
|
|
|
|
|
. "/cgi-bin/\""; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
else { |
112
|
0
|
|
|
|
|
0
|
push @lines, " ScriptAlias " . $vals->{'cgi'}; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# options needs some directory logic included if it's going to be used |
118
|
|
|
|
|
|
|
# I won't be using this initially, but maybe eventually... |
119
|
|
|
|
|
|
|
#push @lines, " Options " . $vals->{'options'} if $vals->{'options'}; |
120
|
|
|
|
|
|
|
|
121
|
1
|
50
|
|
|
|
3
|
push @lines, " CustomLog " . $vals->{'customlog'} if $vals->{'customlog'}; |
122
|
1
|
50
|
|
|
|
10
|
push @lines, " CustomError " . $vals->{'customerror'} |
123
|
|
|
|
|
|
|
if $vals->{'customerror'}; |
124
|
1
|
50
|
|
|
|
5
|
if ( $vals->{'ssl'} ) { |
125
|
0
|
0
|
0
|
|
|
0
|
if ( !$vals->{'sslkey'} |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
126
|
|
|
|
|
|
|
or !$vals->{'sslcert'} |
127
|
|
|
|
|
|
|
or !-f $vals->{'sslkey'} |
128
|
|
|
|
|
|
|
or !$vals->{'sslcert'} ) |
129
|
|
|
|
|
|
|
{ |
130
|
0
|
|
|
|
|
0
|
return $prov->error( |
131
|
|
|
|
|
|
|
"ssl is enabled but either the key or cert is missing!" ); |
132
|
|
|
|
|
|
|
} |
133
|
0
|
|
|
|
|
0
|
push @lines, " SSLEngine on"; |
134
|
0
|
0
|
|
|
|
0
|
push @lines, " SSLCertificateKey " . $vals->{'sslkey'} |
135
|
|
|
|
|
|
|
if $vals->{'sslkey'}; |
136
|
0
|
0
|
|
|
|
0
|
push @lines, " SSLCertificateFile " . $vals->{'sslcert'} |
137
|
|
|
|
|
|
|
if $vals->{'sslcert'}; |
138
|
|
|
|
|
|
|
} |
139
|
1
|
|
|
|
|
2
|
push @lines, "</VirtualHost>\n"; |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
# write vhost definition to a file |
142
|
1
|
|
|
|
|
7
|
my ($vhosts_conf) = $self->get_file($vals); |
143
|
|
|
|
|
|
|
|
144
|
1
|
50
|
|
|
|
12
|
return 1 if $p{test_mode}; |
145
|
|
|
|
|
|
|
|
146
|
0
|
0
|
|
|
|
0
|
if ( -f $vhosts_conf ) { |
147
|
0
|
|
|
|
|
0
|
$prov->audit("appending to file: $vhosts_conf"); |
148
|
0
|
|
|
|
|
0
|
$util->file_write( $vhosts_conf, |
149
|
|
|
|
|
|
|
lines => \@lines, |
150
|
|
|
|
|
|
|
append => 1, |
151
|
|
|
|
|
|
|
); |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
else { |
154
|
0
|
|
|
|
|
0
|
$prov->audit("writing to file: $vhosts_conf"); |
155
|
0
|
|
|
|
|
0
|
$util->file_write( $vhosts_conf, lines => \@lines ); |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
0
|
|
|
|
|
0
|
$self->restart($vals); |
159
|
|
|
|
|
|
|
|
160
|
0
|
|
|
|
|
0
|
$prov->audit("returning success"); |
161
|
0
|
|
|
|
|
0
|
return 1; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub conf_get_dir { |
165
|
|
|
|
|
|
|
|
166
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
167
|
0
|
|
|
|
|
0
|
my %p = validate( |
168
|
|
|
|
|
|
|
@_, |
169
|
|
|
|
|
|
|
{ 'conf' => HASHREF, |
170
|
|
|
|
|
|
|
'debug' => { type => SCALAR, optional => 1, default => 1 }, |
171
|
|
|
|
|
|
|
}, |
172
|
|
|
|
|
|
|
); |
173
|
|
|
|
|
|
|
|
174
|
0
|
|
|
|
|
0
|
my $conf = $p{'conf'}; |
175
|
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
0
|
my $prefix = "/usr/local"; |
177
|
0
|
|
|
|
|
0
|
my $apachectl = "$prefix/sbin/apachectl"; |
178
|
|
|
|
|
|
|
|
179
|
0
|
0
|
|
|
|
0
|
unless ( -x $apachectl ) { |
180
|
0
|
|
|
|
|
0
|
$apachectl = $util->find_bin( "apachectl", |
181
|
|
|
|
|
|
|
debug => 0, |
182
|
|
|
|
|
|
|
fatal => 0 |
183
|
|
|
|
|
|
|
); |
184
|
|
|
|
|
|
|
|
185
|
0
|
0
|
|
|
|
0
|
unless ( -x $apachectl ) { |
186
|
0
|
|
|
|
|
0
|
die "apache->conf_get_dir: failed to find apachectl! |
187
|
|
|
|
|
|
|
Is Apache installed correctly?\n"; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# the -V flag to apachectl returns this string: |
192
|
|
|
|
|
|
|
# -D SERVER_CONFIG_FILE="etc/apache22/httpd.conf" |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# and we can grab the path to httpd.conf from the string |
195
|
0
|
0
|
|
|
|
0
|
if ( grep ( /SERVER_CONFIG_FILE/, `$apachectl -V` ) =~ /=\"(.*)\"/ ) { |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
# and return a fully qualified path to httpd.conf |
198
|
0
|
0
|
0
|
|
|
0
|
if ( -f "$prefix/$1" && -s "$prefix/$1" ) { |
199
|
0
|
|
|
|
|
0
|
return "$prefix/$1"; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
warn |
203
|
0
|
|
|
|
|
0
|
"apachectl returned $1 as the location of your httpd.conf file but $prefix/$1 does not exist! I'm sorry but I cannot go on like this. Please fix your Apache install and try again.\n"; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
# apachectl did not return anything useful from -V, must be apache 1.x |
207
|
0
|
|
|
|
|
0
|
my @paths; |
208
|
|
|
|
|
|
|
my @found; |
209
|
|
|
|
|
|
|
|
210
|
0
|
0
|
|
|
|
0
|
if ( $OSNAME eq "darwin" ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
211
|
0
|
|
|
|
|
0
|
push @paths, "/opt/local/etc"; |
212
|
0
|
|
|
|
|
0
|
push @paths, "/private/etc"; |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
elsif ( $OSNAME eq "freebsd" ) { |
215
|
0
|
|
|
|
|
0
|
push @paths, "/usr/local/etc"; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
elsif ( $OSNAME eq "linux" ) { |
218
|
0
|
|
|
|
|
0
|
push @paths, "/etc"; |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
else { |
221
|
0
|
|
|
|
|
0
|
push @paths, "/usr/local/etc"; |
222
|
0
|
|
|
|
|
0
|
push @paths, "/opt/local/etc"; |
223
|
0
|
|
|
|
|
0
|
push @paths, "/etc"; |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
PATH: |
227
|
0
|
|
|
|
|
0
|
foreach my $path (@paths) { |
228
|
0
|
0
|
0
|
|
|
0
|
if ( !-e $path && !-d $path ) { |
229
|
0
|
|
|
|
|
0
|
next PATH; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
0
|
|
|
|
|
0
|
@found = `find $path -name httpd.conf`; |
233
|
0
|
|
|
|
|
0
|
chomp @found; |
234
|
0
|
|
|
|
|
0
|
foreach my $find (@found) { |
235
|
0
|
0
|
|
|
|
0
|
if ( -f $find ) { |
236
|
0
|
|
|
|
|
0
|
return $find; |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
0
|
|
|
|
|
0
|
return; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub restart { |
245
|
|
|
|
|
|
|
|
246
|
0
|
|
|
0
|
0
|
0
|
my ( $self, $vals ) = @_; |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# restart apache |
249
|
|
|
|
|
|
|
|
250
|
0
|
0
|
|
|
|
0
|
print "restarting apache.\n" if $vals->{'debug'}; |
251
|
|
|
|
|
|
|
|
252
|
0
|
0
|
|
|
|
0
|
if ( -x "/usr/local/etc/rc.d/apache2.sh" ) { |
|
|
0
|
|
|
|
|
|
253
|
0
|
|
|
|
|
0
|
$util->syscmd( "/usr/local/etc/rc.d/apache2.sh stop" ); |
254
|
0
|
|
|
|
|
0
|
$util->syscmd( "/usr/local/etc/rc.d/apache2.sh start" ); |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
elsif ( -x "/usr/local/etc/rc.d/apache.sh" ) { |
257
|
0
|
|
|
|
|
0
|
$util->syscmd( "/usr/local/etc/rc.d/apache.sh stop" ); |
258
|
0
|
|
|
|
|
0
|
$util->syscmd( "/usr/local/etc/rc.d/apache.sh start" ); |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
else { |
261
|
0
|
|
|
|
|
0
|
my $apachectl = $util->find_bin( "apachectl" ); |
262
|
0
|
0
|
|
|
|
0
|
if ( -x $apachectl ) { |
263
|
0
|
|
|
|
|
0
|
$util->syscmd( "$apachectl graceful" ); |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
else { |
266
|
0
|
|
|
|
|
0
|
warn "WARNING: couldn't restart Apache!\n "; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
sub enable { |
272
|
|
|
|
|
|
|
|
273
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
274
|
|
|
|
|
|
|
|
275
|
0
|
|
|
|
|
0
|
my %p = validate( @_, { request => { type => HASHREF } } ); |
276
|
0
|
|
|
|
|
0
|
my $vals = $p{'request'}; |
277
|
|
|
|
|
|
|
|
278
|
0
|
0
|
|
|
|
0
|
if ( $self->exists( request => $vals) ) { |
279
|
|
|
|
|
|
|
return { |
280
|
0
|
|
|
|
|
0
|
error_code => 400, |
281
|
|
|
|
|
|
|
error_desc => "Sorry, that virtual host is already enabled." |
282
|
|
|
|
|
|
|
}; |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
|
285
|
0
|
|
|
|
|
0
|
print "enabling $vals->{'vhost'} \n"; |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
# get the file the disabled vhost would live in |
288
|
0
|
|
|
|
|
0
|
my ($vhosts_conf) = $self->get_file($vals); |
289
|
|
|
|
|
|
|
|
290
|
0
|
0
|
|
|
|
0
|
print "the disabled vhost should be in $vhosts_conf.disabled\n" |
291
|
|
|
|
|
|
|
if $vals->{'debug'}; |
292
|
|
|
|
|
|
|
|
293
|
0
|
0
|
|
|
|
0
|
unless ( -s "$vhosts_conf.disabled" ) { |
294
|
|
|
|
|
|
|
return { |
295
|
0
|
|
|
|
|
0
|
error_code => 400, |
296
|
|
|
|
|
|
|
error_desc => "That vhost is not disabled, I cannot enable it!" |
297
|
|
|
|
|
|
|
}; |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
0
|
|
|
|
|
0
|
$vals->{'disabled'} = 1; |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
# split the file into two parts |
303
|
0
|
|
|
|
|
0
|
( undef, my $match, $vals ) = $self->get_match($vals); |
304
|
|
|
|
|
|
|
|
305
|
0
|
|
|
|
|
0
|
print "enabling: \n", join( "\n", @$match ), "\n"; |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
# write vhost definition to a file |
308
|
0
|
0
|
|
|
|
0
|
if ( -f $vhosts_conf ) { |
309
|
0
|
0
|
|
|
|
0
|
print "appending to file: $vhosts_conf\n" if $vals->{'debug'}; |
310
|
0
|
|
|
|
|
0
|
$util->file_write( $vhosts_conf, |
311
|
|
|
|
|
|
|
lines => $match, |
312
|
|
|
|
|
|
|
append => 1 |
313
|
|
|
|
|
|
|
); |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
else { |
316
|
0
|
0
|
|
|
|
0
|
print "writing to file: $vhosts_conf\n" if $vals->{'debug'}; |
317
|
0
|
|
|
|
|
0
|
$util->file_write( $vhosts_conf, lines => $match ); |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
0
|
|
|
|
|
0
|
$self->restart($vals); |
321
|
|
|
|
|
|
|
|
322
|
0
|
0
|
|
|
|
0
|
if ( $vals->{'documentroot'} ) { |
323
|
0
|
|
|
|
|
0
|
print "docroot: $vals->{'documentroot'} \n"; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# chmod 755 the documentroot directory |
326
|
0
|
0
|
0
|
|
|
0
|
if ( $vals->{'documentroot'} && -d $vals->{'documentroot'} ) { |
327
|
0
|
|
|
|
|
0
|
my $chmod = $util->find_bin( "chmod" ); |
328
|
0
|
|
|
|
|
0
|
$util->syscmd( "$chmod 755 $vals->{'documentroot'}" ); |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
|
332
|
0
|
0
|
|
|
|
0
|
print "returning success or error\n" if $vals->{'debug'}; |
333
|
0
|
|
|
|
|
0
|
return { error_code => 200, error_desc => "vhost enabled successfully" }; |
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
sub disable { |
337
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
338
|
|
|
|
|
|
|
|
339
|
0
|
|
|
|
|
0
|
my %p = validate( @_, { request => { type => HASHREF } } ); |
340
|
0
|
|
|
|
|
0
|
my $vals = $p{'request'}; |
341
|
|
|
|
|
|
|
|
342
|
0
|
0
|
|
|
|
0
|
if ( ! $self->exists( request => $vals) ) { |
343
|
0
|
|
|
|
|
0
|
warn "Sorry, that virtual host does not exist."; |
344
|
0
|
|
|
|
|
0
|
return; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
0
|
|
|
|
|
0
|
print "disabling $vals->{'vhost'}\n"; |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
# get the file the vhost lives in |
350
|
0
|
|
|
|
|
0
|
$vals->{'disabled'} = 0; |
351
|
0
|
|
|
|
|
0
|
my ($vhosts_conf) = $self->get_file($vals); |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
# split the file into two parts |
354
|
0
|
|
|
|
|
0
|
( my $new, my $match, $vals ) = $self->get_match($vals); |
355
|
|
|
|
|
|
|
|
356
|
0
|
|
|
|
|
0
|
print "Disabling: \n" . join( "\n", @$match ) . "\n"; |
357
|
|
|
|
|
|
|
|
358
|
0
|
|
|
|
|
0
|
$util->file_write( "$vhosts_conf.new", lines => $new ); |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
# write out the .disabled file (append if existing) |
361
|
0
|
0
|
|
|
|
0
|
if ( -f "$vhosts_conf.disabled" ) { |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
# check to see if it's already in there |
364
|
0
|
|
|
|
|
0
|
$vals->{'disabled'} = 1; |
365
|
0
|
|
|
|
|
0
|
( undef, my $dis_match, $vals ) = $self->get_match($vals); |
366
|
|
|
|
|
|
|
|
367
|
0
|
0
|
|
|
|
0
|
if ( @$dis_match[1] ) { |
368
|
0
|
|
|
|
|
0
|
print "it's already in $vhosts_conf.disabled. skipping append.\n"; |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
else { |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
# if not, append it |
373
|
0
|
0
|
|
|
|
0
|
print "appending to file: $vhosts_conf.disabled\n" |
374
|
|
|
|
|
|
|
if $vals->{'debug'}; |
375
|
0
|
|
|
|
|
0
|
$util->file_write( "$vhosts_conf.disabled", |
376
|
|
|
|
|
|
|
lines => $match, |
377
|
|
|
|
|
|
|
append => 1, |
378
|
|
|
|
|
|
|
); |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
else { |
382
|
0
|
0
|
|
|
|
0
|
print "writing to file: $vhosts_conf.disabled\n" if $vals->{'debug'}; |
383
|
0
|
|
|
|
|
0
|
$util->file_write( "$vhosts_conf.disabled", |
384
|
|
|
|
|
|
|
lines => $match, |
385
|
|
|
|
|
|
|
); |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
|
388
|
0
|
0
|
0
|
|
|
0
|
if ( ( -s "$vhosts_conf.new" ) && ( -s "$vhosts_conf.disabled" ) ) { |
389
|
0
|
0
|
|
|
|
0
|
print "Yay, success!\n" if $vals->{'debug'}; |
390
|
0
|
0
|
|
|
|
0
|
if ( $< eq 0 ) { |
391
|
1
|
|
|
1
|
|
1146
|
use File::Copy; # this only works if we're root |
|
1
|
|
|
|
|
3057
|
|
|
1
|
|
|
|
|
470
|
|
392
|
0
|
|
|
|
|
0
|
move( "$vhosts_conf.new", $vhosts_conf ); |
393
|
|
|
|
|
|
|
} |
394
|
|
|
|
|
|
|
else { |
395
|
0
|
|
|
|
|
0
|
my $mv = $util->find_bin( "move" ); |
396
|
0
|
|
|
|
|
0
|
$util->syscmd( "$mv $vhosts_conf.new $vhosts_conf" ); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
else { |
400
|
|
|
|
|
|
|
return { |
401
|
0
|
|
|
|
|
0
|
error_code => 500, |
402
|
|
|
|
|
|
|
error_desc => |
403
|
|
|
|
|
|
|
"Oops, the size of $vhosts_conf.new or $vhosts_conf.disabled is zero. This is a likely indication of an error. I have left the files for you to examine and correct" |
404
|
|
|
|
|
|
|
}; |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
0
|
|
|
|
|
0
|
$self->restart($vals); |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
# chmod 0 the HTML directory |
410
|
0
|
0
|
0
|
|
|
0
|
if ( $vals->{'documentroot'} && -d $vals->{'documentroot'} ) { |
411
|
0
|
|
|
|
|
0
|
my $chmod = $util->find_bin( "chmod" ); |
412
|
0
|
|
|
|
|
0
|
$util->syscmd( "$chmod 0 $vals->{'documentroot'}" ); |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
|
415
|
0
|
0
|
|
|
|
0
|
print "returning success or error\n" if $vals->{'debug'}; |
416
|
0
|
|
|
|
|
0
|
return { error_code => 200, error_desc => "vhost disabled successfully" }; |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
sub destroy { |
420
|
|
|
|
|
|
|
|
421
|
0
|
|
|
0
|
1
|
0
|
my ( $self, $vals ) = @_; |
422
|
|
|
|
|
|
|
|
423
|
0
|
0
|
|
|
|
0
|
unless ( $self->exists( request => $vals) ) { |
424
|
|
|
|
|
|
|
return { |
425
|
0
|
|
|
|
|
0
|
error_code => 400, |
426
|
|
|
|
|
|
|
error_desc => "Sorry, that virtual host does not exist." |
427
|
|
|
|
|
|
|
}; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
|
430
|
0
|
|
|
|
|
0
|
print "deleting vhost " . $vals->{'vhost'} . "\n"; |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
# this isn't going to be pretty. |
433
|
|
|
|
|
|
|
# basically, we need to parse through the config file, find the right vhost container, and then remove only that vhost |
434
|
|
|
|
|
|
|
# I'll do that by setting a counter that trips every time I enter a vhost and counts the lines (so if the servername declaration is on the 5th or 1st line, I'll still know where to nip the first line containing the virtualhost opening declaration) |
435
|
|
|
|
|
|
|
# |
436
|
|
|
|
|
|
|
|
437
|
0
|
|
|
|
|
0
|
my ($vhosts_conf) = $self->get_file($vals); |
438
|
0
|
|
|
|
|
0
|
my ( $new, $drop ) = $self->get_match($vals); |
439
|
|
|
|
|
|
|
|
440
|
0
|
|
|
|
|
0
|
print "Dropping: \n" . join( "\n", @$drop ) . "\n"; |
441
|
|
|
|
|
|
|
|
442
|
0
|
0
|
0
|
|
|
0
|
if ( scalar @$new == 0 || scalar @$drop == 0 ) { |
443
|
|
|
|
|
|
|
return { |
444
|
0
|
|
|
|
|
0
|
error_code => 500, |
445
|
|
|
|
|
|
|
error_desc => "yikes, something went horribly wrong!" |
446
|
|
|
|
|
|
|
}; |
447
|
|
|
|
|
|
|
} |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
# now, just for fun, lets make sure things work out OK |
450
|
|
|
|
|
|
|
# we'll write out @new and @drop and compare them to make sure |
451
|
|
|
|
|
|
|
# the two total the same size as the original |
452
|
|
|
|
|
|
|
|
453
|
0
|
|
|
|
|
0
|
$util->file_write( "$vhosts_conf.new", lines => $new ); |
454
|
0
|
|
|
|
|
0
|
$util->file_write( "$vhosts_conf.drop", lines => $drop ); |
455
|
|
|
|
|
|
|
|
456
|
0
|
0
|
|
|
|
0
|
if ( ( ( -s "$vhosts_conf.new" ) + ( -s "$vhosts_conf.drop" ) ) |
457
|
|
|
|
|
|
|
== -s $vhosts_conf ) |
458
|
|
|
|
|
|
|
{ |
459
|
0
|
|
|
|
|
0
|
print "Yay, success!\n"; |
460
|
1
|
|
|
1
|
|
6
|
use File::Copy; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
1853
|
|
461
|
0
|
|
|
|
|
0
|
move( "$vhosts_conf.new", $vhosts_conf ); |
462
|
0
|
|
|
|
|
0
|
unlink("$vhosts_conf.drop"); |
463
|
|
|
|
|
|
|
} |
464
|
|
|
|
|
|
|
else { |
465
|
|
|
|
|
|
|
return { |
466
|
0
|
|
|
|
|
0
|
error_code => 500, |
467
|
|
|
|
|
|
|
error_desc => |
468
|
|
|
|
|
|
|
"Oops, the size of $vhosts_conf.new and $vhosts_conf.drop combined is not the same as $vhosts_conf. This is a likely indication of an error. I have left the files for you to examine and correct" |
469
|
|
|
|
|
|
|
}; |
470
|
|
|
|
|
|
|
} |
471
|
|
|
|
|
|
|
|
472
|
0
|
|
|
|
|
0
|
$self->restart($vals); |
473
|
|
|
|
|
|
|
|
474
|
0
|
0
|
|
|
|
0
|
print "returning success or error\n" if $vals->{'debug'}; |
475
|
0
|
|
|
|
|
0
|
return { error_code => 200, error_desc => "vhost deletion successful" }; |
476
|
|
|
|
|
|
|
} |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
sub get_vhosts { |
479
|
2
|
|
|
2
|
0
|
4
|
my $self = shift; |
480
|
|
|
|
|
|
|
|
481
|
2
|
|
|
|
|
6
|
my $vhosts_conf = $prov->{config}{Apache}{vhosts}; |
482
|
2
|
50
|
|
|
|
6
|
return $vhosts_conf if $vhosts_conf; |
483
|
|
|
|
|
|
|
|
484
|
2
|
0
|
|
|
|
9
|
$vhosts_conf |
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
485
|
|
|
|
|
|
|
= lc( $OSNAME eq 'linux' ) ? '/etc/httpd/conf.d' |
486
|
|
|
|
|
|
|
: lc( $OSNAME eq 'darwin' ) ? '/etc/apache2/extra/httpd-vhosts.conf' |
487
|
|
|
|
|
|
|
: lc( $OSNAME eq 'freebsd' ) ? '/usr/local/etc/apache2/Includes' |
488
|
|
|
|
|
|
|
: warn "could not determine where your apache vhosts are\n"; |
489
|
|
|
|
|
|
|
|
490
|
2
|
50
|
|
|
|
8
|
return $vhosts_conf if $vhosts_conf; |
491
|
0
|
|
|
|
|
0
|
$prov->error( "you must set [Apache][etc] in provision.conf" ); |
492
|
|
|
|
|
|
|
} |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
sub exists { |
495
|
|
|
|
|
|
|
|
496
|
1
|
|
|
1
|
1
|
2
|
my $self = shift; |
497
|
|
|
|
|
|
|
|
498
|
1
|
|
|
|
|
19
|
my %p = validate( @_, { request => { type => HASHREF } } ); |
499
|
1
|
|
|
|
|
6
|
my $vals = $p{'request'}; |
500
|
|
|
|
|
|
|
|
501
|
1
|
|
|
|
|
4
|
my $vhost = lc( $vals->{vhost} ); |
502
|
1
|
|
|
|
|
5
|
my $vhosts_conf = $self->get_vhosts; |
503
|
|
|
|
|
|
|
|
504
|
1
|
50
|
|
|
|
122
|
if ( -d $vhosts_conf ) { |
|
|
50
|
|
|
|
|
|
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
# test to see if the vhosts exists |
507
|
|
|
|
|
|
|
# this implies some sort of unique naming mechanism for vhosts |
508
|
|
|
|
|
|
|
# For now, this requires that the file be the same as the domain name |
509
|
|
|
|
|
|
|
# (example.com) for the domain AND any subdomains. This means subdomain |
510
|
|
|
|
|
|
|
# declarations live within the domain file. |
511
|
|
|
|
|
|
|
|
512
|
0
|
|
|
|
|
0
|
my ($vh_file_name) = $vhost =~ /([a-z0-9-]+\.[a-z0-9-]+)(\.)?$/; |
513
|
0
|
|
|
|
|
0
|
$prov->audit("cleaned up vhost name: $vh_file_name"); |
514
|
|
|
|
|
|
|
|
515
|
0
|
|
|
|
|
0
|
$prov->audit("searching for vhost $vhost in $vh_file_name"); |
516
|
0
|
|
|
|
|
0
|
my $vh_file_path = "$vhosts_conf/$vh_file_name.conf"; |
517
|
|
|
|
|
|
|
|
518
|
0
|
0
|
|
|
|
0
|
if ( !-f $vh_file_path ) { # file does not exist |
519
|
0
|
|
|
|
|
0
|
$prov->audit("vhost $vhost does not exist"); |
520
|
0
|
|
|
|
|
0
|
return; |
521
|
|
|
|
|
|
|
}; |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
# the file exists that the virtual host should be in. |
524
|
|
|
|
|
|
|
# determine if the vhost is defined in it |
525
|
0
|
|
|
|
|
0
|
require Apache::ConfigFile; |
526
|
0
|
|
|
|
|
0
|
my $ac = |
527
|
|
|
|
|
|
|
Apache::ConfigFile->read( file => $vh_file_path, ignore_case => 1 ); |
528
|
|
|
|
|
|
|
|
529
|
0
|
|
|
|
|
0
|
for my $vh ( $ac->cmd_context( VirtualHost => '*:80' ) ) { |
530
|
0
|
|
|
|
|
0
|
my $server_name = $vh->directive('ServerName'); |
531
|
0
|
0
|
|
|
|
0
|
$prov->audit( "ServerName $server_name") if $vals->{'debug'}; |
532
|
0
|
0
|
|
|
|
0
|
return 1 if ( $vhost eq $server_name ); |
533
|
|
|
|
|
|
|
|
534
|
0
|
|
|
|
|
0
|
my $alias = 0; |
535
|
0
|
|
|
|
|
0
|
foreach my $server_alias ( $vh->directive('ServerAlias') ) { |
536
|
0
|
0
|
|
|
|
0
|
return 1 if ( $vhost eq $server_alias ); |
537
|
0
|
0
|
|
|
|
0
|
if ( $vals->{'debug'} ) { |
538
|
0
|
0
|
|
|
|
0
|
print "\tServerAlias " unless $alias; |
539
|
0
|
|
|
|
|
0
|
print "$server_alias "; |
540
|
|
|
|
|
|
|
} |
541
|
0
|
|
|
|
|
0
|
$alias++; |
542
|
|
|
|
|
|
|
} |
543
|
0
|
0
|
0
|
|
|
0
|
print "\n" if ( $alias && $vals->{'debug'} ); |
544
|
|
|
|
|
|
|
} |
545
|
0
|
|
|
|
|
0
|
return 0; |
546
|
|
|
|
|
|
|
} |
547
|
|
|
|
|
|
|
elsif ( -f $vhosts_conf ) { |
548
|
0
|
|
|
|
|
0
|
print "parsing vhosts from file $vhosts_conf\n"; |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
# my $ac = |
551
|
|
|
|
|
|
|
# Apache::ConfigFile->read( file => $vhosts_conf, ignore_case => 1 ); |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
# for my $vh ( $ac->cmd_context( VirtualHost => '*:80' ) ) { |
554
|
|
|
|
|
|
|
# my $server_name = $vh->directive('ServerName'); |
555
|
|
|
|
|
|
|
# print "ServerName $server_name\n" if $vals->{'debug'}; |
556
|
|
|
|
|
|
|
# return 1 if ( $vhost eq $server_name ); |
557
|
|
|
|
|
|
|
# |
558
|
|
|
|
|
|
|
# my $alias = 0; |
559
|
|
|
|
|
|
|
# foreach my $server_alias ( $vh->directive('ServerAlias') ) { |
560
|
|
|
|
|
|
|
# return 1 if ( $vhost eq $server_alias ); |
561
|
|
|
|
|
|
|
# if ( $vals->{'debug'} ) { |
562
|
|
|
|
|
|
|
# print "\tServerAlias " unless $alias; |
563
|
|
|
|
|
|
|
# print "$server_alias "; |
564
|
|
|
|
|
|
|
# } |
565
|
|
|
|
|
|
|
# $alias++; |
566
|
|
|
|
|
|
|
# } |
567
|
|
|
|
|
|
|
# print "\n" if ( $alias && $vals->{'debug'} ); |
568
|
|
|
|
|
|
|
# } |
569
|
|
|
|
|
|
|
|
570
|
0
|
|
|
|
|
0
|
return; |
571
|
|
|
|
|
|
|
} |
572
|
|
|
|
|
|
|
|
573
|
1
|
|
|
|
|
6
|
return; |
574
|
|
|
|
|
|
|
} |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
sub show { |
577
|
|
|
|
|
|
|
|
578
|
0
|
|
|
0
|
1
|
0
|
my ( $self, $vals ) = @_; |
579
|
|
|
|
|
|
|
|
580
|
0
|
0
|
|
|
|
0
|
unless ( $self->exists($vals) ) { |
581
|
|
|
|
|
|
|
return { |
582
|
0
|
|
|
|
|
0
|
error_code => 400, |
583
|
|
|
|
|
|
|
error_desc => "Sorry, that virtual host does not exist." |
584
|
|
|
|
|
|
|
}; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
|
587
|
0
|
|
|
|
|
0
|
my ($vhosts_conf) = $self->get_file($vals); |
588
|
|
|
|
|
|
|
|
589
|
0
|
|
|
|
|
0
|
( my $new, my $match, $vals ) = $self->get_match($vals); |
590
|
0
|
|
|
|
|
0
|
print "showing: \n" . join( "\n", @$match ) . "\n"; |
591
|
|
|
|
|
|
|
|
592
|
0
|
|
|
|
|
0
|
return { error_code => 100, error_desc => "exiting normally" }; |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
sub get_file { |
596
|
|
|
|
|
|
|
|
597
|
1
|
|
|
1
|
1
|
3
|
my ( $self, $vals ) = @_; |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
# determine the path to the file the vhost is stored in |
600
|
1
|
|
|
|
|
5
|
my $vhosts_conf = $self->get_vhosts(); |
601
|
1
|
50
|
|
|
|
19
|
if ( -d $vhosts_conf ) { |
602
|
0
|
|
|
|
|
0
|
my ($vh_file_name) |
603
|
|
|
|
|
|
|
= lc( $vals->{'vhost'} ) =~ /([a-z0-9-]+\.[a-z0-9-]+)(\.)?$/; |
604
|
0
|
|
|
|
|
0
|
$vhosts_conf .= "/$vh_file_name.conf"; |
605
|
|
|
|
|
|
|
} |
606
|
|
|
|
|
|
|
else { |
607
|
1
|
50
|
|
|
|
6
|
if ( $vhosts_conf !~ /\.conf$/ ) { |
608
|
1
|
|
|
|
|
3
|
$vhosts_conf .= ".conf"; |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
} |
611
|
|
|
|
|
|
|
|
612
|
1
|
|
|
|
|
3
|
return $vhosts_conf; |
613
|
|
|
|
|
|
|
} |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
sub get_match { |
616
|
|
|
|
|
|
|
|
617
|
0
|
|
|
0
|
1
|
|
my ( $self, $vals ) = @_; |
618
|
|
|
|
|
|
|
|
619
|
0
|
|
|
|
|
|
my ($vhosts_conf) = $self->get_file($vals); |
620
|
0
|
0
|
|
|
|
|
$vhosts_conf .= ".disabled" if $vals->{'disabled'}; |
621
|
|
|
|
|
|
|
|
622
|
0
|
0
|
|
|
|
|
print "reading in the vhosts file $vhosts_conf\n" if $vals->{'debug'}; |
623
|
0
|
|
|
|
|
|
my @lines = $util->file_read( $vhosts_conf); |
624
|
|
|
|
|
|
|
|
625
|
0
|
|
|
|
|
|
my ( $in, $match, @new, @drop ); |
626
|
0
|
|
|
|
|
|
LINE: foreach my $line (@lines) { |
627
|
0
|
0
|
|
|
|
|
if ($match) { |
628
|
0
|
0
|
|
|
|
|
print "match: $line\n" if $vals->{'debug'}; |
629
|
0
|
|
|
|
|
|
push @drop, $line; |
630
|
0
|
0
|
|
|
|
|
if ( $line =~ /documentroot[\s+]["]?(.*?)["]?[\s+]?$/i ) { |
631
|
0
|
0
|
|
|
|
|
print "setting documentroot to $1\n" if $vals->{'debug'}; |
632
|
0
|
|
|
|
|
|
$vals->{'documentroot'} = $1; |
633
|
|
|
|
|
|
|
} |
634
|
|
|
|
|
|
|
} |
635
|
0
|
|
|
|
|
|
else { push @new, $line } |
636
|
|
|
|
|
|
|
|
637
|
0
|
0
|
|
|
|
|
if ( $line =~ /^[\s+]?<\/virtualhost/i ) { |
638
|
0
|
|
|
|
|
|
$in = 0; |
639
|
0
|
|
|
|
|
|
$match = 0; |
640
|
0
|
|
|
|
|
|
next LINE; |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
|
643
|
0
|
0
|
|
|
|
|
$in++ if $in; |
644
|
|
|
|
|
|
|
|
645
|
0
|
0
|
|
|
|
|
if ( $line =~ /^[\s+]?<virtualhost/i ) { |
646
|
0
|
|
|
|
|
|
$in = 1; |
647
|
0
|
|
|
|
|
|
next LINE; |
648
|
|
|
|
|
|
|
} |
649
|
|
|
|
|
|
|
|
650
|
0
|
|
|
|
|
|
my ($servername) = $line =~ /([a-z0-9-\.]+)(:\d+)?(\s+)?$/i; |
651
|
0
|
0
|
0
|
|
|
|
if ( $servername && $servername eq lc( $vals->{'vhost'} ) ) { |
652
|
0
|
|
|
|
|
|
$match = 1; |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
# determine how many lines are in @new |
655
|
0
|
|
|
|
|
|
my $length = @new; |
656
|
0
|
0
|
|
|
|
|
print "array length: $length\n" if $vals->{'debug'}; |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
# grab the lines from @new going back to the <virtualhost> declaration |
659
|
|
|
|
|
|
|
# and push them onto @drop |
660
|
0
|
|
|
|
|
|
for ( my $i = $in; $i > 0; $i-- ) { |
661
|
0
|
|
|
|
|
|
push @drop, @new[ ( $length - $i ) ]; |
662
|
0
|
0
|
|
|
|
|
unless ( $vals->{'documentroot'} ) { |
663
|
0
|
0
|
|
|
|
|
if ( @new[ ( $length - $i ) ] |
664
|
|
|
|
|
|
|
=~ /documentroot[\s+]["]?(.*?)["]?[\s+]?$/i ) |
665
|
|
|
|
|
|
|
{ |
666
|
0
|
0
|
|
|
|
|
print "setting documentroot to $1\n" |
667
|
|
|
|
|
|
|
if $vals->{'debug'}; |
668
|
0
|
|
|
|
|
|
$vals->{'documentroot'} = $1; |
669
|
|
|
|
|
|
|
} |
670
|
|
|
|
|
|
|
} |
671
|
|
|
|
|
|
|
} |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
# remove those lines from @new |
674
|
0
|
|
|
|
|
|
for ( my $i = 0; $i < $in; $i++ ) { pop @new; } |
|
0
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
} |
677
|
|
|
|
|
|
|
|
678
|
0
|
|
|
|
|
|
return \@new, \@drop, $vals; |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
1; |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
=pod |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
=head1 NAME |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
Provision::Unix::Web::Apache - provision web hosting accounts on Apache |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
=head1 VERSION |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
version 1.06 |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
=head1 SYNOPSIS |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
=head1 FUNCTIONS |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
=head2 create |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
Create an Apache vhost container like this: |
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
<VirtualHost *:80 > |
704
|
|
|
|
|
|
|
ServerName blockads.com |
705
|
|
|
|
|
|
|
ServerAlias ads.blockads.com |
706
|
|
|
|
|
|
|
DocumentRoot /usr/home/blockads.com/ads |
707
|
|
|
|
|
|
|
ServerAdmin admin@blockads.com |
708
|
|
|
|
|
|
|
CustomLog "| /usr/local/sbin/cronolog /usr/home/example.com/logs/access.log" combined |
709
|
|
|
|
|
|
|
ErrorDocument 404 "blockads.com |
710
|
|
|
|
|
|
|
</VirtualHost> |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
my $apache->create($vals, $conf); |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
Required values: |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
ip - an ip address |
717
|
|
|
|
|
|
|
name - vhost name (ServerName) |
718
|
|
|
|
|
|
|
docroot - Apache DocumentRoot |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
Optional values |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
serveralias - Apache ServerAlias names (comma seperated) |
723
|
|
|
|
|
|
|
serveradmin - Server Admin (email address) |
724
|
|
|
|
|
|
|
cgi - CGI directory |
725
|
|
|
|
|
|
|
customlog - obvious |
726
|
|
|
|
|
|
|
customerror - obvious |
727
|
|
|
|
|
|
|
sslkey - SSL certificate key |
728
|
|
|
|
|
|
|
sslcert - SSL certificate |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
=head2 enable |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
Enable a (previously) disabled virtual host. |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
$apache->enable($vals, $conf); |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
=head2 disable |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
Disable a previously disabled vhost. |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
$apache->disable($vals, $conf); |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
=head2 destroy |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
Delete's an Apache vhost. |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
$apache->destroy(); |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
=head2 exists |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
Tests to see if a vhost definition already exists in your Apache config file(s). |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
=head2 show |
753
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
Shows the contents of a virtualhost block that matches the virtual domain name passed in the $vals hashref. |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
$apache->show($vals, $conf); |
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
=head2 get_file |
759
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
If vhosts are each in their own file, this determines the file name the vhost will live in and returns it. The general methods on my systems works like this: |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
example.com would be stored in $apache/vhosts/example.com.conf |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
so would any subdomains of example.com. |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
thus, a return value for *.example.com will be "$apache/vhosts/example.com.conf". |
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
$apache is looked up from the contents of $conf. |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
=head2 get_match |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
Find a vhost declaration block in the Apache config file(s). |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
=head1 BUGS |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
Please report any bugs or feature requests to C<bug-unix-provision-virtualos at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Provision-Unix>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
=head1 SUPPORT |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
perldoc Provision::Unix |
783
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
You can also look for information at: |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
=over 4 |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Provision-Unix> |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
L<http://annocpan.org/dist/Provision-Unix> |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
=item * CPAN Ratings |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
L<http://cpanratings.perl.org/d/Provision-Unix> |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
=item * Search CPAN |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
L<http://search.cpan.org/dist/Provision-Unix> |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
=back |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
=head1 AUTHOR |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
Matt Simerson <msimerson@cpan.org> |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
This software is copyright (c) 2013 by The Network People, Inc.. |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
817
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
=cut |
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
__END__ |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
|