1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #include <config.h>
24:
25: #include "euidaccess-stat.h"
26:
27: #include <unistd.h>
28:
29: #ifndef F_OK
30: # define F_OK 0
31: # define X_OK 1
32: # define W_OK 2
33: # define R_OK 4
34: #endif
35:
36: #include "group-member.h"
37: #include "stat-macros.h"
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50: bool
51: euidaccess_stat (struct stat const *st, int mode)
52: {
53: uid_t euid;
54: unsigned int granted;
55:
56:
57: if (R_OK == 4 && W_OK == 2 && X_OK == 1 && F_OK == 0)
58: mode &= 7;
59: else
60: mode = ((mode & R_OK ? 4 : 0)
61: + (mode & W_OK ? 2 : 0)
62: + (mode & X_OK ? 1 : 0));
63:
64: if (mode == 0)
65: return true;
66:
67: euid = geteuid ();
68:
69:
70:
71: if (euid == 0 && ((mode & X_OK) == 0
72: || (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
73: return true;
74:
75:
76: if ( S_IRUSR == (4 << 6)
77: && S_IWUSR == (2 << 6)
78: && S_IXUSR == (1 << 6)
79: && S_IRGRP == (4 << 3)
80: && S_IWGRP == (2 << 3)
81: && S_IXGRP == (1 << 3)
82: && S_IROTH == (4 << 0)
83: && S_IWOTH == (2 << 0)
84: && S_IXOTH == (1 << 0))
85: granted = st->st_mode;
86: else
87: granted = ( (st->st_mode & S_IRUSR ? 4 << 6 : 0)
88: + (st->st_mode & S_IWUSR ? 2 << 6 : 0)
89: + (st->st_mode & S_IXUSR ? 1 << 6 : 0)
90: + (st->st_mode & S_IRGRP ? 4 << 3 : 0)
91: + (st->st_mode & S_IWGRP ? 2 << 3 : 0)
92: + (st->st_mode & S_IXGRP ? 1 << 3 : 0)
93: + (st->st_mode & S_IROTH ? 4 << 0 : 0)
94: + (st->st_mode & S_IWOTH ? 2 << 0 : 0)
95: + (st->st_mode & S_IXOTH ? 1 << 0 : 0));
96:
97: if (euid == st->st_uid)
98: granted >>= 6;
99: else
100: {
101: gid_t egid = getegid ();
102: if (egid == st->st_gid || group_member (st->st_gid))
103: granted >>= 3;
104: }
105:
106: if ((mode & ~granted) == 0)
107: return true;
108:
109: return false;
110: }
111:
112:
113: #ifdef TEST
114: # include <errno.h>
115: # include <stdio.h>
116: # include <stdlib.h>
117:
118: # include "error.h"
119: # define _(msg) msg
120:
121: char *program_name;
122:
123: int
124: main (int argc, char **argv)
125: {
126: char *file;
127: int mode;
128: bool ok;
129: struct stat st;
130:
131: program_name = argv[0];
132: if (argc < 3)
133: abort ();
134: file = argv[1];
135: mode = atoi (argv[2]);
136: if (lstat (file, &st) != 0)
137: error (EXIT_FAILURE, errno, _("cannot stat %s"), file);
138:
139: ok = euidaccess_stat (&st, mode);
140: printf ("%s: %s\n", file, ok ? "y" : "n");
141: exit (0);
142: }
143: #endif