C#: how to programmatically change permissions in a file share folder in another domain RRS feed

  • Question

  • I've got 2 domains: DE and DE2. There is a file share in DE. User DE\superuser has rights to change the permissions for the subfolders of the file share (to grant permissions to other users).

    I've adapted the code from this article to impersonate the user (my complete sample project is here). The code works fine without impersonation, if I try to update ACL of a local folder in a machine in DE2 domain.

    So, what I'm trying to do is to make a call of a standard .NET class method (System.IO.DirectoryInfo.SetAccessControl) to change the ACL of DE-based file share on behalf of impersonated DE\superuser, while my console app is working in DE2 domain on behalf of a DE2\user.

    I can do this manually, i.e. while I'm logged in to machine in DE2 domain I can open the DE-based file share in Windows Explorer (and it asks me for login/password of DE\superuser:


    Then I can go to the standard Windows "Permissions" dialog of the folder:

    and change the permissions (ACL) of the folder after another question about the login/password of DE\superuser:

    But when I try to do this via the code (the project referenced above) I've got the exception:

    Do I need to implement some kind of SMB protocol interaction by myself or am I missing a setting/flag/method in order to achieve what I want?

    Please, mark as answer, if this helps.

    Thursday, November 22, 2018 2:31 PM

All replies

  • The exception seems to be thrown during the translation from NTAccount to SecurityIdentifier. The NTAccount.TranslateToSids method calls LsaOpenPolicy, LsaLookupNames2, and LsaClose. The SystemName argument of the LsaOpenPolicy call is always null there, meaning the local system. According to my experiments, LsaLookupNames2 does not recognize the name of a foreign domain in that case, but it will work if you pass the name of the target computer to LsaOpenPolicy.

    Thus, you would need to:

    • Write definitions for the LSA_UNICODE_STRING, LSA_REFERENCED_DOMAIN_LIST, and LSA_TRANSLATED_SID2 structures.
    • Write Platform Invoke declarations for the LsaOpenPolicy, LsaLookupNames2, LsaFreeMemory, and LsaClose functions. (The declaration of LsaOpenPolicy in Reference Source has the wrong type for the SystemName parameter. It has to be a pointer or reference to LSA_UNICODE_STRING, not a plain string. This bug is harmless if SystemName is null.)
    • Call the Win32 functions and check for errors.
    • Construct a SecurityIdentifier instance using the PSID from LSA_TRANSLATED_SID2.
    • Specify that SecurityIdentifier as the IdentityReference when you construct a FileSystemAccessRule.
    Thursday, November 22, 2018 4:20 PM