Initial commit to Gerrit
[profile/ivi/quota.git] / ldap-scripts / setSystemQuotas.pl
1 #!/usr/bin/perl -w
2
3 # $0 -b "ou=People,dc=borgia,dc=com" -Q /dev/with/quota=0:0:0:0 -F '(attr=value)'
4
5 # Synopsis
6 # setSystemQuotas.pl is a script solely for modifying the quota attribute in
7 # LDAP.  It expects that the users you intend to have quotas already have the
8 # systemQuotas objectClass set.
9 # This tool is capable of applying standard LDAP filters to the user-supplied
10 # base DN for modifying multiple users' quotas at once.
11
12 # Examples:
13 # Set quota on /dev/sda7 and /dev/sda8 for user stefan
14 # ./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
15 #
16 # Set quota on /dev/sda8 for user all People with description of Student
17 # ./setSystemQuotas.pl -b "ou=People,dc=borgia,dc=com" -Q /dev/sda8=40000:44000:1000:1100 -F "(description=Student)"
18 #
19 # Delete quotas for user stefan
20 # ./setSystemQuotas.pl -b "uid=stefan,ou=People,dc=borgia,dc=com"
21
22 use strict;
23 use Net::LDAP;
24 use Getopt::Long;
25
26 chomp(my $Password = `cat /etc/ldap.secret`);
27 my $Host = 'localhost';
28 my $Port = '389';
29 my $BindDN = 'cn=Manager,dc=borgia,dc=com';
30 my $SSL = 0;
31
32 my $b = '';
33 my %Q = ();
34 my $F = '';
35 GetOptions(
36         'b=s' => \$b,
37         'Q=s' => \%Q,
38         'F=s' => \$F,
39 );
40 die "Usage: $0 -b userdn [-F '(extrafilter)'] [-Q /fs=sb:hb:sf:hf ...]\n" unless $b;
41 foreach ( keys %Q ) {
42         local @_ = split /:/, $Q{$_};
43         unless ( $#_ == 3 ) {
44                 print "Ignoring $_: invalid format\n";
45                 delete $Q{$_};
46         }
47 }
48
49 my $ldap = connectLDAP();
50
51 my $quota = {};
52 my $search;
53 $search = $ldap->search(
54         base => $b,
55         filter => "(&(objectClass=systemQuotas)$F)",
56         attrs => ['*', 'quota'],
57 );
58 $search->code && die $search->error;
59 my $i = 0;
60 my $max = $search->count;
61 for ( $i=0; $i<$max; $i++ ) {
62         my $entry = $search->entry($i);
63         my $dn = $entry->dn;
64         if ( keys %Q ) {
65                 $quota->{$dn} = 1;
66                 foreach ( $entry->get_value('quota') ) {
67                         my @quota = split /:/;
68                         my $fs = shift @quota;
69                         delete $quota->{$dn} if $quota->{$dn} == 1;
70                         $quota->{$dn}->{$fs} = join ':', @quota;
71                 }
72         } else {
73                 $quota->{$dn} = 0;
74                 delete $quota->{$dn} unless $entry->get_value('quota');
75         }
76 }
77         
78 foreach my $dn ( keys %{$quota} ) {
79         if ( ref $quota->{$dn} eq 'HASH' ) {
80 print STDERR "Modify $dn:\n";
81                 foreach ( keys %Q ) {
82 print STDERR "\t$_:$Q{$_}\n";
83                         $quota->{$dn}->{$_} = $Q{$_};
84                 }
85                 my @quota = map { "$_:$quota->{$dn}->{$_}" } keys %{$quota->{$dn}};
86                 my $modify = $ldap->modify(
87                         $dn,
88                         replace => {
89                                 quota => [@quota],
90                         },
91                 );
92                 $modify->code && warn "Failed to modify quota: ", $modify->error, "\n";
93         } else {
94                 if ( $quota->{$dn} == 1 ) {
95                         delete $quota->{$dn};
96 print STDERR "Add $dn:\n";
97                         foreach ( keys %Q ) {
98 print STDERR "\t$_:$Q{$_}\n";
99                                 $quota->{$dn}->{$_} = $Q{$_}
100                         }
101                         my @quota = map { "$_:$quota->{$dn}->{$_}" } keys %{$quota->{$dn}};
102                         my $modify = $ldap->modify(
103                                 $dn,
104                                 add => {
105                                         quota => [@quota],
106                                 },
107                         );
108                         $modify->code && warn "Failed to modify quota: ", $modify->error, "\n";
109                 } elsif ( $quota->{$dn} == 0 ) {
110 print STDERR "Delete $dn:\n";
111                         my $modify = $ldap->modify(
112                                 $dn,
113                                 delete => ['quota'],
114                         );
115                         $modify->code && warn "Failed to modify quota: ", $modify->error, "\n";
116                 }
117         }
118 }
119 $ldap->unbind;
120
121 sub connectLDAP {
122         # bind to a directory with dn and password
123         my $ldap = Net::LDAP->new(
124                 $Host,
125                 port => $Port,
126                 version => 3,
127 #                debug => 0xffff,
128         ) or die "Can't contact LDAP server ($@)\n";
129         if ( $SSL ) {
130                 $ldap->start_tls(
131                         # verify => 'require',
132                         # clientcert => 'mycert.pem',
133                         # clientkey => 'mykey.pem',
134                         # decryptkey => sub { 'secret'; },
135                         # capath => '/usr/local/cacerts/'
136                 ); 
137         }
138         $ldap->bind($BindDN, password=>$Password);
139         return $ldap;
140 }