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@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("/",@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";