Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

(0x80070035): The network path was not found

788 views
Skip to first unread message

dotAge

unread,
Jan 15, 2009, 5:22:06 AM1/15/09
to
I have a machine (name:EX) that joined to the DMZ domain(DC=DMZ,DC=corp), the
DMZ domain is one way trust INTRA domain (DC=INTRA,DC=com, it is not trust
DMZ domain). User DMZ\DMZADMIN is one of the administrator of EX, DMZ and
INTRA domain users can be added to local groups of EX by DMZ\DMZADMIN in
Computer Management GUI.

The following code works fine on my test environment (the test environment
is joined to the INTRA domain):

public bool IsMemberOf(string userAccount, string groupAccount)
{
UserPrincipal up = GetUserPrincipalByAccount(userAccount);
GroupPrincipal gp = GetGroupPrincipalByAccount(groupAccount);
return up.IsMemberOf(gp);
}

protected UserPrincipal GetUserPrincipalByAccount(string account)
{
Account a = new Account(account);
if (!principalContexts.ContainsKey(a.Domain)) return null;
PrincipalContext ctx = principalContexts[a.Domain].Context;
if (ctx == null) return null;
UserPrincipal p = UserPrincipal.FindByIdentity(ctx, a.UserName);
return p;
}

private GroupPrincipal GetGroupPrincipalByAccount(string groupAccount)
{
Account a = new Account(groupAccount);
if (!principalContexts.ContainsKey(a.Domain)) return null;
PrincipalContext ctx = principalContexts[a.Domain].Context;
if (ctx == null) return null;
GroupPrincipal p = GroupPrincipal.FindByIdentity(ctx, a.UserName);
return p;
}

public class Account:IEquatable<Account>
{
private string domain = string.Empty;

public string Domain
{
get { return domain; }
set
{
if (value != null) domain = value.ToUpper();
else domain = value;
if (domain == Environment.MachineName || domain ==
"LOCALHOST") domain = ".";
}
}

private string userName = string.Empty;

public string UserName
{
get { return userName; }
set
{
if (value != null) userName = value.ToLower();
else userName = value;
}
}

public Account(string accountString)
{
int i = accountString.IndexOf('\\');
userName = accountString;
if (i >= 0)
{
Domain = accountString.Substring(0, i);
if (accountString.Length > i) userName =
accountString.Substring(i + 1).ToLower();
}
else domain = ".";
}
/// <summary>
/// Get regular account name, format as "DOMAIN\username"
/// </summary>
/// <returns>regular account name string</returns>
public override string ToString()
{
string toString = "";
if (domain == ".") toString = Environment.MachineName;
else toString = domain;
return toString + "\\" + userName;
}

#region IEquatable<Account> Members

public bool Equals(Account other)
{
return (domain == other.Domain && userName == other.userName);
}

#endregion
}

When I call the function IsMemberOf("aLocalUser", "aLocalGroup") on the
EX.DMZ.corp(which is my production environment), it failed by the exception:

System.Runtime.InteropServices.COMException (0x80070035): The network path
was not found. at System.DirectoryServices.DirectoryEntry.Bind(Boolean
throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at
System.DirectoryServices.DirectoryEntry.get_AdsObject() at
System.DirectoryServices.PropertyValueCollection.PopulateList() at
System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry,
String propertyName) at
System.DirectoryServices.PropertyCollection.get_Item(String propertyName) at
System.DirectoryServices.AccountManagement.SAMStoreCtx.ResolveCrossStoreRefToPrincipal(Object
o) at
System.DirectoryServices.AccountManagement.SAMMembersSet.MoveNextForeign() at
System.DirectoryServices.AccountManagement.SAMMembersSet.MoveNext() at
System.DirectoryServices.AccountManagement.PrincipalCollectionEnumerator.MoveNext()
at
System.DirectoryServices.AccountManagement.PrincipalCollection.ContainsEnumTest(Principal
principal) at
System.DirectoryServices.AccountManagement.PrincipalCollection.Contains(Principal
principal) at
System.DirectoryServices.AccountManagement.Principal.IsMemberOf(GroupPrincipal
group) at Pei.DirectoryServices.ADHelper.IsMemberOf(String userAccount,
String groupAccount)

If I remove all non-local user accounts (such as DMZ\xxxx or INTRA\xxxxx,)
from the "aLocalGroup", the function works again!
I have right set the user credentials to connect the context stores, and can
create new user account to the LocalMachine, DMZ and INTRA domain by the
credentials.
I continue try resolving the problem by changing credetials for these
stores, null user, DMZ\DMZADMIN, INTRA\ADMIN, and I have changed Application
Pool Identity from LocalSystem to NetworkService, all failed by the same
exception!

Any idea?

Joe Kaplan

unread,
Jan 19, 2009, 10:06:58 AM1/19/09
to
If this works with the same type of trust set up in one environment but not
in another then the problem is likely network-related. However, if this
doesn't work in any environment, it may be the case that the SAM provider
cannot deal with the external foreign principals. There may not be much you
can do with this.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
"dotAge" <dot...@discussions.microsoft.com> wrote in message
news:FEF3D268-E6DF-4A37...@microsoft.com...

dotAge

unread,
Jan 20, 2009, 12:26:01 AM1/20/09
to
I try to replace the function IsMemberOf by this code:

foreach (Principal p in gp.Members)
{
if (up.Sid == p.Sid) return true;
}
The enumerator gp.Members throws the same exception.

continue try adding the impersonation code:
using (Impersonation impersonation = new Impersonation("DMZADMIN", "dmz",
"*******")) {
//.......
}

it throwed a different exception:

System.DirectoryServices.AccountManagement.PrincipalOperationException: An
error (5) occurred while enumerating the group membership. The member's SID
could not be resolved. at
System.DirectoryServices.AccountManagement.SAMMembersSet.IsLocalMember(Byte[]
sid) at
System.DirectoryServices.AccountManagement.SAMMembersSet.MoveNextLocal() at

System.DirectoryServices.AccountManagement.SAMMembersSet.MoveNext() at
System.DirectoryServices.AccountManagement.PrincipalCollectionEnumerator.MoveNext()
at
System.DirectoryServices.AccountManagement.PrincipalCollection.ContainsEnumTest(Principal
principal) at
System.DirectoryServices.AccountManagement.PrincipalCollection.Contains(Principal
principal) at
System.DirectoryServices.AccountManagement.Principal.IsMemberOf(GroupPrincipal group)

I think may be there is a bug in the GroupPrincipal.Members enumorator with
the scenario. No other way, I have to give up it, replace with the following
code, it worked well:

UserPrincipal up = GetUserPrincipalByAccount(userAccount);
GroupPrincipal gp = GetGroupPrincipalByAccount(groupAccount);

DirectoryEntry de = (DirectoryEntry)gp.GetUnderlyingObject();
object m = de.Invoke("Members");
foreach (object u in (IEnumerable)m)
{
DirectoryEntry ude = new DirectoryEntry(u);
SecurityIdentifier sid = new
SecurityIdentifier((byte[])ude.Properties["objectSid"].Value, 0);
if (sid == up.Sid) return true;
}
return false;

Joe Kaplan

unread,
Jan 20, 2009, 10:36:53 AM1/20/09
to
I think you are probably right. It should work and you should not have to
write workaround code here. At least you managed to come up with a solution
though.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
"dotAge" <dot...@discussions.microsoft.com> wrote in message

news:64B48D8D-2CC5-4A1D...@microsoft.com...

0 new messages