1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                  David Korn <dgk@research.att.com>                   *
19*                   Phong Vo <kpv@research.att.com>                    *
20*                                                                      *
21***********************************************************************/
22#pragma prototyped
23/*
24 * G. S. Fowler
25 * D. G. Korn
26 * AT&T Bell Laboratories
27 *
28 * shell library support
29 */
30
31#include <ast.h>
32#include <sys/stat.h>
33
34/*
35 * return pointer to the full path name of the shell
36 *
37 * SHELL is read from the environment and must start with /
38 *
39 * if set-uid or set-gid then the executable and its containing
40 * directory must not be owned by the real user/group
41 *
42 * root/administrator has its own test
43 *
44 * astconf("SH",NiL,NiL) is returned by default
45 *
46 * NOTE: csh is rejected because the bsh/csh differentiation is
47 *       not done for `csh script arg ...'
48 */
49
50char*
51pathshell(void)
52{
53	register char*	sh;
54	int		ru;
55	int		eu;
56	int		rg;
57	int		eg;
58	struct stat	st;
59
60	static char*	val;
61
62	if ((sh = getenv("SHELL")) && *sh == '/' && strmatch(sh, "*/(sh|*[!cC]sh)*([[:digit:]])?(-+([.[:alnum:]]))?(.exe)"))
63	{
64		if (!(ru = getuid()) || !eaccess("/bin", W_OK))
65		{
66			if (stat(sh, &st))
67				goto defshell;
68			if (ru != st.st_uid && !strmatch(sh, "?(/usr)?(/local)/?([ls])bin/?([[:lower:]])sh?(.exe)"))
69				goto defshell;
70		}
71		else
72		{
73			eu = geteuid();
74			rg = getgid();
75			eg = getegid();
76			if (ru != eu || rg != eg)
77			{
78				char*	s;
79				char	dir[PATH_MAX];
80
81				s = sh;
82				for (;;)
83				{
84					if (stat(s, &st))
85						goto defshell;
86					if (ru != eu && st.st_uid == ru)
87						goto defshell;
88					if (rg != eg && st.st_gid == rg)
89						goto defshell;
90					if (s != sh)
91						break;
92					if (strlen(s) >= sizeof(dir))
93						goto defshell;
94					strcpy(dir, s);
95					if (!(s = strrchr(dir, '/')))
96						break;
97					*s = 0;
98					s = dir;
99				}
100			}
101		}
102		return sh;
103	}
104 defshell:
105	if (!(sh = val))
106	{
107		if (!*(sh = astconf("SH", NiL, NiL)) || *sh != '/' || eaccess(sh, X_OK) || !(sh = strdup(sh)))
108			sh = "/bin/sh";
109		val = sh;
110	}
111	return sh;
112}
113