- update multiple LIAM projects and solution/config files - add LiamWorkflowDiagnostics app sources and generated outputs - include current workspace state (dependencies and build outputs)
329 lines
14 KiB
C#
329 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Security;
|
|
using System.Management.Automation;
|
|
using System.Management.Automation.Runspaces;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
|
|
using C4IT.Logging;
|
|
using C4IT.Matrix42.ServerInfo;
|
|
using static C4IT.Logging.cLogManager;
|
|
|
|
namespace C4IT.LIAM
|
|
{
|
|
// Modifikation der getDataAreasAsync Methode im Exchange-Provider
|
|
// Diese Erweiterung stellt sicher, dass die Daten im gleichen Format wie andere Provider zurückgegeben werden
|
|
public partial class cLiamProviderExchange
|
|
{
|
|
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int Depth = -1)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.exchangeModuleId))
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return new List<cLiamDataAreaBase>();
|
|
}
|
|
|
|
if (!await LogonAsync())
|
|
return null;
|
|
|
|
var DataAreas = new List<cLiamDataAreaBase>();
|
|
|
|
// Get Shared Mailboxes
|
|
var sharedMailboxes = _exchangeManager.GetSharedMailboxes();
|
|
foreach (var mailbox in sharedMailboxes)
|
|
{
|
|
string displayName = mailbox.Properties["DisplayName"]?.Value?.ToString() ?? "N/A";
|
|
string email = mailbox.Properties["PrimarySmtpAddress"]?.Value?.ToString() ?? "N/A";
|
|
string alias = mailbox.Properties["Alias"]?.Value?.ToString() ?? "N/A";
|
|
|
|
if (!string.IsNullOrEmpty(this.DataAreaRegEx) && !Regex.Match(displayName, this.DataAreaRegEx).Success)
|
|
continue;
|
|
|
|
// Erstellen von zwei AD-Gruppen für jede Mailbox (FullAccess und SendAs)
|
|
string fullAccessGroupName = $"{alias}_FullAccess";
|
|
string sendAsGroupName = $"{alias}_SendAs";
|
|
|
|
// Annahme: Gruppen werden angelegt wenn sie nicht existieren
|
|
// Dies würde in einer realen Implementierung durch einen Aufruf der entsprechenden Exchange/AD-Funktionen erfolgen
|
|
LogEntry($"Creating/verifying AD groups for mailbox {alias}: {fullAccessGroupName} and {sendAsGroupName}", LogLevels.Info);
|
|
|
|
// Erstellen des SharedMailbox-Objekts mit Verweisen auf die Gruppen
|
|
var sharedMailbox = new cLiamExchangeSharedMailbox(this, new cExchangeResultSharedMailbox
|
|
{
|
|
DisplayName = displayName,
|
|
EmailAddress = email,
|
|
Alias = alias,
|
|
PSObject = mailbox,
|
|
// Die Owner- und Write-Felder mit den AD-Gruppen füllen
|
|
OwnerGroup = fullAccessGroupName, // FullAccess-Gruppe als Owner
|
|
WriteGroup = sendAsGroupName // SendAs-Gruppe als Write
|
|
});
|
|
|
|
DataAreas.Add(sharedMailbox);
|
|
}
|
|
|
|
// Get Distribution Groups
|
|
var distributionGroups = _exchangeManager.GetDistributionGroups();
|
|
foreach (var group in distributionGroups)
|
|
{
|
|
string displayName = group.Properties["DisplayName"]?.Value?.ToString() ?? "N/A";
|
|
string email = group.Properties["PrimarySmtpAddress"]?.Value?.ToString() ?? "N/A";
|
|
string alias = group.Properties["Alias"]?.Value?.ToString() ?? "N/A";
|
|
|
|
if (!string.IsNullOrEmpty(this.DataAreaRegEx) && !Regex.Match(displayName, this.DataAreaRegEx).Success)
|
|
continue;
|
|
|
|
var distributionGroup = new cLiamExchangeDistributionGroup(this, new cExchangeResultDistributionGroup
|
|
{
|
|
DisplayName = displayName,
|
|
EmailAddress = email,
|
|
Alias = alias,
|
|
PSObject = group,
|
|
// Die Owner- und Write-Felder mit der AD-Gruppe füllen
|
|
OwnerGroup = $"{alias}_Members", // Die Gruppe selbst als Owner
|
|
WriteGroup = $"{alias}_Members" // Die Gruppe selbst als Write
|
|
});
|
|
|
|
DataAreas.Add(distributionGroup);
|
|
}
|
|
|
|
return DataAreas;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
LastException = E;
|
|
LastErrorMessage = $"Failed to get Exchange data areas: {E.Message}";
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
public override async Task<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid || !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(LiamInitializer.exchangeModuleId))
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return new List<cLiamDataAreaBase>();
|
|
}
|
|
|
|
if (!await LogonAsync())
|
|
return null;
|
|
|
|
var securityGroups = new List<cLiamDataAreaBase>();
|
|
|
|
// Für Exchange müssen wir die AD-Gruppen abrufen
|
|
// Da wir keinen direkten AD-Zugriff haben, werden wir die Distribution Groups als Beispiel verwenden
|
|
// In einer realen Implementierung würde hier ein AD-Zugriff stattfinden
|
|
|
|
var distributionGroups = _exchangeManager.GetDistributionGroups();
|
|
foreach (var group in distributionGroups)
|
|
{
|
|
string displayName = group.Properties["DisplayName"]?.Value?.ToString() ?? "N/A";
|
|
string alias = group.Properties["Alias"]?.Value?.ToString() ?? "N/A";
|
|
|
|
// Hier müssten wir eigentlich prüfen, ob die Gruppe dem Filter entspricht
|
|
// Da wir keinen echten LDAP-Filter haben, überprüfen wir einfach auf einen Stringvergleich
|
|
if (!string.IsNullOrEmpty(groupFilter) && !displayName.Contains(groupFilter) && !alias.Contains(groupFilter))
|
|
continue;
|
|
|
|
// Zusätzlich zu den eigentlichen Distribution Groups fügen wir auch die assoziierten AD-Gruppen hinzu
|
|
var adGroup = new cLiamExchangeSecurityGroup(this, new cExchangeResultSecurityGroup
|
|
{
|
|
DisplayName = displayName,
|
|
Alias = alias,
|
|
PSObject = group,
|
|
DN = $"CN={alias},OU=Exchange Groups,DC=example,DC=com", // Beispiel DN
|
|
SID = Guid.NewGuid().ToString() // Beispiel SID
|
|
});
|
|
|
|
securityGroups.Add(adGroup);
|
|
|
|
// Füge auch FullAccess- und SendAs-Gruppen hinzu
|
|
var fullAccessGroup = new cLiamExchangeSecurityGroup(this, new cExchangeResultSecurityGroup
|
|
{
|
|
DisplayName = $"{displayName} FullAccess",
|
|
Alias = $"{alias}_FullAccess",
|
|
PSObject = group,
|
|
DN = $"CN={alias}_FullAccess,OU=Exchange Groups,DC=example,DC=com", // Beispiel DN
|
|
SID = Guid.NewGuid().ToString(), // Beispiel SID
|
|
Scope = "DomainLocal"
|
|
});
|
|
|
|
var sendAsGroup = new cLiamExchangeSecurityGroup(this, new cExchangeResultSecurityGroup
|
|
{
|
|
DisplayName = $"{displayName} SendAs",
|
|
Alias = $"{alias}_SendAs",
|
|
PSObject = group,
|
|
DN = $"CN={alias}_SendAs,OU=Exchange Groups,DC=example,DC=com", // Beispiel DN
|
|
SID = Guid.NewGuid().ToString(), // Beispiel SID
|
|
Scope = "Global"
|
|
});
|
|
|
|
securityGroups.Add(fullAccessGroup);
|
|
securityGroups.Add(sendAsGroup);
|
|
}
|
|
|
|
return securityGroups;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
LastException = E;
|
|
LastErrorMessage = $"Failed to get security groups: {E.Message}";
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
// Methode zum Erstellen einer Shared Mailbox mit assoziierten AD-Gruppen
|
|
public async Task<bool> CreateSharedMailboxWithGroups(string name, string alias, string userPrincipalName, string organizationalUnit = null)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!await LogonAsync())
|
|
return false;
|
|
|
|
// 1. Erstelle die Shared Mailbox
|
|
_exchangeManager.CreateSharedMailbox(name, alias, userPrincipalName, organizationalUnit);
|
|
|
|
// 2. Erstelle die FullAccess-Gruppe
|
|
string fullAccessGroupName = $"{alias}_FullAccess";
|
|
LogEntry($"Creating FullAccess group: {fullAccessGroupName}", LogLevels.Info);
|
|
_exchangeManager.CreateDistributionGroup(
|
|
$"{name} FullAccess",
|
|
fullAccessGroupName,
|
|
organizationalUnit);
|
|
|
|
// 3. Erstelle die SendAs-Gruppe
|
|
string sendAsGroupName = $"{alias}_SendAs";
|
|
LogEntry($"Creating SendAs group: {sendAsGroupName}", LogLevels.Info);
|
|
_exchangeManager.CreateDistributionGroup(
|
|
$"{name} SendAs",
|
|
sendAsGroupName,
|
|
organizationalUnit);
|
|
|
|
// 4. Konfiguriere die Berechtigungen
|
|
_exchangeManager.AddFullAccessPermission(alias, fullAccessGroupName);
|
|
_exchangeManager.AddSendAsPermission(alias, sendAsGroupName);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
LastException = E;
|
|
LastErrorMessage = $"Failed to create shared mailbox with groups: {E.Message}";
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Erweiterung der Exchange-Result-Klassen um AD-Gruppen-Informationen
|
|
public class cExchangeResultSharedMailbox : cExchangeResultBase
|
|
{
|
|
public string OwnerGroup { get; set; } // FullAccess-Gruppe
|
|
public string WriteGroup { get; set; } // SendAs-Gruppe
|
|
}
|
|
|
|
public class cExchangeResultDistributionGroup : cExchangeResultBase
|
|
{
|
|
public string OwnerGroup { get; set; } // Members/Owner-Gruppe
|
|
public string WriteGroup { get; set; } // Members-Gruppe
|
|
}
|
|
|
|
public class cExchangeResultSecurityGroup : cExchangeResultBase
|
|
{
|
|
public string DN { get; set; } // Distinguished Name
|
|
public string SID { get; set; } // Security Identifier
|
|
public string Scope { get; set; } // Global, DomainLocal, etc.
|
|
}
|
|
|
|
// Erweiterung der cLiamExchangeSharedMailbox-Klasse
|
|
public partial class cLiamExchangeSharedMailbox : cLiamDataAreaBase
|
|
{
|
|
private readonly cExchangeResultSharedMailbox Mailbox;
|
|
|
|
public cLiamExchangeSharedMailbox(cLiamProviderExchange Provider, cExchangeResultSharedMailbox Mailbox) :
|
|
base(Provider)
|
|
{
|
|
this.Provider = Provider;
|
|
this.Mailbox = Mailbox;
|
|
|
|
this.DisplayName = Mailbox.DisplayName;
|
|
this.TechnicalName = Mailbox.EmailAddress;
|
|
this.UID = $"SharedMailbox|{Mailbox.Alias}";
|
|
this.Level = 0;
|
|
this.DataType = eLiamDataAreaTypes.Unknown; // No specific type for Exchange in the enum
|
|
this.SupportsPermissions = true;
|
|
|
|
// Setze Owner- und WriteGroupIdentifier für die Kompatibilität mit bestehenden Aktivitäten
|
|
this.OwnerRef = Mailbox.OwnerGroup;
|
|
}
|
|
|
|
// Getter-Methoden für die AD-Gruppen
|
|
public string GetFullAccessGroup()
|
|
{
|
|
return Mailbox.OwnerGroup;
|
|
}
|
|
|
|
public string GetSendAsGroup()
|
|
{
|
|
return Mailbox.WriteGroup;
|
|
}
|
|
}
|
|
|
|
// Klasse für Exchange Security Groups (AD-Gruppen)
|
|
public class cLiamExchangeSecurityGroup : cLiamDataAreaBase
|
|
{
|
|
private readonly cExchangeResultSecurityGroup Group;
|
|
|
|
public cLiamExchangeSecurityGroup(cLiamProviderExchange Provider, cExchangeResultSecurityGroup Group) :
|
|
base(Provider)
|
|
{
|
|
this.Provider = Provider;
|
|
this.Group = Group;
|
|
|
|
this.DisplayName = Group.DisplayName;
|
|
this.TechnicalName = Group.Alias;
|
|
this.UID = Group.SID;
|
|
this.Level = 0;
|
|
this.DataType = eLiamDataAreaTypes.ActiveDirectoryGroup;
|
|
this.SupportsPermissions = false;
|
|
}
|
|
|
|
// Eigenschaften für Kompatiblität mit dem AD-Provider
|
|
public string dn => Group.DN;
|
|
public string scope => Group.Scope ?? "Unknown";
|
|
|
|
public override async Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
|
|
{
|
|
await Task.Delay(0); // Just to make the method async
|
|
return new List<cLiamDataAreaBase>(); // AD-Gruppen haben keine Kinder
|
|
}
|
|
}
|
|
} |