[Samba] Printer Migration hackery

Martin Whinnery <martin.whinnery at sbirmc.ac.uk> e008993 at cobalt.sbirmc.ac.uk
Mon Jul 22 00:52:02 GMT 2002


Hokay.

It appears that enumdrivers / getdriver in rpcclient is broken, and won't
be fixed soon. I'd fix it meself, but hey, I'm too busy clearing
skyscrapers in a single bound and moving faster than a speeding bullet. Or
maybe I looked at the cvs once and got REALLY scared.

Unfortunately, I can't wait, so I've come up with a nasty hack to help us
with querying samba for the details of installed printer drivers.

It's filthy nasty perl, not really fit for human consumption, but it
works. For now at least. If the format of ntdrivers.tdb changes, or if
samba stops using it, this won't work anymore.

This is a first hack. The LDIF style output is not right. But the info is
there. Hopefully it will be of some use to some people.

One question for the samba team though:

When I run 'strings' against ntdrivers.tdb, I get pretty sensible output.
One thing confuses me though. What significance does the entry 'PJL
Language Monitor' Hold? Does it precede the one file which implements the
monitor? Or all the files? Or what?

Martin Whinnery
Assistant Network Manager
South Birmingham College

 -----------snip--------------------------- #!/usr/bin/perl -w
#

$USER = "myuser";
$PASSWD = hispassword";
$DRIVERTDBFILE = "/the/path/to/ntdrivers.tdb";
$PRINTDOLLARPATH = "/the/print$/path";
#Where in LDAP you keep your printers
$LDAPPRINTERBASE = "ou=hosts,dc=example,dc=com";
#Where in LDAP you keep your printer drivers
$LDAPDRIVERBASE = "applicationentity=printerdrivers,o=microsoft.com,ou=software,dc=example,dc=com";

$dummy = 0;
$myaddr = qx/nmblookup -A 127.0.0.1 | grep '<20>'/;
$myaddr =~ s/[\t ]+/ /g;
$myaddr =~ s/^ //;
( $myname, $dummy ) = split(/ /,$myaddr);

open RPCCLIENT, "rpcclient $myname -U $USER%$PASSWD -c 'enumprinters' |";
while (<RPCCLIENT>) {
    $line = $_;
    chop $line;
    if ( $line =~ /name:\[/ ) {
	$line =~ s/.+\\\\.+\\//;
	$line =~ s/]//;
    $printers{$line}{"name"}=$line;
    }    
}
close RPCCLIENT;

foreach $printer ( sort keys %printers ) {
    open RPCCLIENT, "rpcclient $myname -U $USER%$PASSWD -c 'getprinter $printer 2' | grep ':\\[' |";
while (<RPCCLIENT>) {
    $line = $_;
    chop $line;
    $line =~ s/^\t//;
    ( $attrib, $value ) = split(/:/,$line);
    $value =~ s/[\[\]]//g;
    $printers{$printer}{$attrib} = $value;
}    
close RPCCLIENT;
}

$/ = "";
open RPCCLIENT, "rpcclient $myname -U $USER%$PASSWD -c 'enumdrivers 2' | egrep ':\|^\$' |";
while (<RPCCLIENT>) {
    $line = $_;
$line =~ s/Printer Driver Info 2:\n//;
#$line =~ s/[\t ] +//g;
$line =~ s/[\[\]]//g;
$line =~ s/^[^:]+: |(\n)[^:]+: /$1/g;
$line =~ s/\\/\//g;
$line =~ s/$myname//gi;
$line =~ s/print\$/$PRINTDOLLARPATH/g;
$line =~ s/\/+/\//g;
( $version, $drivername, $architecture, $driverpath,
  $datafile, $configfile ) = split(/\n/, $line);
$drivers{$drivername}{"version"} = $version;
$drivers{$drivername}{"architecture"} = $architecture;
$drivers{$drivername}{"driverpath"} = $driverpath;
$drivers{$drivername}{"datafile"} = $datafile;
$drivers{$drivername}{"configfile"} = $configfile;
}    
close RPCCLIENT;

$/ = "\n";
open(DRIVERTDB, "strings $DRIVERTDBFILE | grep -v 'BBBBBBBB' |");
$dummy = <DRIVERTDB>;
$dummy = <DRIVERTDB>;
$dummy = <DRIVERTDB>;
while (<DRIVERTDB>) {
    $line = $_;
if ($line =~ /^&/) {
    $drivername = <DRIVERTDB>;
    $arch = <DRIVERTDB>;
    chop $drivername;
    chop $arch;
} else {
    if ($line =~ /\\print\$\\/) {
	chop $line;
	$line =~ s/\\/\//g;
	$line =~ s/print\$/$PRINTDOLLARPATH/g;
	$line =~ s/\/+/\//g;
	push @{$drivers{$drivername}{"FILES"}}, ($line);
    }
}
}

close DRIVERTDB;

foreach $printer ( sort keys %printers ) {
    print "dn: cn=$printer,$LDAPPRINTERBASE\n";
print "changetype: modify\n";
print "replace: drivername\n";
print "drivername: " . $printers{$printer}{"drivername"} . "\n\n";
}

foreach $driver ( sort keys %drivers ) {
    print "dn: cn=$driver,$LDAPDRIVERBASE\n";
print "architecture: " . $drivers{$driver}{"architecture"} . "\n";
print "driverfile: " . $drivers{$driver}{"driverpath"} . "\n";
print "configfile: " . $drivers{$driver}{"configfile"} . "\n";
print "datafile: " . $drivers{$driver}{"datafile"} . "\n";
foreach $file (@{$drivers{$driver}{"FILES"}}) {
    print "file: " . $file . "\n";
}
print "\n";
}






More information about the samba mailing list