| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
# $Id: Admin.pm,v 1.24 2008/11/07 00:46:29 Martin Exp $ |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
=head1 NAME |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
Win32::IIS::Admin - Administer Internet Information Service on Windows |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
use Win32::IIS::Admin; |
|
11
|
|
|
|
|
|
|
my $oWIA = new Win32::IIS::Admin; |
|
12
|
|
|
|
|
|
|
$oWIA->create_virtual_dir(-dir_name => 'cgi-bin', |
|
13
|
|
|
|
|
|
|
-path => 'C:\wwwroot\cgi-bin', |
|
14
|
|
|
|
|
|
|
-executable => 1); |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
Enables you to do a few administration tasks on a IIS webserver. |
|
19
|
|
|
|
|
|
|
Currently only works for IIS 5 (i.e. Windows 2000 Server). |
|
20
|
|
|
|
|
|
|
Currently there are very few tasks it can do. |
|
21
|
|
|
|
|
|
|
On non-Windows systems, the module can be loaded, but |
|
22
|
|
|
|
|
|
|
new() always returns undef. |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 METHODS |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=over |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=cut |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
package Win32::IIS::Admin; |
|
31
|
|
|
|
|
|
|
|
|
32
|
4
|
|
|
4
|
|
131297
|
use strict; |
|
|
4
|
|
|
|
|
10
|
|
|
|
4
|
|
|
|
|
136
|
|
|
33
|
4
|
|
|
4
|
|
23
|
use warnings; |
|
|
4
|
|
|
|
|
9
|
|
|
|
4
|
|
|
|
|
103
|
|
|
34
|
|
|
|
|
|
|
|
|
35
|
4
|
|
|
4
|
|
3419
|
use Data::Dumper; |
|
|
4
|
|
|
|
|
30753
|
|
|
|
4
|
|
|
|
|
243
|
|
|
36
|
4
|
|
|
4
|
|
3526
|
use File::Spec::Functions; |
|
|
4
|
|
|
|
|
3689
|
|
|
|
4
|
|
|
|
|
358
|
|
|
37
|
4
|
|
|
4
|
|
3495
|
use IO::String; |
|
|
4
|
|
|
|
|
18924
|
|
|
|
4
|
|
|
|
|
136
|
|
|
38
|
|
|
|
|
|
|
|
|
39
|
4
|
|
|
4
|
|
37
|
use constant DEBUG => 0; |
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
285
|
|
|
40
|
4
|
|
|
4
|
|
20
|
use constant DEBUG_EXEC => 0; |
|
|
4
|
|
|
|
|
9
|
|
|
|
4
|
|
|
|
|
153
|
|
|
41
|
4
|
|
|
4
|
|
20
|
use constant DEBUG_EXT => 0; |
|
|
4
|
|
|
|
|
8
|
|
|
|
4
|
|
|
|
|
148
|
|
|
42
|
4
|
|
|
4
|
|
20
|
use constant DEBUG_FETCH => 0; |
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
139
|
|
|
43
|
4
|
|
|
4
|
|
53
|
use constant DEBUG_PARSE => 0; |
|
|
4
|
|
|
|
|
32
|
|
|
|
4
|
|
|
|
|
183
|
|
|
44
|
4
|
|
|
4
|
|
20
|
use constant DEBUG_SET => 0; |
|
|
4
|
|
|
|
|
5
|
|
|
|
4
|
|
|
|
|
16488
|
|
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
our |
|
47
|
|
|
|
|
|
|
$VERSION = do { my @r = (q$Revision: 1.24 $ =~ /\d+/g); sprintf "%d."."%03d" x $#r, @r }; |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=item new |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Returns a new Win32::IIS::Admin object, or undef if there is any problem |
|
52
|
|
|
|
|
|
|
(such as, IIS is not installed on the local machine!). |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=cut |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub new |
|
57
|
|
|
|
|
|
|
{ |
|
58
|
4
|
|
|
4
|
1
|
681
|
my ($class, %parameters) = @_; |
|
59
|
4
|
50
|
|
|
|
27
|
if ($^O ne 'MSWin32') |
|
60
|
|
|
|
|
|
|
{ |
|
61
|
4
|
|
|
|
|
6
|
DEBUG && print STDERR " DDD this is not windows\n"; |
|
62
|
4
|
|
|
|
|
17
|
return undef; |
|
63
|
|
|
|
|
|
|
} # if |
|
64
|
|
|
|
|
|
|
# Find out where IIS is installed. |
|
65
|
|
|
|
|
|
|
# Find the cscript executable: |
|
66
|
0
|
|
|
|
|
|
my (@asTry, $sCscript); |
|
67
|
0
|
|
|
|
|
|
push @asTry, catfile($ENV{windir}, 'system32', 'cscript.exe'); |
|
68
|
0
|
|
|
|
|
|
foreach my $sTry (@asTry) |
|
69
|
|
|
|
|
|
|
{ |
|
70
|
0
|
0
|
|
|
|
|
if (-f $sTry) |
|
71
|
|
|
|
|
|
|
{ |
|
72
|
0
|
|
|
|
|
|
$sCscript = $sTry; |
|
73
|
0
|
|
|
|
|
|
last; |
|
74
|
|
|
|
|
|
|
} # if |
|
75
|
|
|
|
|
|
|
} # foreach |
|
76
|
0
|
|
|
|
|
|
DEBUG && print STDERR " DDD cscript is ==$sCscript==\n"; |
|
77
|
0
|
0
|
|
|
|
|
if ($sCscript eq '') |
|
78
|
|
|
|
|
|
|
{ |
|
79
|
0
|
|
|
|
|
|
warn "can not find executable cscript\n"; |
|
80
|
0
|
|
|
|
|
|
return undef; |
|
81
|
|
|
|
|
|
|
} # if |
|
82
|
|
|
|
|
|
|
# Get a list of logical drives: |
|
83
|
0
|
|
|
|
|
|
eval q{use Win32API::File qw( :DRIVE_ )}; |
|
84
|
0
|
0
|
|
|
|
|
if ($@) |
|
85
|
|
|
|
|
|
|
{ |
|
86
|
0
|
|
|
|
|
|
DEBUG && warn " EEE can not use Win32API::File because $@\n"; |
|
87
|
0
|
|
|
|
|
|
return undef; |
|
88
|
|
|
|
|
|
|
} # if |
|
89
|
0
|
|
|
|
|
|
my @asDrive = Win32API::File::getLogicalDrives(); |
|
90
|
0
|
|
|
|
|
|
DEBUG && print STDERR " DDD logical drives are: @asDrive\n"; |
|
91
|
|
|
|
|
|
|
# See which ones are hard drives: |
|
92
|
0
|
|
|
|
|
|
my @asHD; |
|
93
|
0
|
|
|
|
|
|
foreach my $sDrive (@asDrive) |
|
94
|
|
|
|
|
|
|
{ |
|
95
|
0
|
|
|
|
|
|
my $sType = Win32API::File::GetDriveType($sDrive); |
|
96
|
0
|
0
|
|
|
|
|
push @asHD, $sDrive if ($sType eq eval'DRIVE_FIXED'); |
|
97
|
|
|
|
|
|
|
} # foreach |
|
98
|
0
|
|
|
|
|
|
DEBUG && print STDERR " DDD hard drives are: @asHD\n"; |
|
99
|
|
|
|
|
|
|
# Find the adsutil.vbs script: |
|
100
|
0
|
|
|
|
|
|
my $sAdsutil = ''; |
|
101
|
0
|
|
|
|
|
|
@asTry = (); |
|
102
|
|
|
|
|
|
|
# This is the default location, according to microsoft.com: |
|
103
|
0
|
|
|
|
|
|
push @asTry, catdir($ENV{windir}, qw( System32 Inetsrv AdminSamples )); |
|
104
|
|
|
|
|
|
|
# This is where I find it on my old IIS installation: |
|
105
|
0
|
|
|
|
|
|
push @asTry, map { catdir($_, qw( inetpub AdminScripts )) } @asHD; |
|
|
0
|
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
|
@asTry = map { catfile($_, 'adsutil.vbs') } @asTry; |
|
|
0
|
|
|
|
|
|
|
|
107
|
0
|
|
|
|
|
|
foreach my $sTry (@asTry) |
|
108
|
|
|
|
|
|
|
{ |
|
109
|
0
|
0
|
|
|
|
|
if (-f $sTry) |
|
110
|
|
|
|
|
|
|
{ |
|
111
|
0
|
|
|
|
|
|
$sAdsutil = $sTry; |
|
112
|
0
|
|
|
|
|
|
last; |
|
113
|
|
|
|
|
|
|
} # if |
|
114
|
|
|
|
|
|
|
} # foreach |
|
115
|
0
|
|
|
|
|
|
DEBUG && print STDERR " DDD adsutil is ==$sAdsutil==\n"; |
|
116
|
0
|
0
|
|
|
|
|
if ($sAdsutil eq '') |
|
117
|
|
|
|
|
|
|
{ |
|
118
|
0
|
|
|
|
|
|
warn "can not find adsutil.vbs\n"; |
|
119
|
0
|
|
|
|
|
|
return undef; |
|
120
|
|
|
|
|
|
|
} # if |
|
121
|
|
|
|
|
|
|
# Now we have all the info we need to get started: |
|
122
|
0
|
|
|
|
|
|
my %hash = ( |
|
123
|
|
|
|
|
|
|
adsutil => $sAdsutil, |
|
124
|
|
|
|
|
|
|
cscript => $sCscript, |
|
125
|
|
|
|
|
|
|
); |
|
126
|
0
|
|
0
|
|
|
|
my $self = bless (\%hash, ref ($class) || $class); |
|
127
|
0
|
|
|
|
|
|
return $self; |
|
128
|
|
|
|
|
|
|
} # new |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
# Not published. |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub _config_set_value |
|
134
|
|
|
|
|
|
|
{ |
|
135
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
136
|
0
|
|
|
|
|
|
local $" = ','; |
|
137
|
0
|
|
|
|
|
|
DEBUG_SET && print STDERR " DDD _config_set_value(@_)\n"; |
|
138
|
|
|
|
|
|
|
# Required arg1 = section: |
|
139
|
0
|
|
0
|
|
|
|
my $sSection = shift || ''; |
|
140
|
0
|
0
|
|
|
|
|
return unless ($sSection ne ''); |
|
141
|
|
|
|
|
|
|
# Required arg2 = parameter name: |
|
142
|
0
|
|
0
|
|
|
|
my $sParameter = shift || ''; |
|
143
|
0
|
0
|
|
|
|
|
return unless ($sParameter ne ''); |
|
144
|
|
|
|
|
|
|
# Remaining arg(s) will be taken as the value(s) for this parameter. |
|
145
|
0
|
0
|
|
|
|
|
return unless @_; |
|
146
|
0
|
|
|
|
|
|
my $sRes = $self->_execute_script('adsutil', 'SET', "$sSection/$sParameter", map { qq/"$_"/ } @_); |
|
|
0
|
|
|
|
|
|
|
|
147
|
0
|
0
|
|
|
|
|
if ($sRes =~ m!ERROR TRYING TO GET THE SCHEMA!i) |
|
148
|
|
|
|
|
|
|
{ |
|
149
|
|
|
|
|
|
|
# Unknown parameter name: |
|
150
|
0
|
|
|
|
|
|
$self->_add_error($sRes); |
|
151
|
0
|
|
|
|
|
|
return; |
|
152
|
|
|
|
|
|
|
} # if |
|
153
|
0
|
0
|
|
|
|
|
if ($sRes =~ m!ERROR TRYING TO GET THE OBJECT!i) |
|
154
|
|
|
|
|
|
|
{ |
|
155
|
|
|
|
|
|
|
# Section does not exist: |
|
156
|
0
|
|
|
|
|
|
$self->_add_error($sRes); |
|
157
|
0
|
|
|
|
|
|
return; |
|
158
|
|
|
|
|
|
|
} # if |
|
159
|
0
|
0
|
|
|
|
|
if ($sRes =~ m!ERROR TRYING TO SET THE PROPERTY!i) |
|
160
|
|
|
|
|
|
|
{ |
|
161
|
|
|
|
|
|
|
# Type mismatch |
|
162
|
0
|
|
|
|
|
|
$self->_add_error($sRes); |
|
163
|
0
|
|
|
|
|
|
return; |
|
164
|
|
|
|
|
|
|
} # if |
|
165
|
|
|
|
|
|
|
# Assume success at this point: |
|
166
|
0
|
|
|
|
|
|
return ''; |
|
167
|
|
|
|
|
|
|
} # _config_set_value |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# Not published. |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
sub _config_get_value |
|
173
|
|
|
|
|
|
|
{ |
|
174
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
175
|
0
|
|
|
|
|
|
local $" = ','; |
|
176
|
0
|
|
|
|
|
|
DEBUG_FETCH && print STDERR " DDD _config_get_value(@_)\n"; |
|
177
|
|
|
|
|
|
|
# Required arg1 = section: |
|
178
|
0
|
|
0
|
|
|
|
my $sSection = shift || ''; |
|
179
|
0
|
0
|
|
|
|
|
return unless ($sSection ne ''); |
|
180
|
|
|
|
|
|
|
# Required arg2 = parameter name: |
|
181
|
0
|
|
0
|
|
|
|
my $sParameter = shift || ''; |
|
182
|
0
|
0
|
|
|
|
|
return unless ($sParameter ne ''); |
|
183
|
0
|
|
|
|
|
|
my $sRes = $self->_execute_script('adsutil', 'GET', "$sSection/$sParameter"); |
|
184
|
0
|
0
|
|
|
|
|
if ($sRes =~ m!ERROR TRYING TO GET!i) |
|
185
|
|
|
|
|
|
|
{ |
|
186
|
0
|
|
|
|
|
|
$self->_add_error($sRes); |
|
187
|
0
|
|
|
|
|
|
return; |
|
188
|
|
|
|
|
|
|
} # if |
|
189
|
0
|
|
|
|
|
|
my $oIS = IO::String->new($sRes); |
|
190
|
0
|
|
|
|
|
|
my $sLine = <$oIS>; |
|
191
|
0
|
0
|
|
|
|
|
if ($sLine =~ m!\A(\S+)\s+:\s+\((\S+)\)\s*(.+)\Z!) |
|
192
|
|
|
|
|
|
|
{ |
|
193
|
0
|
|
|
|
|
|
my ($sProperty, $sType, $sValue) = ($1, $2, $3); |
|
194
|
0
|
|
|
|
|
|
my @asValue; |
|
195
|
0
|
0
|
|
|
|
|
if ($sType eq 'STRING') |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
{ |
|
197
|
|
|
|
|
|
|
# Protect backslashes, in case this value is a dir/file path: |
|
198
|
0
|
|
|
|
|
|
$sValue =~ s!\\!/!g; |
|
199
|
0
|
|
|
|
|
|
$sValue = eval $sValue; |
|
200
|
0
|
|
|
|
|
|
return $sValue; |
|
201
|
|
|
|
|
|
|
} # if STRING |
|
202
|
|
|
|
|
|
|
elsif ($sType eq 'INTEGER') |
|
203
|
|
|
|
|
|
|
{ |
|
204
|
0
|
|
|
|
|
|
$sValue = eval $sValue; |
|
205
|
0
|
|
|
|
|
|
return $sValue; |
|
206
|
|
|
|
|
|
|
} # if INTEGER |
|
207
|
|
|
|
|
|
|
elsif ($sType eq 'EXPANDSZ') |
|
208
|
|
|
|
|
|
|
{ |
|
209
|
|
|
|
|
|
|
# Protect backslashes, this value is a dir/file path: |
|
210
|
0
|
|
|
|
|
|
$sValue =~ s!\\!/!g; |
|
211
|
0
|
|
|
|
|
|
$sValue = eval $sValue; |
|
212
|
0
|
|
|
|
|
|
$sValue =~ s!%([^%]+)%!$ENV{$1}!g; |
|
213
|
0
|
|
|
|
|
|
return $sValue; |
|
214
|
|
|
|
|
|
|
} # if INTEGER |
|
215
|
|
|
|
|
|
|
elsif ($sType eq 'BOOLEAN') |
|
216
|
|
|
|
|
|
|
{ |
|
217
|
0
|
|
|
|
|
|
$sValue = ($sValue eq 'True'); |
|
218
|
0
|
|
|
|
|
|
return $sValue; |
|
219
|
|
|
|
|
|
|
} |
|
220
|
|
|
|
|
|
|
elsif ($sType eq 'LIST') |
|
221
|
|
|
|
|
|
|
{ |
|
222
|
0
|
|
|
|
|
|
my @asValue = (); |
|
223
|
0
|
0
|
|
|
|
|
if ($sValue =~ m!(\d+)\sItems!) |
|
224
|
|
|
|
|
|
|
{ |
|
225
|
0
|
|
|
|
|
|
my $iCount = 0 + $1; |
|
226
|
|
|
|
|
|
|
ITEM_OF_LIST: |
|
227
|
0
|
|
|
|
|
|
for (1..$iCount) |
|
228
|
|
|
|
|
|
|
{ |
|
229
|
0
|
|
|
|
|
|
my $sSubline = <$oIS>; |
|
230
|
0
|
0
|
|
|
|
|
if ($sSubline =~ m!\A\s+\042([^"]+)\042!) # |
|
231
|
|
|
|
|
|
|
{ |
|
232
|
0
|
|
|
|
|
|
push @asValue, $1; |
|
233
|
|
|
|
|
|
|
} # if |
|
234
|
|
|
|
|
|
|
else |
|
235
|
|
|
|
|
|
|
{ |
|
236
|
0
|
|
|
|
|
|
print STDERR " WWW list item does not look like string, in line ==$sLine==\n"; |
|
237
|
|
|
|
|
|
|
} |
|
238
|
|
|
|
|
|
|
} # for ITEM_OF_LIST |
|
239
|
|
|
|
|
|
|
} # if |
|
240
|
|
|
|
|
|
|
else |
|
241
|
|
|
|
|
|
|
{ |
|
242
|
0
|
|
|
|
|
|
print STDERR " WWW found LIST type but not item count at line ==$sLine==\n"; |
|
243
|
0
|
|
|
|
|
|
next LINE_OF_CONFIG; |
|
244
|
|
|
|
|
|
|
} |
|
245
|
0
|
|
|
|
|
|
return \@asValue; |
|
246
|
|
|
|
|
|
|
} # if LIST |
|
247
|
|
|
|
|
|
|
elsif ($sType eq 'MimeMapList') |
|
248
|
|
|
|
|
|
|
{ |
|
249
|
0
|
|
|
|
|
|
my %hash; |
|
250
|
0
|
|
|
|
|
|
while ($sValue =~ m!"(\S+)"!g) |
|
251
|
|
|
|
|
|
|
{ |
|
252
|
0
|
|
|
|
|
|
my ($sExt, $sType) = split(',', $1); |
|
253
|
0
|
|
|
|
|
|
$hash{$sExt} = $sType; |
|
254
|
|
|
|
|
|
|
} # while |
|
255
|
0
|
|
|
|
|
|
return \%hash; |
|
256
|
|
|
|
|
|
|
} |
|
257
|
|
|
|
|
|
|
else |
|
258
|
|
|
|
|
|
|
{ |
|
259
|
0
|
|
|
|
|
|
print STDERR " EEE unknown type =$sType=\n"; |
|
260
|
|
|
|
|
|
|
} |
|
261
|
|
|
|
|
|
|
} # if PropertyName : (TYPE) value |
|
262
|
|
|
|
|
|
|
else |
|
263
|
|
|
|
|
|
|
{ |
|
264
|
0
|
|
|
|
|
|
DEBUG_PARSE && print STDERR " WWW unparsable line ==$sLine==\n"; |
|
265
|
|
|
|
|
|
|
} |
|
266
|
0
|
|
|
|
|
|
return; |
|
267
|
|
|
|
|
|
|
} # _config_get_value |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=item iis_version |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Returns the version of IIS found on this machine, |
|
273
|
|
|
|
|
|
|
in a decimal number format like "6.0". |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=cut |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
sub iis_version |
|
278
|
|
|
|
|
|
|
{ |
|
279
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
280
|
0
|
0
|
|
|
|
|
if (! defined $self->{_iss_version_}) |
|
281
|
|
|
|
|
|
|
{ |
|
282
|
0
|
|
|
|
|
|
my $iMajor = $self->_config_get_value('/W3SVC/Info', |
|
283
|
|
|
|
|
|
|
'MajorIIsVersionNumber'); |
|
284
|
0
|
|
|
|
|
|
my $iMinor = $self->_config_get_value('/W3SVC/Info', |
|
285
|
|
|
|
|
|
|
'MinorIIsVersionNumber'); |
|
286
|
0
|
|
|
|
|
|
$self->{_iss_version_} = "$iMajor.$iMinor"; |
|
287
|
|
|
|
|
|
|
} # if |
|
288
|
0
|
|
|
|
|
|
return $self->{_iss_version_}; |
|
289
|
|
|
|
|
|
|
} # iis_version |
|
290
|
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=item get_timeout |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
Returns the IIS timeout value. |
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=cut |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
sub get_timeout |
|
299
|
|
|
|
|
|
|
{ |
|
300
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
301
|
0
|
|
|
|
|
|
$self->_config_get_value('/W3SVC', 'CGITimeout'); |
|
302
|
|
|
|
|
|
|
} # set_timeout |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=item set_timeout |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
Given an integer, |
|
308
|
|
|
|
|
|
|
sets the IIS timeout to that value. |
|
309
|
|
|
|
|
|
|
Does no checking on the value passed in, so use carefully! |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=cut |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub set_timeout |
|
314
|
|
|
|
|
|
|
{ |
|
315
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
316
|
|
|
|
|
|
|
# Required arg1 = an integer: |
|
317
|
0
|
|
|
|
|
|
my $iArg = shift() + 0; |
|
318
|
0
|
|
|
|
|
|
$self->_config_set_value('/W3SVC', 'CGITimeout', $iArg); |
|
319
|
|
|
|
|
|
|
} # set_timeout |
|
320
|
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=item path_of_virtual_dir |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
Given the name of a virtual directory (or 'ROOT'), |
|
325
|
|
|
|
|
|
|
returns the absolute full path of where the physical files are located. |
|
326
|
|
|
|
|
|
|
Returns undef if there is no virtual directory matching the name given. |
|
327
|
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=cut |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
sub path_of_virtual_dir |
|
331
|
|
|
|
|
|
|
{ |
|
332
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
333
|
0
|
|
0
|
|
|
|
my $sDir = shift || ''; |
|
334
|
0
|
0
|
|
|
|
|
if ($sDir eq '') |
|
335
|
|
|
|
|
|
|
{ |
|
336
|
0
|
|
|
|
|
|
$self->_add_error(qq(Argument is required on path_of_virtual_dir.)); |
|
337
|
0
|
|
|
|
|
|
return; |
|
338
|
|
|
|
|
|
|
} # if |
|
339
|
|
|
|
|
|
|
# We cravenly refuse to modify anything but the default #1 webserver: |
|
340
|
0
|
|
|
|
|
|
my $sWebsite = 1; |
|
341
|
0
|
0
|
|
|
|
|
if ($sDir eq 'ROOT') |
|
342
|
|
|
|
|
|
|
{ |
|
343
|
0
|
|
|
|
|
|
goto ROOT; |
|
344
|
|
|
|
|
|
|
} # if |
|
345
|
0
|
|
|
|
|
|
my $sVersion = $self->iis_version; |
|
346
|
0
|
0
|
|
|
|
|
if ("6.0" le $sVersion) |
|
347
|
|
|
|
|
|
|
{ |
|
348
|
0
|
|
|
|
|
|
my $sSection = join('/', 'W3SVC', $sWebsite); |
|
349
|
0
|
|
0
|
|
|
|
my $sRes .= $self->_execute_script('iisvdir', '/query', $sSection) || ''; |
|
350
|
0
|
0
|
|
|
|
|
if ($sRes =~ m!Error!) |
|
351
|
|
|
|
|
|
|
{ |
|
352
|
0
|
|
|
|
|
|
$self->_add_error($sRes); |
|
353
|
0
|
|
|
|
|
|
return; |
|
354
|
|
|
|
|
|
|
} # if |
|
355
|
0
|
|
|
|
|
|
DEBUG_FETCH && print STDERR " DDD iisvdir returned:", $sRes; |
|
356
|
0
|
|
|
|
|
|
my $oIS = IO::String->new($sRes); |
|
357
|
|
|
|
|
|
|
FIND_DIVIDER_LINE: |
|
358
|
0
|
|
|
|
|
|
while (my $sLine = <$oIS>) |
|
359
|
|
|
|
|
|
|
{ |
|
360
|
0
|
0
|
|
|
|
|
last if ($sLine =~ m!={22}!); |
|
361
|
|
|
|
|
|
|
} # while FIND_DIVIDER_LINE |
|
362
|
|
|
|
|
|
|
VIR_DIR_LINE: |
|
363
|
0
|
|
|
|
|
|
while (my $sLine = <$oIS>) |
|
364
|
|
|
|
|
|
|
{ |
|
365
|
0
|
|
|
|
|
|
chomp $sLine; |
|
366
|
0
|
|
|
|
|
|
my ($sVirDir, $sPath) = split(/ +/, $sLine); |
|
367
|
0
|
|
|
|
|
|
DEBUG_FETCH && print STDERR " DDD found virdir=$sVirDir==>$sPath\n"; |
|
368
|
|
|
|
|
|
|
# Question: do we want to match the vir-dir name |
|
369
|
|
|
|
|
|
|
# case-INsensitively? |
|
370
|
0
|
0
|
|
|
|
|
if ($sVirDir =~ m!\A/?$sDir\Z!) |
|
371
|
|
|
|
|
|
|
{ |
|
372
|
0
|
|
|
|
|
|
return $sPath; |
|
373
|
|
|
|
|
|
|
} # if |
|
374
|
|
|
|
|
|
|
} # while VIR_DIR_LINE |
|
375
|
0
|
|
|
|
|
|
return ''; |
|
376
|
|
|
|
|
|
|
} # if |
|
377
|
|
|
|
|
|
|
ROOT: |
|
378
|
|
|
|
|
|
|
# If we get here, we must be using IIS 5.0: |
|
379
|
0
|
|
|
|
|
|
my $sSection = join('/', '', 'W3SVC', $sWebsite, 'ROOT'); |
|
380
|
0
|
0
|
|
|
|
|
if ($sDir !~ m!\AROOT\Z!i) |
|
381
|
|
|
|
|
|
|
{ |
|
382
|
0
|
|
|
|
|
|
$sSection .= "/$sDir"; |
|
383
|
|
|
|
|
|
|
} # if |
|
384
|
0
|
|
0
|
|
|
|
my $sPath = $self->_config_get_value($sSection, 'Path') || ''; |
|
385
|
0
|
|
|
|
|
|
return $sPath; |
|
386
|
|
|
|
|
|
|
} # path_of_virtual_dir |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=item create_virtual_dir |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Given the following named arguments, create a virtual directory on the |
|
392
|
|
|
|
|
|
|
default #1 server on the local machine's IIS instance. |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=over |
|
395
|
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=item -dir_name => 'virtual' |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
This is the virtual directory name as it will appear to your browsers. |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=item -path => 'C:/local/path' |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
This is the full path the the actual location of the data files. |
|
403
|
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=item -executable => 1 |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
Give this argument if your virtual directory holds executable programs. |
|
407
|
|
|
|
|
|
|
Default is 0 (NOT executable). |
|
408
|
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=back |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
=cut |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
sub create_virtual_dir |
|
414
|
|
|
|
|
|
|
{ |
|
415
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
416
|
0
|
|
|
|
|
|
my %hArgs = @_; |
|
417
|
0
|
|
0
|
|
|
|
$hArgs{-dir_name} ||= ''; |
|
418
|
0
|
0
|
|
|
|
|
if ($hArgs{-dir_name} eq '') |
|
419
|
|
|
|
|
|
|
{ |
|
420
|
0
|
|
|
|
|
|
$self->_add_error(qq(Argument -dir_name is required on create_virtual_dir.)); |
|
421
|
0
|
|
|
|
|
|
return; |
|
422
|
|
|
|
|
|
|
} # if |
|
423
|
0
|
|
0
|
|
|
|
$hArgs{-path} ||= ''; |
|
424
|
0
|
0
|
|
|
|
|
if ($hArgs{-path} eq '') |
|
425
|
|
|
|
|
|
|
{ |
|
426
|
0
|
|
|
|
|
|
$self->_add_error(qq(Argument -path is required on create_virtual_dir.)); |
|
427
|
0
|
|
|
|
|
|
return; |
|
428
|
|
|
|
|
|
|
} # if |
|
429
|
0
|
|
0
|
|
|
|
$hArgs{-executable} ||= 0; |
|
430
|
|
|
|
|
|
|
# print STDERR Dumper(\%hArgs); |
|
431
|
|
|
|
|
|
|
# We cravenly refuse to modify anything but the default #1 webserver: |
|
432
|
0
|
|
|
|
|
|
my $sWebsite = 1; |
|
433
|
|
|
|
|
|
|
# First, see if a virtual directory with the same name is already |
|
434
|
|
|
|
|
|
|
# exists: |
|
435
|
0
|
|
|
|
|
|
my $sPath = $self->path_of_virtual_dir($hArgs{-dir_name}); |
|
436
|
0
|
|
|
|
|
|
my $sRes = ''; |
|
437
|
0
|
0
|
|
|
|
|
if ($sPath ne '') |
|
438
|
|
|
|
|
|
|
{ |
|
439
|
|
|
|
|
|
|
# There is already a virtual directory with that name. Create a |
|
440
|
|
|
|
|
|
|
# sensible error message: |
|
441
|
0
|
0
|
|
|
|
|
if ($sPath ne $hArgs{-path}) |
|
442
|
|
|
|
|
|
|
{ |
|
443
|
0
|
|
|
|
|
|
$self->_add_error(qq(There is already a virtual directory named '$hArgs{-dir_name}', but it points to $sPath)); |
|
444
|
0
|
|
|
|
|
|
return; |
|
445
|
|
|
|
|
|
|
} # if |
|
446
|
0
|
|
|
|
|
|
$self->_add_error(qq(There is already a virtual directory named '$hArgs{-dir_name}' pointing to $sPath)); |
|
447
|
|
|
|
|
|
|
# Fall through and (try to) set the access rules. |
|
448
|
|
|
|
|
|
|
} # if |
|
449
|
|
|
|
|
|
|
else |
|
450
|
|
|
|
|
|
|
{ |
|
451
|
|
|
|
|
|
|
# Virtual dir not there, create it: |
|
452
|
0
|
|
|
|
|
|
my @asArgs = ('mkwebdir', |
|
453
|
|
|
|
|
|
|
qq(-v "$hArgs{-dir_name}","$hArgs{-path}"), |
|
454
|
|
|
|
|
|
|
qq(-w $sWebsite), |
|
455
|
|
|
|
|
|
|
# qq(-c $sComputer), |
|
456
|
|
|
|
|
|
|
); |
|
457
|
0
|
0
|
|
|
|
|
if ('6.0' le $self->iis_version) |
|
458
|
|
|
|
|
|
|
{ |
|
459
|
0
|
|
|
|
|
|
@asArgs = ('iisvdir', '/create', "W3SVC/$sWebsite", |
|
460
|
|
|
|
|
|
|
$hArgs{-dir_name}, $hArgs{-path}); |
|
461
|
|
|
|
|
|
|
} # if |
|
462
|
0
|
|
0
|
|
|
|
$sRes .= $self->_execute_script(@asArgs) || ''; |
|
463
|
0
|
0
|
|
|
|
|
if ($sRes =~ m!Error!) |
|
464
|
|
|
|
|
|
|
{ |
|
465
|
0
|
|
|
|
|
|
$self->_add_error($sRes); |
|
466
|
0
|
|
|
|
|
|
return; |
|
467
|
|
|
|
|
|
|
} # if |
|
468
|
|
|
|
|
|
|
} # else |
|
469
|
|
|
|
|
|
|
# Whether the dir was already defined or not, try to set permissions |
|
470
|
|
|
|
|
|
|
# as requested: |
|
471
|
0
|
0
|
|
|
|
|
if ($hArgs{-executable}) |
|
472
|
|
|
|
|
|
|
{ |
|
473
|
0
|
|
|
|
|
|
my $sSection = join('/', '', 'W3SVC', $sWebsite, 'Root', $hArgs{-dir_name}); |
|
474
|
0
|
0
|
|
|
|
|
if ('6.0' le $self->iis_version) |
|
475
|
|
|
|
|
|
|
{ |
|
476
|
0
|
|
|
|
|
|
$sRes .= $self->_config_set_value($sSection, "AccessExecute", 'True'); |
|
477
|
|
|
|
|
|
|
# These seem to get turned on by default, but we'll make them |
|
478
|
|
|
|
|
|
|
# explicit anyway: |
|
479
|
0
|
|
|
|
|
|
$sRes .= $self->_config_set_value($sSection, "AccessScript", 'True'); |
|
480
|
0
|
|
|
|
|
|
$sRes .= $self->_config_set_value($sSection, "AccessRead", 'True'); |
|
481
|
|
|
|
|
|
|
} |
|
482
|
|
|
|
|
|
|
else |
|
483
|
|
|
|
|
|
|
{ |
|
484
|
|
|
|
|
|
|
# For some reason, the argument to chaccess has no leading slash |
|
485
|
|
|
|
|
|
|
# (some other scripts require leading slash): |
|
486
|
0
|
|
|
|
|
|
$sSection =~ s!\A/!!; |
|
487
|
|
|
|
|
|
|
# Set accesses for execution: |
|
488
|
0
|
|
|
|
|
|
$sRes .= $self->_execute_script('chaccess', |
|
489
|
|
|
|
|
|
|
-a => $sSection, |
|
490
|
|
|
|
|
|
|
qw( +execute +read +script ), |
|
491
|
|
|
|
|
|
|
); |
|
492
|
|
|
|
|
|
|
} # else |
|
493
|
|
|
|
|
|
|
} # if |
|
494
|
0
|
|
|
|
|
|
return $sRes; |
|
495
|
|
|
|
|
|
|
} # create_virtual_dir |
|
496
|
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=item add_extension_restriction |
|
499
|
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
Given the following named arguments, |
|
501
|
|
|
|
|
|
|
adds an "extension restriction" to |
|
502
|
|
|
|
|
|
|
the default #1 server on the local machine's IIS instance. |
|
503
|
|
|
|
|
|
|
Only works on IIS version 6.0. |
|
504
|
|
|
|
|
|
|
Note: no checking is done on the arguments, |
|
505
|
|
|
|
|
|
|
so it is possible to add bogus/duplicate/conflicting/illegal values to your IIS configuration. |
|
506
|
|
|
|
|
|
|
For more information, see |
|
507
|
|
|
|
|
|
|
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/79652e88-e713-4aa5-a88c-8e2bd6a2955e.mspx?mfr=true |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
=over |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
=item -allow => <0, 1> |
|
512
|
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
Send 0 if this is a "deny" rule; send 1 if this is an "allow" rule. |
|
514
|
|
|
|
|
|
|
The default is 0, deny. |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
=item -path => |
|
517
|
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
The full path to the executable or extension. |
|
519
|
|
|
|
|
|
|
This argument is required. |
|
520
|
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=item -groupid => |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
"A non-localizable string used to identify groups of extensions." |
|
524
|
|
|
|
|
|
|
Default is empty string. |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=item -description => |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
"A localizable description of the extension." |
|
529
|
|
|
|
|
|
|
Default is empty string. |
|
530
|
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
=back |
|
532
|
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
=cut |
|
534
|
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
sub add_extension_restriction |
|
536
|
|
|
|
|
|
|
{ |
|
537
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
538
|
|
|
|
|
|
|
# print STDERR " DDD add_extension_restriction()\n"; |
|
539
|
0
|
0
|
|
|
|
|
if ($self->iis_version < 6.0) |
|
540
|
|
|
|
|
|
|
{ |
|
541
|
0
|
|
|
|
|
|
return; |
|
542
|
|
|
|
|
|
|
} # if |
|
543
|
|
|
|
|
|
|
# Set defaults, and get arguments: |
|
544
|
0
|
|
|
|
|
|
my %hArgs = ( |
|
545
|
|
|
|
|
|
|
-allow => 0, |
|
546
|
|
|
|
|
|
|
-groupid => '', |
|
547
|
|
|
|
|
|
|
-description => '', |
|
548
|
|
|
|
|
|
|
@_, |
|
549
|
|
|
|
|
|
|
# At present, this argument is not alterable: |
|
550
|
|
|
|
|
|
|
-deletable => 1, |
|
551
|
|
|
|
|
|
|
); |
|
552
|
|
|
|
|
|
|
# Verify all argument values: |
|
553
|
0
|
0
|
|
|
|
|
$hArgs{-allow} = 0 if ($hArgs{-allow} ne '1'); |
|
554
|
0
|
0
|
|
|
|
|
if (! exists $hArgs{-path}) |
|
555
|
|
|
|
|
|
|
{ |
|
556
|
0
|
|
|
|
|
|
$self->add_error("add_extension_restriction() called without required argument -path"); |
|
557
|
0
|
|
|
|
|
|
return; |
|
558
|
|
|
|
|
|
|
} # if |
|
559
|
|
|
|
|
|
|
# Construct the new Registry value: |
|
560
|
0
|
|
|
|
|
|
my $s = join(',', @hArgs{qw( -allow -path -deletable -groupid -description )}); |
|
561
|
|
|
|
|
|
|
# print STDERR " DDD s=$s=\n"; |
|
562
|
0
|
|
|
|
|
|
my $ra = $self->_config_get_value('/W3SVC', 'WebSvcExtRestrictionList'); |
|
563
|
|
|
|
|
|
|
# print STDERR " DDD before, list is ", Dumper($ra); |
|
564
|
0
|
|
|
|
|
|
push @{$ra}, $s; |
|
|
0
|
|
|
|
|
|
|
|
565
|
0
|
|
|
|
|
|
$self->_config_set_value('/W3SVC', 'WebSvcExtRestrictionList', @{$ra}); |
|
|
0
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
} # add_extension_restriction |
|
567
|
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
=item remove_extension_restriction |
|
570
|
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
Given the full path of an existing "extension restriction" in |
|
572
|
|
|
|
|
|
|
the default #1 server on the local machine's IIS instance, |
|
573
|
|
|
|
|
|
|
removes that restriction. |
|
574
|
|
|
|
|
|
|
If more than one restriction refers to the same path, |
|
575
|
|
|
|
|
|
|
they will all be removed. |
|
576
|
|
|
|
|
|
|
Only works on IIS version 6.0. |
|
577
|
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
=cut |
|
579
|
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
sub remove_extension_restriction |
|
581
|
|
|
|
|
|
|
{ |
|
582
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
583
|
|
|
|
|
|
|
# Required arg1 = path element: |
|
584
|
0
|
|
0
|
|
|
|
my $sPath = shift || ''; |
|
585
|
0
|
|
|
|
|
|
DEBUG_EXT && print STDERR " DDD remove_extension_restriction($sPath)\n"; |
|
586
|
0
|
|
|
|
|
|
$self->_remove_extension_restriction_by_elem($sPath, 1); |
|
587
|
|
|
|
|
|
|
} # remove_extension_restriction |
|
588
|
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
=item remove_extension_restriction_group |
|
591
|
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
Given the group ID of an existing "extension restriction" in |
|
593
|
|
|
|
|
|
|
the default #1 server on the local machine's IIS instance, |
|
594
|
|
|
|
|
|
|
removes all restrictions of that group. |
|
595
|
|
|
|
|
|
|
Only works on IIS version 6.0. |
|
596
|
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=cut |
|
598
|
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
sub remove_extension_restriction_group |
|
600
|
|
|
|
|
|
|
{ |
|
601
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
602
|
|
|
|
|
|
|
# Required arg1 = path element: |
|
603
|
0
|
|
0
|
|
|
|
my $sValue = shift || ''; |
|
604
|
0
|
|
|
|
|
|
DEBUG_EXT && print STDERR " DDD remove_extension_restriction_group($sValue)\n"; |
|
605
|
0
|
|
|
|
|
|
$self->_remove_extension_restriction_by_elem($sValue, 3); |
|
606
|
|
|
|
|
|
|
} # remove_extension_restriction_group |
|
607
|
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
sub _remove_extension_restriction_by_elem |
|
610
|
|
|
|
|
|
|
{ |
|
611
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
612
|
|
|
|
|
|
|
# Required arg1 = path element: |
|
613
|
0
|
|
0
|
|
|
|
my $sValue = shift || ''; |
|
614
|
|
|
|
|
|
|
# Required arg2 = element number: |
|
615
|
0
|
|
|
|
|
|
my $iElem = shift; |
|
616
|
|
|
|
|
|
|
# Verify all argument values: |
|
617
|
0
|
0
|
|
|
|
|
return if ! defined($iElem); |
|
618
|
0
|
0
|
|
|
|
|
return if ($iElem < 0); |
|
619
|
0
|
0
|
|
|
|
|
return if (4 < $iElem); |
|
620
|
0
|
0
|
|
|
|
|
if ($sValue eq '') |
|
621
|
|
|
|
|
|
|
{ |
|
622
|
0
|
|
|
|
|
|
return; |
|
623
|
|
|
|
|
|
|
} # if |
|
624
|
0
|
0
|
|
|
|
|
if ($self->iis_version < 6.0) |
|
625
|
|
|
|
|
|
|
{ |
|
626
|
0
|
|
|
|
|
|
return; |
|
627
|
|
|
|
|
|
|
} # if |
|
628
|
0
|
|
|
|
|
|
my $rasOrig = $self->_config_get_value('/W3SVC', 'WebSvcExtRestrictionList'); |
|
629
|
0
|
|
|
|
|
|
DEBUG_EXT && print STDERR " DDD before, list is ", Dumper($rasOrig); |
|
630
|
0
|
|
|
|
|
|
my @asNew; |
|
631
|
0
|
|
|
|
|
|
foreach my $s (@$rasOrig) |
|
632
|
|
|
|
|
|
|
{ |
|
633
|
0
|
|
|
|
|
|
my @asElem = split(',', $s); |
|
634
|
0
|
0
|
0
|
|
|
|
if (($asElem[$iElem] || '') eq $sValue) |
|
635
|
|
|
|
|
|
|
{ |
|
636
|
0
|
|
|
|
|
|
DEBUG_EXT && print STDERR " DDD found one to remove\n"; |
|
637
|
|
|
|
|
|
|
} |
|
638
|
|
|
|
|
|
|
else |
|
639
|
|
|
|
|
|
|
{ |
|
640
|
0
|
|
|
|
|
|
push @asNew, $s; |
|
641
|
|
|
|
|
|
|
} |
|
642
|
|
|
|
|
|
|
} # foreach |
|
643
|
0
|
|
|
|
|
|
DEBUG_EXT && print STDERR " DDD after, list is ", Dumper(\@asNew); |
|
644
|
0
|
|
|
|
|
|
$self->_config_set_value('/W3SVC', 'WebSvcExtRestrictionList', @asNew); |
|
645
|
|
|
|
|
|
|
} # _remove_extension_restriction_by_elem |
|
646
|
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
=item restart_iis |
|
649
|
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
Restarts the IIS service on the local machine. |
|
651
|
|
|
|
|
|
|
Assumes that IISReset.exe is in your path. |
|
652
|
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
=cut |
|
654
|
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
sub restart_iis |
|
656
|
|
|
|
|
|
|
{ |
|
657
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
658
|
|
|
|
|
|
|
# Assume that IISReset is in the path: |
|
659
|
0
|
|
|
|
|
|
my $sProg = 'IISReset'; |
|
660
|
0
|
|
|
|
|
|
my $iRes = system(qq'$sProg /RESTART'); |
|
661
|
0
|
0
|
|
|
|
|
if ($iRes) |
|
662
|
|
|
|
|
|
|
{ |
|
663
|
|
|
|
|
|
|
# print STDERR "$sProg failed: $!"; # for debugging |
|
664
|
0
|
|
|
|
|
|
$self->add_error("$sProg failed: $!"); |
|
665
|
|
|
|
|
|
|
} # if |
|
666
|
|
|
|
|
|
|
} # restart_iis |
|
667
|
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
=item errors |
|
670
|
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
Method not implemented. |
|
672
|
|
|
|
|
|
|
In the current version, error messages are printed to STDERR as they occur. |
|
673
|
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
=cut |
|
675
|
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
sub errors |
|
677
|
0
|
|
|
0
|
1
|
|
{ |
|
678
|
|
|
|
|
|
|
} # errors |
|
679
|
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
sub _add_error |
|
681
|
|
|
|
|
|
|
{ |
|
682
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
683
|
0
|
|
|
|
|
|
print STDERR "@_\n"; |
|
684
|
|
|
|
|
|
|
} # add_error |
|
685
|
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
sub _execute_script |
|
687
|
|
|
|
|
|
|
{ |
|
688
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
689
|
0
|
|
|
|
|
|
my $sVBS = shift; |
|
690
|
|
|
|
|
|
|
# Figure out exactly which script the caller wants to execute. |
|
691
|
|
|
|
|
|
|
# Cscript needs the full path: |
|
692
|
0
|
|
|
|
|
|
my $sScriptFname; |
|
693
|
0
|
0
|
|
|
|
|
if (defined $self->{$sVBS}) |
|
694
|
|
|
|
|
|
|
{ |
|
695
|
|
|
|
|
|
|
# User requested a script which we have already located. |
|
696
|
0
|
|
|
|
|
|
$sScriptFname = $self->{$sVBS}; |
|
697
|
|
|
|
|
|
|
} |
|
698
|
|
|
|
|
|
|
else |
|
699
|
|
|
|
|
|
|
{ |
|
700
|
|
|
|
|
|
|
# adsutil.vbs is the only script we bother to physically locate; |
|
701
|
|
|
|
|
|
|
# all other scripts are next to cscript itself: |
|
702
|
0
|
|
|
|
|
|
$sScriptFname = $self->{cscript}; |
|
703
|
0
|
|
|
|
|
|
$sScriptFname =~ s!cscript\.exe!$sVBS.vbs!i; |
|
704
|
|
|
|
|
|
|
} |
|
705
|
0
|
|
|
|
|
|
my $sCmd = join(' ', $self->{cscript}, '-nologo', $sScriptFname, @_); |
|
706
|
0
|
|
|
|
|
|
DEBUG_EXEC && print STDERR " DDD exec ==$sCmd==\n"; |
|
707
|
0
|
|
|
|
|
|
my $sRes = qx/$sCmd/; |
|
708
|
0
|
|
|
|
|
|
print STDERR " DDD result ===$sRes===\n" if (1 < DEBUG_EXEC); |
|
709
|
0
|
|
|
|
|
|
return $sRes; |
|
710
|
|
|
|
|
|
|
} # _execute_script |
|
711
|
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
=back |
|
713
|
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
=head1 BUGS |
|
715
|
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
To report a bug, please use L. |
|
717
|
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
=head1 AUTHOR |
|
719
|
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
Martin Thurn C |
|
721
|
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
This program is free software; you can redistribute |
|
725
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself. |
|
726
|
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
=cut |
|
728
|
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
1; |
|
730
|
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
__END__ |