Cisco-Conf

 view release on metacpan or  search on metacpan

lib/Cisco/Conf.pm  view on Meta::CPAN


=pod

=head2 Remove($configFile, $name)

(Class method) Removes configuration C<$name> from the list of configurations
in the file C<$configFile>.

Only root may add or remove configurations.

=cut

sub Remove($$$) {
    my($class, $file, $name) = @_;

    if ($< != 0  ||  $> != 0) {
	die "Must be root to remove routers.\n";
    } 

    my($config) = $class->_ReadConfigFile($file);
    if (!exists($config->{'hosts'}->{$name})) {
	die "A host $name doesn't exist.";
    }
    delete $config->{'hosts'}->{$name};
    $class->_SaveConfigFile($file, $config);
    $class;
}


=pod

=head2 Read($configFile, $name)

(Class method) Reads the configuration of the host C<$name> from the
configuration file C<$configFile> and returns a I<Cisco::Conf> instance
representing the host.

=cut


sub Read ($$$) {
    my ($class, $configFile, $name) = @_;
    my $config;
    if (!ref($configFile)) {
        $config = $class->_ReadConfigFile($configFile);
    } else {
	$config = $configFile;
    }
    if (!exists($config->{'hosts'}->{$name})) {
	die "No such host: $name";
    }
    my $self = $config->{'hosts'}->{$name};
    bless($self, (ref($class) || $class));
    my $key;
    foreach $key (qw(editors ci local_addr tftp_prefix)) {
	if (!exists($self->{$key})) {
	    $self->{$key} = $config->{$key};
	}
    }
    $self->{'configFile'} = $configFile;
    my($euid, $epasswd, $euser) = getpwuid($>);
    my($ruid, $rpasswd, $ruser) = getpwuid($<);
    my($user);
    foreach $user (@{$self->{'users'}}) {
	if ($user eq $euid  ||  $user eq $euser  ||
	    $user eq $ruid  ||  $user eq $ruser) {
	    return $self;
	}
    }
    die "You have no permissions to access host $name.";
}


=pod

=head2 Edit($editor, $file, $tmpDir)

(Instance method) Invoke the editor C<$editor> to edit the configuration
file. If $editor is not defined, use $ENV{'EDITOR'} or the first editor
from the list of editors in the configuration file. (The I<editors>
attribute.)

For security reasons valid editors are restricted to those from the
configuration file. Editing takes place in the directory $tmpDir,
so that we can change the EUID to the users.

Example:

    $self->Edit('emacs', 'myrouter.conf', '/tmp');

=cut


sub _System($$) {
    my($class, $command) = @_;
    $! = 0;
    my $rc = system $command;
    if ($rc == 0xff00) {
	die "Command $command failed: " .
	    ($!  ||  "Unknown system error");
    } elsif ($rc) {
	die "Command $command exited, error status $rc";
    }
}


sub _Edit ($$$$) {
    my($self, $editor, $file, $tmpDir) = @_;

    if ($< == $>) {
	# We aren't running SUID, so things are easy.
	return $self->_System(sprintf("%s %s", $editor, $file));
    }

    #   Editing a file is a true security problem. :-(
    #   Most editors have escape sequences that allow to execute
    #   arbitrary shell commands with. When running suid root,
    #   this means that we can do just anything!
    #
    #   We try to work around this problem as follows:
    #   First we create a copy of the file that should be
    #   edited. The real user becomes owner of this file.



( run in 3.282 seconds using v1.01-cache-2.11-cpan-d8267643d1d )