Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
POSIX.6
- X-seq: zsh-workers 3088
- From: Zefram <zefram@xxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxxx
- Subject: POSIX.6
- Date: Sat, 26 Apr 1997 20:49:55 +0100 (BST)
-----BEGIN PGP SIGNED MESSAGE-----
This patch adds some new features, that make the shell aware of POSIX.1e
(POSIX.6) capability (privilege) sets. (An implementation of POSIX.1e
is currently being developed for Linux; it is currently a bit more than
sufficient to support this code.)
The patch changes the prompt code such that a `#' prompt will be triggered
by POSIX.1e capabilities, as well as EUID zero. This test is also made
available in the conditional syntax, as `%(!'.
The patch adds a new module, which provides a builtin `cap' with which
the shell's current capabilities can be examined and set. This is a
crucial feature for a shell in the POSIX.1e environment. The module also
implements the related POSIX utilities, getcap and setcap; due to the
braindead POSIX design, this actually provides significantly different
semantics from the usual situation of these being distinct programs.
-zefram
*** configure.in 1997/03/31 00:07:33 1.36
--- configure.in 1997/04/26 04:13:29
***************
*** 315,321 ****
AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \
termios.h sys/param.h sys/filio.h string.h memory.h \
limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \
! locale.h errno.h stdlib.h unistd.h)
if test $dynamic = yes; then
AC_CHECK_HEADERS(dlfcn.h)
fi
--- 315,321 ----
AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \
termios.h sys/param.h sys/filio.h string.h memory.h \
limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \
! locale.h errno.h stdlib.h unistd.h sys/capability.h)
if test $dynamic = yes; then
AC_CHECK_HEADERS(dlfcn.h)
fi
***************
*** 420,425 ****
--- 420,427 ----
AC_CHECK_LIB(dl, dlopen)
fi
+ AC_CHECK_LIB(cap, cap_init)
+
dnl ---------------------
dnl CHECK TERMCAP LIBRARY
dnl ---------------------
***************
*** 508,514 ****
getlogin setpgid gettimeofday gethostname mkfifo wait3 difftime \
sigblock sigsetmask sigrelse sighold killpg sigaction getrlimit \
sigprocmask setuid seteuid setreuid setresuid setsid strerror \
! nis_list initgroups fchdir)
if test $dynamic = yes; then
AC_CHECK_FUNCS(dlopen dlerror dlsym dlclose)
fi
--- 510,516 ----
getlogin setpgid gettimeofday gethostname mkfifo wait3 difftime \
sigblock sigsetmask sigrelse sighold killpg sigaction getrlimit \
sigprocmask setuid seteuid setreuid setresuid setsid strerror \
! nis_list initgroups fchdir cap_init)
if test $dynamic = yes; then
AC_CHECK_FUNCS(dlopen dlerror dlsym dlclose)
fi
*** Doc/Makefile.in 1997/03/31 00:37:36 1.11
--- Doc/Makefile.in 1997/04/26 05:43:36
***************
*** 92,97 ****
--- 92,98 ----
Zsh/compat.yo Zsh/compctl.yo Zsh/cond.yo Zsh/exec.yo Zsh/expn.yo \
Zsh/filelist.yo Zsh/files.yo Zsh/func.yo Zsh/grammar.yo Zsh/guide.yo \
Zsh/index.yo Zsh/intro.yo Zsh/invoke.yo Zsh/jobs.yo Zsh/modules.yo \
+ Zsh/mod_cap.yo \
Zsh/mod_clone.yo Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_deltochar.yo \
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_stat.yo \
Zsh/mod_zle.yo Zsh/options.yo \
*** Doc/Zsh/guide.yo 1997/03/30 00:49:03 1.10
--- Doc/Zsh/guide.yo 1997/04/26 05:44:20
***************
*** 104,109 ****
--- 104,110 ----
Zsh Modules
+ menu(The cap Module)
menu(The clone Module)
menu(The comp1 Module)
menu(The compctl Module)
*** ...................... Thu Sep 7 20:04:30 1995
--- Doc/Zsh/mod_cap.yo Sat Apr 26 06:52:41 1997
***************
*** 0 ****
--- 1,28 ----
+ texinode(The cap Module)(The clone Module)()(Zsh Modules)
+ sect(The cap Module)
+ The tt(cap) module is used for manipulating POSIX.1e (POSIX.6) capability
+ sets. If the operating system does not support this interface, the
+ builtins defined by this module will do nothing.
+ The builtins in this module are:
+
+ startitem()
+ findex(cap)
+ cindex(capabilities, setting)
+ item(tt(cap) [ var(capabilities) ])(
+ Change the shell's process capability sets to the specified var(capabilities),
+ otherwise display the shell's current capabilities.
+ )
+ findex(getcap)
+ cindex(capabilities, getting from files)
+ item(tt(getcap) var(filename) ...)(
+ This is a built-in implementation of the POSIX standard utility. It displays
+ the capability sets on each specified var(filename).
+ )
+ findex(setcap)
+ cindex(capabilities, setting on files)
+ item(tt(setcap) var(capabilities) var(filename) ...)(
+ This is a built-in implementation of the POSIX standard utility. It sets
+ the capability sets on each specified var(filename) to the specified
+ var(capabilities).
+ )
+ enditem()
*** Doc/Zsh/mod_clone.yo 1997/03/17 04:22:14 1.1
--- Doc/Zsh/mod_clone.yo 1997/04/26 05:44:44
***************
*** 1,4 ****
! texinode(The clone Module)(The comp1 Module)()(Zsh Modules)
sect(The clone Module)
The tt(clone) module makes available one builtin command:
--- 1,4 ----
! texinode(The clone Module)(The comp1 Module)(The cap Module)(Zsh Modules)
sect(The clone Module)
The tt(clone) module makes available one builtin command:
*** Doc/Zsh/modules.yo 1997/03/27 01:57:34 1.2
--- Doc/Zsh/modules.yo 1997/04/26 05:45:58
***************
*** 11,16 ****
--- 11,19 ----
. The modules available are:
startitem()
+ item(tt(cap))(
+ Builtins for manipulating POSIX.1e (POSIX.6) capability (privilege) sets.
+ )
item(tt(clone))(
A builtin that can clone a running shell onto another terminal.
)
***************
*** 40,45 ****
--- 43,49 ----
)
enditem()
startmenu()
+ menu(The cap Module)
menu(The clone Module)
menu(The comp1 Module)
menu(The compctl Module)
***************
*** 50,55 ****
--- 54,60 ----
menu(The stat Module)
menu(The zle Module)
endmenu()
+ includefile(Zsh/mod_cap.yo)
includefile(Zsh/mod_clone.yo)
includefile(Zsh/mod_comp1.yo)
includefile(Zsh/mod_compctl.yo)
*** Doc/Zsh/prompt.yo 1997/03/30 17:09:18 1.4
--- Doc/Zsh/prompt.yo 1997/04/26 05:56:22
***************
*** 124,131 ****
Clears to end of line.
)
item(tt(%#))(
! A `tt(#)' if the shell is running as root, a `tt(%)' if not.
! Equivalent to `tt(%(#.#.%%))'.
)
item(tt(%v))(
vindex(psvar, use of)
--- 124,135 ----
Clears to end of line.
)
item(tt(%#))(
! A `tt(#)' if the shell is running with privileges, a `tt(%)' if not.
! Equivalent to `tt(%(!.#.%%))'.
! The definition of `privileged', for these purposes, is that either the
! effective user ID is zero, or, if POSIX.1e capabilities are supported, that
! at least one capability is raised in either the Effective or Inheritable
! capability vectors.
)
item(tt(%v))(
vindex(psvar, use of)
***************
*** 171,176 ****
--- 175,181 ----
sitem(tt(S))(True if the tt(SECONDS) parameter is at least var(n).)
sitem(tt(v))(True if the array tt(psvar) has at least var(n) elements.)
sitem(tt(_))(True if at least var(n) shell constructs were started.)
+ sitem(tt(!))(True if the shell is running with privileges.)
endsitem()
)
xitem(tt(%<)var(string)tt(<))
*** Src/init.c 1997/03/30 18:54:12 1.49
--- Src/init.c 1997/04/26 04:19:17
***************
*** 449,455 ****
prompt = ztrdup("");
prompt2 = ztrdup("");
} else if (emulation == EMULATE_KSH || emulation == EMULATE_SH) {
! prompt = ztrdup(geteuid() ? "$ " : "# ");
prompt2 = ztrdup("> ");
} else {
prompt = ztrdup("%m%# ");
--- 449,455 ----
prompt = ztrdup("");
prompt2 = ztrdup("");
} else if (emulation == EMULATE_KSH || emulation == EMULATE_SH) {
! prompt = ztrdup(privasserted() ? "# " : "$ ");
prompt2 = ztrdup("> ");
} else {
prompt = ztrdup("%m%# ");
*** Src/mods.conf 1997/03/27 01:57:50 1.11
--- Src/mods.conf 1997/04/26 04:47:48
***************
*** 19,24 ****
--- 19,25 ----
# (This would be rather neater if we could rely on shell functions in sh.)
#
+ cap: Modules/cap.o
example: Modules/example.o
files: Modules/files.o
clone: Modules/clone.o
*** Src/prompt.c 1997/03/30 17:09:23 1.11
--- Src/prompt.c 1997/04/26 06:01:24
***************
*** 210,215 ****
--- 210,218 ----
case '_':
test = (cmdsp >= arg);
break;
+ case '!':
+ test = privasserted();
+ break;
default:
test = -1;
break;
***************
*** 493,499 ****
break;
case '#':
addbufspc(1);
! *bp++ = (geteuid())? '%' : '#';
break;
case 'v':
if (!arg)
--- 496,502 ----
break;
case '#':
addbufspc(1);
! *bp++ = privasserted() ? '#' : '%';
break;
case 'v':
if (!arg)
*** Src/system.h 1997/03/31 00:07:41 1.15
--- Src/system.h 1997/04/26 04:21:52
***************
*** 415,420 ****
--- 415,424 ----
# endif
#endif
+ #ifdef HAVE_SYS_CAPABILITY_H
+ # include <sys/capability.h>
+ #endif
+
/* DIGBUFSIZ is the length of a buffer which can hold the -LONG_MAX-1 *
* converted to printable decimal form including the sign and the *
* terminating null character. Below 0.30103 > lg 2. */
*** Src/utils.c 1997/03/31 07:51:11 1.73
--- Src/utils.c 1997/04/26 04:39:19
***************
*** 3525,3530 ****
--- 3525,3562 ----
return -1;
}
+ /* Check whether the shell is running with privileges in effect. *
+ * This is the case if EITHER the euid is zero, OR (if the system *
+ * supports POSIX.1e (POSIX.6) capability sets) the process' *
+ * Effective or Inheritable capability sets are non-empty. */
+
+ /**/
+ int
+ privasserted(void)
+ {
+ if(!geteuid())
+ return 1;
+ #ifdef HAVE_CAP_INIT
+ {
+ cap_t caps = cap_get_proc();
+ if(caps) {
+ /* POSIX doesn't define a way to test whether a capability set *
+ * is empty or not. Typical. I hope this is conforming... */
+ cap_flag_value_t val;
+ cap_value_t n;
+ for(n = 0; !cap_get_flag(caps, n, CAP_EFFECTIVE, &val); n++)
+ if(val ||
+ (!cap_get_flag(caps, n, CAP_INHERITABLE, &val) && val)) {
+ cap_free(&caps);
+ return 1;
+ }
+ cap_free(&caps);
+ }
+ }
+ #endif /* HAVE_CAP_INIT */
+ return 0;
+ }
+
#ifdef DEBUG
/**/
*** Src/Modules/Makefile.in 1997/03/29 14:22:10 1.21
--- Src/Modules/Makefile.in 1997/04/26 04:48:32
***************
*** 105,118 ****
../signames.h ../system.h ../zsh.h ../ztype.h ../../config.h
# generated prototypes
! PROTO = example.pro files.pro clone.pro sched.pro stat.pro
# target modules
! MODULES = example.so files.so clone.so sched.so stat.so
# object files
! OBJS = example.o files.o clone.o sched.o stat.o
! DOBJS = example..o files..o clone..o sched..o stat..o
ALLOBJS = $(OBJS) $(DOBJS)
--- 105,118 ----
../signames.h ../system.h ../zsh.h ../ztype.h ../../config.h
# generated prototypes
! PROTO = cap.pro example.pro files.pro clone.pro sched.pro stat.pro
# target modules
! MODULES = cap.so example.so files.so clone.so sched.so stat.so
# object files
! OBJS = cap.o example.o files.o clone.o sched.o stat.o
! DOBJS = cap..o example..o files..o clone..o sched..o stat..o
ALLOBJS = $(OBJS) $(DOBJS)
***************
*** 133,138 ****
--- 133,139 ----
$(PROTO): ../makepro.sed
+ cap.so: cap..o
example.so: example..o
files.so: files..o
clone.so: clone..o
*** ..................... Thu Sep 7 20:04:30 1995
--- Src/Modules/cap.c Sat Apr 26 06:17:17 1997
***************
*** 0 ****
--- 1,151 ----
+ /*
+ * $Id$
+ *
+ * cap.c - POSIX.1e (POSIX.6) capability set manipulation
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 1997 Andrew Main
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Andrew Main or the Zsh Development Group be liable
+ * to any party for direct, indirect, special, incidental, or consequential
+ * damages arising out of the use of this software and its documentation,
+ * even if Andrew Main and the Zsh Development Group have been advised of
+ * the possibility of such damage.
+ *
+ * Andrew Main and the Zsh Development Group specifically disclaim any
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose. The software
+ * provided hereunder is on an "as is" basis, and Andrew Main and the
+ * Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+
+ #include "zsh.h"
+
+ #include "cap.pro"
+
+ #ifdef HAVE_CAP_INIT
+
+ static int
+ bin_cap(char *nam, char **argv, char *ops, int func)
+ {
+ int ret = 0;
+ cap_t caps;
+ if(*argv) {
+ caps = cap_from_text(*argv);
+ if(!caps) {
+ zwarnnam(nam, "invalid capability string", NULL, 0);
+ return 1;
+ }
+ if(cap_set_proc(caps)) {
+ zwarnnam(nam, "can't change capabilites: %e", NULL, errno);
+ ret = 1;
+ }
+ } else {
+ char *result;
+ ssize_t length;
+ caps = cap_get_proc();
+ if(caps)
+ result = cap_to_text(caps, &length);
+ if(!caps || !result) {
+ zwarnnam(nam, "can't get capabilites: %e", NULL, errno);
+ ret = 1;
+ } else
+ puts(result);
+ }
+ cap_free(&caps);
+ return ret;
+ }
+
+ static int
+ bin_getcap(char *nam, char **argv, char *ops, int func)
+ {
+ int ret = 0;
+
+ do {
+ char *result;
+ ssize_t length;
+ cap_t caps = cap_get_file(*argv);
+ if(caps)
+ result = cap_to_text(caps, &length);
+ if (!caps || !result) {
+ zwarnnam(nam, "%s: %e", *argv, errno);
+ ret = 1;
+ } else
+ printf("%s %s\n", *argv, result);
+ cap_free(&caps);
+ } while(*++argv);
+ return ret;
+ }
+
+ static int
+ bin_setcap(char *nam, char **argv, char *ops, int func)
+ {
+ cap_t caps;
+ int ret = 0;
+
+ caps = cap_from_text(*argv++);
+ if(!caps) {
+ zwarnnam(nam, "invalid capability string", NULL, 0);
+ return 1;
+ }
+
+ do {
+ if(cap_set_file(*argv, caps)) {
+ zwarnnam(nam, "%s: %e", *argv, errno);
+ ret = 1;
+ }
+ } while(*++argv);
+ cap_free(&caps);
+ return ret;
+ }
+
+ #else /* !HAVE_CAP_INIT */
+
+ static int
+ bin_notavail(char *nam, char **argv, char *ops, int func)
+ {
+ zwarnnam(nam, "not available on this system", NULL, 0);
+ return 1;
+ }
+
+ # define bin_cap bin_notavail
+ # define bin_getcap bin_notavail
+ # define bin_setcap bin_notavail
+
+ #endif /* !HAVE_CAP_INIT */
+
+ /* module paraphernalia */
+
+ static struct binlist bintab[] = {
+ { "cap", 0, bin_cap, 0, 1, 0, NULL, NULL, 0 },
+ { "getcap", 0, bin_getcap, 1, -1, 0, NULL, NULL, 0 },
+ { "setcap", 0, bin_setcap, 2, -1, 0, NULL, NULL, 0 },
+ };
+
+ /**/
+ int BOOT(
+ boot_cap)(Module m)
+ {
+ return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+ }
+
+ #ifdef MODULE
+
+ /**/
+ int CLEANUP(
+ cleanup_cap)(Module m)
+ {
+ deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+ return 0;
+ }
+ #endif
-----BEGIN PGP SIGNATURE-----
Version: 2.6.3ia
Charset: ascii
iQCVAwUBM2IpYnD/+HJTpU/hAQFT5QP/ZRgcrTZX95f2d4jP0H23zfS3QXuy9wmY
oveB4nn2eopCRjTAU5Uhrq9X0LCojfJZrnfBKgOkCwxC1fmRgNXdS8q24Nz2Ej4p
qFM/3B1zPkH9DgIl9hHn81NPTjiWF9IUGSiRErpexYOFCEoiAfc6LaFSCCwS9Wdv
zrEPfjPW794=
=Jdca
-----END PGP SIGNATURE-----
Messages sorted by:
Reverse Date,
Date,
Thread,
Author