summaryrefslogtreecommitdiff
path: root/src/lib/libast/preroot
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
commit3950ffe2a485479f6561c27364d3d7df5a21d124 (patch)
tree468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/preroot
downloadksh-upstream.tar.gz
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/preroot')
-rw-r--r--src/lib/libast/preroot/getpreroot.c165
-rw-r--r--src/lib/libast/preroot/ispreroot.c71
-rw-r--r--src/lib/libast/preroot/realopen.c47
-rw-r--r--src/lib/libast/preroot/setpreroot.c75
4 files changed, 358 insertions, 0 deletions
diff --git a/src/lib/libast/preroot/getpreroot.c b/src/lib/libast/preroot/getpreroot.c
new file mode 100644
index 0000000..3747d19
--- /dev/null
+++ b/src/lib/libast/preroot/getpreroot.c
@@ -0,0 +1,165 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ * return the real absolute pathname of the preroot dir for cmd
+ * if cmd==0 then current preroot path returned
+ */
+
+#include <ast.h>
+#include <preroot.h>
+
+#if FS_PREROOT
+
+#include <ast_dir.h>
+#include <ls.h>
+#include <error.h>
+#include <stdio.h>
+
+#ifndef ERANGE
+#define ERANGE E2BIG
+#endif
+
+#define ERROR(e) {errno=e;goto error;}
+
+char*
+getpreroot(char* path, const char* cmd)
+{
+ register int c;
+ register FILE* fp;
+ register char* p;
+ char buf[PATH_MAX];
+
+ if (!path) path = buf;
+ if (cmd)
+ {
+ sfsprintf(buf, sizeof(buf), "set x `%s= %s - </dev/null 2>&1`\nwhile :\ndo\nshift\ncase $# in\n[012]) break ;;\nesac\ncase \"$1 $2\" in\n\"+ %s\") echo $3; exit ;;\nesac\ndone\necho\n", PR_SILENT, cmd, PR_COMMAND);
+ if (!(fp = popen(buf, "rug"))) return(0);
+ for (p = path; (c = getc(fp)) != EOF && c != '\n'; *p++ = c);
+ *p = 0;
+ pclose(fp);
+ if (path == p) return(0);
+ return(path == buf ? strdup(path) : path);
+ }
+ else
+ {
+ char* d;
+ DIR* dirp = 0;
+ int namlen;
+ int euid;
+ int ruid;
+ struct dirent* entry;
+ struct stat* cur;
+ struct stat* par;
+ struct stat* tmp;
+ struct stat curst;
+ struct stat parst;
+ struct stat tstst;
+ char dots[PATH_MAX];
+
+ cur = &curst;
+ par = &parst;
+ if ((ruid = getuid()) != (euid = geteuid())) setuid(ruid);
+ if (stat(PR_REAL, cur) || stat("/", par) || cur->st_dev == par->st_dev && cur->st_ino == par->st_ino) ERROR(ENOTDIR);
+
+ /*
+ * like getcwd() but starting at the preroot
+ */
+
+ d = dots;
+ *d++ = '/';
+ p = path + PATH_MAX - 1;
+ *p = 0;
+ for (;;)
+ {
+ tmp = cur;
+ cur = par;
+ par = tmp;
+ if ((d - dots) > (PATH_MAX - 4)) ERROR(ERANGE);
+ *d++ = '.';
+ *d++ = '.';
+ *d = 0;
+ if (!(dirp = opendir(dots))) ERROR(errno);
+#if !_dir_ok || _mem_dd_fd_DIR
+ if (fstat(dirp->dd_fd, par)) ERROR(errno);
+#else
+ if (stat(dots, par)) ERROR(errno);
+#endif
+ *d++ = '/';
+ if (par->st_dev == cur->st_dev)
+ {
+ if (par->st_ino == cur->st_ino)
+ {
+ closedir(dirp);
+ *--p = '/';
+ if (ruid != euid) setuid(euid);
+ if (path == buf) return(strdup(p));
+ if (path != p)
+ {
+ d = path;
+ while (*d++ = *p++);
+ }
+ return(path);
+ }
+#ifdef D_FILENO
+ while (entry = readdir(dirp))
+ if (D_FILENO(entry) == cur->st_ino)
+ {
+ namlen = D_NAMLEN(entry);
+ goto found;
+ }
+#endif
+
+ /*
+ * this fallthrough handles logical naming
+ */
+
+ rewinddir(dirp);
+ }
+ do
+ {
+ if (!(entry = readdir(dirp))) ERROR(ENOENT);
+ namlen = D_NAMLEN(entry);
+ if ((d - dots) > (PATH_MAX - 1 - namlen)) ERROR(ERANGE);
+ memcpy(d, entry->d_name, namlen + 1);
+ if (stat(dots, &tstst)) ERROR(errno);
+ } while (tstst.st_ino != cur->st_ino || tstst.st_dev != cur->st_dev);
+ found:
+ if (*p) *--p = '/';
+ if ((p -= namlen) <= (path + 1)) ERROR(ERANGE);
+ memcpy(p, entry->d_name, namlen);
+ closedir(dirp);
+ dirp = 0;
+ }
+ error:
+ if (dirp) closedir(dirp);
+ if (ruid != euid) setuid(euid);
+ }
+ return(0);
+}
+
+#else
+
+NoN(getpreroot)
+
+#endif
diff --git a/src/lib/libast/preroot/ispreroot.c b/src/lib/libast/preroot/ispreroot.c
new file mode 100644
index 0000000..36bf62c
--- /dev/null
+++ b/src/lib/libast/preroot/ispreroot.c
@@ -0,0 +1,71 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ * return 1 if dir [any dir] is the preroot
+ */
+
+#include <ast.h>
+#include <preroot.h>
+
+#if FS_PREROOT
+
+#include <ls.h>
+
+/*
+ * return 1 if files a and b are the same under preroot
+ *
+ * NOTE: the kernel disables preroot for set-uid processes
+ */
+
+static int
+same(const char* a, const char* b)
+{
+ int i;
+ int euid;
+ int ruid;
+
+ struct stat ast;
+ struct stat bst;
+
+ if ((ruid = getuid()) != (euid = geteuid())) setuid(ruid);
+ i = !stat(a, &ast) && !stat(b, &bst) && ast.st_dev == bst.st_dev && ast.st_ino == bst.st_ino;
+ if (ruid != euid) setuid(euid);
+ return(i);
+}
+
+int
+ispreroot(const char* dir)
+{
+ static int prerooted = -1;
+
+ if (dir) return(same("/", dir));
+ if (prerooted < 0) prerooted = !same("/", PR_REAL);
+ return(prerooted);
+}
+
+#else
+
+NoN(ispreroot)
+
+#endif
diff --git a/src/lib/libast/preroot/realopen.c b/src/lib/libast/preroot/realopen.c
new file mode 100644
index 0000000..387559b
--- /dev/null
+++ b/src/lib/libast/preroot/realopen.c
@@ -0,0 +1,47 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ * disable preroot and open path relative to the real root
+ */
+
+#include <ast.h>
+#include <preroot.h>
+
+#if FS_PREROOT
+
+int
+realopen(const char* path, int mode, int perm)
+{
+ char buf[PATH_MAX + 8];
+
+ if (*path != '/' || !ispreroot(NiL)) return(-1);
+ strcopy(strcopy(buf, PR_REAL), path);
+ return(open(buf, mode, perm));
+}
+
+#else
+
+NoN(realopen)
+
+#endif
diff --git a/src/lib/libast/preroot/setpreroot.c b/src/lib/libast/preroot/setpreroot.c
new file mode 100644
index 0000000..1e8b6c1
--- /dev/null
+++ b/src/lib/libast/preroot/setpreroot.c
@@ -0,0 +1,75 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ * force current command to run under dir preroot
+ */
+
+#include <ast.h>
+#include <preroot.h>
+
+#if FS_PREROOT
+
+#include <option.h>
+
+void
+setpreroot(register char** argv, const char* dir)
+{
+ register char* s;
+ register char** ap;
+ int argc;
+ char* cmd;
+ char** av;
+ char buf[PATH_MAX];
+
+ if ((argv || (argv = opt_info.argv)) && (dir || (dir = getenv(PR_BASE)) && *dir) && !ispreroot(dir) && (*(cmd = *argv++) == '/' || (cmd = pathpath(cmd, NiL, PATH_ABSOLUTE|PATH_REGULAR|PATH_EXECUTE, buf, sizeof(buf)))))
+ {
+ argc = 3;
+ for (ap = argv; *ap++; argc++);
+ if (av = newof(0, char*, argc, 0))
+ {
+ ap = av;
+ *ap++ = PR_COMMAND;
+ *ap++ = (char*)dir;
+ *ap++ = cmd;
+ while (*ap++ = *argv++);
+ if (!(s = getenv(PR_SILENT)) || !*s)
+ {
+ sfprintf(sfstderr, "+");
+ ap = av;
+ while (s = *ap++)
+ sfprintf(sfstderr, " %s", s);
+ sfprintf(sfstderr, "\n");
+ sfsync(sfstderr);
+ }
+ execv(*av, av);
+ free(av);
+ }
+ }
+}
+
+#else
+
+NoN(setpreroot)
+
+#endif