/***********************************************************************1* *2* This software is part of the ast package *3* Copyright (c) 1985-2011 AT&T Intellectual Property *4* and is licensed under the *5* Eclipse Public License, Version 1.0 *6* by AT&T Intellectual Property *7* *8* A copy of the License is available at *9* http://www.eclipse.org/org/documents/epl-v10.html *10* (with md5 checksum b35adb5213ca9657e911e9befb180842) *11* *12* Information and Software Systems Research *13* AT&T Research *14* Florham Park NJ *15* *16* Glenn Fowler <[email protected]> *17* David Korn <[email protected]> *18* Phong Vo <[email protected]> *19* *20***********************************************************************/21#pragma prototyped22/*23* G. S. Fowler24* D. G. Korn25* AT&T Bell Laboratories26*27* shell library support28*/2930#include <ast.h>31#include <sys/stat.h>3233/*34* return pointer to the full path name of the shell35*36* SHELL is read from the environment and must start with /37*38* if set-uid or set-gid then the executable and its containing39* directory must not be owned by the real user/group40*41* root/administrator has its own test42*43* astconf("SH",NiL,NiL) is returned by default44*45* NOTE: csh is rejected because the bsh/csh differentiation is46* not done for `csh script arg ...'47*/4849char*50pathshell(void)51{52register char* sh;53int ru;54int eu;55int rg;56int eg;57struct stat st;5859static char* val;6061if ((sh = getenv("SHELL")) && *sh == '/' && strmatch(sh, "*/(sh|*[!cC]sh)*([[:digit:]])?(-+([.[:alnum:]]))?(.exe)"))62{63if (!(ru = getuid()) || !eaccess("/bin", W_OK))64{65if (stat(sh, &st))66goto defshell;67if (ru != st.st_uid && !strmatch(sh, "?(/usr)?(/local)/?([ls])bin/?([[:lower:]])sh?(.exe)"))68goto defshell;69}70else71{72eu = geteuid();73rg = getgid();74eg = getegid();75if (ru != eu || rg != eg)76{77char* s;78char dir[PATH_MAX];7980s = sh;81for (;;)82{83if (stat(s, &st))84goto defshell;85if (ru != eu && st.st_uid == ru)86goto defshell;87if (rg != eg && st.st_gid == rg)88goto defshell;89if (s != sh)90break;91if (strlen(s) >= sizeof(dir))92goto defshell;93strcpy(dir, s);94if (!(s = strrchr(dir, '/')))95break;96*s = 0;97s = dir;98}99}100}101return sh;102}103defshell:104if (!(sh = val))105{106if (!*(sh = astconf("SH", NiL, NiL)) || *sh != '/' || eaccess(sh, X_OK) || !(sh = strdup(sh)))107sh = "/bin/sh";108val = sh;109}110return sh;111}112113114