diff options
author | Lars Wendler <polynomial-c@gentoo.org> | 2016-02-23 08:42:09 +0100 |
---|---|---|
committer | Lars Wendler <polynomial-c@gentoo.org> | 2016-02-23 08:42:28 +0100 |
commit | 2e5cbc1691bba9bff270fc29084423cd38852269 (patch) | |
tree | bc0d7ae2e4f22e9aee232007d4201a57c6cd9c69 /sys-fs/quota | |
parent | dev-ruby/shorturl: add ruby23 (diff) | |
download | gentoo-2e5cbc1691bba9bff270fc29084423cd38852269.tar.gz gentoo-2e5cbc1691bba9bff270fc29084423cd38852269.tar.bz2 gentoo-2e5cbc1691bba9bff270fc29084423cd38852269.zip |
sys-fs/quota: Install ldap-scripts with USE=ldap (bug #575424).
Package-Manager: portage-2.2.27
Signed-off-by: Lars Wendler <polynomial-c@gentoo.org>
Diffstat (limited to 'sys-fs/quota')
-rwxr-xr-x | sys-fs/quota/files/ldap-scripts/applySystemQuotas.pl | 104 | ||||
-rwxr-xr-x | sys-fs/quota/files/ldap-scripts/edquota_editor | 32 | ||||
-rw-r--r-- | sys-fs/quota/files/ldap-scripts/quota.schema | 18 | ||||
-rwxr-xr-x | sys-fs/quota/files/ldap-scripts/setSystemQuotas.pl | 140 | ||||
-rw-r--r-- | sys-fs/quota/files/ldap-scripts/setquota-ldap.pl | 148 | ||||
-rw-r--r-- | sys-fs/quota/quota-4.03.ebuild | 7 |
6 files changed, 446 insertions, 3 deletions
diff --git a/sys-fs/quota/files/ldap-scripts/applySystemQuotas.pl b/sys-fs/quota/files/ldap-scripts/applySystemQuotas.pl new file mode 100755 index 000000000000..41c74d919d37 --- /dev/null +++ b/sys-fs/quota/files/ldap-scripts/applySystemQuotas.pl @@ -0,0 +1,104 @@ +#!/usr/bin/perl -w + +# $0 -b "ou=People,dc=borgia,dc=com" -F '(attr=value)' + +# Synopsis +# applyQuotas.pl is a script solely for making the quota set within LDAP take +# affect by running the linuxquota tool edquota with the figures set in LDAP. +# This tool is capable of applying standard LDAP filters to the user-supplied +# base DN for applying multiple users' quotas at once. + +# Examples: +# Apply the quotas using the linuxquota tool edquota for user stefan +# ./applySystemQuotas.pl -b "uid=stefan,ou=People,dc=borgia,dc=com" +# +# Apply the quotas using the linuxquota tool edquota for all People with description of Student +# ./applySystemQuotas.pl -b "ou=People,dc=borgia,dc=com" -F "(description=Student)" + +use strict; +use Net::LDAP; +use Getopt::Long; + +chomp(my $Password = `cat /etc/ldap.secret`); +my $Host = 'localhost'; +my $Port = '389'; +my $BindDN = 'cn=Manager,dc=borgia,dc=com'; +my $SSL = 0; +my $edquota_editor = '/usr/sbin/edquota_editor'; +my $edquota = '/usr/sbin/edquota'; + +my $b = ''; +my $F = ''; +GetOptions( + 'b=s' => \$b, + 'F=s' => \$F, +); + +die "Usage: $0 -b basedn [-F '(extrafilter)']\n" unless $b; + +my $ldap = connectLDAP(); + +my $search; +$search = $ldap->search( + base => $b, + filter => "(&(objectClass=systemQuotas)$F)", + attrs => ['uid', 'quota'], +); +$search->code && die $search->error; +my $i = 0; +my $max = $search->count; +for ( $i=0; $i<$max; $i++ ) { + my $entry = $search->entry($i); + my $editor = $ENV{'VISUAL'} if $ENV{'VISUAL'}; + $ENV{'VISUAL'} = $edquota_editor; + $ENV{'QUOTA_USER'} = $entry->get_value('uid'); + # Delete all existing quotas for QUOTA_USER + $ENV{'QUOTA_FILESYS'} = '*'; + $ENV{'QUOTA_SBLOCKS'} = 0; + $ENV{'QUOTA_HBLOCKS'} = 0; + $ENV{'QUOTA_SFILES'} = 0; + $ENV{'QUOTA_HFILES'} = 0; + print "$ENV{'QUOTA_USER'}: $ENV{'QUOTA_FILESYS'}:$ENV{'QUOTA_SBLOCKS'},$ENV{'QUOTA_HBLOCKS'},$ENV{'QUOTA_SFILES'},$ENV{'QUOTA_HFILES'}\n"; + qx(/usr/sbin/edquota -u $ENV{'QUOTA_USER'}); + my @quotas = $entry->get_value('quota'); + if ( $#quotas >= 0 ) { + foreach ( @quotas ) { + my @quota = split /:/; + $ENV{'QUOTA_FILESYS'} = $quota[0]; + $ENV{'QUOTA_SBLOCKS'} = $quota[1]; + $ENV{'QUOTA_HBLOCKS'} = $quota[2]; + $ENV{'QUOTA_SFILES'} = $quota[3]; + $ENV{'QUOTA_HFILES'} = $quota[4]; + print "$ENV{'QUOTA_USER'}: $ENV{'QUOTA_FILESYS'}:$ENV{'QUOTA_SBLOCKS'},$ENV{'QUOTA_HBLOCKS'},$ENV{'QUOTA_SFILES'},$ENV{'QUOTA_HFILES'}\n"; + qx($edquota -u $ENV{'QUOTA_USER'}); + } + } + if ($editor) { + $ENV{'VISUAL'} = $editor; + } + else { + delete $ENV{'VISUAL'}; + } +} +$search = $ldap->unbind; + +sub connectLDAP { + # bind to a directory with dn and password + my $ldap = Net::LDAP->new( + $Host, + port => $Port, + version => 3, +# debug => 0xffff, + ) or die "Can't contact LDAP server ($@)\n"; + if ( $SSL ) { + $ldap->start_tls( + # verify => 'require', + # clientcert => 'mycert.pem', + # clientkey => 'mykey.pem', + # decryptkey => sub { 'secret'; }, + # capath => '/usr/local/cacerts/' + ); + } + $ldap->bind($BindDN, password=>$Password); + return $ldap; +} diff --git a/sys-fs/quota/files/ldap-scripts/edquota_editor b/sys-fs/quota/files/ldap-scripts/edquota_editor new file mode 100755 index 000000000000..fdebd09e35a4 --- /dev/null +++ b/sys-fs/quota/files/ldap-scripts/edquota_editor @@ -0,0 +1,32 @@ +#!/usr/bin/perl -w + +use strict; + +die "QUOTA_USER environment variable not set\n" unless defined $ENV{'QUOTA_USER'}; +die "QUOTA_FILESYS environment variable not set\n" unless defined $ENV{'QUOTA_FILESYS'}; +die "QUOTA_SBLOCKS environment variable not set\n" unless defined $ENV{'QUOTA_SBLOCKS'}; +die "QUOTA_HBLOCKS environment variable not set\n" unless defined $ENV{'QUOTA_HBLOCKS'}; +die "QUOTA_SFILES environment variable not set\n" unless defined $ENV{'QUOTA_SFILES'}; +die "QUOTA_HFILES environment variable not set\n" unless defined $ENV{'QUOTA_HFILES'}; + +open FILE, $ARGV[0]; +my $qdata = join '', (@_=<FILE>); +close FILE; +open FILE, ">$ARGV[0]"; +print FILE &edit_quota_file($qdata, $ENV{'QUOTA_FILESYS'}, $ENV{'QUOTA_SBLOCKS'}, $ENV{'QUOTA_HBLOCKS'}, $ENV{'QUOTA_SFILES'}, $ENV{'QUOTA_HFILES'}); +close FILE; + +# edit_quota_file(data, filesys, sblocks, hblocks, sfiles, hfiles) +sub edit_quota_file { + my($rv, $line, @line, $i); + @line = split /\n/, $_[0]; + for ( $i=0; $i<@line; $i++ ) { + if ($line[$i] =~ /^\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/ && ($1 eq $_[1] || $_[1] eq '*')) { + # new-style line to change + $rv .= " $1 $2 $_[2] $_[3] $5 $_[4] $_[5]\n"; + } else { + $rv .= "$line[$i]\n"; + } + } + return $rv; +} diff --git a/sys-fs/quota/files/ldap-scripts/quota.schema b/sys-fs/quota/files/ldap-scripts/quota.schema new file mode 100644 index 000000000000..b5e216f8db96 --- /dev/null +++ b/sys-fs/quota/files/ldap-scripts/quota.schema @@ -0,0 +1,18 @@ +## +## schema file for Unix Quotas +## Schema for storing Unix Quotas in LDAP +## OIDs are owned by Cogent Innovators, LLC +## +## 1.3.6.1.4.1.19937.1.1.x - attributetypes +## 1.3.6.1.4.1.19937.1.2.x - objectclasses +## + +attributetype ( 1.3.6.1.4.1.19937.1.1.1 NAME 'quota' + DESC 'Quotas (FileSystem:BlocksSoft,BlocksHard,InodesSoft,InodesHard)' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} ) + +objectclass ( 1.3.6.1.4.1.19937.1.2.1 NAME 'systemQuotas' SUP posixAccount AUXILIARY + DESC 'System Quotas' + MUST ( uid ) + MAY ( quota )) diff --git a/sys-fs/quota/files/ldap-scripts/setSystemQuotas.pl b/sys-fs/quota/files/ldap-scripts/setSystemQuotas.pl new file mode 100755 index 000000000000..90ab1e8076c9 --- /dev/null +++ b/sys-fs/quota/files/ldap-scripts/setSystemQuotas.pl @@ -0,0 +1,140 @@ +#!/usr/bin/perl -w + +# $0 -b "ou=People,dc=borgia,dc=com" -Q /dev/with/quota=0:0:0:0 -F '(attr=value)' + +# Synopsis +# setSystemQuotas.pl is a script solely for modifying the quota attribute in +# LDAP. It expects that the users you intend to have quotas already have the +# systemQuotas objectClass set. +# This tool is capable of applying standard LDAP filters to the user-supplied +# base DN for modifying multiple users' quotas at once. + +# Examples: +# Set quota on /dev/sda7 and /dev/sda8 for user stefan +# ./setSystemQuotas.pl -b "uid=stefan,ou=People,dc=borgia,dc=com" -Q /dev/sda7=4000000:4400000:10000:11000 -Q /dev/sda8=4000000:4400000:10000:11000 +# +# Set quota on /dev/sda8 for user all People with description of Student +# ./setSystemQuotas.pl -b "ou=People,dc=borgia,dc=com" -Q /dev/sda8=40000:44000:1000:1100 -F "(description=Student)" +# +# Delete quotas for user stefan +# ./setSystemQuotas.pl -b "uid=stefan,ou=People,dc=borgia,dc=com" + +use strict; +use Net::LDAP; +use Getopt::Long; + +chomp(my $Password = `cat /etc/ldap.secret`); +my $Host = 'localhost'; +my $Port = '389'; +my $BindDN = 'cn=Manager,dc=borgia,dc=com'; +my $SSL = 0; + +my $b = ''; +my %Q = (); +my $F = ''; +GetOptions( + 'b=s' => \$b, + 'Q=s' => \%Q, + 'F=s' => \$F, +); +die "Usage: $0 -b userdn [-F '(extrafilter)'] [-Q /fs=sb:hb:sf:hf ...]\n" unless $b; +foreach ( keys %Q ) { + local @_ = split /:/, $Q{$_}; + unless ( $#_ == 3 ) { + print "Ignoring $_: invalid format\n"; + delete $Q{$_}; + } +} + +my $ldap = connectLDAP(); + +my $quota = {}; +my $search; +$search = $ldap->search( + base => $b, + filter => "(&(objectClass=systemQuotas)$F)", + attrs => ['*', 'quota'], +); +$search->code && die $search->error; +my $i = 0; +my $max = $search->count; +for ( $i=0; $i<$max; $i++ ) { + my $entry = $search->entry($i); + my $dn = $entry->dn; + if ( keys %Q ) { + $quota->{$dn} = 1; + foreach ( $entry->get_value('quota') ) { + my @quota = split /:/; + my $fs = shift @quota; + delete $quota->{$dn} if $quota->{$dn} == 1; + $quota->{$dn}->{$fs} = join ':', @quota; + } + } else { + $quota->{$dn} = 0; + delete $quota->{$dn} unless $entry->get_value('quota'); + } +} + +foreach my $dn ( keys %{$quota} ) { + if ( ref $quota->{$dn} eq 'HASH' ) { +print STDERR "Modify $dn:\n"; + foreach ( keys %Q ) { +print STDERR "\t$_:$Q{$_}\n"; + $quota->{$dn}->{$_} = $Q{$_}; + } + my @quota = map { "$_:$quota->{$dn}->{$_}" } keys %{$quota->{$dn}}; + my $modify = $ldap->modify( + $dn, + replace => { + quota => [@quota], + }, + ); + $modify->code && warn "Failed to modify quota: ", $modify->error, "\n"; + } else { + if ( $quota->{$dn} == 1 ) { + delete $quota->{$dn}; +print STDERR "Add $dn:\n"; + foreach ( keys %Q ) { +print STDERR "\t$_:$Q{$_}\n"; + $quota->{$dn}->{$_} = $Q{$_} + } + my @quota = map { "$_:$quota->{$dn}->{$_}" } keys %{$quota->{$dn}}; + my $modify = $ldap->modify( + $dn, + add => { + quota => [@quota], + }, + ); + $modify->code && warn "Failed to modify quota: ", $modify->error, "\n"; + } elsif ( $quota->{$dn} == 0 ) { +print STDERR "Delete $dn:\n"; + my $modify = $ldap->modify( + $dn, + delete => ['quota'], + ); + $modify->code && warn "Failed to modify quota: ", $modify->error, "\n"; + } + } +} +$ldap->unbind; + +sub connectLDAP { + # bind to a directory with dn and password + my $ldap = Net::LDAP->new( + $Host, + port => $Port, + version => 3, +# debug => 0xffff, + ) or die "Can't contact LDAP server ($@)\n"; + if ( $SSL ) { + $ldap->start_tls( + # verify => 'require', + # clientcert => 'mycert.pem', + # clientkey => 'mykey.pem', + # decryptkey => sub { 'secret'; }, + # capath => '/usr/local/cacerts/' + ); + } + $ldap->bind($BindDN, password=>$Password); + return $ldap; +} diff --git a/sys-fs/quota/files/ldap-scripts/setquota-ldap.pl b/sys-fs/quota/files/ldap-scripts/setquota-ldap.pl new file mode 100644 index 000000000000..7cafc449d824 --- /dev/null +++ b/sys-fs/quota/files/ldap-scripts/setquota-ldap.pl @@ -0,0 +1,148 @@ +#!/usr/bin/perl + +# A Perl wrapper for setquota utility which updates LDAP accordingly. + +# /etc/fstab: usrquota,grpquota +# mount -o remount /f/s +# touch /f/s/aquota.{user,group} +# chmod 600 /f/s/aquota.{user,group} +# quotacheck -cguvamf + +use strict; +use warnings; +use Net::LDAP; +use Net::LDAP::Entry; +use Getopt::Long; +Getopt::Long::Configure ("bundling"); + +my $help = $#ARGV >= 0 ? 0 : 1; +my $ldaphost = 'localhost'; +my $passwordfile = ''; +my $password = ''; +my $binddn = $ENV{BINDDN}; +my $basedn = $ENV{BASEDN}; +my $oc = 'systemQuotas'; +my $attr = 'quota'; +my %Q = (); +my $F = 'cn=*'; +GetOptions( + 'help|?' => \$help, + 'oc|o=s' => \$oc, + 'attr|a=s' => \$attr, + 'quota|Q=s' => \%Q, + 'filter|F=s' => \$F, + 'ldaphost|h=s' => \$ldaphost, + 'basedn|b=s' => \$basedn, + 'binddn|D=s' => \$binddn, + 'password|w=s' => \$password, + 'passwordfile|W=s' => \$passwordfile, +); +die "Usage: $0 -b basedn [-o objectClass] [-a attr] [-F '(extrafilter)'] [-Q +/f/s=sb:hb:gb:sf:hf:gf ...]\n" if $help; +%Q = checkQ(%Q); + +my ($ldap, $bind); +if ( $ldap = Net::LDAP->new($ldaphost, version => 3, timeout => 3) ) { + if ( $binddn && $password ) { + $bind = $ldap->bind($binddn, password=>$password); + } elsif ( $binddn && $passwordfile ){ + $bind = $ldap->bind($binddn, password=>bindpw($passwordfile)); + } else { + $bind = $ldap->bind(); + } + die "Unable to connect to LDAP\n" if $bind->code; + undef $passwordfile; +} else { + die "Unable to connect to LDAP\n"; +} + +my $search = $ARGV[0] ? $ldap->search(base=>$basedn, filter=>"uid=$ARGV[0]") : $ldap->search(base=>$basedn, filter=>$F); +if ( $search->code ) { + die "LDAP Error: ", error($search), "\n"; +} elsif ( $search->count <= 0 ) { + die "0 results found in LDAP\n"; +} else { + my $i = 0; + for ( $i=0; $i<$search->count; $i++ ) { + my $entry = $search->entry($i); + my @oc = $entry->get_value('objectClass'); + # objectClass: $oc + unless ( grep { /^$oc$/ } @oc ) { + my $modify = $ldap->modify($entry->dn, add => {objectClass => $oc}); + if ( $modify->code ) { + print STDERR "Failed to add objectClass $oc:", error($modify), "\n"; + } + } + # $attr: /f/s=sb:hb:sf:hf + if ( $entry->exists($attr) ) { + my @attr = $entry->get_value($attr); + if ( keys %Q ) { + foreach my $fs ( keys %Q ) { + foreach ( @attr ) { + next unless /^$fs=/; + my $modify = $ldap->modify($entry->dn, delete => {$attr => "$_"}); + if ( $modify->code ) { + print STDERR "Failed to delete $attr: $_: ", error($modify), "\n"; + } + } + my $modify = $ldap->modify($entry->dn, add => {$attr => "$fs=$Q{$fs}"}); + if ( $modify->code ) { + print STDERR "Failed to add $attr: $fs=$Q{$fs}: ", error($modify), "\n"; + } else { + print STDERR "Failed to setquota: $fs=$Q{$fs}\n" if setquota($entry->get_value('uid'), $fs, $Q{$fs}); + } + } + } else { + my $modify = $ldap->modify($entry->dn, delete => [($attr)]); + if ( $modify->code ) { + print STDERR "Failed to delete $attr: ", error($modify), "\n"; + } else { + foreach ( @attr ) { + my ($fs) = m!^(/[^=]*)!; + $Q{$fs} = '0:0:0:0:0:0'; + print STDERR "Failed to setquota: $fs=$Q{$fs}\n" if setquota($entry->get_value('uid'), $fs, $Q{$fs}); + } + } + } + } else { + if ( keys %Q ) { + foreach my $fs ( keys %Q ) { + my $modify = $ldap->modify($entry->dn, add => {$attr => "$fs=$Q{$fs}"}); + if ( $modify->code ) { + print STDERR "Failed to add $attr: $fs=$Q{$fs}: ", error($modify), "\n"; + } else { + print STDERR "Failed to setquota: $fs=$Q{$fs}\n" if setquota($entry->get_value('uid'), $fs, $Q{$fs}); + } + } + } + } + } +} + +sub setquota { + $_[2] = '0:0:0:0:0:0' unless $_[2]; + $_[2] =~ /^(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)$/; + qx{/usr/sbin/setquota -u $_[0] $1 $2 $4 $5 $_[1]}; + qx{/usr/sbin/setquota -T -u $_[0] $3 $6 $_[1]}; + return 0; +} + +sub checkQ { + my (%Q) = @_; + foreach ( keys %Q ) { + die "$_: invalid format\n" unless m!^(/[^=]*)! && $Q{$_} =~ /^(\d+):(\d+):(\d+):(\d+):(\d+):(\d+)$/; + } + return %Q; +} + +sub bindpw { + my ($passwordfile) = @_; + open P, $passwordfile or die "Can't open passwordfile: $!"; + chomp(my $password = <P>); + close P; + return $password; +} + +sub error { + return $_[0]->error, "(", $_[0]->code, ")"; +} diff --git a/sys-fs/quota/quota-4.03.ebuild b/sys-fs/quota/quota-4.03.ebuild index a129780adbe3..074c8be5baf6 100644 --- a/sys-fs/quota/quota-4.03.ebuild +++ b/sys-fs/quota/quota-4.03.ebuild @@ -48,6 +48,7 @@ src_prepare() { src_configure() { econf \ + --docdir="${EPREFIX}/usr/share/doc/${PF}" \ $(use_enable nls) \ $(use_enable ldap ldapmail) \ $(use_enable netlink) \ @@ -74,10 +75,10 @@ src_install() { if use ldap ; then insinto /etc/openldap/schema insopts -m0644 - doins ldap-scripts/quota.schema + doins "${FILESDIR}"/ldap-scripts/quota.schema exeinto /usr/share/quota/ldap-scripts - doexe ldap-scripts/*.pl - doexe ldap-scripts/edquota_editor + doexe "${FILESDIR}"/ldap-scripts/*.pl + doexe "${FILESDIR}"/ldap-scripts/edquota_editor fi } |