From 296f0caf7ba6b051aab3ac59d197e6017d7d6bda Mon Sep 17 00:00:00 2001 From: Nicolas Charles Date: Mon, 20 Jun 2016 18:51:29 +0200 Subject: [PATCH] Fixes #8566: userManagement technique doesn't do anything on Windows on version 5 and 6 --- .../userManagement/5.0/metadata.xml | 5 ++ .../userManagement/5.0/userManagement.st | 59 +++++++++++++++++-- .../userManagement/6.0/metadata.xml | 5 ++ .../userManagement/6.0/userManagement.st | 58 ++++++++++++++++-- 4 files changed, 119 insertions(+), 8 deletions(-) diff --git a/techniques/systemSettings/userManagement/userManagement/5.0/metadata.xml b/techniques/systemSettings/userManagement/userManagement/5.0/metadata.xml index 5e317ade2..4b9d3fe14 100644 --- a/techniques/systemSettings/userManagement/userManagement/5.0/metadata.xml +++ b/techniques/systemSettings/userManagement/userManagement/5.0/metadata.xml @@ -29,6 +29,7 @@ It is intended to check the user parameters on the target host. Debian RHEL / CentOS SuSE LES / DES / OpenSuSE + Windows cfengine-community @@ -40,6 +41,10 @@ It is intended to check the user parameters on the target host. + + NOVA + + USERGROUP_USER_LOGIN diff --git a/techniques/systemSettings/userManagement/userManagement/5.0/userManagement.st b/techniques/systemSettings/userManagement/userManagement/5.0/userManagement.st index 21ff3c6d8..14aede5fc 100644 --- a/techniques/systemSettings/userManagement/userManagement/5.0/userManagement.st +++ b/techniques/systemSettings/userManagement/userManagement/5.0/userManagement.st @@ -170,7 +170,7 @@ bundle agent check_usergroup_user_parameters "showtime" expression => isvariable("nameopt[1]"); files: - + !windows:: "/etc/passwd" create => "false", edit_line => set_user_fullname("${usergroup_user_login[${usergroup_user_index}]}","${usergroup_user_index}","${usergroup_user_fullname[${usergroup_user_index}]}"), @@ -192,6 +192,16 @@ bundle agent check_usergroup_user_parameters classes => kept_if_else("usermanagement_user_password_ok_${usergroup_user_index}", "usermanagement_user_password_repaired_${usergroup_user_index}", "usermanagement_user_password_failed_${usergroup_user_index}"), ifvarclass => "(usermanagement_login_add_${usergroup_user_index}_repaired.usermanagement_user_pwoneshot_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})|(usermanagement_user_update_${usergroup_user_index}.usermanagement_user_exists_${usergroup_user_index}.usermanagement_user_pweverytime_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})"; + methods: + windows:: + # check user password + "check_user_password" usebundle => check_usergroup_user_parameters_windows_password("${usergroup_user_login[${usergroup_user_index}]}", "${usergroup_user_password[${usergroup_user_index}]}", "${usergroup_user_index}"), + ifvarclass => "(usermanagement_login_add_${usergroup_user_index}_repaired.usermanagement_user_pwoneshot_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})|(usermanagement_user_update_${usergroup_user_index}.usermanagement_user_exists_${usergroup_user_index}.usermanagement_user_pweverytime_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})"; + + # check user fullname + "check_user_fullname" usebundle => check_usergroup_user_parameters_windows_fullname("${usergroup_user_login[${usergroup_user_index}]}", "${usergroup_user_fullname[${usergroup_user_index}]}", "${usergroup_user_action[${usergroup_user_index}]}", "${nameopt[${usergroup_user_index}]}", "${usergroup_user_index}"), + ifvarclass => "(usermanagement_user_update_${usergroup_user_index}|usermanagement_user_checkpres_${usergroup_user_index}).!usermanagement_user_nameempty_${usergroup_user_index}"; + commands: &if(NOVA)& @@ -209,9 +219,6 @@ bundle agent check_usergroup_user_parameters comment => "Delete the user ${usergroup_user_login[${usergroup_user_index}]}", ifvarclass => "usermanagement_user_exists_${usergroup_user_index}.usermanagement_user_remove_${usergroup_user_index}"; - "\"${sys.winsysdir}\net.exe\"" - args => "USER ${usergroup_user_login[${usergroup_user_index}]} ${usergroup_user_password[${usergroup_user_index}]}", - ifvarclass => "(usermanagement_login_add_${usergroup_user_index}_repaired.usermanagement_user_pwoneshot_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})|(usermanagement_user_exists_${usergroup_user_index}.usermanagement_user_pweverytime_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})"; &endif& linux.showtime:: @@ -330,3 +337,47 @@ bundle edit_line set_user_fullname(user,user_index,fullname) classes => kept_if_else("usermanagement_fullname_edit_${user_index}_kept","usermanagement_fullname_edit_${user_index}_repaired","usermanagement_fullname_edit_${user_index}_error"); } + +# Bundle to check the full name of a user on windows +# Takes the user login, the expected fullname, the action (checkhere for not editing), the FULLNAME set attribute for net.exe and the index for reporting +bundle agent check_usergroup_user_parameters_windows_fullname(user, fullname, usergroup_user_action, nameopt, usergroup_user_index) { + vars: + "current_fullname" string => execresult("Get-WMIObject Win32_UserAccount | where Name -eq '${user}' | ForEach { write-host $_.FullName }", "powershell"); + + classes: + "usermanagement_user_checkpres" expression => strcmp("${usergroup_user_action}","checkhere"); + "user_valid" expression => strcmp("${current_fullname}", "${fullname}"); + + methods: + user_valid:: + "already_correct" usebundle => _classes_success("usermanagement_fullname_edit_${usergroup_user_index}"); + + !user_valid.usermanagement_user_checkpres:: + # fullname is not valid, but don't request to change it + "invalid_user" usebundle => _classes_failure("usermanagement_fullname_edit_${usergroup_user_index}"); + + commands: + # if user is invalid, and we want to enforce fullname: + !user_valid.!usermanagement_user_checkpres:: + "\"${sys.winsysdir}\net.exe\"" + args => "USER ${user} ${nameopt}", + classes => classes_generic("usermanagement_fullname_edit_${usergroup_user_index}"); +} + +# Enforce user password +# takes the user login, the expected password (clear text), and the index for reports +bundle agent check_usergroup_user_parameters_windows_password(user, password, usergroup_user_index) { + vars: + "password_valid" string => execresult("Add-Type -AssemblyName System.DirectoryServices.AccountManagement; $DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('machine', $env:COMPUTERNAME); $DS.ValidateCredentials('${user}', '${password}')", "powershell"); + + + classes: + "usermanagement_user_password_ok_${usergroup_user_index}" expression => strcmp("True", "${password_valid}"), + scope => "namespace"; + + commands: + "\"${sys.winsysdir}\net.exe\"" + args => "USER ${user} ${password}", + classes => kept_if_else("usermanagement_user_password_ok_${usergroup_user_index}", "usermanagement_user_password_repaired_${usergroup_user_index}", "usermanagement_user_password_failed_${usergroup_user_index}"), + ifvarclass => "!usermanagement_user_password_ok_${usergroup_user_index}"; +} diff --git a/techniques/systemSettings/userManagement/userManagement/6.0/metadata.xml b/techniques/systemSettings/userManagement/userManagement/6.0/metadata.xml index 5e317ade2..4b9d3fe14 100644 --- a/techniques/systemSettings/userManagement/userManagement/6.0/metadata.xml +++ b/techniques/systemSettings/userManagement/userManagement/6.0/metadata.xml @@ -29,6 +29,7 @@ It is intended to check the user parameters on the target host. Debian RHEL / CentOS SuSE LES / DES / OpenSuSE + Windows cfengine-community @@ -40,6 +41,10 @@ It is intended to check the user parameters on the target host. + + NOVA + + USERGROUP_USER_LOGIN diff --git a/techniques/systemSettings/userManagement/userManagement/6.0/userManagement.st b/techniques/systemSettings/userManagement/userManagement/6.0/userManagement.st index 9750a82d2..f5f136dc3 100644 --- a/techniques/systemSettings/userManagement/userManagement/6.0/userManagement.st +++ b/techniques/systemSettings/userManagement/userManagement/6.0/userManagement.st @@ -175,7 +175,7 @@ bundle agent check_usergroup_user_parameters "pass1" expression => "any"; files: - + !windows:: "/etc/passwd" create => "false", edit_line => set_user_fullname("${usergroup_user_login[${usergroup_user_index}]}","${usergroup_user_index}","${usergroup_user_fullname[${usergroup_user_index}]}"), @@ -198,6 +198,14 @@ bundle agent check_usergroup_user_parameters ifvarclass => "(usermanagement_login_add_${usergroup_user_index}_repaired.usermanagement_user_pwoneshot_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})|(usermanagement_user_update_${usergroup_user_index}.usermanagement_user_exists_${usergroup_user_index}.usermanagement_user_pweverytime_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})"; methods: + windows:: + # check user password + "check_user_password" usebundle => check_usergroup_user_parameters_windows_password("${usergroup_user_login[${usergroup_user_index}]}", "${usergroup_user_password[${usergroup_user_index}]}", "${usergroup_user_index}"), + ifvarclass => "(usermanagement_login_add_${usergroup_user_index}_repaired.usermanagement_user_pwoneshot_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})|(usermanagement_user_update_${usergroup_user_index}.usermanagement_user_exists_${usergroup_user_index}.usermanagement_user_pweverytime_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})"; + + # check user fullname + "check_user_fullname" usebundle => check_usergroup_user_parameters_windows_fullname("${usergroup_user_login[${usergroup_user_index}]}", "${usergroup_user_fullname[${usergroup_user_index}]}", "${usergroup_user_action[${usergroup_user_index}]}", "${nameopt[${usergroup_user_index}]}", "${usergroup_user_index}"), + ifvarclass => "(usermanagement_user_update_${usergroup_user_index}|usermanagement_user_checkpres_${usergroup_user_index}).!usermanagement_user_nameempty_${usergroup_user_index}"; pass3.((linux|windows).showtime):: @@ -299,9 +307,6 @@ bundle agent check_usergroup_user_parameters comment => "Delete the user ${usergroup_user_login[${usergroup_user_index}]}", ifvarclass => "usermanagement_user_exists_${usergroup_user_index}.usermanagement_user_remove_${usergroup_user_index}"; - "\"${sys.winsysdir}\net.exe\"" - args => "USER ${usergroup_user_login[${usergroup_user_index}]} ${usergroup_user_password[${usergroup_user_index}]}", - ifvarclass => "(usermanagement_login_add_${usergroup_user_index}_repaired.usermanagement_user_pwoneshot_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})|(usermanagement_user_exists_${usergroup_user_index}.usermanagement_user_pweverytime_${usergroup_user_index}.!usermanagement_user_pwempty_${usergroup_user_index})"; &endif& linux.showtime:: @@ -335,3 +340,48 @@ bundle edit_line set_user_fullname(user,user_index,fullname) classes => kept_if_else("usermanagement_fullname_edit_${user_index}_kept","usermanagement_fullname_edit_${user_index}_repaired","usermanagement_fullname_edit_${user_index}_error"); } + +# Bundle to check the full name of a user on windows +# Takes the user login, the expected fullname, the action (checkhere for not editing), the FULLNAME set attribute for net.exe and the index for reporting +bundle agent check_usergroup_user_parameters_windows_fullname(user, fullname, usergroup_user_action, nameopt, usergroup_user_index) { + vars: + "current_fullname" string => execresult("Get-WMIObject Win32_UserAccount | where Name -eq '${user}' | ForEach { write-host $_.FullName }", "powershell"); + + classes: + "usermanagement_user_checkpres" expression => strcmp("${usergroup_user_action}","checkhere"); + "user_valid" expression => strcmp("${current_fullname}", "${fullname}"); + + methods: + user_valid:: + "already_correct" usebundle => _classes_success("usermanagement_fullname_edit_${usergroup_user_index}"); + + !user_valid.usermanagement_user_checkpres:: + # fullname is not valid, but don't request to change it + "invalid_user" usebundle => _classes_failure("usermanagement_fullname_edit_${usergroup_user_index}"); + + commands: + # if user is invalid, and we want to enforce fullname: + !user_valid.!usermanagement_user_checkpres:: + "\"${sys.winsysdir}\net.exe\"" + args => "USER ${user} ${nameopt}", + classes => classes_generic("usermanagement_fullname_edit_${usergroup_user_index}"); +} + +# Enforce user password +# takes the user login, the expected password (clear text), and the index for reports +bundle agent check_usergroup_user_parameters_windows_password(user, password, usergroup_user_index) { + vars: + "password_valid" string => execresult("Add-Type -AssemblyName System.DirectoryServices.AccountManagement; $DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext('machine', $env:COMPUTERNAME); $DS.ValidateCredentials('${user}', '${password}')", "powershell"); + + + classes: + "usermanagement_user_password_ok_${usergroup_user_index}" expression => strcmp("True", "${password_valid}"), + scope => "namespace"; + + commands: + "\"${sys.winsysdir}\net.exe\"" + args => "USER ${user} ${password}", + classes => kept_if_else("usermanagement_user_password_ok_${usergroup_user_index}", "usermanagement_user_password_repaired_${usergroup_user_index}", "usermanagement_user_password_failed_${usergroup_user_index}"), + ifvarclass => "!usermanagement_user_password_ok_${usergroup_user_index}"; + +}