File Safety Functions

From Mailutils
Jump to navigationJump to search

Functions for running file safety checks are implemented in libmailutils. The corresponding prototypes and constants are declared in the header mailutils/util.h[1].

mu_file_safety_check

int mu_file_safety_check (const char *filename, 
                          int mode,
			  uid_t uid,
			  mu_list_t idlist);

The function mu_file_safety_check checks whether the file filename satisfies safety checks described by the mode and uid arguments.

Its arguments are:

filename
Name of the file to check.
mode
A bitmap specifying the checks to perform. It can be constructed as a bitwise OR of one or more of the following flags, corresponding to the main safety checks:
MU_FILE_SAFETY_OWNER_MISMATCH
Check whether the file owner UID equals to the uid argument.
MU_FILE_SAFETY_WORLD_WRITABLE
Fail if the file is world writable (awrfil)
MU_FILE_SAFETY_GROUP_WRITABLE
Fail if the file is group writable (gwrfil)
MU_FILE_SAFETY_LINKED_WRDIR
Fail if the file is a symbolic link located in a (world- or group-) writable directory (linkwrdir)
MU_FILE_SAFETY_DIR_IWGRP
Fail if the file is located in a group-writable directory (gwrdir)
MU_FILE_SAFETY_DIR_IWOTH
Fail if the file is located in a world-writable directory (awrdir)
MU_FILE_SAFETY_WORLD_READABLE
Fail if the file is world readable (awrfil)
MU_FILE_SAFETY_GROUP_READABLE
Fail if the file is group readable (grdfil)
Additionally, the following two defines are provided:
MU_FILE_SAFETY_ALL
All the above checks
MU_FILE_SAFETY_NONE
No checks
uid
UID the file should be owned by, if the MU_FILE_SAFETY_OWNER_MISMATCH mode is specified.
idlist
A list used to avoid checking the same file twice. It is useful if mu_file_safety_check is to be called several times. At the first call to the function, this argument should contain a newly created list. The function uses this list to keep record of the device and inode numbers of processed files. If mu_file_safety_check determines that the file it is about to check is already entered in this list, it will immediately return MU_ERR_EXISTS.
If this is not needed, this argument should be NULL.

The mu_file_safety_check returns 0 if the file passes all checks, or one of the following error codes otherwise:

MU_ERR_PERM_OWNER_MISMATCH
File owner does not match the requested UID.
MU_ERR_PERM_WORLD_WRITABLE
File is world writable
MU_ERR_PERM_GROUP_WRITABLE
File is group writable
MU_ERR_PERM_LINKED_WRDIR
Linked file in a writable directory
MU_ERR_PERM_DIR_IWGRP
File resides in group writable directory
MU_ERR_PERM_DIR_IWOTH
File resides in world writable directory
MU_ERR_PERM_WORLD_READABLE
File is world readable
MU_ERR_PERM_GROUP_READABLE
File is group readable
MU_ERR_EXISTS
The file has already been checked before (see the description of the idlist argument, above).

mu_file_safety_name_to_code

int mu_file_safety_name_to_code (const char *name, int *pcode);

This function converts the symbolic safety check name name to the corresponding MU_FILE_SAFETY constant.

If the conversion succeeds, the function stores the result in the memory location pointed to by the pcode argument and returns 0. If name does not match any safety check name, the function returns MU_ERR_NOENT.

mu_file_safety_name_to_error

int mu_file_safety_name_to_error (const char *name, int *pcode);

This function converts the symbolic safety check name name to the corresponding MU_ERR_PERM error code.

If the conversion succeeds, the function stores the result in the memory location pointed to by the pcode argument and returns 0. If name does not match any safety check name, the function returns MU_ERR_NOENT.

Safety Checks, Modes and Error Codes

The following table summarizes the available safety checks and their corresponding mode and error codes:

Check name Mode Error code
N/A MU_FILE_SAFETY_OWNER_MISMATCH MU_ERR_PERM_OWNER_MISMATCH
awrfil MU_FILE_SAFETY_WORLD_WRITABLE MU_ERR_PERM_WORLD_WRITABLE
gwrfil MU_FILE_SAFETY_GROUP_WRITABLE MU_ERR_PERM_GROUP_WRITABLE
linkwrdir MU_FILE_SAFETY_LINKED_WRDIR MU_ERR_PERM_LINKED_WRDIR
awrdir MU_FILE_SAFETY_DIR_IWGRP MU_ERR_PERM_DIR_IWGRP
gwrdir MU_FILE_SAFETY_DIR_IWOTH MU_ERR_PERM_DIR_IWOTH
ardfil MU_FILE_SAFETY_WORLD_READABLE MU_ERR_PERM_WORLD_READABLE
grdfil MU_FILE_SAFETY_GROUP_READABLE MU_ERR_PERM_GROUP_READABLE

Example

The following example implements a utility which applies the requested safety checks to a set of files. Both check modes and file names are supplied in the command line and can be interspersed. Each check mode begins with a plus sign, in which case the corresponding check is enabled, or with a minus sign in which case it is disabled.

 1#include <stdio.h>
 2#include <stdlib.h>
 3#include <unistd.h>
 4#include <mailutils/types.h>
 5#include <mailutils/error.h>
 6#include <mailutils/errno.h>
 7#include <mailutils/util.h>
 8
 9int
10main (int argc, char **argv)
11{
12  int i;
13  int mode = MU_FILE_SAFETY_OWNER_MISMATCH, rc, m;
14  mu_list_t idlist;
15  uid_t uid;
16
17  if (argc == 1)
18    {
19      mu_error ("usage: %s [+-]mode... file...", argv[0]);
20      exit (1);
21    }
22
23  rc = mu_list_create (&idlist);
24  if (rc)
25    {
26      mu_error ("mu_list_create: %s", mu_strerror (rc));
27      exit (1);
28    }
29  uid = getuid ();
30
31  for (i = 1; i < argc; i++)
32    {
33      if (argv[i][0] == '-' || argv[i][0] == '+')
34        {
35          rc = mu_file_safety_name_to_code (argv[i] + 1, &m);
36          if (rc)
37            {
38              mu_error ("%s: %s", argv[i], mu_strerror (rc));
39              exit (1);
40            }
41          if (argv[i][0] == '-')
42            mode &= ~m;
43          else
44            mode |= m;
45        }
46      else
47        {
48          rc = mu_file_safety_check (argv[i], mode, uid, idlist);
49          printf ("%s: %s\n", argv[i], mu_strerror (rc));
50        }
51    }
52  exit (0);
53}

Notes

See also