a command line tool which executes commands on remote servers. Define tasks in Perl and execute them on remote servers or groups of servers. Rex can be used to: _ Deploy web applications to servers sequentially or in parallel. _ Automate common tasks. _ Provision servers using Rex's builtin tools. From Olivier Cherrier <oc AT symacx.com> with tweaks from sthen@
187 lines
4.4 KiB
Plaintext
187 lines
4.4 KiB
Plaintext
$OpenBSD: patch-lib_Rex_User_OpenBSD_pm,v 1.1.1.1 2019/02/21 04:54:50 afresh1 Exp $
|
|
|
|
Index: lib/Rex/User/OpenBSD.pm
|
|
--- lib/Rex/User/OpenBSD.pm.orig
|
|
+++ lib/Rex/User/OpenBSD.pm
|
|
@@ -14,14 +14,16 @@ our $VERSION = '1.6.0'; # VERSION
|
|
use Rex::Logger;
|
|
use Rex::Commands::MD5;
|
|
use Rex::Helper::Run;
|
|
+use Rex::Helper::Encode;
|
|
use Rex::Commands::Fs;
|
|
-use Rex::User::NetBSD;
|
|
use Rex::Interface::File;
|
|
use Rex::Interface::Fs;
|
|
use Rex::Interface::Exec;
|
|
+use Rex::User::Linux;
|
|
use Rex::Helper::Path;
|
|
+use JSON::MaybeXS;
|
|
|
|
-use base qw(Rex::User::NetBSD);
|
|
+use base qw(Rex::User::Linux);
|
|
|
|
sub new {
|
|
my $that = shift;
|
|
@@ -40,7 +42,8 @@ sub create_user {
|
|
|
|
my $old_pw_md5 = md5("/etc/passwd");
|
|
|
|
- my $uid = $self->get_uid($user);
|
|
+ my $uid = $self->get_uid($user);
|
|
+ my %user_info = $self->get_user($user);
|
|
my $should_create_home;
|
|
|
|
if ( $data->{'create_home'} || $data->{'create-home'} ) {
|
|
@@ -70,7 +73,11 @@ sub create_user {
|
|
}
|
|
|
|
if ( exists $data->{uid} ) {
|
|
- $cmd .= " -u " . $data->{uid};
|
|
+
|
|
+ # On OpenBSD, "usermod -u n login" fails when the user login
|
|
+ # has already n as userid. So skip it from the command arg
|
|
+ # when the uid is already correct.
|
|
+ $cmd .= " -u " . $data->{uid} unless $data->{uid} == $user_info{uid};
|
|
}
|
|
|
|
if ( exists $data->{home} ) {
|
|
@@ -93,6 +100,10 @@ sub create_user {
|
|
$cmd .= " -e '" . $data->{expire} . "'";
|
|
}
|
|
|
|
+ if ( exists $data->{login_class} ) {
|
|
+ $cmd .= " -L '" . $data->{login_class} . "'";
|
|
+ }
|
|
+
|
|
if ( exists $data->{groups} ) {
|
|
my @groups = @{ $data->{groups} };
|
|
my $pri_group = shift @groups;
|
|
@@ -170,6 +181,127 @@ sub create_user {
|
|
ret => $self->get_uid($user),
|
|
},
|
|
;
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+sub get_user {
|
|
+ my ( $self, $user ) = @_;
|
|
+
|
|
+ Rex::Logger::debug("Getting information for $user");
|
|
+ my $rnd_file = get_tmp_file;
|
|
+ my $fh = Rex::Interface::File->create;
|
|
+ my $script = q|
|
|
+ unlink $0;
|
|
+ print to_json([ getpwnam($ARGV[0]) ]);
|
|
+ |;
|
|
+ $fh->open( ">", $rnd_file );
|
|
+ $fh->write($script);
|
|
+ $fh->write( func_to_json() );
|
|
+ $fh->close;
|
|
+
|
|
+ my $data_str = i_run "perl $rnd_file $user", fail_ok => 1;
|
|
+ if ( $? != 0 ) {
|
|
+ die("Error getting user information for $user");
|
|
+ }
|
|
+
|
|
+ my $data = decode_json($data_str);
|
|
+
|
|
+ return (
|
|
+ name => $data->[0],
|
|
+ password => $data->[1],
|
|
+ uid => $data->[2],
|
|
+ gid => $data->[3],
|
|
+ pwchange => $data->[4],
|
|
+ class => $data->[5],
|
|
+ comment => $data->[6],
|
|
+ home => $data->[7],
|
|
+ shell => $data->[8],
|
|
+ expire => $data->[9],
|
|
+ );
|
|
+}
|
|
+
|
|
+sub lock_password {
|
|
+ my ( $self, $user ) = @_;
|
|
+
|
|
+ # Is the password already locked?
|
|
+ my $result = i_run "getent passwd $user", fail_ok => 1;
|
|
+
|
|
+ if ( $result !~ /^$user.*$/ ) {
|
|
+ die "Unexpected result from getent: $result";
|
|
+ }
|
|
+ elsif ( $result =~ /^$user.*-$/ ) {
|
|
+
|
|
+ # Already locked
|
|
+ return { changed => 0 };
|
|
+ }
|
|
+ else {
|
|
+ my $ret = i_run "usermod -Z $user", fail_ok => 1;
|
|
+ if ( $? != 0 ) {
|
|
+ die("Error locking account $user: $ret");
|
|
+ }
|
|
+ return {
|
|
+ changed => 1,
|
|
+ ret => $ret,
|
|
+ };
|
|
+ }
|
|
+}
|
|
+
|
|
+sub unlock_password {
|
|
+ my ( $self, $user ) = @_;
|
|
+
|
|
+ # Is the password already unlocked?
|
|
+ my $result = i_run "getent passwd $user", fail_ok => 1;
|
|
+
|
|
+ if ( $result !~ /^$user.*$/ ) {
|
|
+ die "Unexpected result from getent: $result";
|
|
+ }
|
|
+ elsif ( $result !~ /^$user.*-$/ ) {
|
|
+
|
|
+ # Already unlocked
|
|
+ return { changed => 0 };
|
|
+ }
|
|
+ else {
|
|
+ my $ret = i_run "usermod -U $user", sub { @_ }, fail_ok => 1;
|
|
+ if ( $? != 0 ) {
|
|
+ die("Error unlocking account $user: $ret");
|
|
+ }
|
|
+ return {
|
|
+ changed => 1,
|
|
+ ret => $ret,
|
|
+ };
|
|
+ }
|
|
+}
|
|
+
|
|
+sub rm_user {
|
|
+ my ( $self, $user, $data ) = @_;
|
|
+
|
|
+ Rex::Logger::debug("Removing user $user");
|
|
+
|
|
+ my %user_info = $self->get_user($user);
|
|
+
|
|
+ my $cmd = "userdel";
|
|
+
|
|
+ if ( exists $data->{delete_home} ) {
|
|
+ $cmd .= " -r";
|
|
+ }
|
|
+
|
|
+ my $output = i_run $cmd . " " . $user, fail_ok => 1;
|
|
+ if ( $? == 67 ) {
|
|
+ Rex::Logger::info( "Cannot delete user $user (no such user)", "warn" );
|
|
+ }
|
|
+ elsif ( $? != 0 ) {
|
|
+ die("Error deleting user $user ($output)");
|
|
+ }
|
|
+
|
|
+ if ( exists $data->{delete_home} && is_dir( $user_info{home} ) ) {
|
|
+ Rex::Logger::debug(
|
|
+ "userdel doesn't delete home directory. removing it now by hand...");
|
|
+ rmdir $user_info{home};
|
|
+ }
|
|
+
|
|
+ if ( $? != 0 ) {
|
|
+ die( "Error removing " . $user_info{home} );
|
|
}
|
|
|
|
}
|