[Samba] get quota command - Example

Eric Warnke ericew at gmail.com
Tue Apr 4 15:25:01 GMT 2006


I know when I went looking for a complete example of how to interface
with samba's quota system there was no good ones, so here it is.  I
developed this yesterday with a lot of trial and error.  Feel free to
use this in any way people feel fit.  With this script I can now get
correct used/free reporting based on the output of quota for both
users and groups.

I developed this because samba could not recognize a combination of
NFS and LVM's ext3 quota's through automount.  It was developed on
CentOS4.3 on a poweredge 2800 with shared SCSI storage.

It should work on many more systems than the default because it uses
the mount and quota commands directly, although this may cause some
problems in very large systems due to constant use of perl in the
background.  If nothing else this will serve as a starting point for
those attempting to make heads or tails of the documentation.

Cheers,
Eric Warnke
Systems Administrator - Research IT
State University of New York at Albany



#!/usr/bin/perl
#
# Copyright 2006 Eric Warnke <ewarnke at albany.edu>
# This application may be used for any purpose as long
# as credit is givin to Eric Warnke and to SUNY Albany
#
# This application interfaced SAMBA 3.X series cifs server with
# quota information available through the command line
# application /usr/bin/quota on Centos 4.3
#
# THIS APPLICATION WORKS FOR ME, BUT YOU MAY NEED TO MAKE
# CHANGES FOR IT TO WORK PROPERLY IN YOUR ENVIRONMENT!
#
# USE AT YOUR OWN RISK
#

# Setup safe env so that perl doesn't complain
$ENV{PATH} = ( '/bin', '/usr/bin' );

# Capture environment variables

# Directory for whom quota is to be checked
$directory = $ARGV[0];

# Type of query 2 = user 4 = group 1,3 not quite sure how they work in reality
$type = $ARGV[1];
if ( $type =~ /([1-4])/ ) {
        $type = $1; # untaint
} else {
        die("Incorrect type flag");
}

# UID or GID to be checked
$id = $ARGV[2];
if ( $id =~ /(\d+)/ ) {
        $id = $1; # untaint
} else {
        die("Is that really a uid or gid?");
}

# For some reason, despite what documentation states, samba always
# appears to pass the directory as "." ( quotes part of string )
# this maps to pwd of the script.
#
# This should be changed in samba to always be the full string or be dropped
# as an unnecessary argument
#
if ( $directory eq '"."' ) {
        $directory = `/bin/pwd`;
        chomp($directory);
}

# Debugging, useful for capturing arguments passed to script
#open(LOG,">>/tmp/log.txt");
#print LOG "$directory,$type,$id\n";
#close(LOG);

# Don't know what to do with these since they are never called
if ( $type == 1 || $type == 3 ) {
        print "0 0 0 0 0 0 0\n";
        exit;
}

# Capture the mount point mappings in the system
# this could have also been done through /proc
open(MOUNT, "/bin/mount|");
while ($line = <MOUNT> ) {
        ($def, $temp1, $mp, $temp2) = split(/ /, $line);
        #print "$def,$mp\n";
        $mount_point{$mp} = $def;
}
close(MOUNT);


# Find the mapping for the directory, we may have to loop here
# since with LVM we have to find the DEVICE that it's mapped to
#
# !!!!!!!!!! THIS MAY NEED TO BE CHANGED FOR YOUR SYSTEM !!!!!!
#
do {
        @dirsplit = split(/\//,$directory);
        for($i=@dirsplit; $i!=0; $i--) {
                $test_dir = join("/", at dirsplit[0 .. $i]);
                #print "t $test_dir\n";
                last if ( $mount_point{$test_dir} ne "" );
        }
        $directory = $mount_point{$test_dir};
} until ( ($directory =~ /^\/dev\//)||($directory=~/^\S+:/) );

# Build the quota command necessary
#
if ( $type == 4 ) {
        $typearg = "-g";
} else {
        $typearg = "";
}

$cmd = "/usr/bin/quota $typearg $id";

# Open the output from quota, scan for the mountpoint device
# and then regurgitate the line with some small changes so that
# samba can understand it.
#
open(QUOTA,"$cmd|");
while ( $line = <QUOTA> ) {
        if ( $line =~ /$directory/ ) {
                $line = <QUOTA>;
                print "2";
                print join(" ",split(/\s+/,$line));
                print "\n";
                exit;
        }
}
print "0 0 0 0 0 0 0\n";


More information about the samba mailing list