LCOV - code coverage report
Current view: top level - lib - euidaccess-stat.c (source / functions) Hit Total Coverage
Test: coreutils.info Lines: 0 17 0.0 %
Date: 2018-01-30 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /* euidaccess-stat -- check if effective user id can access lstat'd file
       2             :    This function is probably useful only for choosing whether to issue
       3             :    a prompt in an implementation of POSIX-specified rm.
       4             : 
       5             :    Copyright (C) 2005, 2006 Free Software Foundation, Inc.
       6             : 
       7             :    This program is free software: you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation, either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      19             : 
      20             : /* Adapted for use in GNU remove.c by Jim Meyering.  */
      21             : 
      22             : #include <config.h>
      23             : 
      24             : #include "euidaccess-stat.h"
      25             : 
      26             : #include <unistd.h>
      27             : 
      28             : #ifndef F_OK
      29             : # define F_OK 0
      30             : # define X_OK 1
      31             : # define W_OK 2
      32             : # define R_OK 4
      33             : #endif
      34             : 
      35             : #include "group-member.h"
      36             : #include "stat-macros.h"
      37             : 
      38             : /* Return true if the current user has permission of type MODE
      39             :    on the file from which stat buffer *ST was obtained, ignoring
      40             :    ACLs, attributes, `read-only'ness, etc...
      41             :    Otherwise, return false.
      42             : 
      43             :    Like the reentrant version of euidaccess, but starting with
      44             :    a stat buffer rather than a file name.  Hence, this function
      45             :    never calls access or accessx, and doesn't take into account
      46             :    whether the file has ACLs or other attributes, or resides on
      47             :    a read-only file system.  */
      48             : 
      49             : bool
      50           0 : euidaccess_stat (struct stat const *st, int mode)
      51             : {
      52             :   uid_t euid;
      53             :   unsigned int granted;
      54             : 
      55             :   /* Convert the mode to traditional form, clearing any bogus bits.  */
      56             :   if (R_OK == 4 && W_OK == 2 && X_OK == 1 && F_OK == 0)
      57           0 :     mode &= 7;
      58             :   else
      59             :     mode = ((mode & R_OK ? 4 : 0)
      60             :             + (mode & W_OK ? 2 : 0)
      61             :             + (mode & X_OK ? 1 : 0));
      62             : 
      63           0 :   if (mode == 0)
      64           0 :     return true;                /* The file exists.  */
      65             : 
      66           0 :   euid = geteuid ();
      67             : 
      68             :   /* The super-user can read and write any file, and execute any file
      69             :      that anyone can execute.  */
      70           0 :   if (euid == 0 && ((mode & X_OK) == 0
      71           0 :                     || (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
      72           0 :     return true;
      73             : 
      74             :   /* Convert the file's permission bits to traditional form.  */
      75             :   if (   S_IRUSR == (4 << 6)
      76             :       && S_IWUSR == (2 << 6)
      77             :       && S_IXUSR == (1 << 6)
      78             :       && S_IRGRP == (4 << 3)
      79             :       && S_IWGRP == (2 << 3)
      80             :       && S_IXGRP == (1 << 3)
      81             :       && S_IROTH == (4 << 0)
      82             :       && S_IWOTH == (2 << 0)
      83             :       && S_IXOTH == (1 << 0))
      84           0 :     granted = st->st_mode;
      85             :   else
      86             :     granted = (  (st->st_mode & S_IRUSR ? 4 << 6 : 0)
      87             :                + (st->st_mode & S_IWUSR ? 2 << 6 : 0)
      88             :                + (st->st_mode & S_IXUSR ? 1 << 6 : 0)
      89             :                + (st->st_mode & S_IRGRP ? 4 << 3 : 0)
      90             :                + (st->st_mode & S_IWGRP ? 2 << 3 : 0)
      91             :                + (st->st_mode & S_IXGRP ? 1 << 3 : 0)
      92             :                + (st->st_mode & S_IROTH ? 4 << 0 : 0)
      93             :                + (st->st_mode & S_IWOTH ? 2 << 0 : 0)
      94             :                + (st->st_mode & S_IXOTH ? 1 << 0 : 0));
      95             : 
      96           0 :   if (euid == st->st_uid)
      97           0 :     granted >>= 6;
      98             :   else
      99             :     {
     100           0 :       gid_t egid = getegid ();
     101           0 :       if (egid == st->st_gid || group_member (st->st_gid))
     102           0 :         granted >>= 3;
     103             :     }
     104             : 
     105           0 :   if ((mode & ~granted) == 0)
     106           0 :     return true;
     107             : 
     108           0 :   return false;
     109             : }
     110             : 
     111             : 
     112             : #ifdef TEST
     113             : # include <errno.h>
     114             : # include <stdio.h>
     115             : # include <stdlib.h>
     116             : 
     117             : # include "error.h"
     118             : # define _(msg) msg
     119             : 
     120             : char *program_name;
     121             : 
     122             : int
     123             : main (int argc, char **argv)
     124             : {
     125             :   char *file;
     126             :   int mode;
     127             :   bool ok;
     128             :   struct stat st;
     129             : 
     130             :   program_name = argv[0];
     131             :   if (argc < 3)
     132             :     abort ();
     133             :   file = argv[1];
     134             :   mode = atoi (argv[2]);
     135             :   if (lstat (file, &st) != 0)
     136             :     error (EXIT_FAILURE, errno, _("cannot stat %s"), file);
     137             : 
     138             :   ok = euidaccess_stat (&st, mode);
     139             :   printf ("%s: %s\n", file, ok ? "y" : "n");
     140             :   exit (0);
     141             : }
     142             : #endif

Generated by: LCOV version 1.10