14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin * G. S. Fowler
254887Schin * D. G. Korn
264887Schin * AT&T Bell Laboratories
274887Schin *
284887Schin * shell library support
294887Schin */
304887Schin
314887Schin #include <ast.h>
324887Schin #include <sys/stat.h>
334887Schin
344887Schin /*
354887Schin * return pointer to the full path name of the shell
364887Schin *
374887Schin * SHELL is read from the environment and must start with /
384887Schin *
394887Schin * if set-uid or set-gid then the executable and its containing
404887Schin * directory must not be owned by the real user/group
414887Schin *
424887Schin * root/administrator has its own test
434887Schin *
444887Schin * astconf("SH",NiL,NiL) is returned by default
454887Schin *
464887Schin * NOTE: csh is rejected because the bsh/csh differentiation is
474887Schin * not done for `csh script arg ...'
484887Schin */
494887Schin
504887Schin char*
pathshell(void)514887Schin pathshell(void)
524887Schin {
534887Schin register char* sh;
544887Schin int ru;
554887Schin int eu;
564887Schin int rg;
574887Schin int eg;
584887Schin struct stat st;
594887Schin
604887Schin static char* val;
614887Schin
624887Schin if ((sh = getenv("SHELL")) && *sh == '/' && strmatch(sh, "*/(sh|*[!cC]sh)*([[:digit:]])?(-+([.[:alnum:]]))?(.exe)"))
634887Schin {
644887Schin if (!(ru = getuid()) || !eaccess("/bin", W_OK))
654887Schin {
664887Schin if (stat(sh, &st))
674887Schin goto defshell;
684887Schin if (ru != st.st_uid && !strmatch(sh, "?(/usr)?(/local)/?([ls])bin/?([[:lower:]])sh?(.exe)"))
694887Schin goto defshell;
704887Schin }
714887Schin else
724887Schin {
734887Schin eu = geteuid();
744887Schin rg = getgid();
754887Schin eg = getegid();
764887Schin if (ru != eu || rg != eg)
774887Schin {
784887Schin char* s;
794887Schin char dir[PATH_MAX];
804887Schin
814887Schin s = sh;
824887Schin for (;;)
834887Schin {
844887Schin if (stat(s, &st))
854887Schin goto defshell;
864887Schin if (ru != eu && st.st_uid == ru)
874887Schin goto defshell;
884887Schin if (rg != eg && st.st_gid == rg)
894887Schin goto defshell;
904887Schin if (s != sh)
914887Schin break;
924887Schin if (strlen(s) >= sizeof(dir))
934887Schin goto defshell;
944887Schin strcpy(dir, s);
954887Schin if (!(s = strrchr(dir, '/')))
964887Schin break;
974887Schin *s = 0;
984887Schin s = dir;
994887Schin }
1004887Schin }
1014887Schin }
1024887Schin return sh;
1034887Schin }
1044887Schin defshell:
1054887Schin if (!(sh = val))
1064887Schin {
1074887Schin if (!*(sh = astconf("SH", NiL, NiL)) || *sh != '/' || eaccess(sh, X_OK) || !(sh = strdup(sh)))
1084887Schin sh = "/bin/sh";
1094887Schin val = sh;
1104887Schin }
1114887Schin return sh;
1124887Schin }
113