[0001] [0002] [0003] [0004] [0005] [0006] [0007] [0008] [0009] [0010] [0011] [0012] [0013] [0014] [0015] [0016] [0017] [0018] [0019] [0020] [0021] [0022] [0023] [0024] [0025] [0026] [0027] [0028] [0029] [0030] [0031] [0032] [0033] [0034] [0035] [0036] [0037] [0038] [0039] [0040] [0041] [0042] [0043] [0044] [0045] [0046] [0047] [0048] [0049] [0050] [0051] [0052] [0053] [0054] [0055] [0056] [0057] [0058] [0059] [0060] [0061] [0062] [0063] [0064] [0065] [0066] [0067] [0068] [0069] [0070] [0071] [0072] [0073] [0074] [0075] [0076] [0077] [0078] [0079] [0080] [0081] [0082] [0083] [0084] [0085] [0086] [0087] [0088] [0089] [0090] [0091] [0092] [0093] [0094] [0095] [0096] [0097] [0098] [0099] [0100] [0101] [0102] [0103] [0104] [0105] [0106] [0107] [0108] [0109] [0110] [0111] [0112] [0113] [0114] [0115] [0116] [0117] [0118] [0119] [0120] [0121] [0122] [0123] [0124] [0125] [0126] [0127] [0128] [0129] [0130] [0131] [0132] [0133] [0134] [0135] [0136] [0137] [0138] [0139] [0140] [0141] [0142] [0143] [0144] [0145] [0146] [0147] [0148] [0149] [0150] [0151] [0152] [0153] [0154] [0155] [0156] [0157] [0158] [0159] [0160] [0161] [0162] [0163] [0164] [0165] [0166] [0167] [0168] [0169] [0170] [0171] [0172] [0173] [0174] [0175] [0176] [0177] [0178] [0179] [0180] [0181] [0182] [0183] [0184] [0185] [0186] [0187] [0188] [0189] [0190] [0191] [0192] [0193] [0194] [0195] [0196] [0197] [0198] [0199] [0200] [0201] [0202] [0203] [0204] [0205] [0206] [0207] [0208] [0209] [0210] [0211] [0212] [0213] [0214] [0215] [0216] [0217] [0218] [0219] [0220] [0221] [0222] [0223] [0224] [0225] [0226] [0227] [0228] [0229] [0230] [0231] [0232] [0233] [0234] [0235] [0236] [0237] [0238] [0239] [0240] [0241] [0242] [0243] [0244] [0245] [0246] [0247] [0248] [0249] [0250] [0251] [0252] [0253] [0254] [0255] [0256] [0257] [0258] [0259] [0260] [0261] [0262] [0263] [0264] [0265] [0266] [0267] [0268] [0269] [0270] [0271] [0272] [0273] [0274] [0275] [0276] [0277] [0278] [0279] [0280] [0281] [0282] [0283] [0284] [0285] [0286] [0287] [0288] [0289] [0290] [0291] [0292] [0293] [0294] [0295] [0296] [0297] [0298] [0299] [0300] [0301] [0302] [0303] [0304] [0305] [0306] [0307] [0308] [0309] [0310] [0311] [0312] [0313] [0314] [0315] [0316] [0317] [0318] [0319] [0320] [0321] [0322] [0323] [0324] [0325] [0326] [0327] [0328] [0329] [0330] [0331] [0332] [0333] [0334] [0335] [0336] [0337] [0338] [0339] [0340] [0341] [0342] [0343] [0344] [0345] [0346] [0347] [0348] [0349] [0350] [0351] [0352] [0353] [0354] [0355] [0356] [0357] [0358] [0359] [0360] [0361] [0362] [0363] [0364] [0365] [0366] [0367] [0368] [0369] [0370] [0371] [0372] [0373] [0374] [0375] [0376] [0377] [0378] [0379] [0380] [0381] [0382] [0383] [0384] [0385] [0386] [0387] [0388] [0389] [0390] [0391] [0392] [0393] [0394] [0395] [0396] [0397] [0398] [0399] [0400] [0401] [0402] [0403] [0404] [0405] [0406] [0407] [0408] [0409] [0410] [0411] [0412] [0413] [0414] [0415] [0416] [0417] [0418] [0419] [0420] [0421] [0422] [0423] [0424] [0425] [0426] [0427] [0428] [0429] [0430] [0431] [0432] [0433] [0434] [0435] [0436] [0437] [0438] [0439] [0440] [0441] [0442] [0443] [0444] [0445] [0446] [0447] [0448] [0449] [0450] [0451] [0452] [0453] [0454] [0455] [0456] [0457] [0458] [0459] [0460] [0461] [0462] [0463] [0464] [0465] [0466] [0467] [0468] [0469] [0470] [0471] [0472] [0473] [0474] [0475] [0476] [0477] [0478] [0479] [0480] [0481] [0482] [0483] [0484] [0485] [0486] [0487] [0488] [0489] [0490] [0491] [0492] [0493] [0494] [0495] [0496] [0497] [0498] [0499] [0500] [0501] [0502] [0503] [0504] [0505] [0506] [0507] [0508] [0509] [0510] [0511] [0512] [0513]
# # Dick Munroe (munroe@csworks.com) # # Convert all local address blocks from the OSU configuration # files to a format that can be processed by WASD. # # Usage: # # perl CONVERT-OSU-TO-WASD.PL www_system:osu.conf # # What is produced are files in the current directory. Some # tweaking may be necessary for your configuration to do everything # at your site. # # One thing that I would like to figure out is how to actually # generate HTA files instead of HTL files for authentication if # an authenticator is specified in the OSU configuration. # # The OSU configuration file is expected to be of the form: # # localaddress (cname | ip number) host name # configuration statements # localaddress # use strict ; use File::Basename ; use FileHandle ; use VMS::Filespec ; sub glob2pat { my $globstr = shift; my %patmap = ( '*' => '(.*)', '?' => '.', '[' => '[', ']' => ']', ); $globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge; return '^' . $globstr . '$'; } sub dcl { return '$ ' . $_[0] . "\n" ; } ; sub convertProtToHTL { my $theFileHandle = new FileHandle "< " . $_[0] ; die $_[0] . " does not exist" if (!defined $theFileHandle) ; my $theLine ; my $theRealm ; my @theResult ; while (defined($theLine = $theFileHandle->getline())) { chomp $theLine ; if ($theLine =~ m/^<realm>\s+(.*)/) { $theRealm = $1 ; } elsif ($theLine =~ m/^(\w+?)\s+(\w+)/) { push @theResult,$1 . "=" . $2 ; } elsif ($theLine =~ m/^\s*#/) { push @theResult,$theLine ; } else { push @theResult,"# " . $theLine ; } } my @theReturnValue ; $theReturnValue[0] = $theRealm ; $theReturnValue[1] = (join "\n",@theResult) . "\n" ; return @theReturnValue ; } ; my $theBusyCount ; my $theCurrentHost ; my $theInputFile = new FileHandle "< " . $ARGV[0] ; my $theLine ; my %theLocalAddressBlocks ; my %theProtectionDomains ; while (defined($theLine = $theInputFile->getline())) { chomp $theLine ; # # Ignore blank lines. # next if ($theLine eq "") ; # # And comments. # next if ($theLine =~ m/^\s*#/) ; last if ($theLine =~ m/^localaddress\s*(#.*$|$)/i) ; # # The OSU file local address block provides either a # canonical name or an ip address followed by a host # name. We use the host name to define the virtual # service. # if ($theLine =~ m/^localaddress\s+(cname|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(localhost|([\w-]+(\.[\w-]+)+))/i) { $theCurrentHost = $2 ; $theLocalAddressBlocks{$theCurrentHost}{'ip'} = $1 ; } elsif ($theLine =~ m/^localaddress\s+\@listen_backlog=(\d+)/i) { $theBusyCount = $1 if ($theBusyCount < $1) ; } elsif ($theLine =~ m/^localaddress/i) { print "ERROR: ",$theLine,"\n" ; } else { if ($theLine =~ m/^\s*protect\s+([^\s]+)\s+([^\s]+)/i) { if (-e $2) { $theProtectionDomains{$theCurrentHost}{$1} = $2 ; } else { print "ERROR: ",$theLine,"\n" ; } } else { push @{$theLocalAddressBlocks{$theCurrentHost}{'configuration'}},$theLine ; } ; } } ; undef $theInputFile ; my $theFileHandle ; $theFileHandle = rmsexpand('sys$disk:[].httpd$service',$ARGV[0]) ; $theFileHandle = new FileHandle "> " . $theFileHandle ; print $theFileHandle "#\n" ; print $theFileHandle "# Generated from ",$ARGV[0]," by convert-osu-to-wasd.pl\n" ; print $theFileHandle "#\n" ; foreach (sort keys %theLocalAddressBlocks) { my $theScheme ; foreach $theScheme ("http", "https") { print $theFileHandle "[[$theScheme://",$_,"]]\n" ; print $theFileHandle "[ServiceIpAddress] ",$theLocalAddressBlocks{$_}{ip},"\n" if ($theLocalAddressBlocks{$_}{ip} ne 'cname') ; print $theFileHandle "\n" ; } ; } ; undef $theFileHandle ; my %theAcls ; $theFileHandle = rmsexpand('sys$disk:[].httpd$map',$ARGV[0]) ; $theFileHandle = new FileHandle "> " . $theFileHandle ; print $theFileHandle "#\n" ; print $theFileHandle "# Generated from ",$ARGV[0]," by convert-osu-to-wasd.pl\n" ; print $theFileHandle "#\n" ; foreach (sort keys %theLocalAddressBlocks) { my @theLengths ; my @theResult ; foreach (@{$theLocalAddressBlocks{$_}{'configuration'}}) { if (m/^(redirect|map)\s+([^\s]+)\s+([^\s]+)/i) { push @theResult,[$1, unixify($2), unixify($3)] ; } elsif (m/^(exec)\s+([^\s]+)\s+([^\s]+)/i) { push @theResult,[$1, unixify($2), '/0::"task=wwwexec"' . unixify($3) . "*"] ; } elsif (m/^(pass)\s+([^\s]+)\s*([^\s]*)/i) { push @theResult,[$1, unixify($2), unixify($3)] ; } else { push @theResult,"# " . $_ ; } if ((ref $theResult[$#theResult]) ne "") { my $theIndex ; for ($theIndex = 0; $theIndex < scalar(@{$theResult[$#theResult]}); $theIndex++) { if ($theLengths[$theIndex] < length($theResult[$#theResult]->[$theIndex])) { $theLengths[$theIndex] = length($theResult[$#theResult]->[$theIndex]) ; } } } ; } @{$theLocalAddressBlocks{$_}{result}} = @theResult ; # print $theFileHandle "if (host:$_*)\n" ; print $theFileHandle "[[",$_,"]]\n" ; foreach (@theResult) { my $theRef = ref $_ ; if ($theRef eq "") { print $theFileHandle " ",$_,"\n" ; } else { my $theIndex ; my $theString ; for ($theIndex = 0; $theIndex < scalar(@{$_}); $theIndex++) { $theString = $theString . sprintf("%-" . sprintf("%d", $theLengths[$theIndex]) . "s",$_->[$theIndex]) . " " ; } ; print $theFileHandle " ",$theString,"\n" ; } } # print $theFileHandle "endif\n" ; print $theFileHandle "\n" ; } undef $theFileHandle ; my %theConvertedProtectionDomains ; $theFileHandle = rmsexpand('sys$disk:[].httpd$auth',$ARGV[0]) ; $theFileHandle = new FileHandle "> " . $theFileHandle ; print $theFileHandle "#\n" ; print $theFileHandle "# Generated from ",$ARGV[0]," by convert-osu-to-wasd.pl\n" ; print $theFileHandle "#\n" ; foreach (sort keys %theProtectionDomains) { my $theDomain = $_ ; # print $theFileHandle "if (host:",$theDomain,")\n\n" ; print $theFileHandle "[[",$theDomain,"]]\n\n" ; foreach (sort keys %{$theProtectionDomains{$theDomain}}) { my $theFileName = $theProtectionDomains{$theDomain}{$_} ; if (! exists($theConvertedProtectionDomains{$theFileName})) { @{$theConvertedProtectionDomains{$theFileName}} = convertProtToHTL($theFileName) ; } print $theFileHandle "[\"",$theConvertedProtectionDomains{$theFileName}[0],"\"=",uc((fileparse($theFileName,'\..*'))[0]),"=list]\n" ; print $theFileHandle $_," r+w\n" ; print $theFileHandle "\n" ; } # print $theFileHandle "endif\n\" ; print $theFileHandle "\n" ; } undef $theFileHandle ; foreach (sort keys %theConvertedProtectionDomains) { $theFileHandle = new FileHandle "> " . rmsexpand('sys$disk:[].$htl',$_) ; print $theFileHandle "#\n" ; print $theFileHandle "# Converted from $_ by convert-osu-to-wasd.pl\n" ; print $theFileHandle "#\n" ; print $theFileHandle $theConvertedProtectionDomains{$_}[1] ; undef $theFileHandle ; } if (defined($theBusyCount)) { $theFileHandle = new FileHandle "> " . rmsexpand('sys$disk:[].httpd$config',$ARGV[0]) ; print $theFileHandle "[Busy] ",$theBusyCount,"\n" if (defined($theBusyCount)) ; undef $theFileHandle ; } ; # # Produce a DCL procedure that will get "close" to the protections # necessary to run the OSU content and cgis from the new WASD # server. Basically what's happening here is that every directory # that needs read access (shows up in a redirect, map, or pass) # will have protection set to: # # S:RWED,O:RWED,G:RE,W:RE # # for all files, including directories. # # An ACL setting the following will then be applied to the directory # and all subdirectorys: # # (DEFAULT_PROTECTION,SYSTEM:RWED,OWNER:RWED,GROUP:RE,WORLD:RE) # # Which will keep the right protections going. # # Execute directories will have the following protections set: # # S:RWED,O:RWED,G:RE,W:E # # which will allow anybody to execute things. An ACL will be placed # on all directories: # # (DEFAULT_PROTECTION,SYSTEM:RWED,OWNER:RWED,GROUP:RE,WORLD:E) # # In addition, all .DAT files (and you will need to do this manually # for all files that need to be written by these CGIs) will have an # acl added that allows http$nobody full access. # # (IDENTIFIER=WASD_HTTP_NOBODY,ACCESS=READ+WRITE+EXECUTE+DELETE) # # Remember that this is just a template and should be inspected # carefully before executing. # $theFileHandle = rmsexpand('sys$disk:[].set-protection',$ARGV[0]) ; $theFileHandle = new FileHandle "> " . $theFileHandle ; print $theFileHandle dcl("!") ; print $theFileHandle dcl("! Generated from " . $ARGV[0] . " by convert-osu-to-wasd.pl") ; print $theFileHandle dcl("!") ; print $theFileHandle dcl("EXIT") ; print $theFileHandle dcl("") ; print $theFileHandle dcl('DEFAULT_DIRECTORY = F$ENVIRONMENT("DEFAULT")') ; foreach (sort keys %theLocalAddressBlocks) { if (exists($theLocalAddressBlocks{$_}{result}) && scalar(@{$theLocalAddressBlocks{$_}{result}})) { my $theIndex ; OUTER : for ($theIndex = 0; $theIndex < scalar(@{$theLocalAddressBlocks{$_}{result}}) - 1; $theIndex++) { next if (ref(${$theLocalAddressBlocks{$_}{result}}[$theIndex]) eq '') ; my @theResults = @{${$theLocalAddressBlocks{$_}{result}}[$theIndex]} ; my @theInnerResults ; my $theResult = $theResults[2] ; my $theInnerIndex ; if ($theResults[0] eq 'exec') { @theInnerResults = @{${$theLocalAddressBlocks{$_}{result}}[$theIndex]} ; $theResult = $theInnerResults[2] ; } else { for ($theInnerIndex = $theIndex + 1; $theInnerIndex < scalar(@{$theLocalAddressBlocks{$_}{result}}); $theInnerIndex++) { @theInnerResults = @{${$theLocalAddressBlocks{$_}{result}}[$theInnerIndex]} ; my $theMatch = glob2pat($theInnerResults[1]) ; if ($theResult =~ m/$theMatch/) { if ($theInnerResults[2] ne '') { my $theTemp = $1 ; $theResult = $theInnerResults[2] ; $theResult =~ s/\*/$theTemp/ ; last if ($theInnerResults[0] ne 'map') ; } ; } ; } ; } ; $theResult =~ s/\/.*::.*?\//\// ; $theResult = vmsify($theResult) ; $theResult =~ s/\].*/\]/ ; $theAcls{$theResult}{$theInnerResults[0]}++ ; } } } my $theLastKey ; my $theLastKeyMatch ; foreach (sort { $b cmp $a } keys %theAcls) { my $theRoot = $_ ; chop $theRoot ; if (! defined($theLastKey)) { $theLastKey = $theRoot ; $theLastKeyMatch = quotemeta($theLastKey) ; } elsif ($theRoot =~ m/^$theLastKeyMatch\./) { my $theMap ; my $theOriginalKey = $theLastKey . "]" ; my $theUndefFlag = 1 ; foreach $theMap ("pass", "exec") { $theUndefFlag = $theUndefFlag && (((defined($theAcls{$theOriginalKey}{$theMap})) && (defined($theAcls{$_}{$theMap}))) || ((!defined($theAcls{$theOriginalKey}{$theMap})) && (!defined($theAcls{$_}{$theMap})))) ; } ; undef $theAcls{$_} if ($theUndefFlag) ; } else { $theLastKey = $theRoot ; $theLastKeyMatch = quotemeta($theLastKey) ; } } ; foreach (sort keys %theAcls) { next if (!defined($theAcls{$_})) ; my $theDirectory = $_ ; $theDirectory = uc($theDirectory) ; print $theFileHandle dcl("!") ; print $theFileHandle dcl("SET DEFAULT $theDirectory") ; $theDirectory =~ s/^.+\[([^\]]*).*/$1/ ; $theDirectory =~ s/^([^\.]+\.)*// ; my $theDirectoryAce ; my $theDirectoryProtection ; if ((defined($theAcls{$_}{'pass'}) && defined($theAcls{$_}{'exec'})) || defined($theAcls{$_}{'pass'})) { $theDirectoryAce = "(DEFAULT_PROTECTION,SYSTEM:RWED,OWNER:RWED,GROUP:RE,WORLD:RE)" ; $theDirectoryProtection = "(SYSTEM:RWED,OWNER:RWED,GROUP:RE,WORLD:RE)" ; } else { $theDirectoryAce = "(DEFAULT_PROTECTION,SYSTEM:RWED,OWNER:RWED,GROUP:RE,WORLD:E)" ; $theDirectoryProtection = "(SYSTEM:RWED,OWNER:RWED,GROUP:RE,WORLD:E)" ; } ; print $theFileHandle dcl("SET FILE /PROTECTION=$theDirectoryProtection [-]$theDirectory.DIR;") ; print $theFileHandle dcl("SET FILE /PROTECTION=$theDirectoryProtection [...]*.*;*") ; print $theFileHandle dcl("SET ACL /ACL=$theDirectoryAce [-]$theDirectory.DIR;") ; print $theFileHandle dcl("SET ACL /LIKE=(OBJECT_TYPE=FILE,OBJECT_NAME=[-]$theDirectory.DIR;) [...]*.DIR;") ; my $theDataAce = "(IDENTIFIER=WASD_HTTP_NOBODY,ACCESS=READ+WRITE+EXECUTE+DELETE)" ; if (defined($theAcls{$_}{'exec'})) { print $theFileHandle dcl("SET ACL /ACL=$theDataAce [...]*.DAT;*") ; } } ; print $theFileHandle dcl("!") ; print $theFileHandle dcl("SET DEFAULT 'DEFAULT_DIRECTORY'") ; print $theFileHandle dcl("EXIT") ; undef $theFileHandle ;