dsccommunity / SecurityPolicyDsc

A wrapper around secedit.exe to configure local security policies
MIT License
177 stars 53 forks source link

AccountPolicy Fails with "The parameter is incorrect." & "Incorrect function." #121

Closed begna112 closed 4 years ago

begna112 commented 5 years ago

Details of the scenario you tried and the problem that is occurring

I'm having an issue that may or may not be the same as #119. In my case, the mof is being applied by the LocalSystem user on Windows 2016. I've tried using the PsDscRunAsCredential parameter but this resource doesn't seem to support it.

Verbose logs showing the problem

Here's some relevant logs:

secedit arguments: /configure /db C:\Windows\TEMP\DscSecedit.sdb /cfg C:\Windows\TEMP\accountPolicyToAdd.inf
Testing AccountPolicy: Minimum_Password_Length
Current policy: 8 Desired policy: 0
An error occurred running method 'Set' in resource 'AccountPolicy' for resourceID '[AccountPolicy]SetPasswordPolicies': System.Management.Automation.RuntimeException: Failed to update Account Policy Minimum_Password_Length,Enforce_password_history,Maximum_Password_Age,Password_must_meet_complexity_requirements. Refer to %windir%\security\logs\scesrv.log for details.

scesrv.log includes:

----Configure Security Policy...
Error 87: The parameter is incorrect.
    Error configuring password information.
Error 1: Incorrect function.
    System Access configuration was completed with one or more errors.

    Configuration of Registry Values was completed successfully.

    Audit/Log configuration was completed successfully.

Secedit-OutPut.txt:

Completed 1 percent (0/63)  Process Privilege Rights area        
Completed 25 percent (15/63)    Process Privilege Rights area        
Completed 25 percent (15/63)    Process Group Membership area        
Completed 49 percent (30/63)    Process Group Membership area        
Completed 49 percent (30/63)    Process Registry Keys area        
Completed 49 percent (30/63)    Process File Security area        
Completed 49 percent (30/63)    Process Services area        
Completed 65 percent (40/63)    Process Services area        
Completed 73 percent (45/63)    Process Services area        
Completed 73 percent (45/63)    Process Security Policy area        
Completed 77 percent (48/63)    Process Security Policy area        
Completed 84 percent (52/63)    Process Security Policy area        
Completed 88 percent (55/63)    Process Security Policy area        
Completed 93 percent (58/63)    Process Security Policy area        
Completed 100 percent (63/63)   Process Security Policy area        

The parameter is incorrect.

The task has completed with an error.
See log %windir%\security\logs\scesrv.log for detail info.

This is the accountPolicyToAdd.inf that it generates:

[Unicode]
Unicode=yes
[System Access]
MinimumPasswordLength=0
PasswordHistorySize=0
MaximumPasswordAge=0
PasswordComplexity=0
[Version]
signature="$CHICAGO$"
Revision=1

Suggested solution to the issue

If the issue is that it's being run by LocalSystem, please support running with PsDscRunAsCredential. I can't really test this as I'm applying it with a service.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

My configuration:

AccountPolicy SetPasswordPolicies {
    Name      = "PasswordPolicies"
    Enforce_password_history = 0
    Maximum_Password_Age     = 0
    Minimum_Password_Age     = 0
    Minimum_Password_Length  = 0
    Password_must_meet_complexity_requirements  = "Disabled"
    Store_passwords_using_reversible_encryption = 'Disabled'
}

The operating system the target node is running

OsName               : Microsoft Windows Server 2016 Standard
OsOperatingSystemSKU : StandardServerEdition
OsArchitecture       : 64-bit
WindowsBuildLabEx    : 14393.2273.amd64fre.rs1_release_1.180427-1811
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

Version and build of PowerShell the target node is running

Name                           Value
----                           -----
PSVersion                      5.1.14393.2273
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.2273
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Version of the DSC module that was used ('dev' if using current dev branch)

2.8.0.0

begna112 commented 5 years ago

I was able to verify that running the following as a local administrator gives the same error:

$Args = "/configure /db C:\Windows\TEMP\secedit\DscSecedit.sdb /cfg C:\Windows\TEMP\secedit\accountPolicyToAdd.inf"

Invoke-Expression -Command "secedit $Args"

Is it possible that the sdb is malformed?

begna112 commented 5 years ago

I think I've discovered the core of this issue.

I set the setting how I want them in local group policy and then used mmc + the Security Configuration and Teemplate snap-in to export my current settings.

What it exported was this:

[System Access]
MinimumPasswordAge = 0
MaximumPasswordAge = -1
MinimumPasswordLength = 0
PasswordComplexity = 0
PasswordHistorySize = 0
LockoutBadCount = 0
RequireLogonToChangePassword = 0
ForceLogoffWhenHourExpire = 0
NewAdministratorName = "Administrator"
NewGuestName = "Guest"
ClearTextPassword = 0
LSAAnonymousNameLookup = 0
EnableAdminAccount = 1
EnableGuestAccount = 0

Note that MaximumPasswordAge = -1.

When I manually edit the accountPolicyToAdd.inf to change that value from 0 to -1, secedit works as expected.

Looking at the documentation, it seems to imply that expected values are 0-999, but it also says -1 is equivalent to 0. https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/hh994573(v%3dws.10) However, this seems to not actually be the case and secedit requires the -1, not 0, at least in Server 2016.

Unfortunately, this dsc resource does not support a value of -1 for the field:

System.Management.Automation.RuntimeException error processing property 'Maximum_Password_Age' OF TYPE 'AccountPolicy': Cannot convert value "-1" to type "System.UInt64". Error: "Value was either too large or too small for a UInt64."

In this project's code, the issue is created by these lines:

        [Parameter()]
        [ValidateRange(0, 999)]
        [System.UInt32]
        $Maximum_Password_Age,

https://github.com/PowerShell/SecurityPolicyDsc/blob/64bb9fc79905ec1e4a2b877e9d0f7f9407e7a421/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.psm1#L86

At the very least this validate range need to be set to -1 through 999 and the type changed to System.Int32 or a translation built in somewhere to change a value of 0 to -1.

begna112 commented 5 years ago

Tried making the change myself but I think it's just a bit over my head and requires more changes than just the lines I pointed out above.

I changed [System.Uint32] to [System.Int32] and [ValidateRange(0,999)] to [ValidateRange(-1,999)] in both the Set and Test-TargetResource functions of MSFT_AccountPolicy.psm1. That resulted in this error:

ConvertTo-MOFInstance : System.Management.Automation.RuntimeException error processing property 'Maximum_Password_Age' OF TYPE 'AccountPolicy': Cannot convert value "-1" to type "System.UInt64". Error: "Value was either too large or too small for a UInt64."At C:\workspaces\MerchFTDS2\src\MerchFTDS2\Merch\SecurityPoliciesMOF.ps1:18 char:9
+   AccountPolicy
At line:341 char:16
+     $aliasId = ConvertTo-MOFInstance $keywordName $canonicalizedValue
+                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Write-Error], InvalidOperationException
    + FullyQualifiedErrorId : FailToProcessProperty,ConvertTo-MOFInstance
Compilation errors occurred while processing configuration 'SecurityPolicies'. Please review the errors reported in error stream and modify your configuration code appropriately.
At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:3917 char:5
+     throw $ErrorRecord
+     ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (SecurityPolicies:String) [], InvalidOperationException
    + FullyQualifiedErrorId : FailToProcessConfiguration

I additionally tried changing the MSFT_AccountPolicy.schema.mof to account for the type change: [Write] Uint32 Maximum_Password_Age; to [Write] Int32 Maximum_Password_Age; but received these errors:

ImportCimAndScriptKeywordsFromModule : Cim deserializer threw an error when deserializing file C:\Program Files\WindowsPowerShell\Modules\SecurityPolicyDsc\2.8.0.3\DSCResources\MSFT_Acco
At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:2120 char:50
+ ... dResource = ImportCimAndScriptKeywordsFromModule -Module $mod -Resour ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], PSInvalidOperationException
    + FullyQualifiedErrorId : System.Management.Automation.PSInvalidOperationException,ImportCimAndScriptKeywordsFromModule

ImportCimAndScriptKeywordsFromModule : Syntax error:
 At line:7, char:40
 Buffer:
ger Maximum_Password_Age^;

At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:2120 char:50
+ ... dResource = ImportCimAndScriptKeywordsFromModule -Module $mod -Resour ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], CimException
    + FullyQualifiedErrorId : Microsoft.Management.Infrastructure.CimException,ImportCimAndScriptKeywordsFromModule

PSDesiredStateConfiguration\Node : The term 'SecurityPolicyDsc\AccountPolicy' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\workspaces\MerchFTDS2\src\MerchFTDS2\Merch\SecurityPoliciesMOF.ps1:15 char:5
+     Node localhost {
+     ~~~~
    + CategoryInfo          : ObjectNotFound: (SecurityPolicyDsc\AccountPolicy:String) [PSDesiredStateConfiguration\node], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : CommandNotFoundException,PSDesiredStateConfiguration\node

Compilation errors occurred while processing configuration 'SecurityPolicies'. Please review the errors reported in error stream and modify your configuration code appropriately.
At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:3917 char:5
+     throw $ErrorRecord
+     ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (SecurityPolicies:String) [], InvalidOperationException
    + FullyQualifiedErrorId : FailToProcessConfiguration
jcwalker commented 5 years ago

@begna112 thanks for reporting the issue and the detailed repro! I'll do my best to look into a solution as soon as work allows it.

rdtechie commented 4 years ago

I have the same issue when applying the setting 'Store_passwords_using_reversible_encryption'. Receiving the following error message: Cannot convert value "-1" to type "System.UInt64". Error: "Value was either too large or too small for a UInt64."

gaelcolas commented 4 years ago

to fix that, not only you'd have to change the psm1 as @begna112 did, you'd also need to change the MOF Schema here: https://github.com/dsccommunity/SecurityPolicyDsc/blob/dev/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.schema.mof#L8

You can't use -1 for an unsigned 32bit Integer. I am not familiar enough with the code so I don't know why UInt32 was chosen (usually because that's how Windows API enums are using for bitwise operations), but using something like Int should be fine if the value range is only -1..999.

begna112 commented 4 years ago

The issue described here was fixed in 2.9.0.0.

@rdtechie if you're still having your issue, you might want to open another issue.

Closing this issue.