public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] repo/gentoo:master commit in: sys-fs/quota/, sys-fs/quota/files/ldap-scripts/
@ 2016-02-23  7:42 Lars Wendler
  0 siblings, 0 replies; only message in thread
From: Lars Wendler @ 2016-02-23  7:42 UTC (permalink / raw
  To: gentoo-commits

commit:     2e5cbc1691bba9bff270fc29084423cd38852269
Author:     Lars Wendler <polynomial-c <AT> gentoo <DOT> org>
AuthorDate: Tue Feb 23 07:42:09 2016 +0000
Commit:     Lars Wendler <polynomial-c <AT> gentoo <DOT> org>
CommitDate: Tue Feb 23 07:42:28 2016 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2e5cbc16

sys-fs/quota: Install ldap-scripts with USE=ldap (bug #575424).

Package-Manager: portage-2.2.27
Signed-off-by: Lars Wendler <polynomial-c <AT> gentoo.org>

 .../quota/files/ldap-scripts/applySystemQuotas.pl  | 104 +++++++++++++++
 sys-fs/quota/files/ldap-scripts/edquota_editor     |  32 +++++
 sys-fs/quota/files/ldap-scripts/quota.schema       |  18 +++
 sys-fs/quota/files/ldap-scripts/setSystemQuotas.pl | 140 +++++++++++++++++++
 sys-fs/quota/files/ldap-scripts/setquota-ldap.pl   | 148 +++++++++++++++++++++
 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 0000000..41c74d9
--- /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 0000000..fdebd09
--- /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 0000000..b5e216f
--- /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 0000000..90ab1e8
--- /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 0000000..7cafc44
--- /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 a129780..074c8be 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
 }


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2016-02-23  7:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-23  7:42 [gentoo-commits] repo/gentoo:master commit in: sys-fs/quota/, sys-fs/quota/files/ldap-scripts/ Lars Wendler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox