source: branches/fc11-dev/server/common/patches/httpd-suexec-scripts.patch @ 1146

Last change on this file since 1146 was 1146, checked in by mitchb, 15 years ago
Version, context, etc. fixups to build Apache on Fedora 11
File size: 9.0 KB
  • httpd-2.2.2/support/Makefile.in

    # scripts.mit.edu httpd suexec patch
    # Copyright (C) 2006, 2007, 2008  Jeff Arnold <jbarnold@mit.edu>,
    #                                 Joe Presbrey <presbrey@mit.edu>,
    #                                 Anders Kaseorg <andersk@mit.edu>,
    #                                 Geoffrey Thomas <geofft@mit.edu>
    #
    # 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 the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
    #
    # See /COPYRIGHT in this repository for more information.
    #
    old new  
    6060
    6161suexec_OBJECTS = suexec.lo
    6262suexec: $(suexec_OBJECTS)
    63         $(LINK) $(suexec_OBJECTS)
     63        $(LINK) -lselinux $(suexec_OBJECTS)
    6464
    6565htcacheclean_OBJECTS = htcacheclean.lo
    6666htcacheclean: $(htcacheclean_OBJECTS)
  • httpd-2.2.2/configure.in

    old new  
    559559APACHE_HELP_STRING(--with-suexec-userdir,User subdirectory),[
    560560  AC_DEFINE_UNQUOTED(AP_USERDIR_SUFFIX, "$withval", [User subdirectory] ) ] )
    561561
     562AC_ARG_WITH(suexec-trusteddir,
     563APACHE_HELP_STRING(--with-suexec-trusteddir,Trusted SuExec directory),[
     564  AC_DEFINE_UNQUOTED(AP_TRUSTED_DIRECTORY, "$withval", [Trusted SuExec directory] ) ] )
     565
    562566AC_ARG_WITH(suexec-docroot,
    563567APACHE_HELP_STRING(--with-suexec-docroot,SuExec root directory),[
    564568  AC_DEFINE_UNQUOTED(AP_DOC_ROOT, "$withval", [SuExec root directory] ) ] )
  • httpd-2.2.11/support/suexec.c

    old new  
    3030 *
    3131 */
    3232
     33#define STATIC_CAT_PATH "/usr/local/bin/static-cat"
     34#define PHP_PATH "/usr/bin/php-cgi"
     35
    3336#include "apr.h"
    3437#include "ap_config.h"
    3538#include "suexec.h"
     
    4649#include <stdio.h>
    4750#include <stdarg.h>
    4851#include <stdlib.h>
     52#include <selinux/selinux.h>
    4953
    5054#ifdef HAVE_PWD_H
    5155#include <pwd.h>
     
    9599{
    96100    /* variable name starts with */
    97101    "HTTP_",
     102    "HTTPS_",
    98103    "SSL_",
    99104
    100105    /* variable name is */
     
    245250    environ = cleanenv;
    246251}
    247252
     253static const char *static_extensions[] = {
     254    "html",
     255    "css",
     256    "gif",
     257    "jpg",
     258    "png",
     259    "htm",
     260    "jpeg",
     261    "js",
     262    "ico",
     263    "xml",
     264    "xsl",
     265    "tiff",
     266    "tif",
     267    "tgz",
     268    "tar",
     269    "jar",
     270    "zip",
     271    "pdf",
     272    "ps",
     273    "doc",
     274    "xls",
     275    "ppt",
     276    "swf",
     277    "mp3",
     278    "mov",
     279    "wmv",
     280    "mpg",
     281    "mpeg",
     282    "avi",
     283    "il",
     284    "JPG",
     285    "xhtml",
     286    "svg",
     287    "xaml",
     288    "xap",
     289    NULL
     290};
     291
     292static int is_static_extension(const char *file)
     293{
     294    const char *extension = strrchr(file, '.');
     295    const char **p;
     296    if (extension == NULL) return 0;
     297    for (p = static_extensions; *p; ++p) {
     298        if (strcmp(extension + 1, *p) == 0) return 1;
     299    }
     300    return 0;
     301}
     302
     303static int is_php_extension(const char *file)
     304{
     305    const char *extension = strrchr(file, '.');
     306    if (extension == NULL) return 0;
     307    return strcmp(extension + 1, "php") == 0;
     308}
     309
    248310int main(int argc, char *argv[])
    249311{
    250312    int userdir = 0;        /* ~userdir flag             */
     313    int trusteddir = 0;     /* TRUSTED_DIRECTORY flag    */
    251314    uid_t uid;              /* user information          */
    252315    gid_t gid;              /* target group placeholder  */
    253316    char *target_uname;     /* target user name          */
     
    350413#endif /*_OSD_POSIX*/
    351414
    352415    /*
     416     * First check if this is an absolute path to the directory
     417     * of trusted executables. These are supposed to be security
     418     * audited to check parameters and validity on their own...
     419     */
     420    if (strstr(cmd, AP_TRUSTED_DIRECTORY) == cmd) {
     421        if (strstr(cmd, "/../") != NULL) {
     422            log_err("invalid command (%s)\n", cmd);
     423            exit(104);
     424        }
     425        trusteddir = 1;
     426        goto TRUSTED_DIRECTORY;
     427    }
     428
     429    /*
    353430     * Check for a leading '/' (absolute path) in the command to be executed,
    354431     * or attempts to back up out of the current directory,
    355432     * to protect against attacks.  If any are
     
    371448        userdir = 1;
    372449    }
    373450
     451TRUSTED_DIRECTORY:
    374452    /*
    375453     * Error out if the target username is invalid.
    376454     */
     
    452530     * Error out if attempt is made to execute as root or as
    453531     * a UID less than AP_UID_MIN.  Tsk tsk.
    454532     */
    455     if ((uid == 0) || (uid < AP_UID_MIN)) {
     533    if ((uid == 0) || (uid < AP_UID_MIN && uid != 102)) {
    456534        log_err("cannot run as forbidden uid (%d/%s)\n", uid, cmd);
    457535        exit(107);
    458536    }
     
    484562        log_err("failed to setuid (%ld: %s)\n", uid, cmd);
    485563        exit(110);
    486564    }
     565    if (is_selinux_enabled()) {
     566        if (uid == 102) {
     567            if (setexeccon("system_u:system_r:signup_t:s0") == -1) {
     568                log_err("failed to setexeccon (%ld: %s) to signup_t\n", uid, cmd);
     569                exit(201);
     570            }
     571        } else {
     572            if (setexeccon("user_u:user_r:user_t:s0") == -1) {
     573                log_err("failed to setexeccon (%ld: %s) to user_t\n", uid, cmd);
     574                exit(202);
     575            }
     576        }
     577    }
     578
     579    setenv("HOME", target_homedir, 1);
    487580
    488581    /*
    489582     * Get the current working directory, as well as the proper
     
    506599            log_err("cannot get docroot information (%s)\n", target_homedir);
    507600            exit(112);
    508601        }
     602        size_t expected_len = strlen(target_homedir)+1+strlen(AP_USERDIR_SUFFIX)+1;
     603        char *expected = malloc(expected_len);
     604        snprintf(expected, expected_len, "%s/%s", target_homedir, AP_USERDIR_SUFFIX);
     605        if (strncmp(cwd, expected, expected_len-1) != 0) {
     606            log_err("error: file's directory not a subdirectory of user's home directory (%s, %s)\n", cwd, expected);
     607            exit(114);
     608        }
     609    }
     610    else if (trusteddir) {
     611        if (((chdir(AP_TRUSTED_DIRECTORY)) != 0) ||
     612            ((getcwd(dwd, AP_MAXPATH)) == NULL) |
     613            ((chdir(cwd)) != 0)) {
     614            log_err("cannot get docroot information (%s)\n", AP_TRUSTED_DIRECTORY);
     615            exit(112);
     616        }
    509617    }
    510618    else {
    511619        if (((chdir(AP_DOC_ROOT)) != 0) ||
     
    532640    /*
    533641     * Error out if cwd is writable by others.
    534642     */
     643#if 0
    535644    if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) {
    536645        log_err("directory is writable by others: (%s)\n", cwd);
    537646        exit(116);
    538647    }
     648#endif
    539649
    540650    /*
    541651     * Error out if we cannot stat the program.
    542652     */
    543     if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) {
     653    if (((lstat(cmd, &prg_info)) != 0) /*|| (S_ISLNK(prg_info.st_mode))*/) {
    544654        log_err("cannot stat program: (%s)\n", cmd);
    545655        exit(117);
    546656    }
     
    548658    /*
    549659     * Error out if the program is writable by others.
    550660     */
     661#if 0
    551662    if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) {
    552663        log_err("file is writable by others: (%s/%s)\n", cwd, cmd);
    553664        exit(118);
    554665    }
     666#endif
    555667
    556668    /*
    557669     * Error out if the file is setuid or setgid.
     
    565677     * Error out if the target name/group is different from
    566678     * the name/group of the cwd or the program.
    567679     */
     680#if 0
    568681    if ((uid != dir_info.st_uid) ||
    569682        (gid != dir_info.st_gid) ||
    570683        (uid != prg_info.st_uid) ||
     
    576689                prg_info.st_uid, prg_info.st_gid);
    577690        exit(120);
    578691    }
     692#endif
    579693    /*
    580694     * Error out if the program is not executable for the user.
    581695     * Otherwise, she won't find any error in the logs except for
    582696     * "[error] Premature end of script headers: ..."
    583697     */
    584     if (!(prg_info.st_mode & S_IXUSR)) {
     698    if (!is_static_extension(cmd) && !is_php_extension(cmd) &&
     699        !(prg_info.st_mode & S_IXUSR)) {
    585700        log_err("file has no execute permission: (%s/%s)\n", cwd, cmd);
    586701        exit(121);
    587702    }
    588703
     704    if (is_static_extension(cmd)) {
     705        argv[2] = STATIC_CAT_PATH;
     706        execv(STATIC_CAT_PATH, &argv[2]);
     707        log_err("(%d)%s: static_cat exec failed (%s)\n", errno, strerror(errno), argv[2]);
     708        exit(255);
     709    }
     710    if (is_php_extension(cmd)) {
     711        setenv("PHPRC", ".", 1);
     712        argv[1] = PHP_PATH;
     713        argv[2] = "-f";
     714        execv(PHP_PATH, &argv[1]);
     715        log_err("(%d)%s: php exec failed (%s)\n", errno, strerror(errno), argv[2]);
     716        exit(255);
     717    }
     718
    589719#ifdef AP_SUEXEC_UMASK
    590720    /*
    591721     * umask() uses inverse logic; bits are CLEAR for allowed access.
Note: See TracBrowser for help on using the repository browser.