diff --git a/src/Interfaces/ILDAPService.cs b/src/Interfaces/ILDAPService.cs index 9df4a28..54e8b45 100644 --- a/src/Interfaces/ILDAPService.cs +++ b/src/Interfaces/ILDAPService.cs @@ -12,6 +12,6 @@ public interface ILdapService Task> GetDomainsAsync(); public Task GetADComputerAsync(string domainName, LdapCredential ldapCredential, string distinguishedName); public Task> SearchADComputersAsync(string domainName, LdapCredential ldapCredential, string query); - public Task ClearLapsPassword(string domainName, LdapCredential ldapCredential, string distinguishedName, LAPSVersion version, bool encrypted); + public Task ClearLapsPassword(string domainName, LdapCredential ldapCredential, string distinguishedName, LAPSVersion version); } } diff --git a/src/Pages/LAPS.razor.cs b/src/Pages/LAPS.razor.cs index 2127c39..2336abe 100644 --- a/src/Pages/LAPS.razor.cs +++ b/src/Pages/LAPS.razor.cs @@ -52,7 +52,6 @@ private async Task ClearLapsPassword(ADComputer computer) if (_tab != null && computer.LAPSInformations != null) { LAPSVersion version = LAPSVersion.v1; - bool encrypted = false; if (_tab.ActivePanel.ID.ToString() == "v1") { @@ -62,7 +61,6 @@ private async Task ClearLapsPassword(ADComputer computer) if (_tab.ActivePanel.ID.ToString() == "v2") { version = LAPSVersion.v2; - encrypted = computer.LAPSInformations.Single(x => x.Version == LAPSVersion.v2 && x.IsCurrent).WasEncrypted; } var parameters = new DialogParameters { ["ContentText"] = $"Clear LAPS {version} Password on Computer '{computer.Name}' ?{Environment.NewLine}You have to invoke gpupdate /force on computer '{computer.Name}' in order so set a new LAPS password", ["CancelButtonText"] = "Cancel", ["ConfirmButtonText"] = "Clear", ["ConfirmButtonColor"] = Color.Error }; IDialogReference dialog = Dialog.Show("Clear LAPS Password", parameters,new DialogOptions() { NoHeader = true }); @@ -72,7 +70,7 @@ private async Task ClearLapsPassword(ADComputer computer) { computer.LAPSInformations.Clear(); await InvokeAsync(StateHasChanged); - await LDAPService.ClearLapsPassword(DomainName ?? await sessionManager.GetDomainAsync(), LdapCredential ?? await sessionManager.GetLdapCredentialsAsync(), computer.DistinguishedName, version, encrypted); + await LDAPService.ClearLapsPassword(DomainName ?? await sessionManager.GetDomainAsync(), LdapCredential ?? await sessionManager.GetLdapCredentialsAsync(), computer.DistinguishedName, version); Snackbar.Add($"LAPS {version} Password for computer '{computer.Name}' successfully cleared! - Please invoke gpupdate on {computer.Name} to set a new LAPS Password", Severity.Success); } } diff --git a/src/Properties/launchSettings.json b/src/Properties/launchSettings.json index 906673e..6052be9 100644 --- a/src/Properties/launchSettings.json +++ b/src/Properties/launchSettings.json @@ -18,7 +18,13 @@ "commandName": "Project", "launchBrowser": true, "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "Domains__0__Name": "prime.k-sys.io", + "Domains__0__Ldap__Server": "ldap.prime.k-sys.io", + "Domains__0__Ldap__Port": "636", + "Domains__0__Ldap__UseSSL": "true", + "Domains__0__Ldap__SearchBase": "OU=Klett IT GmbH,DC=prime,DC=k-sys,DC=io", + " Domains__0__Ldap__TrustAllCertificates": "true" }, "applicationUrl": "https://localhost:7213;http://localhost:5213", "dotnetRunMessages": true diff --git a/src/Services/LDAPService.cs b/src/Services/LDAPService.cs index 9179676..4f21330 100644 --- a/src/Services/LDAPService.cs +++ b/src/Services/LDAPService.cs @@ -3,12 +3,9 @@ using LAPS_WebUI.Interfaces; using LAPS_WebUI.Models; using LdapForNet; -using LdapForNet.Native; using Microsoft.Extensions.Options; using Serilog; -using System; using System.Runtime.InteropServices; -using System.Security.Principal; using System.Text; using System.Text.Json; using static LdapForNet.Native.Native; @@ -89,9 +86,8 @@ public async Task TestCredentialsAsync(string domainName, LdapCredential l } } - public async Task ClearLapsPassword(string domainName, LdapCredential ldapCredential, string distinguishedName, LAPSVersion version, bool encrypted) + public async Task ClearLapsPassword(string domainName, LdapCredential ldapCredential, string distinguishedName, LAPSVersion version) { - Domain? domain = _Domains.Value.SingleOrDefault(x => x.Name == domainName) ?? throw new Exception($"No configured domain found with name {domainName}"); if (ldapCredential is null) { @@ -99,48 +95,29 @@ public async Task ClearLapsPassword(string domainName, LdapCredential ldap } using LdapConnection? ldapConnection = await CreateBindAsync(domainName, ldapCredential.UserName, ldapCredential.Password) ?? throw new Exception("LDAP bind failed!"); - string? defaultNamingContext = domain.Ldap.SearchBase; string attribute = string.Empty; if (version == LAPSVersion.v1) { - attribute = "ms-Mcs-AdmPwd"; + attribute = "ms-Mcs-AdmPwdExpirationTime"; } if (version == LAPSVersion.v2) { - attribute = encrypted ? "msLAPS-EncryptedPassword" : "msLAPS-Password"; + attribute = "msLAPS-PasswordExpirationTime"; } - var ldapSearchResult = (await ldapConnection.SearchAsync(defaultNamingContext, $"(&(objectCategory=computer)(distinguishedName={distinguishedName}))", [attribute], LdapSearchScope.LDAP_SCOPE_SUB)).SingleOrDefault(); - - if (ldapSearchResult != null) + var resetRequest = new DirectoryModificationAttribute { - var resetRequest = new DirectoryModificationAttribute - { - LdapModOperation = LdapModOperation.LDAP_MOD_DELETE, - Name = attribute - }; - - if (version == LAPSVersion.v1 || !encrypted) - { - resetRequest.Add(ldapSearchResult.DirectoryAttributes[attribute].GetValues().First().ToString()); - } - else - { - resetRequest.Add(ldapSearchResult.DirectoryAttributes[attribute].GetValues().First().ToArray()); - } + LdapModOperation = LdapModOperation.LDAP_MOD_REPLACE, + Name = attribute + }; - var response = (ModifyResponse)await ldapConnection.SendRequestAsync(new ModifyRequest(distinguishedName, resetRequest)); + resetRequest.Add(DateTime.Now.ToFileTimeUtc().ToString()); - return response.ResultCode == ResultCode.Success; - } - else - { - throw new Exception($"AD Computer with DN '{distinguishedName}' could not be found"); - } + var response = (ModifyResponse)await ldapConnection.SendRequestAsync(new ModifyRequest(distinguishedName, resetRequest)); - + return response.ResultCode == ResultCode.Success; } public async Task GetADComputerAsync(string domainName, LdapCredential ldapCredential, string distinguishedName) @@ -181,7 +158,7 @@ public async Task ClearLapsPassword(string domainName, LdapCredential ldap Version = LAPSVersion.v1, Account = null, Password = ldapSearchResult.DirectoryAttributes["ms-Mcs-AdmPwd"].GetValues().First().ToString(), - PasswordExpireDate = DateTime.FromFileTimeUtc(Convert.ToInt64(ldapSearchResult.DirectoryAttributes["ms-Mcs-AdmPwdExpirationTime"].GetValues().First().ToString())), + PasswordExpireDate = DateTime.FromFileTimeUtc(Convert.ToInt64(ldapSearchResult.DirectoryAttributes["ms-Mcs-AdmPwdExpirationTime"].GetValues().First().ToString())).ToLocalTime(), IsCurrent = true, PasswordSetDate = null }; @@ -219,10 +196,10 @@ public async Task ClearLapsPassword(string domainName, LdapCredential ldap Account = msLAPS_Payload.ManagedAccountName, Password = msLAPS_Payload.Password, WasEncrypted = !domain.Laps.EncryptionDisabled, - PasswordExpireDate = DateTime.FromFileTimeUtc(Convert.ToInt64(ldapSearchResult.DirectoryAttributes["msLAPS-PasswordExpirationTime"].GetValues().First().ToString())), + PasswordExpireDate = DateTime.FromFileTimeUtc(Convert.ToInt64(ldapSearchResult.DirectoryAttributes["msLAPS-PasswordExpirationTime"].GetValues().First().ToString())).ToLocalTime(), IsCurrent = true, - PasswordSetDate = DateTime.FromFileTimeUtc(Int64.Parse(msLAPS_Payload.PasswordUpdateTime!, System.Globalization.NumberStyles.HexNumber)) - + PasswordSetDate = DateTime.FromFileTimeUtc(Int64.Parse(msLAPS_Payload.PasswordUpdateTime!, System.Globalization.NumberStyles.HexNumber)).ToLocalTime() + }; ADComputer.LAPSInformations.Add(lapsInformationEntry); @@ -245,7 +222,7 @@ public async Task ClearLapsPassword(string domainName, LdapCredential ldap Account = historic_msLAPS_Payload.ManagedAccountName, Password = historic_msLAPS_Payload.Password, PasswordExpireDate = null, - PasswordSetDate = DateTime.FromFileTimeUtc(Int64.Parse(historic_msLAPS_Payload.PasswordUpdateTime!, System.Globalization.NumberStyles.HexNumber)) + PasswordSetDate = DateTime.FromFileTimeUtc(Int64.Parse(historic_msLAPS_Payload.PasswordUpdateTime!, System.Globalization.NumberStyles.HexNumber)).ToLocalTime() }; ADComputer.LAPSInformations.Add(historicLapsInformationEntry);