xref: /illumos-gate/usr/src/contrib/ast/src/lib/libast/comp/eaccess.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                   Phong Vo <kpv@research.att.com>                    *
20*b30d1939SAndy Fiddaman *                                                                      *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #pragma prototyped
23*b30d1939SAndy Fiddaman /*
24*b30d1939SAndy Fiddaman  * access() euid/egid implementation
25*b30d1939SAndy Fiddaman  */
26*b30d1939SAndy Fiddaman 
27*b30d1939SAndy Fiddaman #include <ast.h>
28*b30d1939SAndy Fiddaman #include <errno.h>
29*b30d1939SAndy Fiddaman #include <ls.h>
30*b30d1939SAndy Fiddaman 
31*b30d1939SAndy Fiddaman #include "FEATURE/eaccess"
32*b30d1939SAndy Fiddaman 
33*b30d1939SAndy Fiddaman #if _lib_eaccess
34*b30d1939SAndy Fiddaman 
35*b30d1939SAndy Fiddaman NoN(eaccess)
36*b30d1939SAndy Fiddaman 
37*b30d1939SAndy Fiddaman #else
38*b30d1939SAndy Fiddaman 
39*b30d1939SAndy Fiddaman #if defined(__EXPORT__)
40*b30d1939SAndy Fiddaman #define extern	__EXPORT__
41*b30d1939SAndy Fiddaman #endif
42*b30d1939SAndy Fiddaman 
43*b30d1939SAndy Fiddaman extern int
44*b30d1939SAndy Fiddaman eaccess(const char* path, register int flags)
45*b30d1939SAndy Fiddaman {
46*b30d1939SAndy Fiddaman #ifdef EFF_ONLY_OK
47*b30d1939SAndy Fiddaman 	return access(path, flags|EFF_ONLY_OK);
48*b30d1939SAndy Fiddaman #else
49*b30d1939SAndy Fiddaman #if _lib_euidaccess
50*b30d1939SAndy Fiddaman 	return euidaccess(path, flags);
51*b30d1939SAndy Fiddaman #else
52*b30d1939SAndy Fiddaman 	register int	mode;
53*b30d1939SAndy Fiddaman 	struct stat	st;
54*b30d1939SAndy Fiddaman 
55*b30d1939SAndy Fiddaman 	static int	init;
56*b30d1939SAndy Fiddaman 	static uid_t	ruid;
57*b30d1939SAndy Fiddaman 	static uid_t	euid;
58*b30d1939SAndy Fiddaman 	static gid_t	rgid;
59*b30d1939SAndy Fiddaman 	static gid_t	egid;
60*b30d1939SAndy Fiddaman 
61*b30d1939SAndy Fiddaman 	if (!init)
62*b30d1939SAndy Fiddaman 	{
63*b30d1939SAndy Fiddaman 		ruid = getuid();
64*b30d1939SAndy Fiddaman 		euid = geteuid();
65*b30d1939SAndy Fiddaman 		rgid = getgid();
66*b30d1939SAndy Fiddaman 		egid = getegid();
67*b30d1939SAndy Fiddaman 		init = (ruid == euid && rgid == egid) ? 1 : -1;
68*b30d1939SAndy Fiddaman 	}
69*b30d1939SAndy Fiddaman 	if (init > 0 || flags == F_OK)
70*b30d1939SAndy Fiddaman 		return access(path, flags);
71*b30d1939SAndy Fiddaman 	if (stat(path, &st))
72*b30d1939SAndy Fiddaman 		return -1;
73*b30d1939SAndy Fiddaman 	mode = 0;
74*b30d1939SAndy Fiddaman 	if (euid == 0)
75*b30d1939SAndy Fiddaman 	{
76*b30d1939SAndy Fiddaman 		if (!S_ISREG(st.st_mode) || !(flags & X_OK) || (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
77*b30d1939SAndy Fiddaman 			return 0;
78*b30d1939SAndy Fiddaman 		goto nope;
79*b30d1939SAndy Fiddaman 	}
80*b30d1939SAndy Fiddaman 	else if (euid == st.st_uid)
81*b30d1939SAndy Fiddaman 	{
82*b30d1939SAndy Fiddaman 		if (flags & R_OK)
83*b30d1939SAndy Fiddaman 			mode |= S_IRUSR;
84*b30d1939SAndy Fiddaman 		if (flags & W_OK)
85*b30d1939SAndy Fiddaman 			mode |= S_IWUSR;
86*b30d1939SAndy Fiddaman 		if (flags & X_OK)
87*b30d1939SAndy Fiddaman 			mode |= S_IXUSR;
88*b30d1939SAndy Fiddaman 	}
89*b30d1939SAndy Fiddaman 	else if (egid == st.st_gid)
90*b30d1939SAndy Fiddaman 	{
91*b30d1939SAndy Fiddaman #if _lib_getgroups
92*b30d1939SAndy Fiddaman 	setgroup:
93*b30d1939SAndy Fiddaman #endif
94*b30d1939SAndy Fiddaman 		if (flags & R_OK)
95*b30d1939SAndy Fiddaman 			mode |= S_IRGRP;
96*b30d1939SAndy Fiddaman 		if (flags & W_OK)
97*b30d1939SAndy Fiddaman 			mode |= S_IWGRP;
98*b30d1939SAndy Fiddaman 		if (flags & X_OK)
99*b30d1939SAndy Fiddaman 			mode |= S_IXGRP;
100*b30d1939SAndy Fiddaman 	}
101*b30d1939SAndy Fiddaman 	else
102*b30d1939SAndy Fiddaman 	{
103*b30d1939SAndy Fiddaman #if _lib_getgroups
104*b30d1939SAndy Fiddaman 		register int	n;
105*b30d1939SAndy Fiddaman 
106*b30d1939SAndy Fiddaman 		static int	ngroups = -2;
107*b30d1939SAndy Fiddaman 		static gid_t*	groups;
108*b30d1939SAndy Fiddaman 
109*b30d1939SAndy Fiddaman 		if (ngroups == -2)
110*b30d1939SAndy Fiddaman 		{
111*b30d1939SAndy Fiddaman 			if ((ngroups = getgroups(0, (gid_t*)0)) <= 0)
112*b30d1939SAndy Fiddaman 				ngroups = NGROUPS_MAX;
113*b30d1939SAndy Fiddaman 			if (!(groups = newof(0, gid_t, ngroups + 1, 0)))
114*b30d1939SAndy Fiddaman 				ngroups = -1;
115*b30d1939SAndy Fiddaman 			else
116*b30d1939SAndy Fiddaman 				ngroups = getgroups(ngroups, groups);
117*b30d1939SAndy Fiddaman 		}
118*b30d1939SAndy Fiddaman 		n = ngroups;
119*b30d1939SAndy Fiddaman 		while (--n >= 0)
120*b30d1939SAndy Fiddaman 			if (groups[n] == st.st_gid)
121*b30d1939SAndy Fiddaman 				goto setgroup;
122*b30d1939SAndy Fiddaman #endif
123*b30d1939SAndy Fiddaman 		if (flags & R_OK)
124*b30d1939SAndy Fiddaman 			mode |= S_IROTH;
125*b30d1939SAndy Fiddaman 		if (flags & W_OK)
126*b30d1939SAndy Fiddaman 			mode |= S_IWOTH;
127*b30d1939SAndy Fiddaman 		if (flags & X_OK)
128*b30d1939SAndy Fiddaman 			mode |= S_IXOTH;
129*b30d1939SAndy Fiddaman 	}
130*b30d1939SAndy Fiddaman 	if ((st.st_mode & mode) == mode)
131*b30d1939SAndy Fiddaman 		return 0;
132*b30d1939SAndy Fiddaman  nope:
133*b30d1939SAndy Fiddaman 	errno = EACCES;
134*b30d1939SAndy Fiddaman 	return -1;
135*b30d1939SAndy Fiddaman #endif
136*b30d1939SAndy Fiddaman #endif
137*b30d1939SAndy Fiddaman }
138*b30d1939SAndy Fiddaman 
139*b30d1939SAndy Fiddaman #endif
140