diff options
author | ru <ru@FreeBSD.org> | 2002-01-22 15:15:38 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2002-01-22 15:15:38 +0000 |
commit | 566f6c525032b28586b7049329405dcbbfdc6b33 (patch) | |
tree | b843ee6d7f9d5b335d6928f8fd3a4ba82f1a02c9 /gnu | |
parent | bcc37863333c63967dd3fff9afbdade9c7651296 (diff) | |
download | FreeBSD-src-566f6c525032b28586b7049329405dcbbfdc6b33.zip FreeBSD-src-566f6c525032b28586b7049329405dcbbfdc6b33.tar.gz |
Reincarnate SETUID code in man(1), not compiled in by default.
The code will be fixed for all known security vulnerabilities,
and a make.conf(5) knob (ENABLE_SUID_MAN) will be provided for
those who still want it installed setuid for whatever reasons.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/man/man/man.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/gnu/usr.bin/man/man/man.c b/gnu/usr.bin/man/man/man.c index 35fb3ae..7b6fc41 100644 --- a/gnu/usr.bin/man/man/man.c +++ b/gnu/usr.bin/man/man/man.c @@ -45,11 +45,6 @@ #endif #endif -#ifdef SECURE_MAN_UID -extern uid_t getuid (); -extern int setuid (); -#endif - #ifdef STDC_HEADERS #include <stdlib.h> #else @@ -121,6 +116,11 @@ static char args[] = "M:P:S:adfhkm:p:w?"; #endif #endif +#ifdef SETUID +uid_t ruid; +uid_t euid; +#endif + int main (argc, argv) int argc; @@ -158,6 +158,12 @@ main (argc, argv) gripe_no_name (tmp); } +#ifdef SETUID + ruid = getuid(); + euid = geteuid(); + seteuid(ruid); +#endif + while (optind < argc) { nextarg = argv[optind++]; @@ -1107,7 +1113,7 @@ restore_sigs() * 1 for success and 0 for failure. */ int -make_cat_file (path, man_file, cat_file) +make_cat_file (path, man_file, cat_file, manid) register char *path; register char *man_file; register char *cat_file; @@ -1148,16 +1154,29 @@ make_cat_file (path, man_file, cat_file) if (debug) fprintf (stderr, "\ntrying command: %s\n", command); else { + +#ifdef SETUID + if (manid) + seteuid(ruid); +#endif if ((pp = popen(command, "r")) == NULL) { s = errno; fprintf(stderr, "Failed.\n"); errno = s; perror("popen"); +#ifdef SETUID + if (manid) + seteuid(euid); +#endif unlink(temp); restore_sigs(); fclose(fp); return 0; } +#ifdef SETUID + if (manid) + seteuid(euid); +#endif f = 0; while ((s = getc(pp)) != EOF) { @@ -1293,7 +1312,24 @@ format_and_display (path, man_file, cat_file) } else { - found = make_cat_file (path, man_file, cat_file); + +#ifdef SETUID + seteuid(euid); + found = make_cat_file (path, man_file, cat_file, 1); + seteuid(ruid); + + if (!found) + { + /* Try again as real user - see note below. + By running with + effective group (user) ID == real group (user) ID + except for the call above, I believe the problems + of reading private man pages is avoided. */ + found = make_cat_file (path, man_file, cat_file, 0); + } +#else + found = make_cat_file (path, man_file, cat_file, 0); +#endif if (found) { /* |