#!/usr/bin/perl -w # # update-pam # # Copyright (C) 2004 Fabio Tranchitella # Copyright (C) 2004 Giuseppe Sacco # # update-pam is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, # or (at your option) any later version. # use strict; use Getopt::Long; use File::Basename qw(basename); use File::Temp qw(tempfile); my $CONF_DIR = "./pam.d"; my $VERSION = '0.01'; sub main { my ($m_add, $m_remove, $m_enable, $m_disable, $m_version, $m_help, $before, $after, $service, $control, $type); $m_add = $m_remove = $m_enable = $m_disable = 0; $after = $before = $service = $control = $type = ""; GetOptions( 'add|a' => \$m_add, 'remove|r' => \$m_remove, 'enable|e' => \$m_enable, 'disable|d' => \$m_disable, 'service=s' => \$service, 'control=s' => \$control, 'type=s' => \$type, 'before=s' => \$before, 'after=s' => \$after, 'version|v' => \$m_version, 'help|h' => \$m_help ); version() if ($m_version); usage() if ($m_help or ($m_add + $m_remove + $m_enable + $m_disable) != 1 or (not $control and $m_add) or not $type or not @ARGV or ($before ne "" and $after ne "")); $service = "common-" . $type if $service eq ""; my $entry = shift @ARGV if @ARGV; if ($m_add) { return apply("add", $entry, $service, $control, $type, $before, $after); } elsif ($m_remove) { return apply("remove", $entry, $service, $control, $type); } elsif ($m_enable) { return apply("enable", $entry, $service, $control, $type); } elsif ($m_disable) { return apply("disable", $entry, $service, $control, $type); } } sub apply { my ($action, $entry, $service, $control, $type, $before, $after) = @_; my $output = ""; open(IN, "$CONF_DIR/$service") or die "Couldn't open $CONF_DIR/$service $!\n"; while () { if ($_ =~ /^#/ and $_ !~ /^##/ or $_ =~ /^[\s\t]+/) { $output .= $_; } elsif ($action eq "add" and $_ =~ /^(\#\#)?(session|account|auth|password)[\s\t]+ (requisite|required|sufficient|optional|\[[^\]]+\]) [\s\t]+(\S+)\s?(.*)/x and $2 eq $type and $entry ne "") { if (($before eq "" and $after eq "") or $before eq "$4") { $output .= $type . "\t" . $control . "\t" . $entry . "\n" . $_; $entry = ""; } elsif ($after eq "$4") { $output .= $_ . $type . "\t" . $control . "\t" . $entry . "\n"; $entry = ""; } else { $output .= $_; } } elsif ($action eq "remove" and $_ =~ /^$type[\s\t]+ (requisite|required|sufficient|optional|\[[^\]]+\]) [\s\t]+$entry(\s(.*)$|$)/x) { ; } elsif ($action eq "disable" and $_ =~ /^$type[\s\t]+ (requisite|required|sufficient|optional|\[[^\]]+\]) [\s\t]+$entry(\s(.*)$|$)/x) { $output .= ("##" . $_); } elsif ($action eq "enable" and $_ =~ /\#\#$type[\s\t]+ (requisite|required|sufficient|optional|\[[^\]]+\]) [\s\t]+$entry(\s(.*)$|$)/x) { $_ =~ s/^##//; $output .= $_; } else { $output .= $_; } } close IN; if ($entry eq "") { my ($tmp, $filetmp) = tempfile('pam.tmpXXXX') or die ("Couldn't open a temporary file: $!\n"); print $tmp $output; close($tmp); rename("$filetmp", "$CONF_DIR/$service") or die "Couldn't rename ".$filetmp.": $!\n"; return 0; } return 1; } sub usage { print <