diff --git a/pkgtool.pm b/pkgtool.pm index 39b9f99..80f9e12 100644 --- a/pkgtool.pm +++ b/pkgtool.pm @@ -540,6 +540,15 @@ my $global_cfg_syntax = { } } }, + 'group' => { + Type => 'string' + }, + 'members' => { + Type => 'list', + Elements => { + Type => 'string' + } + }, 'user' => { Type => 'string' }, @@ -2899,6 +2908,22 @@ sub do_net_user ($$;$$$$) return 1; } +sub do_net_group_member ($$) +{ + my ($groupname, $member) = @_; + + my $sourcefile = $ENV{systemroot}.'\\System32\\net.exe'; + my $paramlist = ['localgroup', $groupname, $member, '/add']; + my ($error, $exitcode) = run_exe('global', undef, undef, undef, $sourcefile, $paramlist, 0); + if (defined $error) { + print_log('global', ERROR, 'Error adding user %s to group %s: %s', + $member, $groupname, $error); + return 0; + } + print_log('global', DEBUG1, 'Added user %s to group %s', $member, $groupname); + return 1; +} + sub do_modify_user ($$$$$) { my ($username, $fullname, $enabled, $pwchange, $pwexpires) = @_; @@ -3305,6 +3330,78 @@ sub handle_directory ($$$$$$) return 1; } +sub handle_group ($$$) +{ + my ($pkg, $counters, $update) = @_; + + my $name = $$pkg{name}; + my $hostname = $ENV{'COMPUTERNAME'}; + my $groupname = $$pkg{'group'}; + my $members = $$pkg{'members'}; + $members = [] unless defined $members; + + my $sourcefile = $ENV{systemroot}.'\\System32\\wbem\\wmic.exe'; + my $paramlist = ['path', 'win32_groupuser', 'where', '(groupcomponent="win32_group.name=\''.$groupname.'\',domain=\''.$hostname.'\'")']; + my $result = []; + my ($error, $exitcode) = run_exe('global', undef, undef, undef, $sourcefile, $paramlist, 0, $result); + if (defined $error) { + print_log('global', ERROR, 'Error checking for group %s: %s', $groupname, $error); + push @{$$counters{FailList}}, $name; + $$counters{FailCount}++; + return 0; + } + my $header; + my $found; + my $users = {}; + my $groups = {}; + if (defined $$result[0] && $$result[0] !~ /No Instance/o) { + ($header, $result) = parse_wmic($result); + foreach my $row (@$result) { + my $member = $$row{PartComponent}; + next unless defined $member; + + if ($member =~ /Win32_Group\.Domain="([^"]*)",Name="([^"]*)"/oi) { + my $domain = lc($1); + my $group = lc($2); + $$groups{$domain.'\\'.$group} = 1; + } + elsif ($member =~ /Win32_UserAccount\.Domain="([^"]*)",Name="([^"]*)"/oi) { + my $domain = lc($1); + my $user = lc($2); + $$groups{$domain.'\\'.$user} = 1; + } + } + } + + foreach my $member (@$members) { + my $name = lc($member); + if (defined $$groups{$name} || defined $$users{$name}) { + print_log('global', WARNING, 'User %s a member of group %s - OK', + $member, $groupname); + } + else { + print_log('global', WARNING, 'User %s not a member of group %s - %s', + $member, $groupname, $update ? 'adding' : 'ADD'); + if ($update) { + my $rc = do_net_group_member($groupname, $member); + if (! $rc) { + push @{$$counters{FailList}}, $groupname.'/'.$member; + $$counters{FailCount}++; + next; + } + push @{$$counters{InstalledList}}, $groupname.'/'.$member; + $$counters{InstalledCount}++; + } + else { + push @{$$counters{ToInstallList}}, $groupname.'/'.$member; + $$counters{ToInstallCount}++; + } + } + } + + return 1; +} + sub handle_user ($$$) { my ($pkg, $counters, $update) = @_; @@ -3464,6 +3561,9 @@ sub handle_pkg ($$$$$$) if (defined $$pkg{'user'}) { return handle_user($pkg, $counters, $update); } + if (defined $$pkg{'group'}) { + return handle_group($pkg, $counters, $update); + } if (defined $$pkg{'directory'}) { return handle_directory($config, $pkg, $vars, $base_directory, $counters, $update); }