Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get-CertificationAuthority raises an exception on a workgroup CA #156

Closed
exchange12rocks opened this issue Jul 13, 2021 · 17 comments
Closed
Labels
bug Bug. An issue exist in our code. fixed-vNext The item is fixed in development code. Will be available in next release.

Comments

@exchange12rocks
Copy link

PS C:\Users\Administrator> Get-CertificationAuthority
Exception calling "GetAdPkiContainer" with "1" argument(s): "Operation is not supported on this platform."
At C:\Program Files\WindowsPowerShell\Modules\PSPKI\Server\Get-CertificationAuthority.ps1:18 char:9
+         $DSList = [SysadminsLV.PKI.Management.ActiveDirectory.DsPkiCo ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : PlatformNotSupportedException


DisplayName                              ComputerName              IsAccessible ServiceStatus Type
-----------                              ------------              ------------ ------------- ----
My Root CA                               ROOTCA01                  True         Running       Standalone Root CA
@Crypt32 Crypt32 added the non-issue Misconfiguration on client end or behavior is expected and by design label Jul 13, 2021
@Crypt32
Copy link
Collaborator

Crypt32 commented Jul 13, 2021

Yes, this is expected. The documentation says that it retrieves only CAs registered in Active Directory, thus depends on AD. For workgroup environments you have to use Connect-CertificationAuthority command instead. Note that remote CAs from workgroup are not supported, only local CAs are supported.

@exchange12rocks
Copy link
Author

exchange12rocks commented Jul 13, 2021

I see, thank you for the quick response. But it seems the command does return useful results, just with an additional error - I can use the resulting CA object in other commands just fine.

Do you think it would be possible to join Get-CertificationAuthority's and Connect-CertificationAuthority's functionality in a single command?

@Crypt32
Copy link
Collaborator

Crypt32 commented Jul 13, 2021

I see, thank you for the quick response. But it seems the command does return useful results, just with an additional error - I can use the resulting CA object in other commands just fine.

That's interesting, because there is a check if you are in domain or not:

and if you are not connected to domain, the Get-CertificationAuthority should return you nothing.

Do you think it would be possible to join Get-CertificationAuthority's and Connect-CertificationAuthority's functionality in a single command?

I don't know if it possible to merge both commands without breaking things.

@exchange12rocks
Copy link
Author

exchange12rocks commented Jul 13, 2021

It seems that the $NoDomain variable is not defined - I did not find it anywhere in the code besides that line. And when it is not defined, it is effectively processed as $false. And -not $false is $true therefore the condition resolves to $true and the GetAdPkiContainer method tries to execute and then all other code in the function executes as well, because by default $ErrorActionPreference is set to Continue.

@Crypt32
Copy link
Collaborator

Crypt32 commented Jul 13, 2021

Actually, this variable is defined here:

[bool]$NoDomain = $true # computer is a member of workgroup

and it should be properly initialized with $true because ADSI calls to RootDSE must fail in workgroup environment.

@exchange12rocks
Copy link
Author

Interesting: GitHub does not show it in the search results: https://github.com/PKISolutions/PSPKI/search?q=NoDomain

@exchange12rocks
Copy link
Author

As for variable initialization, when I run $Domain = ([ADSI]"LDAP://RootDSE").ConfigurationNamingContext on a non-domain machine, I do not receive an exception, therefore the catch section does not get invoked, which, in turn, sets $NoDomain = $false.

@Crypt32
Copy link
Collaborator

Crypt32 commented Jul 13, 2021

As for variable initialization, when I run $Domain = ([ADSI]"LDAP://RootDSE").ConfigurationNamingContext on a non-domain machine, I do not receive an exception, therefore the catch section does not get invoked, which, in turn, sets $NoDomain = $false.

gotcha! This is an interesting behavior of PowerShell which I need to fix.

@exchange12rocks
Copy link
Author

Perhaps we could query (Get-CimInstance -ClassName 'Win32_ComputerSystem').PartOfDomain for better detection?

@Crypt32 Crypt32 added the bug Bug. An issue exist in our code. label Jul 13, 2021
Crypt32 added a commit that referenced this issue Jul 13, 2021
@Crypt32
Copy link
Collaborator

Crypt32 commented Jul 13, 2021

Perhaps we could query (Get-CimInstance -ClassName 'Win32_ComputerSystem').PartOfDomain for better detection?

I solved this in slightly different way:

[void][System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain()

I need to ensure that there is at least one online domain controller rather (because I need to fetch some data from there) than just check domain membership. Anyway, Get-CertificationAuthority should behave like it is intended. But I will take a look if I can make it working in workgroups without breaking existing syntax.

@Crypt32 Crypt32 removed the non-issue Misconfiguration on client end or behavior is expected and by design label Jul 13, 2021
@exchange12rocks
Copy link
Author

exchange12rocks commented Jul 13, 2021

Maybe it is worth to implement both checks? Querying an non-existent domain controller takes time - the request waits and then fails by timeout. What if first we will check that WMI class and if it returns true, then we will query a DC? It should improve module loading time on workgroup computers.

@Crypt32
Copy link
Collaborator

Crypt32 commented Jul 13, 2021

I just checked the code: mentioned line fails immediately if you are not part of domain. If you are part of domain, but disconnected -- the delay is inevitable. It appears, the method call already implements domain membership check internally before trying to contact DCs.

@exchange12rocks
Copy link
Author

Yes, you are correct - thank you!

@Crypt32
Copy link
Collaborator

Crypt32 commented Jul 13, 2021

I think, this commit should do the work, though haven't tested: 0b8764b

In the else clause I mimic Connect-CertificationAuthority command by attempting to reach local CA. This means that in workgroup, the Get-CertificationAuthority will return only one local CA at most or throw the error if one is not found. It would be nice if you would find a time to test this little commit. I think it should do the trick.

@exchange12rocks
Copy link
Author

Thank you, Vadims!

@exchange12rocks
Copy link
Author

Seems to be working all right on my workgroup CA, but of course currently these two functions are only partially compatible by parameter sets: Connect-CertificationAuthority supports connection to remote servers and more than one computer name.

@Crypt32 Crypt32 added the fixed-vNext The item is fixed in development code. Will be available in next release. label Sep 9, 2021
@Crypt32
Copy link
Collaborator

Crypt32 commented Jun 15, 2023

Fixed in v4.0.0

@Crypt32 Crypt32 closed this as completed Jun 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug. An issue exist in our code. fixed-vNext The item is fixed in development code. Will be available in next release.
Projects
None yet
Development

No branches or pull requests

2 participants