Win32::Perms - Manages object permissions for Windows NT


NAME

Win32::Perms - Manages object permissions for Windows NT


SYNOPSIS

  use Win32::Perms;


DESCRIPTION

This extension provides the ability for a Perl script to manage permissions on files, directories, registry keys, network shares and printer shares. The management of permissions is tightly tied to Windows NT (for registry keys, shared directories and printer shares). Windows 95/98 does not support the type of security that relates to permissions. Additionally file and directory permissions only work on drives which have been formatted with the NTFS file system.


GENERAL USE:

Win32::Perms is a Win32 Perl 5 extension that manages permissions on Win32 objects. Valid Win32 objects include files, directories, registry keys, network shares and printer shares.

This thing is very young and needs maturing. All functions work but not all path types are supported yet. Currently the following objects are supported: files directories registry keys network shares printer shares

**Named pipes are not yet supported since they are considered by Win32 to be Kernel objects and not proper files. Although you can pass in a Win32::Perms object when creating a Win32::Pipe object. This will set the specified permissions on the named pipe. For more information refer to the latest version of Win32::Pipe:

    http://www.roth.net/perl/pipe/

Explanation:

Okay, this thing needs some explaining. Permissions are placed on Win32 objects such as files, directories and registry keys. Now, let's say that you want to place permissions so user 'cartman' can only read a file but 'administrator' has full access....

The first thing you need to understand is that usernames and groupnames are just strings of text that mean nothing to Win32. The OS does not care what a ``Administrator'' string is. It does care, however, about a funky long thing that looks like:

        S-1-5-21-143982112-578333669-1869494990-500

You see, an odd looking number like this is what Win32 sees when it thinks of the Administrator account. When the Administrator logs in Win32 looks up this fancy sting and applies it whenever it needs to identify the user. For humans it is simply easier to refer to 'Administrator'. The string is really a text representation of a binary memory structure which is called a Security IDentifier (SID). Every username, groupname, domainname and machine name have a SID tucked away somewhere in the Registry.

So if you want to grant the user 'cartman' some permissions you must first request Win32 to lookup the SID for the 'cartman' account. The same goes for the 'administrator' account.

Once you have a SID you need to create a thing called an Access Control Entry (ACE). An ACE is a combination of SID, permissions and some flags. You simply make an ACE for cartman and an ACE for administrator. Sounds simple so far...

Now that you have this collection of ACEs you need to glue them altogether. You do this by creating an Access Control List (ACL). An ACL is simply a list of ACEs. Once you have created an ACL you can apply it to the object (file, dir, registry key, etc).

But wait, not so fast. Having created you nice shiny ACL makes you happy and all, but we are not out of this yet. There are two types of ACLs. The type of ACL that most users are familiar with is the one which allows you to determine who can access to what. This is what you created the cartman and administrator ACEs for in the first place. This ACL is known as a Discresionary Access Control List (DACL). Makes sense since it is up to your descression who has access, eh?

The other type of ACL is one that most administrators are familiar with. This is the one which determines if and how the object is audited. This way you can set it such that when the object is successfull opened an entry is placed in the event log. There are successful audits and there are failure audits. This type of audit ACL is known as a System Access Control List (SACL).

By the way, if you have an empty DACL (that is a DACL that contains no ACEs) then that means that nobody will be granted access to the object (except for the owner, but that comes later). When you think about it this makes sense. An empty DACL means that it has no ACEs. Since each ACE describes who has what access; no ACEs must mean that nobody is denied AND nobody is granted access. Therefore no one has access. An empty SACL simply means that no auditing takes place on the object.

Okay, one last wrinkle to toss in. It is possible to create a NULL DACL. A NULL DACL is *NOT* the same as an empty DACL. An empty DACL means that you have a chunk of memory allocated that represents a DACL but no ACEs are inside of it. A NULL DACL means that no memory has been allocated for the DACL. (The NULL comes from the fact that since there is no memory allocated for the DACL you supply a NULL pointer whenever a function requires a DACL). A NULL DACL will be interpreted by Win32 as neither granting access to anyone nor denying access to anyone. This confusion is resolved by Win32 implicitly granting FULL access to EVERYONE! (this is why when you create a new net share in Explorer and do not specify any permissions you see, by default, that full access is granted to everyone -- the share has a NULL DACL)

A NULL DACL is the polar opposite of an EMPTY DACL. NULL DACL means everyone has full access. Empty DACL means no one has any access.

A NULL SACL, by the way, will do the same as an empty SACL (no auditing is performed).

If this makes sense thus far then you are going to find the rest of this as pretty easy.

Two more very simple concepts and then on to the meaning of life: owner and group. Most Win32 objects can have an owner and group. An owner is just a SID of who ``owns'' the object. The owner is never denied access to the object, ever. Even if the DACL explicitly denies access to the user, the fact that he is the owner allows him to get to it. An owner can either be a user SID or a group SID. Yes, the Administrators group can be the owner of a file (which means that anyone who is a member of the Administrators group would share in the ownership).

The last simple thing is just like the owner except that it is a group (aka primary group). This does not really mean much to Win32 but it exists for compatibility with POSIX. An object's primary group can be any Global Group. And that is about it. It does not grant anything neat-o or cool. It simply is. Oh yeah, the owner and group are SIDs. They are not ACEs since there are no permissions and/or flags that are associated with the them. Just simply SIDs.

If you take your DACL and SACL and toss in an owner SID and a primary group SID then you have what is known as a Security Descriptor (SD). Ahh, this is it! This is what a Win32::Perms object really is; a security descriptor!

Most Win32 API functions that allow you to create or manipulate objects allow you to supply a security descriptor. Which means all of this madness applies to any securable Win32 object.

When you create a Win32::Perms object you are creating an empty Security Descriptor. This means that it has no owner SID, no primary group SID and it has both a NULL DACL and a NULL SACL.

If you create a Win32::Perms object passing in a path or Win32::Registry object then an empty SD is created which will immediately import the DACL, SACL, owner and group.

A Note about containers

Containers are objects that hold other objects. For example a directory is a container (since it holds file and other directory objects) but a file is not a container. Registry keys are securable containers since they can hold other Registry keys. However there are no securable non-container Registry objects (values could be considered non-container Registry objects except that a value can not be secured). Named Pipes, Network shares and printers are not considered securable containers either.

When you create a Win32::Perms object it will be either a container or a non-container. You can query the Perms object to see if it is a container by calling:

  $PermObject->IsContainer();

You can only secure objects that are the same type as the Win32::Perm object. That is to say, a container Perm object can only secure containers and vise-versa. This is so that a directory Perm object that is securing objects recursively do not accidently secure files with a directory Permission.

Example:

In this example we will be placing read only permissions for cartman and full permissions for administrator on the file c:\test.txt and removing all references for guest from and then explicity denying joel access to the c:\temp directory.

 use Win32::Perms;
    # Create an empty SD
 $File = new Win32::Perms;
    # Create and import at the same time
 $Dir  = new Win32::Perms('c:/temp');
    # One of two ways to add an ACE
 $File->Allow('cartman', READ);
    # The second way to add an ACE
 $File->Add( {Account=>'administrator', Mask=>FULL } );
    # Set the file's permissions
 $File->Set('c:/test.txt');
    # One of three ways to remove an ACE
 $Dir->Remove('guest');
    # Deny access
 $Dir->Deny( 'joel', FULL );
    # Set the directory permissions (no need to specify the
    # path since the object was created with it)
 $Dir->Set();
    # If you are curious about the contents of the SD...
 $Dir->Dump;
    # Now let's clear out all entries...
 $Dir->Remove( -1 );
    # Let's get an array of hashes (each hash is an ACE)
 $File->Get( \@List );
    # Now let's add the list to our directory
 $Dir->Add( @List );
    # Now, for jokes, let's set the new directory permissions
    # No need to specify a path since the object was created with one.
 $Dir->Set();

Accounts:

The Win32::Perms makes use of user, machine and domain accounts. This can be any valid account. For example:

        Joel
        Administrator
        Guest
        SERVER_A$

In addition to accounts, groups are also valid (both local and global groups):

        Managers
        Administrators
        Guests
        Friends

To specify a particular account or group from a particular domain you can prepend the account with a domain name followed by a single backslash:

        ACCOUNTING\Joel
        TECH_GROUP\Administrator
        TECH_GROUP\Domain Admins
        NEW_YORK\Guests

It is often necessary to specify a user account from a particular machine. The machine can be a Primary Domain Controller, Backup Domain Controller, NT Server, or NT Workstation. Since local groups are machine specific (not domain wide as global groups are) it is necessary to specify which machine a local group belongs to.

To specify a particular machine instead of a domain you specify the proper name of the machine (with double backslashes prepending the name) followed by a backslash and the account or group name:

        \\Server_A\Administrators
        \\JOHNS_PC\IUSR_MACHINE
        \\PRIMARY_DC\Guest

Methods:


Appendix A. Path formats.

When specifying a path for the following methods:

        new
        Import
        Set

you can use one of two formats:

        path
        object_type:path

The first format (path) is simply the path of the object such as:

        c:\temp\file.txt
        d:\Program Files\Office
        \\server\share
        \\server\share\dir\file.txt
        \\server\printer
        HKEY_LOCAL_MACHINE\Software
        \\machine\HKEY_LOCAL_MACHINE\Software

The second format (object_type:path) is the path prepended by a object type and colon:

        file:c:\temp\file.txt
        dir:d:\Program Files\Office
        share:\\server\share
        file:\\server\share\dir\file.txt
        printer:\\server\printer
        registry:HKEY_LOCAL_MACHINE\Software
        registry:\\machine\HKEY_LOCAL_MACHINE\Software

Note that file: and dir: are synonyms; either can be used.


SEE ALSO

The Official Win32::Perms Home Page:

  http://www.roth.net/perl/perms/


AUTHOR

Dave Roth ( http://www.roth.net/contact/ )


COPYRIGHT AND LICENSE

Copyright (c) 1998-2002 Dave Roth

Courtesy of Roth Consulting ( http://www.roth.net/ )

This library may be copied or modified only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5.0 source kit.

 Win32::Perms - Manages object permissions for Windows NT