#!/usr/bin/perl -w ##=====================================================================## ## Copyright (C) 2001-2004 Stephen Zarkos. All rights reserved. ## Obsid@Sentry.net ## ## Please see file: COPYRIGHT for further copyright information and ## disclaimer. Or online at http://www.SentryFirewall.com/files/COPYRIGHT ##=====================================================================## ## File: file_functions.pl $ENV{PATH} = "/bin:/sbin"; umask 022; ##-------------------------------------------------------------------------## ## Sub create_dir(). ## Makes a directory. sub create_dir { return 0 if (!(defined($_[0])) || ($_[0] eq '')); my $dval = "$_[0]"; my $mask = ''; $dval =~ s/^mkdir[\s\t]+//; if ($dval =~ /\:/) { ($dval,$mask) = split(/\:/,$dval,2); } return 1 if (-d "$dval"); ## Check to see if file exists, but is not a directory. if ((-e "$dval") && (! -d "$dval")) { print("ERROR: create_dir(): unable to create directory $dval, file exists.\n"); &do_log("ERROR: create_dir(): unable to create directory $dval, file exists."); return 0; } if ($mask =~ /^\d{3,4}$/) { if ($mask =~ /^\d{3}$/) { ## Mask is three digits. Probably not what the user wants, so we just ## append a 0 to the front and hope for the best. $mask = '0' . "$mask"; } } else { $mask = 0755; } if (! mkdir($dval,$mask)) { print("ERROR: create_dir(): unable to create directory $dval, ($!).\n"); &do_log("ERROR: create_dir(): unable to create directory $dval, ($!)."); return 0; } return 1; } ## End sub create_dir(). ##-------------------------------------------------------------------------## ##-------------------------------------------------------------------------## ## Sub vrfy_file(). ## vrfy_file takes in one variable; a hash key name($var). ## This function verifies the existence of a file. If the path/filename exists ## as stated in the sentry.conf file, then the function returns 1. Otherwise ## vrfy_file() tries to find the file using the $m_point path and then passes ## $var onto locate_file() to try and locate the file using the $path{1..10} ## variables. ## Returns 0 on failure, 1 on success, 2 on syntax or misc. error. sub vrfy_file { return 0 if (!(defined($_[0])) || ($_[0] eq '')); return 0 if (!(exists($prefs{$_[0]}))); my $var = "$_[0]"; my $status = 0; ## Return if path/filename is already valid. return 1 if (-f "$prefs{$var}"); ## Some stuff we shouldn't try to locate... return 2 if (($prefs{"$var"} eq '') || ($var eq '')); return 2 if ($var =~ /^device\d$/); return 2 if ($var =~ /^(http|ftp)_proxy$/); return 2 if ($var =~ /^proxy\-(user|passwd)$/); return 2 if ($var eq 'start_webmin'); return 2 if ($var eq 'debug'); return 2 if ($var =~ /^path\d{1,2}$/); ## If $prefs{"$var"} is a URL, call retr_file_net() to retrieve the file. ## NOTE: This is an explicit URL, so if this fails, we do not bother to ## check the path{1..10} variables. if (($prefs{"$var"} =~ /^[hH]{1}[tT]{2}[pP]{1}[sS]?:\/\//) || ($prefs{"$var"} =~ /^[sS]?[fF]{1}[tT]{1}[pP]{1}:\/\//) || ($prefs{"$var"} =~ /^[sS]{1}[cC]{1}[pP]{1}:\/\//)) { $status = &retr_file_net($var); return 1 if ($status == 1); return 0; } ## Check to see if ${m_point}/$prefs{"$var"} works. if ($var ne 'include') { ## Possible deep recursion issue if 'include' directive reparsed. if (-f "${m_point}/$prefs{$var}") { $prefs{"$var"} =~ s/^\/+//; &do_log("INFO: Using \"${m_point}/$prefs{$var}\" instead of \"$prefs{$var}\""); $prefs{"$var"} = "${m_point}/$prefs{$var}"; $prefs{"$var"} =~ s/\/{2,}/\//g; return 1; } } ## File still does not exist, call locate_file() to iterate through $path{1..10} variables. $status = &locate_file($var); return 0 if ($status != 1); return 1; } ## End sub vrfy_file(). ##-------------------------------------------------------------------------## ##-------------------------------------------------------------------------## ## Sub locate_file(). sub locate_file { return 0 if (!(defined($_[0])) || ($_[0] eq '')); return 0 if (!(exists($prefs{$_[0]}))); my $var = "$_[0]"; my $tmpvar = ''; my $status = 0; my $num = 0; ## Iterate through $path{1..10} variables to find $prefs{$var}. foreach $num (1..10) { next if !(exists($prefs{"path${num}"})); $prefs{"$var"} =~ s/^\/+//; $prefs{"path${num}"} =~ s/\/+$//; if (($prefs{"path${num}"} =~ /^[hH]{1}[tT]{2}[pP]{1}[sS]?:\/\//) || ($prefs{"path${num}"} =~ /^[sS]?[fF]{1}[tT]{1}[pP]{1}:\/\//) || ($prefs{"path${num}"} =~ /^[sS]{1}[cC]{1}[pP]{1}:\/\//)) { $tmpvar = "$prefs{$var}"; $prefs{$var} = "$prefs{\"path${num}\"}/$prefs{$var}"; $status = &retr_file_net("$var", 'NOERR'); if ($status == 1) { &do_log("INFO: Found \"${tmpvar}\" using \"$prefs{\"path${num}\"}/${tmpvar}\"."); return 1; } else { $prefs{"$var"} = "$tmpvar"; } } elsif (-f "$prefs{\"path${num}\"}/$prefs{$var}") { &do_log("INFO: Using \"$prefs{\"path${num}\"}/$prefs{$var}\" instead of \"$prefs{$var}\"."); $prefs{"$var"} = "$prefs{\"path${num}\"}/$prefs{$var}"; $prefs{"$var"} =~ s/\/{2,}/\//g; return 1; } } return 0; } ## End sub locate_file(). ##-------------------------------------------------------------------------## ##-------------------------------------------------------------------------## ## Sub retr_file_net(). ## Retrieve file if destination looks like a http(s)/(s)ftp/scp URI. sub retr_file_net { return 0 if (!(defined($_[0])) || ($_[0] eq '')); return 0 if (!(exists($prefs{$_[0]}))); my $opt = (defined($_[1])) ? "$_[1]" : 'NULL'; my $var = "$_[0]"; my $status = 0; if (!($net > 0)) { print "ERROR: retr_file_net(): Unable to retrieve ${var}, device not configured.\n"; &do_log("ERROR: retr_file_net(): Unable to retrieve ${var}, device not configured."); return 0; } if (($prefs{"$var"} =~ /^[hH]{1}[tT]{2}[pP]{1}[sS]?:\/\//) || ($prefs{"$var"} =~ /^[sS]?[fF]{1}[tT]{1}[pP]{1}:\/\//) || ($prefs{"$var"} =~ /^[sS]{1}[cC]{1}[pP]{1}:\/\//)) { if ($var ne 'include') { &vrfy_path($var); } $status = &retr_file($var, $prefs{$var}); if (-f "$status") { $prefs{"$var"} = "$status"; return 1; } elsif ($status == 0) { if ($opt ne 'NOERR') { print "ERROR: retr_file_net(): Unable to retrieve \"${var}\".\n"; &do_log("ERROR: retr_file_net(): Unable to retrieve \"${var}\"."); } return 0; } elsif ($status == 2) { if ($opt ne 'NOERR') { print "ERROR: retr_file_net(): Unable to retrieve \"${var}\", request timed out.\n"; &do_log("ERROR: retr_file_net(): Unable to retrieve \"${var}\", request timed out."); } return 0; } } return 0; } ## End sub retr_file_net(). ##-------------------------------------------------------------------------## ##-------------------------------------------------------------------------## ## Sub vrfy_path($) ## Ensure the directory to the passed file exists, call before copying. sub vrfy_path($) { return 0 if (!(defined($_[0])) || ($_[0] eq '')); my @dirs = split( /[\/\\]+/, $_[0] ); my $p = '/'; for (my $i=0;$i<$#dirs;$i++) { next if ($dirs[$i] eq ''); $p .= $dirs[$i]; if (! -d "$p") { if (-e "$p") { &do_log("ERROR: vrfy_path(): \"$p\" exists.\n"); last; } $! = 0; mkdir($p,0755); if ($!) { &do_log("ERROR: vrfy_path(): Unable to make directory \"$p\" ($!).\n"); last; } } $p .= "/"; } return 0; } ## End sub vrfy_path(). ##-------------------------------------------------------------------------## ##-------------------------------------------------------------------------## ## Sub pcopy() ## Copies $src to $trg and creates target directory if needed. ## We just use system(cp..); cause File::Copy isn't versatile enough. sub pcopy { return 0 if (!(defined($_[0])) || ($_[0] eq '')); my $src = $_[0]; my $trg = (defined($_[1])) ? "$_[1]" : '/'; my $opt = (defined($_[2])) ? "$_[2]" : 'NONE'; if ($opt eq 'PERM') { $opt = '-p'; } ## Preserve perms. elsif ($opt eq 'LINK') { $opt = '-dp'; } ## Copy symlink. elsif ($opt eq 'RECURS') { $opt = '-Rdp'; } ## Recurse directory. else { $opt = ''; } ## Normal copy. if ("$src" eq "$trg") { &do_log("WARNING: pcopy(): Copying file $src onto itself."); } else { vrfy_path($trg); system("/bin/cp $opt $src $trg 2>/dev/null"); if ($? > 0) { &do_log("ERROR: pcopy(): unable to copy $src to $trg."); return 0; } } return 1; } ## End sub pcopy(). ##-------------------------------------------------------------------------## ##-------------------------------------------------------------------------## ## Function: do_log() ## Logs to $logfile sub do_log { my $logfile = '/var/log/SENTRY_LOG'; my $log = "$_[0]"; if (open(FH, ">>${logfile}")) { flock(FH,2); print FH "${log}\n"; close(FH); } else { return 0; } return 1; } ## End sub do_log(). ##-------------------------------------------------------------------------## return 1; ## _EOF_ ##