#!/usr/bin/perl -w # # This script attempts to copy all user accounts from the host to # the guest. It does this by copying all user accounts which are not # already present. # # NOTE: Unless '--accounts' was specified upon the 'xen-create-image' # command line we don't do this. # # Steve # -- # https://steve.fi/ use strict; use Env; my $prefix = shift; die "Prefix must be given" unless defined( $prefix ); die "Prefix must be a directory" unless ( -d $prefix ); # # Setup /etc/shadow and /etc/gshadow on Fedora and friends # Closes: #499476) # if (-x "$prefix/usr/sbin/pwconv") { system( "chroot $prefix /usr/sbin/pwconv" ); } if (-x "$prefix/usr/sbin/grpconv") { system( "chroot $prefix /usr/sbin/grpconv" ); } # # Exit unless the 'accounts' variable is set. # exit unless ( $ENV{'accounts'} ); # # Make sure we have $prefix/etc # die "Prefix is missing /etc : $prefix" unless ( -d $prefix . "/etc" ); # # Read all accounts from the installed /etc/passwd on the guest. # my %present; if ( -e $prefix . "/etc/passwd" ) { %present = readAccounts( $prefix . "/etc/passwd" ); } # # Now read the accounts on the host. # my %host = readAccounts( "/etc/passwd" ); # # For each account not present on new installation then add it # foreach my $account ( sort keys( %host ) ) { if ( ! $present{ $account } ) { print "Adding: $account\n"; addAccount( $account ); # # Find any groups the user is member of on the host # and add them on the guest system # addGroups( $account ); } } # # Read the accounts which are already present on the guest image. # sub readAccounts { my ( $file ) = ( @_ ); my %found; open( EXISTING, "<", $file ); foreach my $line ( ) { # # Record the userid + username # if ( $line =~ /^([^:]+):([^:]+):([^:]+)/ ) { my $user = $1; my $pass = $2; my $uid = $3; $found{$user} = 1; } } close( EXISTING ); return( %found ); } # # Add the passwd + shadow accounts for the given user. # sub addAccount { my ( $user ) = ( @_ ); # # passwd file. # open( PASSWD, "<", "/etc/passwd" ); foreach my $line ( ) { chomp( $line ); if ( $line =~ /^\Q$user\E:/ ) { # # Add the line # open( OUTY, ">>", $prefix . "/etc/passwd" ); print OUTY $line . "\n"; close( OUTY ); } } close( PASSWD ); # # shadow file. # open( SHADOW, "<", "/etc/shadow" ) or die "Failed to open : $!"; foreach my $line ( ) { chomp( $line ); if ( $line =~ /^\Q$user\E:/ ) { # # Add the line # open( OUTY, ">>", $prefix . "/etc/shadow" ); print OUTY $line . "\n"; close( OUTY ); } } close( SHADOW ); } # # Find the groups a user is member of on the host, and add them to # those groups on the new guest. # sub addGroups { my( $username ) = ( @_ ); # # Get the groups. # my $groups = `groups $username`; # split off the usernmame. if ( $groups =~ /^([^:]+):(.*)/ ) { $groups = $2; print "User: $username is member of the groups: $groups\n"; } foreach my $g ( split( / /, $groups ) ) { # Make sure the group exists. system( "chroot $prefix /usr/sbin/addgroup $g" ); # add the user to it. system( "chroot $prefix /usr/sbin/adduser $username $g" ); } }