Can you add Members from an External, Trusted Domain to a Group using C#?

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by E » Sat, 22 Mar 2003 07:00:26



Hi all,

If I have Forest A and Forest B, and Forest B trusts Forest A, I can
add a Member from A to a Group in B using the MMC.  I see the user
added to the ForeignSecurityPrincipals and everything works fine.

My question: is it possible to do the same thing in C# using
InteropServices?

That is, using code similar to this (this adds a member from the same
domain):

DirectoryEntry v_group = new DirectoryEntry(FOREST_B_PATH, USERNAME,
PWD);
PropertyValueCollection members = v_group.Properties["member"];
members.Add(USER_DN);
v_group.CommitChanges();

I've read one post about this subject, unfortunately it did not
contain a final solution.  Most of the other posts I've read were
about finding the readable name of an existing entry in the FSP, but
nothing about adding a new one through code.  It's also my
understanding that if the external member already exists in the FSP,
you can refer to it quite easily with its SID, but I need to add new
members to the groups, not re-map existing ones.

thanks!

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by Max L. Vaug » Wed, 26 Mar 2003 02:18:38


You will need to retrieve the SID of the group or user you want to add.  Build a SID bind string, then use that path in the IADsGroup::Add interface.

A SID bind string has the form:
LDAP://<SID=HEX_STRING_SID>

This is the only way to add the user to the group.  The IADsGroup::Add method will automatically create the FSP.

Sincerely,
Max Vaughn [MS]
Microsoft Developer Support

Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use.

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by E » Thu, 27 Mar 2003 08:50:38


Thanks for the advice.  This makes perfect sense, but I'm having a
little trouble actually getting my code to work.  Here's what I did
(in pseudo code):

***** CODE START ********
//This line essentially looks up the DirectoryEntry based on the email
and returns the Property called "objectSID" as a byte array

//Build the SID bind string
String v_bindString = "LDAP://<SID="+BitConverter.ToString( v_sid
)+">";

//The rest of it I didn't change at all except I used the bind string
in the members.add() method
DirectoryEntry v_group = new DirectoryEntry(FOREST_B_GROUP_PATH, USER,
PWD);
PropertyValueCollection members = v_group.Properties["member"];
members.Add(v_bindString);
v_group.CommitChanges();
******* CODE END *********

I get the error that says "there is no such object on the server".

My bind string looks like this:
"LDAP://<SID=01-05-00-00-00-00-00-05-15-00-00-00-8A-A7-32-3F-2F-D5-EC-6D-75-B9-75-54-FB-06-00-00>"

Not exactly sure what I'm doing wrong.  Again, the user I'm getting
the SID for is in Forest A and the group I'm trying to put him in is
in Forest B.  So as long as Forest A is trusted by B, I should be able
to grab the user by SID, right?  Should I use something else besides
the BitConverter() to convert my byte array?

thanks!


Quote:> You will need to retrieve the SID of the group or user you want to add.  Build a SID bind string, then use that path in the IADsGroup::Add interface.

> A SID bind string has the form:
> LDAP://<SID=HEX_STRING_SID>

> This is the only way to add the user to the group.  The IADsGroup::Add method will automatically create the FSP.

> Sincerely,
> Max Vaughn [MS]
> Microsoft Developer Support

> Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use.

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by E » Thu, 27 Mar 2003 08:59:58


I THINK that my bind string needs to look more like this...?

"LDAP://<SID=010500000000000515000000dcf4dc3b16c0ea32dbeb0c50f5010000>"


Quote:> You will need to retrieve the SID of the group or user you want to add.  Build a SID bind string, then use that path in the IADsGroup::Add interface.

> A SID bind string has the form:
> LDAP://<SID=HEX_STRING_SID>

> This is the only way to add the user to the group.  The IADsGroup::Add method will automatically create the FSP.

> Sincerely,
> Max Vaughn [MS]
> Microsoft Developer Support

> Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use.

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by Joe Kapla » Thu, 27 Mar 2003 14:01:11


Yes, no dashes.  That is the drag with the BitConverter.  It is almost
perfect for this function, but not quite.

If you need to use the sid in an LDAP search filter, precede each byte pair
(including the first one) with a \.

Joe K.


> I THINK that my bind string needs to look more like this...?

> "LDAP://<SID=010500000000000515000000dcf4dc3b16c0ea32dbeb0c50f5010000>"




Quote:> > You will need to retrieve the SID of the group or user you want to add.

Build a SID bind string, then use that path in the IADsGroup::Add interface.
Quote:

> > A SID bind string has the form:
> > LDAP://<SID=HEX_STRING_SID>

> > This is the only way to add the user to the group.  The IADsGroup::Add

method will automatically create the FSP.
Quote:

> > Sincerely,
> > Max Vaughn [MS]
> > Microsoft Developer Support

> > Disclaimer: This posting is provided "AS IS" with no warranties, and

confers no rights. You assume all risk for your use.
 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by E » Fri, 28 Mar 2003 02:28:25


So close, yet so far...

So I've fixed my bind string so that it contains no dashes.  This is
essentially what my code looks like now.

/**** code starts ****/
String v_bindString =
"LDAP://<SID=0105000000000005150000008AA7323F2FD5EC6D75B97554FB060000>";

DirectoryEntry v_group = new DirectoryEntry(FOREST_B_GROUP, USER,
PWD);

PropertyValueCollection members = v_group.Properties["member"];
members.Add(v_bindString);
v_group.CommitChanges();

/**** code ends ****/

Now I'm still getting the "no such object" error.  Remember that the
USER I'm trying to access with the bindstring is in an External,
Trusted Forest.  I can add a member from that External Forest with
MMC, so I know the trust exists, so why doesn't it recoginize my SID
bind string?

I'm wondering if I should really be using the
members.Add(v_bindString) line, or something else?  I thought that the
SID bindstring could be substituted for a normal DN.

Is there any other way in C# that I could verify that the trust
exists?


> Yes, no dashes.  That is the drag with the BitConverter.  It is almost
> perfect for this function, but not quite.

> If you need to use the sid in an LDAP search filter, precede each byte pair
> (including the first one) with a \.

> Joe K.



> > I THINK that my bind string needs to look more like this...?

> > "LDAP://<SID=010500000000000515000000dcf4dc3b16c0ea32dbeb0c50f5010000>"



> > > You will need to retrieve the SID of the group or user you want to add.
>  Build a SID bind string, then use that path in the IADsGroup::Add interface.

> > > A SID bind string has the form:
> > > LDAP://<SID=HEX_STRING_SID>

> > > This is the only way to add the user to the group.  The IADsGroup::Add
>  method will automatically create the FSP.

> > > Sincerely,
> > > Max Vaughn [MS]
> > > Microsoft Developer Support

> > > Disclaimer: This posting is provided "AS IS" with no warranties, and
> confers no rights. You assume all risk for your use.

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by Joe Kapla » Fri, 28 Mar 2003 02:46:56


Can you try binding to the domain that the user is in?

LDAP://domainb/<SID=0105000000000005150000008AA7323F2FD5EC6D75B97554FB060000

When you specify no domain in the LDAP path, you will bind by default to the
domain you are logged in to.  That isn't what you want in this case I don't
think.

If it was the same forest, you could try a GC:// bind, but that doesn't
sound like it is the case.

Joe K.


> So close, yet so far...

> So I've fixed my bind string so that it contains no dashes.  This is
> essentially what my code looks like now.

> /**** code starts ****/
> String v_bindString =
> "LDAP://<SID=0105000000000005150000008AA7323F2FD5EC6D75B97554FB060000>";

> DirectoryEntry v_group = new DirectoryEntry(FOREST_B_GROUP, USER,
> PWD);

> PropertyValueCollection members = v_group.Properties["member"];
> members.Add(v_bindString);
> v_group.CommitChanges();

> /**** code ends ****/

> Now I'm still getting the "no such object" error.  Remember that the
> USER I'm trying to access with the bindstring is in an External,
> Trusted Forest.  I can add a member from that External Forest with
> MMC, so I know the trust exists, so why doesn't it recoginize my SID
> bind string?

> I'm wondering if I should really be using the
> members.Add(v_bindString) line, or something else?  I thought that the
> SID bindstring could be substituted for a normal DN.

> Is there any other way in C# that I could verify that the trust
> exists?




> > Yes, no dashes.  That is the drag with the BitConverter.  It is almost
> > perfect for this function, but not quite.

> > If you need to use the sid in an LDAP search filter, precede each byte
pair
> > (including the first one) with a \.

> > Joe K.



> > > I THINK that my bind string needs to look more like this...?

"LDAP://<SID=010500000000000515000000dcf4dc3b16c0ea32dbeb0c50f5010000>"

- Show quoted text -



> > > > You will need to retrieve the SID of the group or user you want to
add.
> >  Build a SID bind string, then use that path in the IADsGroup::Add
interface.

> > > > A SID bind string has the form:
> > > > LDAP://<SID=HEX_STRING_SID>

> > > > This is the only way to add the user to the group.  The
IADsGroup::Add
> >  method will automatically create the FSP.

> > > > Sincerely,
> > > > Max Vaughn [MS]
> > > > Microsoft Developer Support

> > > > Disclaimer: This posting is provided "AS IS" with no warranties, and
> > confers no rights. You assume all risk for your use.

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by E » Fri, 28 Mar 2003 07:12:28


Yes, I just figured that out, too :)

You DO have to include the domain of the external server, as you said.

But the strange part is that if I use that bind string to simply
create a new DirectoryEntry, for example, it works.  So something like
this will resolve:

/**** code start ****/
String v_bindString =
"LDAP://FOREST_A_DOMAIN/<SID=0105000000000005150000008AA7323F2FD5EC6D75B97554FB060000>"
DirectoryEntry v_newTest = new DirectoryEntry(v_bindString,null,
null,AuthenticationTypes.Secure);
/**** code end ****/

This makes a connection as it should and I have a working
DirectoryEntry.

However, if I then go to FOREST_B and bind to a group and then try to
ADD the member from FOREST_A using that same bind string - it gives me
"object not found".  So this doesn't work:

/**** code start ****/
String v_bindString =
"LDAP://FOREST_A_DOMAIN/<SID=0105000000000005150000008AA7323F2FD5EC6D75B97554FB060000>"

//I impersonate an admin user who has admin rights on BOTH Forest A
AND Forest B
ImpersonateUser("FOREST_A","admin","password");

DirectoryEntry v_group = new DirectoryEntry(FOREST_B_GROUP, null,
null, AuthenticationTypes.Secure);

PropertyValueCollection members = v_group.Properties["member"];
members.Add(v_bindString);
v_group.CommitChanges();

EndImpersonation();

/**** code end ****/

Now since I've successfully been able to use that Forest A bind string
as long as I'm in Forest A, it still seems to me that the problem is
just that Forest B doesn't recognize anything from Forest A.

Also remember that this is a one-way Trust.  Forest B trusts Forest A,
but Forest A does NOT trust Forest B.

Here's another thing that stumped me.  I can't seem to refer to a
foreignSecurityPrincipal by its SID.  I walked through my tree,
binding to all sorts of different users using SID and I never had a
problem.  But anytime I try to bind to anything in the FSP, I get the
"no object found" error.

It seems to me this must be related to my main problem, since if I
can't even reference an FSP entry, how could I possibly grab a user in
an external, trusted forest?


> Can you try binding to the domain that the user is in?

> LDAP://domainb/<SID=0105000000000005150000008AA7323F2FD5EC6D75B97554FB060000

> When you specify no domain in the LDAP path, you will bind by default to the
> domain you are logged in to.  That isn't what you want in this case I don't
> think.

> If it was the same forest, you could try a GC:// bind, but that doesn't
> sound like it is the case.

> Joe K.



> > So close, yet so far...

> > So I've fixed my bind string so that it contains no dashes.  This is
> > essentially what my code looks like now.

> > /**** code starts ****/
> > String v_bindString =
> > "LDAP://<SID=0105000000000005150000008AA7323F2FD5EC6D75B97554FB060000>";

> > DirectoryEntry v_group = new DirectoryEntry(FOREST_B_GROUP, USER,
> > PWD);

> > PropertyValueCollection members = v_group.Properties["member"];
> > members.Add(v_bindString);
> > v_group.CommitChanges();

> > /**** code ends ****/

> > Now I'm still getting the "no such object" error.  Remember that the
> > USER I'm trying to access with the bindstring is in an External,
> > Trusted Forest.  I can add a member from that External Forest with
> > MMC, so I know the trust exists, so why doesn't it recoginize my SID
> > bind string?

> > I'm wondering if I should really be using the
> > members.Add(v_bindString) line, or something else?  I thought that the
> > SID bindstring could be substituted for a normal DN.

> > Is there any other way in C# that I could verify that the trust
> > exists?



> > > Yes, no dashes.  That is the drag with the BitConverter.  It is almost
> > > perfect for this function, but not quite.

> > > If you need to use the sid in an LDAP search filter, precede each byte
>  pair
> > > (including the first one) with a \.

> > > Joe K.



> > > > I THINK that my bind string needs to look more like this...?

>  "LDAP://<SID=010500000000000515000000dcf4dc3b16c0ea32dbeb0c50f5010000>"



> > > > > You will need to retrieve the SID of the group or user you want to
>  add.
> > >  Build a SID bind string, then use that path in the IADsGroup::Add
>  interface.

> > > > > A SID bind string has the form:
> > > > > LDAP://<SID=HEX_STRING_SID>

> > > > > This is the only way to add the user to the group.  The
>  IADsGroup::Add
>  method will automatically create the FSP.

> > > > > Sincerely,
> > > > > Max Vaughn [MS]
> > > > > Microsoft Developer Support

> > > > > Disclaimer: This posting is provided "AS IS" with no warranties, and
> > > confers no rights. You assume all risk for your use.

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by E » Fri, 28 Mar 2003 08:07:35


Eureka!!!!

I guess you have to use the Invoke to make this work.  So instead of
doing the members.Add(v_bindString) & commitChanges() lines, you have
to use this block:

String[] v_args = new string[1];
v_args[0]=v_bindString;
v_group.Invoke("Add",v_args);

Finally! :)

Thanks for the great hints and advice along the way!


> Hi all,

> If I have Forest A and Forest B, and Forest B trusts Forest A, I can
> add a Member from A to a Group in B using the MMC.  I see the user
> added to the ForeignSecurityPrincipals and everything works fine.

> My question: is it possible to do the same thing in C# using
> InteropServices?

> That is, using code similar to this (this adds a member from the same
> domain):

> DirectoryEntry v_group = new DirectoryEntry(FOREST_B_PATH, USERNAME,
> PWD);
> PropertyValueCollection members = v_group.Properties["member"];
> members.Add(USER_DN);
> v_group.CommitChanges();

> I've read one post about this subject, unfortunately it did not
> contain a final solution.  Most of the other posts I've read were
> about finding the readable name of an existing entry in the FSP, but
> nothing about adding a new one through code.  It's also my
> understanding that if the external member already exists in the FSP,
> you can refer to it quite easily with its SID, but I need to add new
> members to the groups, not re-map existing ones.

> thanks!

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by Joe Kapla » Fri, 28 Mar 2003 09:13:55


Yeah, the Add method you are invoking allows (actually requires) a full LDAP
URL that would allow you to specify an external domain.  If you were doing
this by hand, my guess is that you would first need to create the entry in
ForeignSecurityPrincipals and then add the DN of that object to the member
attribute, so it would be a two step process.  Invoke is much easier!

Congrats.  I learned a lot from this exchange.

Joe K.


> Eureka!!!!

> I guess you have to use the Invoke to make this work.  So instead of
> doing the members.Add(v_bindString) & commitChanges() lines, you have
> to use this block:

> String[] v_args = new string[1];
> v_args[0]=v_bindString;
> v_group.Invoke("Add",v_args);

> Finally! :)

> Thanks for the great hints and advice along the way!




- Show quoted text -

Quote:> > Hi all,

> > If I have Forest A and Forest B, and Forest B trusts Forest A, I can
> > add a Member from A to a Group in B using the MMC.  I see the user
> > added to the ForeignSecurityPrincipals and everything works fine.

> > My question: is it possible to do the same thing in C# using
> > InteropServices?

> > That is, using code similar to this (this adds a member from the same
> > domain):

> > DirectoryEntry v_group = new DirectoryEntry(FOREST_B_PATH, USERNAME,
> > PWD);
> > PropertyValueCollection members = v_group.Properties["member"];
> > members.Add(USER_DN);
> > v_group.CommitChanges();

> > I've read one post about this subject, unfortunately it did not
> > contain a final solution.  Most of the other posts I've read were
> > about finding the readable name of an existing entry in the FSP, but
> > nothing about adding a new one through code.  It's also my
> > understanding that if the external member already exists in the FSP,
> > you can refer to it quite easily with its SID, but I need to add new
> > members to the groups, not re-map existing ones.

> > thanks!

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by Max L. Vaughn [MSF » Fri, 28 Mar 2003 22:16:36


If you take out the server bind name, does it work?

Sincerely,
Max Vaughn [MS]
Microsoft Developer Support

Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use.

 
 
 

Can you add Members from an External, Trusted Domain to a Group using C#?

Post by Max L. Vaughn [MSF » Fri, 28 Mar 2003 22:18:27


Use the IADsGroup::Add method with the SID bind string.  That should work.  

Please let me know if it does not.

Sincerely,
Max Vaughn [MS]
Microsoft Developer Support

Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights. You assume all risk for your use.

 
 
 

1. Problem enumerating group members with NT4 & trust domains

Hi

We have two domains, say DOMA and DOMB, and multiple sites with a
subnetted TCP/IP WAN between them.

Users running Windows 95 (mainly OSR2) always log into DOMA, which has
a PDC, several BDCs and several member servers at the central IT site,
and BDCs in each of the subnetted remote offices.

DOMB is just a resource domain.  It has a PDC and BDC at the central IT
site (and no DCs or members servers in the remote offices).

There are two one-way trusts between DOMA and DOMB, and all domain
controllers are NT4 SP5.

Because a specific application written by the superusers in DOMB is
required to behave certain ways, and use certain directories and limit
user behaviours according to certain user privileges (such as which
state office they are in, what job function they have, etc), we decided
that ADSI could possibly be used to determine this (much like Kixtart
can determine InGroup membership in a login script) based on the NT
group membership.

We don't really want to duplicate the groups e.g. if DOMA already has
a "STATE1" global group, then we'd rather just trust DOMA
administrators (a different department) to add/remove users to it, and
then we just include "DOMA\STATE1" global group into our STATE1 group
on DOMB.

However, ADSI doesn't seem to be able to enumerate the cross-domain
group memberships or for that matter the cross-domain users belonging
to groups.

So, if DOMA has an account called USER1, and DOMB also has an account
called USER1 (since USER1 might be an admin or developer on the
resource domain, and once in a while he likes to log onto both), then
the enumeration of the local group which has both as members might show
on User Manager for Domains (viewed from DOMB) as:

USER1
GROUP1
DOMA\USER1
DOMA\GROUP1

But from ADSI we just get

USER1
GROUP1
USER1
GROUP1

i.e. no (apparent) way to distinguish which domain the user or group is
from.

Can anyone suggest how it might be possible to get the enumerated group
membership information so that it is able to distinguish which domain
the group or username comes from ?

It seems that something is missing - is this an oversight in the ADSI
model ?

We also find that a user on the subnetted WAN is unable to make ADSI
work (referencing objects in DOMB, the resource domain).  At first he
couldn't log in to DOMB (as a test case), so we got him to change
LMHOSTS to specify the domain controllers for DOMB via #DOM tags (I
seem to recall that this is a possible Microsoft fix for subnetted
domains).  I suspect that a static mapping of the domain in the WINS
servers for DOMA would also resolve this problem.

The LMHOSTS changes still don't let ADSI work across the subnetted
domain though.  *MUST* it be a WINS thing ?  The same user when logged
in at the central site (no subnetting) DOES work correctly.  The same
user logged in via RAS to the central site DOESN'T work correctly.

Any ideas appreciated

Regards

Jason (ADSI newbie chucked in a the deep end)

Sent via Deja.com http://www.deja.com/
Before you buy.

2. connecting Eps. Print to Mustek Scanner.

3. Using ADSI to add group to another group across domain.

4. IADs movehere method

5. Adding member to group with more than 1,000 members

6. Pop mail reader and multi user machine

7. domain users group added, but members are denied access

8. fatal error

9. Adding ID from NT4 Trusted domain to W2K Domain through LDAP Provider and vbscript

10. ADSI,Group Members and C#

11. ADSI and mutliple domains - Adding a user from domain X into a group in domain Y

12. Getting members from group in C#

13. Can I add a group to a group using ADSI?