Dr. Werner Fink 2012-04-27 15:49:04 +00:00 committed by Git OBS Bridge
parent 515c8b107e
commit e332fee402
5 changed files with 314 additions and 847 deletions

View File

@ -1,5 +1,5 @@
'\" -*- coding: UTF-8 -*- '\" -*- coding: UTF-8 -*-
.\" Copyright (C) 2010 Werner Fink .\" Copyright (C) 2010,2012 Werner Fink
.\" .\"
.\" This program is free software; you can redistribute it and/or modify .\" This program is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by .\" it under the terms of the GNU General Public License as published by
@ -15,49 +15,42 @@
.\" along with this program; if not, write to the Free Software .\" along with this program; if not, write to the Free Software
.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA .\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
.\" .\"
.TH NOBODY 8 "Jul 30, 2010" "" "Linux System Administrator's Manual" .TH NOBODY 8 "Apr 27, 2012" "" "Linux System Administrator's Manual"
.SH NAME .SH NAME
nobdy \- for user root run a specific program as user nobody public \- for user root run specific TeX programs as user \fInobody\fP
.br
public \- for all users run specific TeX programs as group \fIpublic\fP
.SH SYNOPSIS .SH SYNOPSIS
.B nobdy .B public
.RB [ ls | find | false | true ] .RB \->\ [ texhash | mktexlsr | mktexmf | mktexpk | mktextfm ]
.SH DESCRIPTION .SH DESCRIPTION
.B Nobody .B Public
drops its privileges if called by the user drops its privileges if called by the user
.I root .I root
by switching over to the user by switching over to the user
.I nobdy .I nobdy
in a clean environment. in a clean environment. For all users the group
.I public
is used.
Currently the following programs are supported: Currently the following programs are supported:
.IP \fBls\fP .IP \fBtexhash\fP
\- list directory contents \- create ls-R databases
.IP \fBtrue\fP .IP \fBmktexlsr\fP
\- do nothing, successfully \- create ls-R databases
.IP \fBfalse\fP .IP \fBmktexmf\fP
\- do nothing, unsuccessfully \- create a Metafont source file
.IP \fBfind\fP .IP \fBfmktexpk\fP
\- search for files in a directory hierarchy \- create a PK file for a font
.IP \fBfmktextfm\fP
\- create a TFM file for a font
.SH NOTES .SH NOTES
For the program \fBfind\fP the options The umask changed to allow members of the group public
.IR -exec , to read and write files.
.IR -execdir ,
.IR -ok ,
.I -okdir
are
.B not
supported.
.SH FILES
.IR /bin/ls ,
.br
.IR /bin/true ,
.br
.IR /bin/false ,
.br
.I /usr/bin/find
.SH AUTHOR .SH AUTHOR
2010 Werner Fink 2012 Werner Fink
.SH "SEE ALSO" .SH "SEE ALSO"
.BR ls (1), .BR texhash (1),
.BR find (1), .BR mktexmf (1),
.BR su (1), .BR mktexpk (1),
.BR mktextfm (1),
.BR sudo (8). .BR sudo (8).

View File

@ -1,7 +1,10 @@
/* /*
* Nobody For user root run a specific program as user nobody * Public For user root run a specific program as user nobody
* for user root and others use group public and umask 0002
* *
* Usage: nobody [texhash|ls|find|false|true] * Usage: public -> [texhash|mktexlsr|mktexmf|mktexpk|mktextfm]
*
* Note: This program has to set sgid public!
* *
* Copyright (C) 2010,2012 Werner Fink * Copyright (C) 2010,2012 Werner Fink
* *
@ -43,12 +46,14 @@ static struct {
const char *run; const char *run;
} *lp, list[] = } *lp, list[] =
{ /* prog run */ { /* prog run */
{ "mktexlsr", "/usr/bin/mktexlsr" }, { "texhash", "/usr/lib/public/mktexlsr" },
{ "texhash", "/usr/bin/mktexlsr" }, { "mktexlsr", "/usr/lib/public/mktexlsr" },
{ "ls", "/bin/ls" }, { "mktexmf", "/usr/lib/public/mktexmf" },
{ "true", "/bin/true" }, { "mktexpk", "/usr/lib/public/mktexpk" },
{ "mktextfm", "/usr/lib/public/mktextfm" },
{ "false", "/bin/false" }, { "false", "/bin/false" },
{ "find", "/usr/bin/find" }, { "true", "/bin/true" },
{ "public", "/bin/true" },
#ifdef DEBUG #ifdef DEBUG
{ "id", "/usr/bin/id" }, { "id", "/usr/bin/id" },
{ "printenv", "/usr/bin/printenv" }, { "printenv", "/usr/bin/printenv" },
@ -79,48 +84,47 @@ static struct {
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *program_name; char *program_name, *slash;
struct passwd *pwd; struct passwd *pwd;
struct group *grp;
uid_t ruid = getuid(); uid_t ruid = getuid();
uid_t euid = geteuid(); uid_t euid = geteuid();
gid_t rgid = getgid(); gid_t rgid = getgid();
gid_t egid = getegid();
if (argc > 1) if ((slash = strrchr(argv[0], '/'))) {
program_name = argv[1]; program_name = ++slash;
else
program_name = "true";
argv++;
argc--;
if (*program_name == '/') {
for (lp = list; lp->run && strcmp(program_name, lp->run ); lp++) ;
} else { } else {
for (lp = list; lp->prog && strcmp(program_name, lp->prog); lp++) ; program_name = argv[0];
} }
for (lp = list; lp->prog && strcmp(program_name, lp->prog); lp++) ;
if (!lp->prog) { if (!lp->prog) {
errno = EBADRQC; errno = EBADRQC;
fprintf(stderr, "nobody: Usage:\n"); fprintf(stderr, "public: Usage:\n");
fprintf(stderr, " nobody ["); fprintf(stderr, " public linked to one of [");
for (lp = list; lp->prog; lp++) for (lp = list; lp->prog; lp++)
fprintf(stderr, "%s%c", lp->prog, (lp+1)->prog ? '|' : '\0'); fprintf(stderr, "%s%c", lp->prog, (lp+1)->prog ? '|' : '\0');
fprintf(stderr, "]\n"); fprintf(stderr, "] names\n");
goto err; goto err;
} }
if ((grp = getgrnam("public")) == (struct group*)0)
goto err;
if (ruid == 0 || euid == 0) { /* If user is root switch over to nobody:public */
int initgrp = 0;
if ((pwd = getpwnam("nobody")) == (struct passwd*)0) if ((pwd = getpwnam("nobody")) == (struct passwd*)0)
goto err; goto err;
if (ruid != pwd->pw_uid || euid != pwd->pw_gid) { if (ruid != pwd->pw_uid)
int initgrp = 0;
if (ruid != pwd->pw_uid) {
initgrp = 1;
ruid = pwd->pw_uid; ruid = pwd->pw_uid;
rgid = pwd->pw_gid;
} else { if (rgid != grp->gr_gid || egid != grp->gr_gid) {
pwd->pw_uid = ruid; initgrp = 1;
pwd->pw_gid = rgid; rgid = grp->gr_gid;
} }
if (setregid(rgid, pwd->pw_gid)) if (setregid(rgid, pwd->pw_gid))
@ -130,8 +134,6 @@ int main(int argc, char *argv[])
if (setreuid(ruid, pwd->pw_uid)) if (setreuid(ruid, pwd->pw_uid))
goto err; goto err;
if (initgrp) {
for (ep = envp; ep->name; ep++) { for (ep = envp; ep->name; ep++) {
if (ep->value) if (ep->value)
continue; continue;
@ -157,47 +159,18 @@ int main(int argc, char *argv[])
setenv(ep->name, ep->value, 1); setenv(ep->name, ep->value, 1);
} }
if (strcmp(lp->prog, "find") == 0) { } else if (rgid != grp->gr_gid || egid != grp->gr_gid) {
int n; rgid = grp->gr_gid;
for (n = 0; n < argc; n++) {
if (!argv[n] || *argv[n] == '\0') if (setregid(rgid, grp->gr_gid))
continue;
if (strncmp(argv[n], "-exec", 5) == 0) {
errno = ENOTSUP;
goto err; goto err;
}
if (strncmp(argv[n], "-ok", 3) == 0) {
errno = ENOTSUP;
goto err;
}
}
}
if (strcmp(lp->prog, "texhash") == 0 || strcmp(lp->prog, "mktexlsr") == 0) {
int n;
char buf[PATH_MAX+1], *lsr, *base;
for (n = 1; n < argc; n++) {
if (!argv[n] || *argv[n] == '\0')
continue;
if ((lsr = realpath(argv[n], buf)) == NULL)
goto err;
if ((base = strrchr(lsr, '/')) == NULL) {
errno = ENOTSUP;
goto err;
}
if (strcmp(base, "/ls-R") != 0) {
errno = ENOTSUP;
goto err;
}
if (access(lsr, W_OK) != 0)
goto err;
}
}
}
} }
umask(0002);
execve(lp->run, argv, environ); execve(lp->run, argv, environ);
err: err:
fprintf(stderr, "nobody: "); fprintf(stderr, "public: ");
perror(program_name); perror(program_name);
return 1; return 1;
} }

View File

@ -178,30 +178,18 @@
# The supporting scripts: # The supporting scripts:
: ${MT_MKTEXNAM=`kpsewhich --format='web2c files' mktexnam`} : ${MT_MKTEXNAM=`kpsewhich --format='web2c files' mktexnam`}
--- texk/kpathsea/mktexlsr --- texk/kpathsea/mktexlsr
+++ texk/kpathsea/mktexlsr 2012-04-23 09:29:20.382064991 +0000 +++ texk/kpathsea/mktexlsr 2012-04-27 14:06:45.670065918 +0000
@@ -15,6 +15,21 @@ version='$Id: mktexlsr 23151 2011-06-27 @@ -36,6 +36,9 @@ Kpathsea manual available at http://tug.
progname=`echo $0 | sed 's%.*/%%'` Report bugs to tex-k@tug.org.
usage="Usage: $progname [OPTION]... [DIR]... "
+nobody="$(id -un nobody)"
+if test -n "$nobody" -a "$(id -urn 2> /dev/null)" != "$nobody" && type -p nobody > /dev/null 2>&1 ; then
+ grep -qE 'nobody:[^:]*:[0-9]+:0:0::::' /etc/shadow
+ if test $? -eq 0 ; then
+ echo "$progname: Warning the password of the user nobody has expired." >&2
+ echo " Please use program \`chage' to set maxdays to 99999." >&2
+ echo ""
+ exit 1
+ fi
+ exec nobody $0 ${1+"$@"}
+fi
+
+MKTEXLSR=true; export MKTEXLSR +MKTEXLSR=true; export MKTEXLSR
+set -o noclobber +set -o noclobber
+ +
Rebuild ls-R filename databases used by TeX. If one or more arguments # MS-DOS and MS-Windows define $COMSPEC or $ComSpec and use `;' to separate
DIRS are given, these are used as the directories in which to build # directories in path lists whereas Unix uses `:'. Make an exception for
ls-R. Else all directories in the search path for ls-R files # Cygwin, which pretends to be UNIX.
@@ -51,6 +66,9 @@ if test "$DOSISH" = "no"; then SEP=':'; @@ -51,6 +54,9 @@ if test "$DOSISH" = "no"; then SEP=':';
# be done before kpsewhich can be called, and thus cannot be put into # be done before kpsewhich can be called, and thus cannot be put into
# mktex.opt. # mktex.opt.
dirname=`echo $0 | sed 's%/*[^/][^/]*$%%'` dirname=`echo $0 | sed 's%/*[^/][^/]*$%%'`
@ -211,7 +199,7 @@
case $dirname in case $dirname in
"") # Do nothing "") # Do nothing
;; ;;
@@ -134,6 +152,7 @@ old_ls_R_magic='% ls-R -- maintained by @@ -134,6 +140,7 @@ old_ls_R_magic='% ls-R -- maintained by
shift shift
} }
@ -219,7 +207,7 @@
for TEXMFLS_R in "$@"; do for TEXMFLS_R in "$@"; do
# Prepend cwd if the directory was relative. # Prepend cwd if the directory was relative.
case "$TEXMFLS_R" in case "$TEXMFLS_R" in
@@ -163,12 +182,23 @@ for TEXMFLS_R in "$@"; do @@ -163,12 +170,23 @@ for TEXMFLS_R in "$@"; do
# want to be silent if the directory doesn't exist, since the ls-R # want to be silent if the directory doesn't exist, since the ls-R
# path ordinarily contains many nonexistent directories. # path ordinarily contains many nonexistent directories.
test -d "$db_dir" || continue test -d "$db_dir" || continue
@ -245,7 +233,7 @@
elif test -s "$db_file" \ elif test -s "$db_file" \
&& test "x`sed '1s/ $//;1q' \"$db_file\"`" != "x$ls_R_magic" \ && test "x`sed '1s/ $//;1q' \"$db_file\"`" != "x$ls_R_magic" \
&& test "x`sed '1s/ $//;1q' \"$db_file\"`" != "x$old_ls_R_magic"; then && test "x`sed '1s/ $//;1q' \"$db_file\"`" != "x$old_ls_R_magic"; then
@@ -179,16 +209,23 @@ for TEXMFLS_R in "$@"; do @@ -179,16 +197,23 @@ for TEXMFLS_R in "$@"; do
# Skip if we cannot write the file: # Skip if we cannot write the file:
kpseaccess -w "$db_file" || { echo "$progname: $db_file: no write permission, skipping..." >&2; continue; } kpseaccess -w "$db_file" || { echo "$progname: $db_file: no write permission, skipping..." >&2; continue; }
@ -273,7 +261,7 @@
# The main task. We put ./: in the output, so top-level files can be # The main task. We put ./: in the output, so top-level files can be
# found via ls-R. Probably irrelevant in practice. The sed command # found via ls-R. Probably irrelevant in practice. The sed command
@@ -202,15 +239,23 @@ for TEXMFLS_R in "$@"; do @@ -202,15 +227,20 @@ for TEXMFLS_R in "$@"; do
vc_dirs='\.\(bzr\|git\|hg\|svn\)\|_darcs' vc_dirs='\.\(bzr\|git\|hg\|svn\)\|_darcs'
(cd "$TEXMFLS_R" && \ls -LRa 2>/dev/null) \ (cd "$TEXMFLS_R" && \ls -LRa 2>/dev/null) \
| sed -e '/^$/{n;s%^\./%%;s%^%./%;}; /^\.$/d; /^\.\.$/d; /^'$vc_dirs'$/d;' \ | sed -e '/^$/{n;s%^\./%%;s%^%./%;}; /^\.$/d; /^\.\.$/d; /^'$vc_dirs'$/d;' \
@ -287,12 +275,9 @@
chmod $PERMS "$db_file_tmp" chmod $PERMS "$db_file_tmp"
- rm -f "$db_file" - rm -f "$db_file"
- mv "$db_file_tmp" "$db_file" - mv "$db_file_tmp" "$db_file"
+ if test -O "$db_file" ; then + if test -w "$db_file" ; then
+ # We're the owner of the $db_file + # Sticky bit is set see line 200
+ mv "$db_file_tmp" "$db_file" + # Temporary unset the noclobber option at line 40
+ else
+ # Sticky bit is set see line 141
+ # Temporary unset the noclobber option at line 20
+ set +o noclobber + set +o noclobber
+ cat "$db_file_tmp" > "$db_file" + cat "$db_file_tmp" > "$db_file"
+ set -o noclobber + set -o noclobber

View File

@ -12,6 +12,9 @@ addFilter(".*world-writable.*/var/cache/fonts/ls-R.*")
addFilter(".*world-writable.*/var/lib/texmf/.*/ls-R.*") addFilter(".*world-writable.*/var/lib/texmf/.*/ls-R.*")
addFilter(".*incorrect-fsf-address.*") addFilter(".*incorrect-fsf-address.*")
addFilter(".*name-repeated-in-summary.*") addFilter(".*name-repeated-in-summary.*")
addFilter(".*non-conffile-in-etc.*/etc/texmf/ls-R.*")
addFilter(".*rpm-buildroot-usage.*") addFilter(".*rpm-buildroot-usage.*")
addFilter(".*binary-or-shlib-calls-gethostbyname.*") addFilter(".*binary-or-shlib-calls-gethostbyname.*")
addFilter(".*invalid-license.*SUSE-TeX.*") addFilter(".*invalid-license.*SUSE-TeX.*")
addFilter(".*permissions-file-setuid-bit.*/usr/bin/public.*")
addFilter(".*zero-length.*")

File diff suppressed because it is too large Load Diff