Setting Up File Tag Permissions in Lasso Professional 8 on Mac OS X and Linux

Introduction

This article contains instructions on how to set up file tag permissions in Lasso Professional 8.1+ on Mac OS X and Linux. Steps that are not specific to Mac OS X may be useful for other operating systems, and even those steps may be adapted. In other words the process to work with the file tags in Lasso is pretty much the same regardless of the operating system, although there are minor differences in the details of OS-specific steps. For complete information, please consult the Lasso Professional Language Guide and Mac OS X Tips that are included in the following directory.

1
~/Applications/Lasso Professional 8/Documentation/

Instructions

Lasso Server Administration

Visit http://myserver.com/ServerAdmin.LassoApp.

Step 1 - Enable File tag category

  • Navigate to Setup > Server > Tags.
  • Enable the File tag category.

Step 2 - Set File Paths

For this step, you need to determine where you want to write the files. On Mac OS X, fully qualified paths begin with ///. For web root paths, start the path with just /. Mounted Volumes begin with ///Volumes/.

Navigate to the location for your Lasso version:

  • 8.1: Setup > Sites > File Paths
  • 8.5+: Sites > Sites > File Paths

Add a Path to the appropriate Site. Examples:

1
2
3
///Library/WebServer/Documents/webroot/pathname/
/webroot/pathname/
///Volumes/Library/WebServer/Documents/webroot/pathname/

There is also an Upload Test in the right panel. Upload a small file to verify that Lasso can upload files and to which temporary directory.

When uploading files, the file is first written to this temporary directory, usually /tmp on Linux or /var/tmp on Mac. To perform file uploads in your web application, you will need to write some Lasso code to copy the uploaded file to its ultimate destination (see my code sample below). The uploaded file is automatically deleted for you, so using a file_copy is preferred over a file_move.

Lasso Site Administration

Visit http://myserver.com/SiteAdmin.LassoApp.

Step 3 - Add file extensions

  • Navigate to Setup > Site > File Extensions.
  • Under File Tags Settings, Add Extension of the file that you want to manipulate.
  • Click Refresh to make sure the settings take hold.

Step 4 - Lasso Security Groups

  • Navigate to Setup > Security > Groups.
  • Create or use an existing group that will have or already has permissions to work on files.
  • If the group does not have status Enabled, click the group name, and enable it.

Step 5 - Lasso Security Users

  • Navigate to Setup > Security > Users.
  • Add a User to the group for working on files, or ensure that there is a user in the group.
  • Give the user a username and password, enable it, and add it to the group. Remember the username and password for later on when you need to use an inline to write files.
  • Click Refresh to make sure the settings take hold.

Step 6 - Lasso Security Filepaths

  • Navigate to Setup > Security > Files.
  • Select group, click on desired filepath (the one you added in Lasso Server Admin), then assign appropriate file permissions.
  • Click Refresh to make sure the settings take hold.
  • Either this group or the AnyUser group must be assigned permissions to work in the temporary files directory ///var/tmp.

Step 7 - Lasso Security Tags

  • Navigate to Setup > Security > Tags.
  • Select Group, Set Group Permissions for the File Tag to Allow.

Caution!

Some users have reported that occasionally the permissions, users and groups they have just set don't take hold. Usually clicking Refresh after changing a setting will make the settings take hold. If that fails, restart Lasso so that it will reload the permissions tables.

Mac OS X and Linux Ownership and Permissions

Step 8 - Managing Operating System Users and Groups

You must set at least one of the owner, group or other user permissions on Mac OS X such that Lasso can perform file tag operations on the directory or file. You must set permissions on the file as well as its containing directory.

Caution!

The following discussion applies to Mac OS X, and begins with 10.4 then moves on to 10.5+, and finally on to Linux.

Background

The user lasso is a member of the group staff. A common setup that will allow Lasso to work on files and directories is where the owner of the file is your username and the group is staff. There are other situations where this will not work, and we will cover those next. Example:

1
2
3
4
5
stevepiercy$ ls -al
total 1080
drwxr-xr-x   71 stevepie  staff   2414 Feb 28 09:32 .
drwxr-xr-x    6 stevepie  staff    204 Jun  8  2005 ..
drwxrwxr-x   16 stevepie  staff    544 Feb 27 22:18 uploads

Here the owner is stevepie and the group is staff. Lasso can operate on the directory uploads because the user lasso is a member of the group staff, and the group staff has Read, Write and eXecute permissions on uploads.

Generally, Lasso requires read, write and execute (rwx) permissions on directories and only read and write (rw-) permissions on files.

The above example might not work in situations where your username is the owner, the web server (apache) is the group and lasso is left out of the picture. Here the problem is that your username must be the owner of the directory in order to FTP files into the directory, and the group apache must be the group of the directory in order to process or serve files within the directory, yet the user or group lasso is neither the owner nor a member of the group.

Operating System Users and Groups

To fix this dilemma, do the following. Mac OS X and Linux have slightly different group structures, but the process is essentially the same.

Edit the file /etc/group.

The file consists of newline separated ASCII records, one line per group, containing four colon-separated (:) fields. These fields are as follows:

1
group_name:password:group_id:members_separated_by_commas
Mac OS X 10.4 and older

Add lasso to the apache group. The group name is typically apache or www. Look for a line in the file like so.

1
apache:*:48:

Change that line by appending the user lasso.

1
apache:*:48:lasso
Mac OS X 10.5+

For 10.5 and later, there are a few differences. 10.5 introduced Access Control Lists (ACLs pronounced ăkˈəls) and the above procedures must be modified as follows.

When you create a new file manually, check its group. On my system the group is admin instead of staff. Therefore I need to add the user lasso to the group admin. The procedure to do so is different from 10.4 and earlier.

1
sudo dscl . -append /Groups/admin GroupMembership lasso
Linux

Add lasso to your group. Look for a line in the file like so.

1
myuser:x:500:

Change that line by appending the user lasso.

1
myuser:x:500:lasso

Important

If you have modified your operating system's groups, then you must restart Lasso Server (just the Lasso service, not the entire server) in order for Lasso to recognize the new users in groups.

Step 9 - Set directory and file permissions

There are multiple wasy to set directory and file permissions on the file system so that Lasso can operate on files. Here are two methods. Adapt to your preference.

Method 1 - Specific Directory and File

This method grants the least privilege necessary, which is a good security practice. It takes a couple more steps than the next method.

Now set the permissions so Lasso can operate on a specific file.

  • Change the group of the directory to staff, admin, or lasso depending on your operating system, and grant read, write and execute (rwx) permissions to the group.
  • Change the group of the file to staff, admin, or lasso depending on your operating system, and grant read and write (rw-) permissions to the group.

The following example modifies a file named log.txt inside a directory named mydirectory in the web site root.

Mac OS X 10.4 and older
1
2
3
4
5
cd /Library/WebServer/Documents/path-to-mysite
sudo chgrp staff mydirectory
sudo chmod g+rwx mydirectory
sudo chown staff mydirectory/log.txt
sudo chmod g+rw  mydirectory/log.txt
Mac OS X 10.5+
1
2
3
4
5
cd /Library/WebServer/Documents/path-to-mysite
sudo chgrp admin mydirectory
sudo chmod g+rwx mydirectory
sudo chown admin mydirectory/log.txt
sudo chmod g+rw  mydirectory/log.txt
Linux
1
2
3
4
5
cd /home/user/path-to-mysite
sudo chgrp lasso mydirectory
sudo chmod g+rwx mydirectory
sudo chown lasso mydirectory/log.txt
sudo chmod g+rw  mydirectory/log.txt
Method 2 - Recursive

This method is a sledgehammer, but it takes only a few steps. This method grants execute permission to files, so be certain you want that.

Now set the permissions so Lasso can operate in a directory and on files in that directory.

  • Change the group of the directory to staff, admin, or lasso depending on your operating system, and grant read, write and execute (rwx) permissions to the group.

The following example modifies a directory named mydirectory in the web site root. The -R (recursive) parameter ensures that all files in the directory and sub-directories can be accessed by Lasso.

Mac OS X 10.4 and older
1
2
3
cd /Library/WebServer/Documents/path-to-mysite
sudo chgrp -R staff mydirectory
sudo chmod -R g+rwx mydirectory
Mac OS X 10.5+
1
2
3
cd /Library/WebServer/Documents/path-to-mysite
sudo chgrp -R admin mydirectory
sudo chmod -R g+rwx mydirectory
Linux
1
2
3
cd /home/user/path-to-mysite
sudo chgrp -R lasso mydirectory
sudo chmod -R g+rwx mydirectory

Note

See the Mac OS X Tips PDF in your Lasso Professional application folder, under Documentation, for more specific details and other examples.

Lasso Code

Step 10 - Code

Finally use the username and password for the Lasso group that can use the file tags in an inline, like so.

1
2
3
inline(-username='XXXXXX', -password='XXXXXX');
    ...file tag stuff...
/inline;

Code Samples

The following code samples may be used to test whether you have set up file permissions correctly. If you get an error, then restart Lasso and try again. If you still get an error, go through this guide from the top.

File Exists

The following sample code can be used to test for the existence of a file, and therefore test for correct file permissions as well. Put it in a file, modify the username and password in the inline as required, then load it in a web browser.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>File Exists (and List Directory)</title>
</head>
<body>
[inline(-username='XXXXXX',-password='XXXXXX',-nothing)]
    <h2>Current authenticated groups:</h2>
    <p>[admin_currentgroups]</p>
    <h2>Does this file exist?</h2>
    <p>[file_exists(response_filepath) ? 'I Lasso, therefore I am.' | 'Existence indeterminable.']</p>
    [
    file_currenterror(-errorcode) != 0
        ? '<h2>File Error:</h2><p>' + file_currenterror(-errorcode) + ': ' + file_currenterror + '</p>';
    error_code != 0
        ? '<h2>Normal Error:</h2><p>' + error_code + ': ' + error_msg + '</p>';
    ]
[/inline]
</body>
</html>

File Create and Write

The following sample code can be used to create and write a file to test file permissions. Put it in a file, modify the username and password as required, as well as the other variables, then load it in a web browser. If successful, you will see No error and a valid link.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>File Create and Write Test</title>
</head>
<body>
[
var(
    'auth'          = array(
        -username = 'XXXXXX', // configure this item
        -password = 'XXXXXX' // configure this item
        ),
    'destpath'              = response_path, // config this item
    'filename'              = 'filename.txt',
    'file_content'  = 'this is some test content.'
);
inline($auth);
    file_create(($destpath + $filename), -fileoverwrite);
    '<p>file_create error: ' + file_currenterror + '</p>';
    file_write(($destpath + $filename), $file_content, -fileoverwrite);
    '<p>file_write error: ' + file_currenterror + '</p>';
/inline;
]
<p><a href="[($destpath + $filename)]">View your file's contents</a>.</p>
</body>
</html>

File Upload

The following sample code can be used to test whether a file uploads and whether you have followed the directions above correctly. Put it in a file, modify the username, password and destination as required, then load it in a web browser.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>File Upload</title>
</head>
<body>
[
var(
    'auth'          = array(
        -username = 'XXXXXX', // configure this item
        -password = 'XXXXXX' // configure this item
        ),
    'dest'          = response_path, // configure this item
    'i'                     = null,
    'errors'        = array,
    'this_file'     = string,
    'upfiles'       = array,
    'files'         = file_uploads,
    'uploaded'      = false
    );

inline($auth, action_params);
    if($files->size);
        iterate($files,$i);
            // reset any Lasso errors
            error_msg = '';
            error_code = 0;
            // Windows developers may need to alter the following statement
            // due to filepath delimiters being '\'.
            $this_file = $i->find('upload.realname')->split('/')->last->split('\\')->last;
            // file_copy is the preferred method to copy a file from the
            // tmp directory.  file_move will fail because the lasso user
            // cannot be assigned permission to write to the tmp directory.
            // Other options include os_process with the shell tag from
            // TagSwap, passthru by Execuchoice, or file_streamcopy for
            // files that exceed the amount of available RAM.
            file_copy(
                $i->find('upload.name'),
                ($dest + $this_file));
            if(file_currenterror(-errorcode) != 0);
                $errors->insert('There was an error uploading your file: ('
                    + file_currenterror(-errorcode)
                    + ') ' + file_currenterror);
            else;
                $uploaded = true;
                $upfiles->insert($dest + $this_file);
            /if;
        /iterate;
    else;
        $errors->insert('No file was uploaded.');
    /if;
/inline;
]
[if($errors->size && action_param('submit'))]
    <p>The following error(s) occurred:</p>
    <ul>[iterate($errors, $i)]
        <li class="error">[$i]</li>[/iterate]
    </ul>
[/if]
[if(!$uploaded)]
    <h2>Select File</h2>
    <form action="[response_filepath]" method="post" enctype="multipart/form-data">
    <p><input type="file" name="filename1" size="30"></p>
    <p><input type="file" name="filename2" size="30"></p>
    <p><input type="submit" name="submit" value="Send File" class="submit"></p>
    </form>
[else]
    <h2>File Upload Successful</h2>
    <p>Download uploaded file.</p>
    <ul>
    [iterate($upfiles,$i)]
        <li><a href="[($i)]">[$i]</a></li>
    [/iterate]
    </ul>
    <p><a href="[response_filepath]">Upload another file</a>.</p>
[/if]
</body>
</html>

Troubleshooting

There was an error uploading your file: (-1) Unknown error 4294967295

This error message appears on CentOS when attempting to upload a file, and the file cannot be copied from the tmp directory to the destination because there is an OS permissions mismatch between apache, lasso and the owner user. See discussion in Steps 8 and 9 for details and a fix.

Uploaded file type cannot be determined

The file_uploads array's upload.type parameter relies upon the original filename extension to arbitrarily assign a file type. For example .jpeg is assigned a file type of jpeg. However, if the user uploads a file with a file extension that does not match its file type, or omits the file extension, then this method returns undesirable results.

To compensate, on Mac OS X and CentOS, the command line utility file can be used to reliably determine the file type.

1
2
3
file /path/to/file.jpg
=>
/path/to/file.jpg JPEG image data, JFIF standard 1.01

Use os_process or os_process with shell to run the command line utility through Lasso.

The result can then be parsed to determine how to properly process the uploaded file.

For security, you should always confirm the actual file type using a MIME sniffer, and if possible, run a virus check against it, and for images, convert it to remove any bad things (like stripping the image meta information).

Goodbye NetInfo, Hello Directory Services

With all versions of Mac OS X previous to Leopard (10.4-), it was relatively easy to use NetInfo to add the user lasso to the group admin in order to allow Lasso to operate on files on Mac OS X. With Leopard (10.5), NetInfo is gone. In its place are several command line utilities that allow you to work with its replacement Directory Services, all of which start with ds.

Replace (foo) with "foo" or keystroke when typing the actual command.

1
ds(tab)(tab)

A list of commands will appear. Use man (utility) to read details of what each does.

In Leopard use the commands dscl and dsmemberutil to perform the following tasks.

To check whether a given user is a member of a given group:

1
dsmemberutil checkmembership -U (user) -G (group)

To see who is in a given group:

1
dscl . -read /Groups/(group)

...and look for the attribute GroupMembership.

To add an existing user to an existing group:

1
dscl / -append /Groups/(group) GroupMembership (user)

To add the user lasso to the group admin:

1
dscl / -append /Groups/admin GroupMembership lasso

Permissive management

Since moving to Leopard, I just wanted to get file stuff to work with Lasso and Mac OS X, so until now I always changed permissions on the parent directory to 777.

1
chmod 777 /path/to/webroot

That's fine on a development environment where there is no concern for file permissions, but it may be cause for concern in a shared hosting environment because other users may be able to access those files.

File permissions changes not working as expected

I recently spent several hours troubleshooting a problem where my ISP and I were using the exact same code samples above (except for username and password) on two different sites, and every single setting enumerated above was identical. One site was able to write and upload files, but the other was not.

Both sites had file perms of 775 on the parent directory to start. When we toggled file perms to 777, then the non-working site worked, but the potential security issue was not acceptable. We at least required 775.

We tried a Lasso Site restart, but the settings would not take hold. Ultimately we had to resort to restarting Lasso Service in order for the settings changes to take hold. Yes, that is exceptionally lame, but it is what it is.

file_write fails

A common frustration comes from the fact that file_write works only on existing files. If you try to use file_write on a file that does not exist, the operation will fail. You must first create the file, either through the Terminal or using Lasso code, like so.

1
file_create: 'file.txt';

File path rules of precedence

There are some undocumented rules of precedence concerning filepaths in Lasso Site Admin. I searched throughout the Lasso Language Guide and the Setup Guide, and found only two references to security that come close, but lack specific information. Please see the chapter "Setting up Security", sections "How Lasso Checks User Security" and "File Permissions".

To provide some assistance to the reader, here is the situation.

There is this default files setting:

1
/ (Read Only) Allow: Read, Inspect

And you have set up two additional filepaths:

1
2
/
///absolute/path/to/uploads/

Under Setup > Security > Files:

1
/

has permissions None.

1
///absolute/path/to/uploads/

has permissions Inspect, Read, Create, Write, Move, Copy, Delete, Any Extension.

File uploads will fail (or require superuser authentication). But change the former's filepath permissions to match the latter's, and file uploads works.

WordPress and .htaccess triggers Lasso permission errors

The .htaccess file commonly used by WordPress can interfere with file_ and pdf_ tags when writing files. To avoid this issue edit the .htaccess file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# BEGIN WordPress
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_URI} !^.*\.LassoApp$                  # add this
    RewriteCond %{REQUEST_URI} !^/file-write-destination/.*$    # add this
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Creating files through an NFS client do not have write permission

From a tip by Fletcher Sandbeck.

On a CentOS 6 cluster with Lasso 8.6 using NFS for a shared web root, files created by an NFS client have read-only permission so writing to them fails. They remain zero bytes and you will get a file permission error. Creating files on the local filesystem works fine.

To remedy the issue, place a file_chmod before the file_write. Since the directory is owned by Lasso it can modify the permissions and the write succeeds.

1
2
3
file_create(#path);
file_chmod(#path, '664');
file_write(#path, #data);

The parent directory would need to have 775 permission.

In the same thread, Ke Carlton suggest that the user id must exist on the NFS host.

Did you like this article? Please send me a Gratipay, as little as 25¢ per week!

Updates, suggestions and comments regarding this article may be sent to Steve Piercy, web@stevepiercy.com or comment using Disqus.


Written by Steve Piercy in Lasso on Wed, Feb 28, 2007.
Last modified: Tue, Dec 2, 2014
Tags: Lasso, file permissions, Linux, Mac OS X

Comments

comments powered by Disqus