Sharing a folder and setting share permissions from VB.NET

May 27, 2010 — 21 Comments

As mentioned in my previous post I have been working on figuring out how to set share permissions (not NTFS permissions) from a VB.NET app for the last couple of days… and I have finally got it working. This code makes use of the NetShareAdd Windows API along with several others to create the share and the ACL to go with it that specifies the permissions. Note that this can also be run against remote computers to create shares on them as well.

I could not find a single working example of doing this from .NET code anywhere on the internet (without using WMI) so hopefully this will help quite a few people out that have spent ages searching, like I did, for an example of the API definitions. I’ve also included a .NET method that wraps up some of the functionality provided by the APIs to make it easier for people to use – so that rather than looking through 150 lines of API stuff to find the bit that you need to change to set the specific permissions you want, you can just call my SharedFolder.ShareExistingFolder method and pass in the relevant parameters and it will do all of the API work for you.

EDIT: Rather than having all of the code in this blog post and on vbforums, I decided it would be easier to just have one location so that I dont have to keep both up to date, so here is my vbforums post where I posted my classes and explanation/examples:  http://www.vbforums.com/showthread.php?t=616267

The code uses the following API functions and structures: NetShareAdd – SHARE_INFO_502 – SECURITY_DESCRIPTOR – EXPLICIT_ACCESS – TRUSTEE – InitializeSecurityDescriptor – SetEntriesInAcl – SetSecurityDescriptorDacl – IsValidSecurityDescriptor

Please let me know if you found this useful or have any questions/suggestions 🙂

Chris

21 responses to Sharing a folder and setting share permissions from VB.NET

  1. 

    Hello Cris,

    First, I would like to thank you for your example.

    I have a question abou the permissions. I saw that you have a Enum, called SharePermissions on SharedFolder.vb. I added another option for “write” permission. I also changed the ShareExistingFolder method, including the verification for “write” option.

    ElseIf SharePermissions(i).Permission = SharedFolder.SharePermissions.Write Then
    .grfAccessPermissions = ACCESS_MASK.GENERIC_WRITE

    I tried the read/write permission with the ACCESS_MASK.GENERIC_WRITE but it did not work.
    How can I have the read/write permission? Is it possible?

    Thank you.

    • 

      Ah yeah sorry I forgot to update the code posted on vbforums with the definition of the Change permission. You cant have just Write with share permissions, you have to have either Read, Change (which is Read + Write) or Full Control.

      This is the number you need to specify for the grfAccessPermissions member if you want to grant change permission: 1245631
      So you could add a member to the ACCESS_MASK enum and define it like so:
      CHANGE = 1245631
      Then you can do this when you share the folder:
      .grfAccessPermissions = ACCESS_MASK.CHANGE

      Hope that helps

  2. 

    It works perfectly!!!

    Thank you very much!

  3. 

    Thank you so much!
    I looked for a way to set read/write permissions to my new shares but I didn’t find how to do it so I was forced to execute a .cmd file instead….(rmtshare with psexec)…on a distant server….My app is much better now! 🙂

  4. 

    First, thank you so much for your work.

    I’ve only one question…

    I’m trying to create a shared folder and grant Full permissions to WorldSid (WellKnownSid).

    On Win XP and Win 7, i’ve no problems… it works perfectly… but I’m havin troubles on Windows Server 2008 SP2 with same code… the API SetEntriesInACL is always returning ERROR_NONE_MAPPED.

    Have you any idea what can be the cause??

    Thanks in advance

    • 

      I’ve never heard of “WorldSID” so I’m afraid I can’t offer much advice… but it seems odd that it would work on Windows 7 but not on 2008. I would suspect there is something different in the configuration of the 2008 machine rather than it being the fact that it is 2008, for example maybe the 2008 machine is not joined to a domain when the other machines are. You might also want to make sure you run the program “As Administrator”, though I would have thought if it was a permissions error you would get an access denied error rather than the None Mapped error (which basically means it could not find the security principal you specified).

  5. 

    Thanks for your replay…

    With WorldSid, I mean the Everyone group… a member of System.Security.Principal.WellKnownSidType enumeration.

    I am running the app as administrator and I’m getting the same problem.

    Then Windows 2008 server is joined to the same domain where the other machines are.

    I’m trying to test the app at adifferent machine with Windows 2008 Server and I’ve the same issue….

    It’s curious that I can grant NTFS permissions to the mentioned SID without any problem. I’m getting error only when I create the share with api call SetEntriesInACL on Windows 2008…

    Any idea?

    Thanks in advance

  6. 

    Well that will be why then. If you look at the post on vbforums I made (where you downloaded my source code from) you will see I mentioned that my code only works on 64 bit if your program is set to compile to x86 and not x64 or AnyCPU. If I ever get chance I’ll try and get it working properly when compiling to x64 but I won’t have time to do that any time soon if I’m honest.

  7. 

    Good Afternoon and Happy New Year!
    I stumbled upon your API’s online searching for a way to set share permissions. While the code works great, I’m running into an issue I’m hoping your expertise might help me solve using this api. Here’s my scenario:

    I’m writing a small app that will do the following:
    1. Create a folder on a server
    2. Create a group in active directory
    3. Share this folder setting the group just created in AD as Full Control for Share permissions.
    4. etc.. it will do more, but this is my sticking point.

    The catch here is that we have a larger AD environment, so when I create the group it’s not getting replicated to the domain controller that the server is talking to. The result is that this application fails for about 15 minutes, after which the replication has occured and then it is successful.

    I’m by no means a programmer. I know the AD side very well, but I can’t seem to modify the code to make it work. My question is this: Is there a way within the sharedFolder.ShareExistingFolder to tell this to pull the group name/sid from a specific domain controller? For example: the server that I’m creating the share on is not talking to the same DC (domain controller) that the computer I’m running that application on is. I need them to speak to the same DC.

    Any help would be appreciated. I scoured everything and I’m at a loss.

    Adam

    • 

      Hmm that is an interesting point. In my code I am specifying the account/group that will be granted permission by name and I’m assuming this is the part that fails for you and gives an error like “name could not be translated” or something like that? If that is the case then perhaps you could try granting the permissions to the SID of the account rather than the name, as then it does not have to do any name resolution so it won’t need to contact a DC. It would be slightly complicated to do this, but should be possible. What you would need to do is to create your new group in AD and then get the SID of that group once it has been created (which you can get from the objectSid attribute of the group), then in the part of my code where the properties on the TRUSTEE object are set (the lines directly after this line: “Dim Account As New TRUSTEE”) instead of setting the TrusteeForm property to TRUSTEE_IS_NAME you would set it to TRUSTEE_IS_SID and then the ptstrname property needs to be set to a pointer to a SID object that is created using the AllocateAndInitializeSid API, passing in the bytes that you got from the objectSid attribute of your new group. If you aren’t too familiar with Windows APIs (and programming in general) then this might be quite hard so if you are really struggling let me know and I’ll see if I can put together an example

  8. 

    Ummmm . . what needs to change to make it work on 64-bit? The app I am writing MUST be compiled as 64 bit because it uses registry writes which go into the wrong part of the registry if I compile as 32 bit.

    • 

      I’m afraid I never did get it working from a 64 bit process. You’ve got the full source code so obviously you can try figure it out yourself

  9. 

    Hello, i´ve used your code to create shares on a Windows Server 2012. Everything worked fine! There is only one issue: Is it possible to enable ABE with VB.NET? I was searching the internet this morning and didn´t find a solution. Do you have an idea?

    Thanks in advance

    radi

Trackbacks and Pingbacks:

  1. VB.NET – Sharing a folder « Cjwdev - May 27, 2010

    […] EDIT: I finally got it working so here is my post that shows how to set the permissions as well: https://cjwdev.wordpress.com/2010/05/27/shared-a-folder-and-setting-share-permissions-from-vb-net/ […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s