Section 6.4. Manage Filesystem Permissions


6.4. Manage Filesystem Permissions

Besides containing content layout and data, many filesystems also provide a layer of access control defined by a set of permissions granted to users on a per-file or per-folder basis. Although command-line modification of file permissions is possible with the cacls.exe tool, MSH also offers two cmdlets, get-acl and set-acl that give scripts access to these Access Control Lists (ACLs).

In this section, we'll look at two approaches to managing file permissions. In the first, we'll see the ease with which MSH can use existing command-line tools. In the second, we'll focus on the MSH-specific cmdlets.

6.4.1. How Do I Do That?

We've already seen how foreach can be used to loop through a number of items generated by a cmdlet, so let's start there:

     MSH D:\MshScripts> foreach ($file in get-childitem) {     >>cacls.exe $file /E /G andy :F     >>}     >>     processed file: C:\tmp\aclchange.msh     processed file: C:\tmp\brownfox.txt     processed file: C:\tmp\output.csv     processed file: C:\tmp\start.msh

This isn't all that different from calling cacls.exe with a wildcard (*) parameter, so let's take it a step further. In this case, we'll recursively modify the permissions in a complete folder structure (still possible with the /T flag on cacls.exe), except for a few files (with the name "private.txt") that we'll leave untouched:

     MSH D:\MshScripts> foreach ($file in $(get-childitem -recurse)) {     >>if ($file.FullName -notlike "*private.txt")     >>{     >>    cacls.exe $file.FullName /E /G Everyone:R > null     >>    "Changing permissions on $($file.FullName)"     >>}     >>else     >>{     >>     "Preserving permissions on $($file.FullName)"     >>}     >>}     >>     Changing permissions on C:\web\default.aspx     Changing permissions on C:\web\report.aspx     Changing permissions on C:\web\tutorial\default.aspx     Preserving permissons on C:\web\tutorial\private.txt     Changing permissions on C:\web\faq\default.aspx

One other practical use is to assign permissions based on folder name. For example, let's consider a shared folder that has named subfolders for individuals. Assuming that the folder names and NT account names match, we can use cacls.exe to grant users permission to control their own folders:

     MSH D:\MshScripts> foreach ($userdir in get-childitem) {     >>cacls.exe $userdir /E /G $($userdir.Name):F     >>}     >>     processed folder: C:\shared\asmith     processed folder: C:\shared\bobt     processed folder: C:\shared\jdoe     processed folder: C:\shared\john

So far, these scenarios could have been addressed with cacls.exe, so let's see what additional capabilities the get-acl and set-acl offer from within MSH. get-acl itself is a simple cmdlet: when given a path, it returns a security descriptor with the permissions and audit characteristics of the target:

     MSH D:\MshScripts> get-childitem | get-acl | where-object     { $_.Owner -like "*andy" }     Path                       Owner                      Access     ----                       -----                      ------     brownfox.txt               MONAD\andy                 BUILTIN\Administrators...

It's possible to combine the output of get-acl with set-acl to effect changes to the permissions of an object. We can take the ACL from one file and apply it to a series of others; this can be convenient when updating permissions across a set of files:

     MSH D:\MshScripts> $acl = get-acl c:\files\knownGoodPermissions.txt     MSH D:\MshScripts> foreach ($file in $(get-childitem c:\files)) { set-acl $file $acl }

Because get-acl is actually returning a .NET Framework object that represents the security information, there are several other tasks that become possible. In this next case, we'll create a function that generates system audit rules and add such a rule to a file to have the operating system track any access:

     MSH D:\MshScripts> function CreateAuditRule {     >>$identity=[System.Security.Principal.NTAccount]"Everyone"     >>$accessMask=[System.Security.AccessControl.FileSystemRights]"ReadAndExecute"     >>$inheritFlag=[System.Security.AccessControl.InheritanceFlags]"None"     >>$propFlag=[System.Security.AccessControl.PropagationFlags]"None"     >>$auditFlag=[System.Security.AccessControl.AuditFlags]"Success,Failure"     >>$args[0].AuditRuleFactory($identity, $accessMask, 0, $inheritFlag, $propFlag, $auditFlag)     >>}     >>     MSH D:\MshScripts> $acl = get-acl brownfox.txt     MSH D:\MshScripts> $rule=CreateAuditRule $acl     MSH D:\MshScripts> $acl.AddAuditRule($rule)     MSH D:\MshScripts> set-acl brownfox.txt $acl

As shown in Figure 6-1, the Advanced Security Settings dialog in Windows Explorer now indicates that this new audit rule has been added to the file.

Figure 6-1. Advanced Security Settings


6.4.2. What Just Happened?

We've covered quite a bit of ground here, so let's go back to the beginning and look at the techniques used in each case.

In the first set of examples, MSH was just providing the mechanism for looping through a list of files, while the actual work was being carried out by the existing cacls.exe tool. Although the foreach syntax is probably familiar to you by now, the & notation is not. We'll look at this in greater detail in Chapter 7, but, at a simple level, the token just instructs MSH to execute the command that follows it. Because cacls.exe fails to match any aliases, functions, or cmdlets, MSH will use the copy of the tool present in the Windows system folder. The structure and format of the options provided to the tool are specific to cacls.exe; it's not an MSH cmdlet and, therefore, it isn't subject to the consistent syntax rules offered by the shell.

get-acl can be used in two ways but has a similar function in both. We first saw it included in a pipeline, taking the output of get-childitem and filling the pipeline with data about the access-control lists and audit rules. Generic cmdlets, such as where-object, can then be used to further process access-control information. Remember, get-member can be used to find out more information about the objects generated by get-acl than just the owner name.

The second get-acl form takes a path as an option. In this case, several ACL objects might be generated if the path contains any wildcards. Because these objects represent security and audit rules only, they are portable and can be reapplied to other items in the filesystem without any side effects to the actual content. It's not necessary to look at or modify the object in these casesit can be passed right through to set-acl.

When modifying or changing security permissions or audit rules, the process does become a little more complicated. The set-acl cmdlet is a lightweight tool for applying a set of permissions to an object. If we don't have immediate access to those permissions or rules (by, say, copying them from another object with get-acl), we need to use the .NET Framework classes to make changes. That's where the CreateAuditRule function comes in.

Although the CreateAuditRule function appears complex, it serves a simple task: it uses a method to create a new audit rule. The first five lines of the function are responsible for setting up the options used to create a new rule. They include the users that the rule applies to; the type of access to track; whether to include rules from parent containers; whether to push this rule onto contents of a folder; and, lastly, whether to track successes, failures, or both. Each of these options is cast as a .NET Framework type, as required by the AuditRuleFactory method. The function eventually calls the method and returns the resulting audit rule.

With the new audit rule in hand, we can add it to the security object given back to us from get-acl using the AddAuditRule method. At this stage, $acl contains both the original information and the extra rule, but as yet no changes have been made to the filesystem. The last step uses set-acl to update the filesystem with the new rule.

6.4.3. What About ...

We only scratched the surface of the information that is returned by get-acl. There's a lot of information available in the returned ACL object that can be used in different cases. For example, the $acl.Access property contains a collection of permissions associated with a file, blending both explicit and inherited permissions.

With the cmdlets we've already covered, it is also possible to manage security permissions in a spreadsheet and have an MSH script that updates the real filesystem to reflect any changes. Imagine a spreadsheet that contains file and folder information row by row, with a separate column for usernames that have certain types of access. Using import-csv, a script could loop through each record and make any permission changes using the set-acl cmdlet or cacls.exe tool.

6.4.4. Where Can I Learn More?

The cacls.exe tool provides some usage information when called with a /? option from the command line. More usage information for the get-acl and set-acl cmdlets is available through get-help.




Monad Jumpstart
Monad Jumpstart
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 117

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net