0

我是几个 Outlook 分发列表 (DL) 的共同所有者。我可以在 Outlook 中编辑它们,直接在其中添加和删除成员。但是,我无法通过简单的 .NET 程序编辑它们:

using System;
using System.DirectoryServices.AccountManagement;

namespace DL_Remove_User
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                RemoveUser("My Distribution List", "jimtut");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.ToString());
            }
        }

        private static void RemoveUser(string dl, string username)
        {
            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "CORP"))
            {
                GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, dl);
                bool result = group.Members.Remove(pc, IdentityType.SamAccountName, username);
                Console.WriteLine(result.ToString());
                group.Save();
            }
        }
    }
}

相同的代码适用于许多其他 DL,但对于一对夫妇,我收到消息“访问被拒绝”。完整的堆栈跟踪:

at System.DirectoryServices.Interop.UnsafeNativeMethods.IAds.SetInfo()

at System.DirectoryServices.DirectoryEntry.CommitChanges()

at System.DirectoryServices.AccountManagement.ADStoreCtx.UpdateGroupMembership(Principal group, DirectoryEntry de, NetCred credentials, AuthenticationTypes authTypes)

at System.DirectoryServices.AccountManagement.SDSUtils.ApplyChangesToDirectory(Principal p, StoreCtx storeCtx, GroupMembershipUpdater updateGroupMembership, NetCred credentials, AuthenticationTypes authTypes)

at System.DirectoryServices.AccountManagement.ADStoreCtx.Update(Principal p)

at System.DirectoryServices.AccountManagement.Principal.Save()

at Department_Distribution_Lists.Program.RemoveUser(String dl, String username) in Program.cs:line 483

当然,“访问被拒绝”确实表示权限问题,但我可以直接在 Outlook 中编辑这些 DL。我什至可以在 AD/LDAP 中查询 DL“所有者”,并且我在集合“msExchCoManagedByLink”中。

关于为什么我可以在 Outlook 中编辑但不能通过 .NET 编辑的任何想法?

4

1 回答 1

0

我终于想通了。我对这个权限问题感到困惑,因为我可以在 Outlook 中编辑 DL,但不能通过 .NET。

我开始寻找可以通过 .NET 编辑的 DL 与我无法编辑的 DL 之间的差异,发现差异在此 GUI 中显示的 AD 属性中表示为“经理可以更新成员列表”:

dl

即使我是“经理”(列表所有者),如果 DL 没有设置该属性,我也只能在 Outlook 中进行编辑。

我不想肉眼检查所有 DL,所以我编写了以下代码来检测 DL 的“真正”所有者/编辑者:

    static List<string> GetGroupOwners(GroupPrincipal group)
    {
        List<string> owners = new List<string>();
        DirectoryEntry deGroup = group.GetUnderlyingObject() as DirectoryEntry;
        ActiveDirectorySecurity ads = deGroup.ObjectSecurity;
        AuthorizationRuleCollection rules = ads.GetAccessRules(true, true, typeof(SecurityIdentifier));
        Guid exRight_Member = new Guid("{bf9679c0-0de6-11d0-a285-00aa003049e2}");

        foreach (ActiveDirectoryAccessRule ar in rules)
        {
            if (ar.ActiveDirectoryRights.HasFlag(ActiveDirectoryRights.GenericWrite) || (ar.ObjectType.Equals(exRight_Member) && ar.ActiveDirectoryRights.HasFlag(ActiveDirectoryRights.WriteProperty)))
            {
                string friendlyName = "";
                try
                {
                    friendlyName = ar.IdentityReference.Translate(typeof(NTAccount)).Value;
                }
                catch
                {
                }
                owners.Add(friendlyName);
            }
        }
        return owners;
    }

如果您想知道谁拥有基于 Outlook 的编辑权限,那就不同了:

    static List<string> GetGroupOwnersOutlook(GroupPrincipal group)
    {
        List<string> owners = new List<string>();
        DirectoryEntry deGroup = group.GetUnderlyingObject() as DirectoryEntry;
        System.DirectoryServices.PropertyCollection r = deGroup.Properties;
        foreach (string a in r["managedBy"])
        {
            owners.Add(a);
        }
        foreach (string a in r["msExchCoManagedByLink"])
        {
            owners.Add(a);
        }

        return owners;
    }
于 2020-02-17T14:28:05.380 回答