Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / November 2003

Tip: Looking for answers? Try searching our database.

Using GetEffectiveRightsFromAcl in CSharp

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Katrin Bibas - 13 Nov 2003 21:39 GMT
Hello,

how can I use GetEffectiveRightsFromAcl in C#? I don't know how to
transform the parameters to the corresponding C# structs.

DWORD GetEffectiveRightsFromAcl(
 PACL pacl,
 PTRUSTEE pTrustee,
 PACCESS_MASK pAccessRights
);

I hope this function will be more efficient than iterating through all
the ACEs manually.

Thanks in advance,
Katrin
Mattias Sj?gren - 13 Nov 2003 22:11 GMT
Katrin,

Try this

enum MULTIPLE_TRUSTEE_OPERATION
{
 NO_MULTIPLE_TRUSTEE,
 TRUSTEE_IS_IMPERSONATE
}

enum TRUSTEE_FORM
{
 TRUSTEE_IS_SID,
 TRUSTEE_IS_NAME,
 TRUSTEE_BAD_FORM,
 TRUSTEE_IS_OBJECTS_AND_SID,
 TRUSTEE_IS_OBJECTS_AND_NAME
}

enum TRUSTEE_TYPE
{
 TRUSTEE_IS_UNKNOWN,
 TRUSTEE_IS_USER,
 TRUSTEE_IS_GROUP,
 TRUSTEE_IS_DOMAIN,
 TRUSTEE_IS_ALIAS,
 TRUSTEE_IS_WELL_KNOWN_GROUP,
 TRUSTEE_IS_DELETED,
 TRUSTEE_IS_INVALID,
 TRUSTEE_IS_COMPUTER
}

struct TRUSTEE
{
 public IntPtr pMultipleTrustee;
 public MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation;
 public TRUSTEE_FORM TrusteeForm;
 public TRUSTEE_TYPE TrusteeType;
 public IntPtr ptstrName;
}

[DllImport("advapi32.dll")]
static extern uint GetEffectiveRightsFromAcl(IntPtr pacl, ref TRUSTEE
pTrustee, out uint pAccessRights);

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.

Katrin Bibas - 14 Nov 2003 09:58 GMT
Thank you for your quick response. I have not worked with IntPtr yet,
so may you tell me how to convert IADsAccessControlList to an IntPtr?

I want to use the distinguishedName of the trustee, so I converted it
with System.Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi to
an IntPtr and set TrusteeForm to TRUSTEE_IS_NAME. Is this the right
way to do it?

Thank you.
Katrin
Mattias Sj?gren - 15 Nov 2003 01:58 GMT
Katrin,

>Thank you for your quick response. I have not worked with IntPtr yet,
>so may you tell me how to convert IADsAccessControlList to an IntPtr?

IntPtr is just the most generic type that can hold any kind of pointer
sized value. If you know that it'll always be an IADsAccessControlList
interface reference, you can probably change the type from IntPtr to
IADsAccessControlList.

>I want to use the distinguishedName of the trustee, so I converted it
>with System.Runtime.InteropServices.Marshal.StringToCoTaskMemAnsi to
>an IntPtr and set TrusteeForm to TRUSTEE_IS_NAME. Is this the right
>way to do it?

I don't know, what do you do with the string pointer after that? It's
possible that you also here can just change the data type from the
generic IntPtr to a string, if that's what you always will use it for,
and the runtime will then take care of the rest.

Mattias

Signature

Mattias Sjögren [MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.

Katrin Bibas - 17 Nov 2003 10:20 GMT
Mattias,

I always get the return value 1336, something's wrong with the ACL
structure.
I tried to use IADsAccessControlList and the string directly, and also
the conversion to the IntPtr with
System.Runtime.InteropServices.Marshal... . Always with the same
result. Here is a snippet of code:

// get the security descriptor
descriptor = entry.Properties["ntSecurityDescriptor"][0] as
ADsSecurityDescriptor;
               
if(descriptor != null)
{
    // get DiscretionaryAcl
    dacl = descriptor.DiscretionaryAcl as IADsAccessControlList;

    TRUSTEE pTrustee = new TRUSTEE();
    pTrustee.MultipleTrusteeOperation =
MULTIPLE_TRUSTEE_OPERATION.NO_MULTIPLE_TRUSTEE;
    pTrustee.pMultipleTrustee = IntPtr.Zero;
    pTrustee.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME;
    pTrustee.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER;
    pTrustee.strName = userDN;

    uint pAccessRights;
       uint result = GetEffectiveRightsFromAcl(dacl, ref pTrustee,
out pAccessRights);
}

Thanks in advance.
Katrin
Stephen Martin - 17 Nov 2003 13:26 GMT
Hi Katrin,

The problem is that the dacl parameter to GetEffectiveRightsFromACL is a
pointer to an ACL structure but you are trying to pass it an
IADsAccessControlList interface pointer. One is a C-style struct the other
is a COM object, they are not interchangeable nor can one be marshalled to
the other.

The AD object does not expose an underlying access control list pointer for
the DACL. In order to use GetEffectiveRightsFromACL you will need to use the
underlying API GetNamedSecurityInfo to retrieve a pointer to a DACL.

> Mattias,
>
[quoted text clipped - 29 lines]
> Thanks in advance.
> Katrin
Katrin Bibas - 17 Nov 2003 19:09 GMT
Hi Stephen,
I thought it must be something like this. Now I use
GetNamedSecurityInfo and the return value is 0 (for
GetNamedSecurityInfo and GetEffectiveRightsFromAcl), so it should
work. But the AccessMask is always 0. Am I still doing something
wrong? I want to get the AccessMask for a user (userDN) on another
DirectoryEntry (entryDN). Here is a new snippet of code:

IntPtr psd = IntPtr.Zero;
IntPtr pZero = IntPtr.Zero;
IntPtr pDacl = IntPtr.Zero;
IntPtr pDacl2 = IntPtr.Zero;

int errorReturn = GetNamedSecurityInfo(entryDN,
(int)SE_OBJECT_TYPE.SE_DS_OBJECT,
DACL_SECURITY_INFORMATION,
out pZero, out pZero, out pDacl, out pZero, out pZero);

errorReturn = GetNamedSecurityInfo(userDN,
(int)SE_OBJECT_TYPE.SE_DS_OBJECT,
DACL_SECURITY_INFORMATION,
out pZero, out pZero, out pDacl2, out pZero, out psd);

TRUSTEE pTrustee = new TRUSTEE();
pTrustee.pMultipleTrustee = IntPtr.Zero;
pTrustee.MultipleTrusteeOperation =
MULTIPLE_TRUSTEE_OPERATION.NO_MULTIPLE_TRUSTEE;
pTrustee.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_SID;
pTrustee.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER;
pTrustee.pName = psd; // this is an IntPtr

uint pAccessRights;
uint result = GetEffectiveRightsFromAcl(pDacl, ref pTrustee, out
pAccessRights);

Thanks in advance,
Katrin
Stephen Martin - 18 Nov 2003 13:38 GMT
Hi Katrin,

You have a couple of problems with your code that I can see.

In your first call to GetNamedSecurityInfo you are ignoring the security
descriptor pointer, you can't do this. This pointer must be freed when you
are done. In your second call to GetNamedSecurityInfo you are retrieving the
security information for the Active Directory object that represents the
user, you are not retrieving information about that user. In particular, the
psd is not a pointer to that user's SID.

You need to use your original TRUSTEE code, modify the GetNamedSecurityInfo
call slightly and add code at the end to free the memory allocated for the
security descriptor. Something like this should work(not tested):

IntPtr psd = IntPtr.Zero;
IntPtr pOwner = IntPtr.Zero;
IntPtr pGroup = IntPtr.Zero;
IntPtr pDacl = IntPtr.Zero;
IntPtr pSacl = IntPtr.Zero;

int errorReturn = GetNamedSecurityInfo(entryDN,
(int)SE_OBJECT_TYPE.SE_DS_OBJECT,
DACL_SECURITY_INFORMATION,
out pOwner, out pGroup, out pDacl, out pSacl, out psd);

TRUSTEE pTrustee = new TRUSTEE();
pTrustee.pMultipleTrustee = IntPtr.Zero;
pTrustee.MultipleTrusteeOperation =
MULTIPLE_TRUSTEE_OPERATION.NO_MULTIPLE_TRUSTEE;
pTrustee.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME;
pTrustee.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER;
pTrustee.strName = userDN;

uint pAccessRights;
uint result = GetEffectiveRightsFromAcl(pDacl, ref pTrustee, out
pAccessRights);

//The security descriptor pointer must always be freed
//when you are done with it.
System.Runtime.InteropServices.Marshal.FreeHGlobal(psd);

> Hi Stephen,
> I thought it must be something like this. Now I use
[quoted text clipped - 33 lines]
> Thanks in advance,
> Katrin
Katrin Bibas - 18 Nov 2003 20:02 GMT
Hi Stephen,

thank you for help. I think I did it now. At first I had a problem with
errorcode 1332. I thought I could use the distinguishedName of the user, but
obviously this did not work. But then I translated it to the NT4-style name,
and now it works.

Katrin

> Hi Katrin,
>
[quoted text clipped - 75 lines]
> > Thanks in advance,
> > Katrin
Katrin Bibas - 27 Nov 2003 18:54 GMT
Hi,

is it possible, that GetEffectiveRightsFromAcl returns wrong values? I get
access masks with rights I didn't expect. This function returns the rights
the trustee really has, not the denied rights, doesn't it? So for example if
I do

if((accessmask & 0x10000) == 0x10000)  // check for standard rights - DELETE
{
...
}

I should get true if the accessmask for the trustee contains this right. But
as far as I know the trustee I am testing does not have this right in the
active directory.
I haven't work with those things that often yet. Is there anything else I
have to pay attention for when using this function? Do some rights override
others?

Thanks in advance.
Katrin
Stephen Martin - 29 Nov 2003 13:25 GMT
Hi Katrin,

Are you sure that the trustee does not have the requested access through
some group membership (possibly indirect such as belonging to a group that
belongs to a group that has the access). I usually don't recommend using
GetEffectiveRightsFromAcl because its results are often incorrect but
sometimes there is no alternative. But GetEffectiveRightsFromAcl usually
errs on the side of giving false negatives (i.e. reporting that a trustee
does not have a certain access when in fact they do have it). I can't say
that I remember it ever giving a false positive.

> Hi,
>
[quoted text clipped - 17 lines]
> Thanks in advance.
> Katrin
Katrin Bibas - 29 Nov 2003 15:06 GMT
Hi Stephen,

I used the admin tools to check the effective rights too, and there was the
same result. Lots of rights were checked although the user does not have
those rights. I have read the article
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:
80/support/kb/articles/q262/2/78.asp&NoWebContent=1. There is written that
sometimes GetEffectiveRightsFromAcl does not return the correct rights. So I
started a new thread about using AccessCheck. Maybe you can help me with
this, too :-)
IsAccessCheck the right way to solve my problem?

Thanks a lot for any help.
Katrin

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.