none
Create a shared folder and assign multi user share permissions

Answers

  • Oops!

    As of Windows 7 - at least - the shares are created by default with readonly on everyone group.  If we reset this with an ace for ull control we can then fall back to the file system for security.

    Here is all it take to crate a share and set permisisons:

    net share myshare=c:\temp /grant:Everyone,full

    This can be exacuted withte SHELL run command from VBScript.

    If you must you can do this:

    net share myshare=c:\temp /grant:domain\group1,full /grant:domain\group2,read /grant:domain\group3,change


    ¯\_(ツ)_/¯



    • Edited by jrv Saturday, September 28, 2013 6:51 PM
    • Marked as answer by Kinkatabau Sunday, September 29, 2013 11:13 AM
    Saturday, September 28, 2013 6:49 PM

All replies

  • For MSAccess you will need to post in the Microsoft Access Developers Forum.  They will help direct you in the use of MSAccess.  This forum is for Admin scripting.

    In Windows with NTFS we usually do not set the permissions on the share as this is not generally very secure.  Share permissions are mostly obsolete.  In NT we set the permissions on the file system.  Share permissions are used when the drive is an FAT drive which does not support security.  In NT all fixed drives will be NTFS by default.

    YUO can use PowerShell or iCACLS to easily set permissions on NTFS folders.  There is no native way to do this in MSAccess. 

    Permissions are generally set once and left.  Permissions are inherited by subfolder structures.  There is no need to do a granular setting in Windows.  I recommend getting one of the many books on administering Windows and NTFS security.  If you do this without a complete understanding of what you are doing you will end up with a mess. 

    Once you understand security then ideas like MSAccess for managing security will seem unnecessary.


    ¯\_(ツ)_/¯

    Wednesday, September 25, 2013 6:55 PM
  • Thanks jrv,

    I know i makes no sense to grant permissions to users via MSAccess in a Win Server 2008, but I have this database where I add projects daily, upon adding a project, i was hoping that by a click of a button, VBA will create necessary folders for that project (which I already have), as well as add user groups to each folder created.

    The intend was to save end user some time. I was told that there are vbscrips that can do that.

    One again, thanks for your time, and will certainly look in to Microsoft Access Developers Forum.

    Reka
    Wednesday, September 25, 2013 7:47 PM
  • But what you are saying has nothing to do with shares.  Folders get permissions but there is no facility in MSAccess to set permissions.  YOU can shell to run ICACLS and set permissions. You will need to post in the MSAccess VBA forum to learn how to do that.

    VBScript has no native ability to set permissions and would only shell to ICACLS to do this.


    ¯\_(ツ)_/¯

    Wednesday, September 25, 2013 7:55 PM
  • Hi jrv,

    I am trying to accomplish this via VBScripts - I can found some code that works for me but it only grants access to one usergroup rather then multiple.

    Source: http://support.smartbear.com/viewarticle.aspx?aid=9027

    I have attached a sample of how how this form looks like, from which I run the above code. I was hopping if I could tweak those ACE code lines I could set it where it enables me to grant access based on what I select on the list box (listed in the attached form).

    I posted a question on MSAccess Forum but have got no port repose, yet. 

    Thanks,

    Reka

    Saturday, September 28, 2013 2:03 PM
  • We don't do that in Windows NT.  We use file system permission.

    You are asking your question in the wrong forum.  You want to ask Access questions in the MS Access forum.


    ¯\_(ツ)_/¯

    Saturday, September 28, 2013 2:57 PM
  • Hi jrv,

    I thought this was the Scripting forum and so my questions has to do with the modification of the script (VBScript) listed below. Please ignore the MS Access image.

    http://support.smartbear.com/viewarticle.aspx?aid=9027

    If you tell me that this link is not a script and that this forum is not Scripting forum, then I will post my question somewhere else.

    Thanks for your time, and sorry for multiple posts. I'm just trying to get this last thing done and I will be out of this forum.

    Once again, appreciate your time and your response.

    Reka

    Saturday, September 28, 2013 3:16 PM
  • Microsoft Access does not use VBScript.  It is VBA.  You need to post in the Access VBA forum.

    http://social.msdn.microsoft.com/Forums/office/en-US/home?forum=accessdev&filter=alltypes&sort=lastpostdesc


    ¯\_(ツ)_/¯

    Saturday, September 28, 2013 3:23 PM
  • What is it about the script that you need to modify?  It seems to have all of the pieces needed.

    I still want you to understand that this is not how we do this in Windows NT. 

    If you wish to pursue this then tell us what error you are getting or what is not happening.  Post the script parts that are failing.


    ¯\_(ツ)_/¯

    Saturday, September 28, 2013 3:27 PM
  • The following script adds only one ACL (one user group), the issue is that I need to be able to add more then 2 user groups. How can I modify it to be able to do that?

    VBScript is as follows:

    Sub Test
      Dim domainName, computerName, path, shareName, shareComment, accountName
      
      Const PERM_READ           = 1179817 
      Const PERM_MODIFY         = 1245631 
      Const PERM_FULL           = 2032127 
      Const MAXIMUM_CONNECTIONS = 10
      
      domainName = "DOMAIN_NAME"
      computerName = "COMPUTER_NAME"
      path = "PATH" ' e.g. "C:\Temp"
      shareName = "SHARE_NAME" ' e.g. "Temp"
      shareComment = "SHARE_COMMENT" ' e.g. "Temp Folder"
      accountName = "ACCOUNT_OR_GROUP_NAME"  
      
      If Not CreateShare(domainName, computerName, path, shareName, shareComment,_
                          accountName, PERM_FULL, MAXIMUM_CONNECTIONS) Then
        Log.Error("A share was not created")
      End If 
    End Sub
     
    Function CreateShare(domainName, computerName, path, shareName, shareComment,_ 
                          accountName, sharePermissions, maximumConnections) 
      Dim services, secDescClass, secDesc, trustee, ace, share, result   
     
      Set services = GetObject(_
                      "WINMGMTS:{impersonationLevel=impersonate,(Security)}!\\" &_
                      computerName & "\ROOT\CIMV2") 
     
      'Create a new share
      Set secDescClass = services.Get("Win32_SecurityDescriptor") 
      Set secDesc = secDescClass.SpawnInstance_() 
     
      Set trustee = SetTrustee(domainName, accountName)
      If trustee Is Nothing Then
        Log.Error("The " & accountName & " account was not found in the " &_ 
                    domainName & " domain")
        CreateShare = False
        Exit Function
      End If 
      Set ace = services.Get("Win32_Ace").SpawnInstance_ 
      ace.Properties_.Item("AccessMask") = sharePermissions 
      ace.Properties_.Item("AceFlags") = 3 
      ace.Properties_.Item("AceType") = 0 
      ace.Properties_.Item("Trustee") = trustee 
      secDesc.Properties_.Item("DACL") = Array(ace)
       
      Set share = services.Get("Win32_Share") 
      result = share.Create(path, shareName, 0, maximumConnections,_
                            shareComment, "", secDesc)
      If 22 = result Then 
        Log.Warning("The '" & shareName & "' share was duplicatied")
      ElseIf 0 <> result Then
        Log.Error("Create() failed")
        CreateShare = False
        Exit Function
      End If 
      CreateShare = True
    End Function 
     
    Function SetTrustee(domainName, strName)
      Dim result
      
      Set result = SetGroupTrustee(domainName, strName)
      If Not(result Is Nothing) Then
        Set SetTrustee = result
        Exit Function
      End If
      Set result = SetAccountTrustee(domainName, strName)
      If Not(result Is Nothing) Then
        Set SetTrustee = result
        Exit Function
      End If
      Set SetTrustee = Nothing
    End Function
     
     
    Function SetAccountTrustee(domainName, strName) 
      Dim objTrustee, account, accountSID 
     
      Set objTrustee = GetObject(_
            "Winmgmts:{impersonationlevel=impersonate}!root/cimv2:Win32_Trustee")._
            Spawninstance_ 
      On Error Resume Next  
      Set account = GetObject(_
     "Winmgmts:{impersonationlevel=impersonate}!root/cimv2:Win32_Account.Name='" &_
     strName & "',Domain='" & domainName &"'")
      If 0 <> Err.Number Then
        Err.Number = 0
        Set SetAccountTrustee = Nothing
        Exit Function
      End If
      On Error Goto 0  
      Set accountSID = GetObject(_
        "Winmgmts:{impersonationlevel=impersonate}!root/cimv2:Win32_SID.SID='" &_
        account.SID &"'") 
      objTrustee.Domain = domainName 
      objTrustee.Name = strName 
      objTrustee.Properties_.item("SID") = accountSID.BinaryRepresentation 
      Set accountSID = Nothing 
      Set account = Nothing 
      Set SetAccountTrustee = objTrustee 
    End Function 
     
     
    Function SetGroupTrustee(domainName, strName) 
      Dim objTrustee, account, accountSID
     
      Set objTrustee = GetObject(_
            "Winmgmts:{impersonationlevel=impersonate}!root/cimv2:Win32_Trustee")._
            Spawninstance_
      On Error Resume Next 
      Set account = GetObject(_
       "Winmgmts:{impersonationlevel=impersonate}!root/cimv2:Win32_Group.Name='" &_
       strName & "',Domain='" & domainName &"'")
      If 0 <> Err.Number Then
        Err.Number = 0
        Set SetGroupTrustee = Nothing
        Exit Function
      End If
      On Error Goto 0 
      Set accountSID = GetObject(_
        "Winmgmts:{impersonationlevel=impersonate}!root/cimv2:Win32_SID.SID='" &_
        account.SID &"'") 
      objTrustee.Domain = domainName 
      objTrustee.Name = strName 
      objTrustee.Properties_.item("SID") = accountSID.BinaryRepresentation 
      Set accountSID = Nothing 
      Set account = Nothing 
      Set SetGroupTrustee = objTrustee 
    End Function

    Saturday, September 28, 2013 3:36 PM
  • You can start by learning how to write VBScript.  Once you learn how to write you can try to modify the script to your needs.

    Here are some links to learning material: http://technet.microsoft.com/en-us/scriptcenter/dd772284

    The purpose of this forum is to help technicians who use scripting or to help those learning to script.  It is not a free script writing or fixing forum.

    From what I can see the script does everything you want or need.  You just need to learn how to read the script.  Once you learnthtt you willbeable to modify it.  If you have an issue with the modification then you can post a question.

    You would be best off posting your request for updates to the script with the author of the script.

    You can also look in the repository for scripts that create shares.


    ¯\_(ツ)_/¯

    Saturday, September 28, 2013 3:57 PM
  • I can read and understand the majority of this code. But, I can't seem to to create multiple ACE1 to ACEn variables, like the existing ACE variable, each using a Trustee set to a different user or group account and set the DACL of the SecDesc using an array of those ACEs:

    SecDesc.Properties_.Item("DACL") = Array(ACE, ACE2, ... ACEn).

    I was hopping someone in this forum or you could help me out with this line of code rather than give me a bunch of links that I have already gone through and advises that I am aware of.

    I do, however, appreciate your efforts. At least you found time and responded. Thanks, I'm out of this forum.

    Reka

    Saturday, September 28, 2013 4:22 PM
  • Post the code you are trying to modify.  You have posted someone else's code link and have mad statements bout what you want to do.  You have not posted what you have tried with any error messages or issue.

    The script you linked is not capable of what you ask without extensive changes.  It is up to you to make those changes.  You have not even tried to update the code.

    The link I posted is closer to what you want.  It already tells you haw to add multiple ACEs in the documentation.  According to the author it was designed to do what you ask.


    ¯\_(ツ)_/¯

    Saturday, September 28, 2013 4:27 PM
  • I added another trustee line (trustee2) and then another ACL (ACL2) 

    Set trustee1 = SetGroupTrustee("pcc.local", "Pricing") 'User group1.
    Set trustee2 = SetGroupTrustee("pcc.local", "Technical") 'User group2.
      
    Set ace1 = Services.Get("Win32_Ace").SpawnInstance_
        ace1.Properties_.Item("AccessMask") = 2032127
        ace1.Properties_.Item("AceFlags") = 3
        ace1.Properties_.Item("AceType") = 0
        ace1.Properties_.Item("trustee1") = trustee1
        
    Set ace2 = Services.Get("Win32_Ace").SpawnInstance_
        ace2.Properties_.Item("AccessMask") = 2032127
        ace2.Properties_.Item("AceFlags") = 3
        ace2.Properties_.Item("AceType") = 0
        ace2.Properties_.Item("trustee2") = trustee2
        
        SecDesc.Properties_.Item("DACL") = Array(ace1,ace2)

    The problem is here:

    Sub ShareSec(Fname, shr, info, Account) 

    The word Account is supposed to pass those two usergroups. The error I get is "Not found" and then debugs at:

    ace1.Properties_.Item("trustee1") = trustee1

    it's as if there is no Pricing usergroup and I know there is because I keep checking.

    Your thoughts...

    Reka

    Saturday, September 28, 2013 4:56 PM
  • You cannot set the DACL twice when you are creating a new share.

    For the second ACE you need to retrieve the SD and use the 'Add' method of the sd class.

    Const SHARE_FULLCONTROL = 2032127
    Const SHARE_READONLY = 0
    
    Set newshare = CreateShare( "testshare", "c:\temp","test share","omega\jvierra",SHARE_FULLCONTROL,null)
    Set ace = CreateWMIAce("omega\testuser",SHARE_FULLCONTROL)
    Set secinfo  = GetShareSecurity(newshare)
    Set sd = secinfo.GetSecurityDescriptor()
    Set dacl = sd.Descriptor.DACL
    dacl.Add ace
    sd.SetSecurityDescriptor dacl

    The re4aswon most of us never set extended sharing security in NT is because it is too hard to manage via WMI or VBScript. It can be relatively easily managed in PowerShell.

    99% of the VBScript examples on the web do not work correctly outside of a narrow set of conditions.  Microsoft has delivered the Wizard and eh commandline tools ICACLS and Subinacl to manage share security. 

    In a domain we usually set the  share to Everyone  - Full Control then use NTFS permissions set by ICACLS.  In PowerShell we can use Set-ACL to control the file system.  This is the standard practice used by nearly all trained admins. It is usually only home users in a workgroup who try to use shares to manage access.  This is made available because home users are not skilled enough to master using NTFS security in a workgroup.

    You will eventually give up on this and use the standard methods of managing a share.  The default when creating a share (in one line) is for Everyone to have full control.  This is by design.  Crete the share and use ICACLS to set permissions.  The permisions can be set in oneline.


    ¯\_(ツ)_/¯



    • Edited by jrv Saturday, September 28, 2013 6:36 PM
    Saturday, September 28, 2013 6:22 PM
  • Oops!

    As of Windows 7 - at least - the shares are created by default with readonly on everyone group.  If we reset this with an ace for ull control we can then fall back to the file system for security.

    Here is all it take to crate a share and set permisisons:

    net share myshare=c:\temp /grant:Everyone,full

    This can be exacuted withte SHELL run command from VBScript.

    If you must you can do this:

    net share myshare=c:\temp /grant:domain\group1,full /grant:domain\group2,read /grant:domain\group3,change


    ¯\_(ツ)_/¯



    • Edited by jrv Saturday, September 28, 2013 6:51 PM
    • Marked as answer by Kinkatabau Sunday, September 29, 2013 11:13 AM
    Saturday, September 28, 2013 6:49 PM
  • Here is why this is not an easy question to ask and have someone do this for you.  I decided to update my share library that is in he repository.  It was posted as an example of how to approach share permissions but no one so far has figured out how to use it.

    Here is an updated version that will add as many accounts as you like to a share.  Unfortunately for you it is in PowerShell.  This is much harder to do in VBScript.  The PowerShell code can show you how you have to approach shares in WMI when modifying the security descriptor. 

    This is not completely tested yet.  It is for information purposes mostly.  I will publish it to the repository when I have tested it more.  It also nee4d to have the help completed.

    # .Description NAME: ShareLibrary.ps1 AUTHOR: James Vierra , Designed Systems & Services DATE : 3/13/2009 COMMENT: 09/15/2011 - Converted to PowerShell V2 09/28/2013 - Updated to add functions Added: "Add-ShareACE" "Get-ShareAccess" Modified to library structure Made adjustment to parameters. Set "New-Share" to create defaultl permissions #

    #requires -version 2.0 function New-Share{ [CmdLetBinding()] param( [Parameter(Mandatory=$true)] [string]$name, [Parameter(Mandatory=$true)] [string]$path, [string]$description = "", [System.Security.Principal.NTAccount]$account='Everyone', $AccessMask=0, [string]$maxallowed = $null ) Write-Verbose "Using WMI to create a new Security Descriptor" $sd = ([WMIClass] "Win32_SecurityDescriptor").CreateInstance() Write-Verbose "Create new ACE" $ace=Create-WMIAce $account $rights Write-Verbose "Add Ace to DACL" $sd.DACL += @($ace.psobject.baseobject) # append $sd.ControlFlags="0x4" # set SE_DACL_PRESENT flag $share = [wmiclass]"Win32_Share" Write-Verbose "Calling WMI to Create share." $result=$share.Create( $path, $name, 0, $maxallowed,$description,$null,$sd ) if($result.returnValue -ne 0){ $resultMsg=switch($result.returnValue){ 0 {'Success'} 2 {'Access Denied'} 8 {'Unknown Failure'} 9 {'Invalid Name'} 10 {'Invalid Level'} 21 {'Invalid Parameter'} 22 {'Duplicate Share'} 23 {'Redirected Path'} 24 {'Unknown Device or Directory'} 25 {'Net Name Not Found'} default {"Unknown Error Code = $_"} } Write-Host "Create share failed with $resultMsg" -ForegroundColor red -BackgroundColor white Write-Error "Create share failed with $resultMsg" }else{ Write-Verbose 'Share created successfully' } } function Create-WMITrustee([string]$NTAccount){ $user = New-Object System.Security.Principal.NTAccount($NTAccount) $strSID = $user.Translate([System.Security.Principal.SecurityIdentifier]) $sid = New-Object security.principal.securityidentifier($strSID) [byte[]]$ba = ,0 * $sid.BinaryLength [void]$sid.GetBinaryForm($ba,0) $Trustee = ([WMIClass] "Win32_Trustee").CreateInstance() $Trustee.SID = $ba $Trustee } function Create-WMIAce{ param( [string]$account, $AccessMask ) $trustee = Create-WMITrustee $account $ace = ([WMIClass] "Win32_ace").CreateInstance() $ace.AccessMask=$AccessMask $ace.AceFlags=0 # set inheritances and propagation flags $ace.AceType=0 # set SystemAudit $ace.Trustee=$trustee $ace } function Add-ShareAce{ [CmdLetBinding()] Param( [Parameter(Mandatory=$true)] [string]$shareUNC, [Parameter(Mandatory=$true)] [System.Security.Principal.NTAccount]$account, [ValidateSet('Read', 'Change', 'Full')] [string]$Access ) $accessMask=switch($access){ read {1441961} change {1507775} full {2032127} } $ace=Create-WMIAce -account $account -AccessMask $AccessMask #get the share and then get the secuity descriptor $shareName=$shareUNC.Replace('\\','').Split('\')[1] $server=$shareUNC.Replace('\\','').Split('\')[0] $share=Get-WmiObject Win32_Share -Filter "Name='$sharename'" -ComputerName $server $sdsetting=$share.GetRelated('Win32_LogicalShareSecuritySetting') $sd=$sdsetting.GetSecurityDescriptor().Descriptor $newsd=([wmiclass]'Win32_SecurityDescriptor').CreateInstance() $newsd.DACL+=$ace $share.SetShareInfo($null,'',$newsd) $share } function Get-ShareAccess{ # # $shareUNC = '\\server\share' # Param( $shareUNC ) $shareName=$shareUNC.Replace('\\','').Split('\')[1] $server=$shareUNC.Replace('\\','').Split('\')[0] $setting=Get-WmiObject Win32_LogicalShareSecuritySetting -Filter "Name='$shareName'" -ComputerName $server $setting.GetSecurityDescriptor().Descriptor.DACL| %{ New-Object PsObject -Property @{ Name=$_.Trustee.Name;AccessMask=$_.AccessMask } } }

    Add-ShareAce -shareUNC omega\testshare -account everyone -Access change

    For quick help

    Add-ShareACE -?


    ¯\_(ツ)_/¯




    • Edited by jrv Saturday, September 28, 2013 11:14 PM
    Saturday, September 28, 2013 11:11 PM
  • Hi jrv,

    Net Share did the job. I dealt with it before, and it didn't deliver but once you wrote that down it worked.
    net share myshare=c:\temp /grant:domain\group1,full /grant:domain\group2,read /grant:domain\group3,change

    I tweaked it to where I can run it via code (Run Command) and it works like a charm.

    For the first time in this forum under this topic, you helped, and I am thankful to you.

    Now, one last mini question: To remove a certain group, i cannot do that, right?

    One way to do that is remove the entire folder from share, then share it again with groups I need.

    Some like this:
    net share myshare /DELETE
    net share myshare=c:\temp /grant:domain\group1,full /grant:domain\group4,read

    Thanks,
    Reka

    "I haven't failed, I've found ten thousand ways that don't work."
    -Thomas Edison (1847-1931)

    Sunday, September 29, 2013 11:26 AM
  • Monday, September 30, 2013 2:49 AM