xref: /onnv-gate/usr/src/lib/libast/common/path/pathshell.c (revision 12068:08a39a083754)
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