[GLLUG] Samba - root preexec & login scripts

Mike Rambo mrambo@lsd.k12.mi.us
Tue, 29 Oct 2002 12:08:49 -0500


Matt Graham wrote:
> 
> On Tuesday 29 October 2002 08:39, after a long battle with technology,
> > >
> > >    root preexec = /home/netlogon/netlogon.pl %U
> > >    root postexec = rm -f /home/netlogon/%U.bat
> > >
> > > ...but doesn't work. I get a 'no domain controller available'
> 
> Yeah.  Also, what's netlogon.pl doing?  If it's short, post it to the
> list (making sure to obfuscate any sensitive data, of course.)  Maybe
> it should log its output to a file....
> 

The perl script is a little large but I'll send it below. Here is sample
output...

[mrambo@mrambo netlogon]$ ./netlogon.pl mrambo
[mrambo@mrambo netlogon]$ ls
total 32
-rw-rw-r--    1 mrambo   mrambo        277 Oct 29 11:36 mrambo.bat
-rw-rw-r--    1 mrambo   mrambo        437 Oct 26 13:32 netlogon.dtd
-rwxrwxr-x    1 mrambo   mrambo       6299 Oct 29 11:36 netlogon.pl
-rw-rw-r--    1 mrambo   mrambo        507 Oct 26 15:28 netlogon.xml
-rw-r--r--    1 mrambo   mrambo       1889 Oct 26 16:04 README
[mrambo@mrambo netlogon]$ cat mrambo.bat
@ECHO "Configuring network services..."
@ECHO "Setting time..."
NET TIME \\topdog /SET /YES
@ECHO "Mounting H:..."
NET USE H: \\topdog\mrambo /YES
@ECHO "Mounting P:..."
NET USE P: \\topdog\public /YES
@ECHO "Welcome Administrators!"
NET USE N: \\topdog\netlogon /YES

But this never gets created on the server when it runs from root
preexec. The only indication I can find that it runs at all is that the
domain logons no longer work and, now that I've upgraded to samba 2.2.6,
I also usually see a hung nmbd process. Without the root preexec and
with a manually created script domain logons are fine and the scripts
run on the workstation as they are supposed to.

> 
> The preexec script runs on the Samba server, so it can be anything.  The
> example referred to in the smb.conf manpage is a csh script.  The
> script you're thinking of is the thing referred to in the logon script=
> parameter, which has to be a .BAT or .CMD file and has to have \r\n
> line endings and such.  Mike, what's the logon script= parameter in
> your smb.conf?
> 

logon script = %U.bat


This is kind of big - and I don't know how it'll translate to email -
but here goes...

#!/usr/bin/perl -w

# netlogon-0.2

use strict;
use XML::Twig;

my $user_name = $ARGV[0] || '';
my $group_name = $ARGV[1] || '';
my $arch_name = $ARGV[2] || '';
my $net_name = $ARGV[3] || '';

# Global variables used throughout the script
my ($homedrive, $shardrive, $sharspace, $servername);
my (@groups, @users);
my $file = 'netlogon.xml';
my $groupmemfile = '/etc/group';
my $output_path = './';
my $script = "\@ECHO \"Configuring network services...\"\r\n";
my $DEBUG = 0; # Set to 1 to enable debug output
my $gname = '';

# XML::Twig handlers
my $twig_handlers = {'global' => \&global_handler,
                     'group' => \&group_handler,
                     'user' => \&user_handler};
my $twig = new XML::Twig(TwigHandlers => $twig_handlers);

$twig->parsefile($file);

# Set the time, mount the global share and users home share
$script .= "\@ECHO \"Setting time...\"\r\n";
$script .= "NET TIME \\\\$servername /SET /YES\r\n";
$script .= "\@ECHO \"Mounting $homedrive...\"\r\n";
$script .= "NET USE $homedrive \\\\$servername\\$user_name /YES\r\n";
$script .= "\@ECHO \"Mounting $shardrive...\"\r\n";
$script .= "NET USE $shardrive \\\\$servername\\$sharspace /YES\r\n";

if($DEBUG == 1) {
    print "Home: $homedrive\n";
    print "Shared: $shardrive $sharspace\n";
    print "Server: $servername\n";
}

# Iterate through the groups
foreach my $group (@groups) {
    open(GMFILE, "$groupmemfile") or die "Can't open group membership
file: $!\n";
    $gname = $group->{name};
    while (<GMFILE>) {
        if (/$gname:/ && /$user_name/) {
            $script .= "\@ECHO \"".$group->{comment}."\"\r\n";
            $script .= "NET USE ".$group->{drive}."
\\\\".$servername."\\".$group->{share}." /YES\r\n";
        }
    }
    close GMFILE;
    if($DEBUG == 1) {
        print "Group->\n";
        print "\tName: ".$group->{name}."\n";
        print "\tComment: ".$group->{comment}."\n";
        print "\tShare: ".$group->{share}."\n";
    }
}

# Iterate through the users
foreach my $user (@users) {
    if($user_name eq $user->{name}) {
        $script .= "\@ECHO \"".$user->{comment}."\"\r\n";
        $script .= "NET USE ".$user->{drive}."
\\\\".$servername."\\".$user->{share}." /YES\r\n";
    }
    if($DEBUG == 1) {
        print "User->\n";
        print "\tName: ".$user->{name}."\n";
        print "\tComment: ".$user->{comment}."\n";
        print "\tShare: ".$user->{share}."\n";
    }
}

if($DEBUG == 1) {
    print "\n\n".$script."\n\n";
}
else {
# Dump the final script to a file
    my $filename = $output_path . "$user_name.bat";
    if(open(SCRIPT, ">$filename")) {
        print SCRIPT $script;
        close(SCRIPT);
    }
}

# Handle the <global/> tag(s)
sub global_handler
{
    my ($twig_obj, $global) = @_;
    $homedrive = $global->first_child('homedrive')->text;
    $shardrive = $global->first_child('shardrive')->text;
    $sharspace = $global->first_child('sharspace')->text;
    $servername = $global->first_child('servername')->text;
}

# Handle the <group/> tag(s)
sub group_handler
{
    my ($twig_obj, $group) = @_;
    my $grp;
    $grp->{name} = $group->first_child('name')->text;
    $grp->{comment} = $group->first_child('comment')->text;
    $grp->{share} = $group->first_child('share')->text;
    $grp->{drive} = $group->first_child('drive')->text;
    push @groups, $grp;
}

# Handle the <user/> tag(s)
sub user_handler
{
    my($twig_obj, $user) = @_;
    my $usr;
    $usr->{name} = $user->first_child('name')->text;
    $usr->{comment} = $user->first_child('comment')->text;
    $usr->{share} = $user->first_child('share')->text;
    $usr->{drive} = $user->first_child('drive')->text;
    push @users, $usr;
}