diff -Naur suphp-0.3.1/src/log.c suphp-0.3.1-solaris/src/log.c --- suphp-0.3.1/src/log.c Sun Sep 28 19:17:51 2003 +++ suphp-0.3.1-solaris/src/log.c Sun Nov 23 16:47:40 2003 @@ -41,7 +41,7 @@ va_end(vargs); // Write message to logfile - log(msg, "error"); + suphp_log(msg, "error"); } void log_info(char *info_msg, ...) @@ -56,10 +56,10 @@ va_end(vargs); // Write message to logfile - log(msg, "info"); + suphp_log(msg, "info"); } -void log(char *msg, char *category) +void suphp_log(char *msg, char *category) { int fd; time_t ts; diff -Naur suphp-0.3.1/src/log.h suphp-0.3.1-solaris/src/log.h --- suphp-0.3.1/src/log.h Sun Sep 28 19:17:51 2003 +++ suphp-0.3.1-solaris/src/log.h Sun Nov 23 16:47:40 2003 @@ -24,7 +24,7 @@ // Functions in log.c void log_error(char* err_msg, ...); void log_info(char* info_msg, ...); -void log(char* msg, char* category); +void suphp_log(char* msg, char* category); #endif diff -Naur suphp-0.3.1/src/suphp.c suphp-0.3.1-solaris/src/suphp.c --- suphp-0.3.1/src/suphp.c Sun Sep 28 19:17:51 2003 +++ suphp-0.3.1-solaris/src/suphp.c Sun Nov 23 16:47:40 2003 @@ -34,28 +34,60 @@ void exec_script(char* scriptname) { char *php_config; - + char *Token,*Value; + // Set the enviroment (for compatibility reasons) - setenv("SCRIPT_URL", getenv("REQUEST_URI"), 1); - setenv("PATH_TRANSLATED", getenv("SCRIPT_FILENAME"), 1); - setenv("PATH_INFO", getenv("SCRIPT_NAME"), 1); - setenv("REDIRECT_SCRIPT_URL", getenv("SCRIPT_URL"), 1); - setenv("REDIRECT_STATUS", "200", 1); // PHP may need this - setenv("REDIRECT_URL", getenv("SCRIPT_URL"), 1); - + + if (Value = getenv("REQUEST_URI")) // returns NULL if no match, else (char *) + { + Token = (char *) malloc(strlen("SCRIPT_URL=" + strlen(Value) + 1)); + putenv(strcat(strcpy(Token,"SCRIPT_URL="), Value)); + free (Token); + } + if (Value = getenv("SCRIPT_FILENAME")) + { + Token = (char *) malloc(strlen("PATH_TRANSLATED=" + strlen(Value) + 1)); + putenv(strcat(strcpy(Token,"PATH_TRANSLATED="), Value)); + free (Token); + } + if (Value = getenv("SCRIPT_NAME")) + { + Token = (char *) malloc(strlen("PATH_INFO=" + strlen(Value) + 1)); + putenv(strcat(strcpy(Token,"PATH_INFO="), Value)); + free (Token); + } + if (Value = getenv("SCRIPT_URL")) + { + Token = (char *) malloc(strlen("REDIRECT_SCRIPT_URL=" + strlen(Value) + 1)); + putenv(strcat(strcpy(Token,"REDIRECT_SCRIPT_URL="), Value)); + free (Token); + } + Token = (char *) malloc(strlen("REDIRECT_STATUS=" + strlen("200") + 1)); + putenv(strcat(strcpy(Token,"REDIRECT_STATUS="), "200")); // PHP may need this + free (Token); + if (Value = getenv("SCRIPT_URL")) + { + Token = (char *) malloc(strlen("REDIRECT_URL=" + strlen(Value) + 1)); + putenv(strcat(strcpy(Token,"REDIRECT_URL="), Value)); + free (Token); + } + // Set secure PATH - setenv("PATH", "/bin:/usr/bin", 1); + putenv("PATH=/bin:/usr/bin"); // Check for PHP_CONFIG environment variable - - if (getenv("PHP_CONFIG")) + + if (Value = getenv("PHP_CONFIG")) { - if ((php_config = strdup(getenv("PHP_CONFIG")))==NULL) - error_exit(ERRCODE_UNKNOWN); - setenv("PHPRC", getenv("PHP_CONFIG"), 1); - unsetenv("PHP_CONFIG"); + if ((php_config = strdup(getenv("PHP_CONFIG"))) == NULL) + error_exit(ERRCODE_UNKNOWN); + Token = (char *) malloc(strlen("PHPRC=") + strlen(Value) + 1); + putenv(strcat(strcpy(Token,"PHPRC="), Value)); + free (Token); + putenv("PHP_CONFIG="); } + // Exec PHP execl(OPT_PATH_TO_PHP, "php", NULL); @@ -63,179 +95,191 @@ int main(int argc, char* argv[]) { + // Check, if program has been started by Apache - struct passwd *apacheuser; - struct passwd *calluser; - struct passwd *targetuser; - struct group *targetgroup; + struct passwd *pw = NULL; + struct passwd apacheuser; + struct passwd calluser; + struct passwd targetuser; + struct group *gr = NULL; + struct group targetgroup; #ifdef OPT_NO_PASSWD - // Declare empty structure for user - struct passwd emptyuser; // Declare variable for information whether to use supplementary groups int use_supp_groups = 1; #endif -#ifdef OPT_NO_GROUP - // Declare emtpy structure for group - struct group emptygroup; -#endif - - char *path_translated; - -#ifdef OPT_NO_PASSWD - // Initialize structure - emptyuser.pw_name = ""; - emptyuser.pw_passwd = ""; - emptyuser.pw_uid = 65534; - emptyuser.pw_gid = 65534; - emptyuser.pw_gecos = ""; - emptyuser.pw_dir = "/dev/null"; - emptyuser.pw_shell = "/bin/false"; -#endif + char *EnvPtr = NULL; + int StrMax = 4096; + char path_translated[StrMax]; -#ifdef OP_NO_GROUP - // Initialize structure - emptygroup.gr_name = ""; - emptygroup.gr_passwd = ""; - emptygroup.gr_gid = 65534; - emptygroup.gr_mem = NULL; -#endif + if ((EnvPtr = getenv("SCRIPT_FILENAME")) != NULL) + { + if (((strlen(EnvPtr)) + 1) < StrMax) + { + strcpy(path_translated, EnvPtr); + } + else + { + log_error("SCRIPT_FILENAME too long to convert to PATH_TRANSLATED" ); + error_exit(ERRCODE_UNKNOWN); + } + } - path_translated = getenv("SCRIPT_FILENAME"); - - if ((apacheuser = getpwnam(OPT_APACHE_USER))==NULL) + if ((pw = getpwnam(OPT_APACHE_USER)) == NULL) { - log_error("Could not get passwd information for Apache user (%s)", OPT_APACHE_USER); - error_exit(ERRCODE_UNKNOWN); + log_error("Could not get passwd information for Apache user (%s)", OPT_APACHE_USER); + error_exit(ERRCODE_UNKNOWN); } - - if ((calluser = getpwuid(getuid()))==NULL) + else { - log_error("Could not get passwd information for calling UID %d", getuid()); - error_exit(ERRCODE_UNKNOWN); + apacheuser.pw_uid = pw->pw_uid; + apacheuser.pw_name = strdup(pw->pw_name); } - if (calluser->pw_uid!=apacheuser->pw_uid) + if ((pw = getpwuid(getuid())) == NULL) + { + log_error("Could not get passwd information for calling UID %d", getuid()); + error_exit(ERRCODE_UNKNOWN); + } + else { - log_error("suPHP was called by %s (%d), not by %s (%d)", calluser->pw_name, calluser->pw_uid, apacheuser->pw_name, apacheuser->pw_uid); - error_exit(ERRCODE_WRONG_PARENT); + calluser.pw_uid = pw->pw_uid; + calluser.pw_name = strdup(pw->pw_name); + } + + if (calluser.pw_uid != apacheuser.pw_uid) + { + log_error("suPHP was called by %s (%d), not by %s (%d)", calluser.pw_name, calluser.pw_uid, apacheuser.pw_name, apacheuser.pw_uid); + error_exit(ERRCODE_WRONG_PARENT); } #ifdef OPT_CHECKPATH // Is the script in the DOCUMENT_ROOT? if(!check_path(path_translated)) { - log_error("Script %s is not in the DOCUMENT_ROOT (%s)", path_translated, getenv("DOCUMENT_ROOT")); - error_exit(ERRCODE_WRONG_PATH); + log_error("Script %s is not in the DOCUMENT_ROOT (%s)", path_translated, getenv("DOCUMENT_ROOT")); + error_exit(ERRCODE_WRONG_PATH); } #endif // Does the script exist? if(!file_exists(path_translated)) { - log_error("File %s not found", path_translated); - error_exit(ERRCODE_FILE_NOT_FOUND); + log_error("File %s not found", path_translated); + error_exit(ERRCODE_FILE_NOT_FOUND); } // Check permissions for the script if(!check_permissions(path_translated)) - error_exit(ERRCODE_WRONG_PERMISSIONS); + error_exit(ERRCODE_WRONG_PERMISSIONS); // Get gid and uid of the file and check it - if ((targetuser = getpwuid(file_get_uid(path_translated)))==NULL) + if ((pw = getpwuid(file_get_uid(path_translated))) == NULL) { #ifdef OPT_NO_PASSWD - emptyuser.pw_uid = file_get_uid(path_translated); - emptyuser.pw_gid = file_get_gid(path_translated); - emptyuser.pw_name = "NOT AVAILABLE"; - targetuser = &emptyuser; - use_supp_groups = 0; + targetuser.pw_uid = file_get_uid(path_translated); + targetuser.pw_gid = file_get_gid(path_translated); + targetuser.pw_name = strdup("NOT AVAILABLE"); + use_supp_groups = 0; #else - log_error ("Could not get passwd information for UID %d", file_get_uid(path_translated)); - error_exit(ERRCODE_UNKNOWN); + log_error ("Could not get passwd information for UID %d", file_get_uid(path_translated)); + error_exit(ERRCODE_UNKNOWN); #endif } + else + { + targetuser.pw_uid = pw->pw_uid; + targetuser.pw_gid = pw->pw_gid; + targetuser.pw_name = strdup(pw->pw_name); + } - if (targetuser->pw_uid < OPT_MIN_UID) + if (targetuser.pw_uid < OPT_MIN_UID) { - log_error ("UID of %s or its target (%d / %s) < %d", path_translated, targetuser->pw_uid, targetuser->pw_name, OPT_MIN_UID); - error_exit(ERRCODE_LOW_UID); + log_error ("UID of %s or its target (%d / %s) < %d", path_translated, targetuser.pw_uid, targetuser.pw_name, OPT_MIN_UID); + error_exit(ERRCODE_LOW_UID); } - if ((targetgroup = getgrgid(file_get_gid(path_translated)))==NULL) + if ((gr = getgrgid(file_get_gid(path_translated))) == NULL) { #ifdef OPT_NO_GROUP - emptygroup.gr_gid = file_get_gid(path_translated); - emptygroup.gr_name = "NOT AVAILABLE"; - targetgroup = &emptygroup; + targetgroup.gr_gid = file_get_gid(path_translated); + targetgroup.gr_name = strdup("NOT AVAILABLE"); #else - log_error ("Could not get group information for GID %d", file_get_gid(path_translated)); - error_exit(ERRCODE_UNKNOWN); + log_error ("Could not get group information for GID %d", file_get_gid(path_translated)); + error_exit(ERRCODE_UNKNOWN); #endif } + else + { + targetgroup.gr_gid = gr->gr_gid; + targetgroup.gr_name = strdup(gr->gr_name); + } - if (targetgroup->gr_gid < OPT_MIN_GID) + if (targetgroup.gr_gid < OPT_MIN_GID) { - log_error ("GID of %s or its target (%d / %s) < %d", path_translated, targetgroup->gr_gid, targetgroup->gr_name, OPT_MIN_GID); - error_exit(ERRCODE_LOW_GID); + log_error ("GID of %s or its target (%d / %s) < %d", path_translated, targetgroup.gr_gid, targetgroup.gr_name, OPT_MIN_GID); + error_exit(ERRCODE_LOW_GID); } // Check if file is a symbollink if (file_is_symbollink(path_translated)) { // Get gid and uid of the symbollink and check if it matches to the target - if (targetuser->pw_uid != file_get_uid_l(path_translated)) - { - log_error ("UID of symbollink %s does not match its target", path_translated); - error_exit(ERRCODE_SYMBOLLINK_NO_MATCH); - } - if (targetgroup->gr_gid != file_get_gid_l(path_translated)) - { - log_error ("GID of symbollink %s does not match its target", path_translated); - error_exit(ERRCODE_SYMBOLLINK_NO_MATCH); - } + if (targetuser.pw_uid != file_get_uid_l(path_translated)) + { + log_error ("UID of symbollink %s does not match its target", path_translated); + error_exit(ERRCODE_SYMBOLLINK_NO_MATCH); + } + if (targetgroup.gr_gid != file_get_gid_l(path_translated)) + { + log_error ("GID of symbollink %s does not match its target", path_translated); + error_exit(ERRCODE_SYMBOLLINK_NO_MATCH); + } } // We have to create the log entry before losing root privileges - log_info("%s executed as user %s (%d), group %s (%d)", path_translated, targetuser->pw_name, targetuser->pw_uid, targetgroup->gr_name, targetgroup->gr_gid); + log_info("%s executed as user %s (%d), group %s (%d)", path_translated, targetuser.pw_name, targetuser.pw_uid, targetgroup.gr_name, targetgroup.gr_gid); + + // Set gid and uid - if (setgid(targetgroup->gr_gid)) + if (setgid(targetgroup.gr_gid) != 0) { - log_error("Could not change GID to %d (%s)", targetgroup->gr_gid, targetgroup->gr_name); - error_exit(ERRCODE_UNKNOWN); + log_error("Could not change GID to %d (%s)", targetgroup.gr_gid, targetgroup.gr_name); + error_exit(ERRCODE_UNKNOWN); } // Initialize supplementary groups for user #ifdef OPT_NO_PASSWD - if (use_supp_groups && initgroups(targetuser->pw_name, targetuser->pw_gid)) + if (use_supp_groups && initgroups(targetuser.pw_name, targetuser.pw_gid)) { - log_error("Could not initialize supplementary groups for user %s (%d)", targetuser->pw_name, targetuser->pw_uid); - error_exit(ERRCODE_UNKNOWN); + log_error("Could not initialize supplementary groups for user %s (%d)", targetuser.pw_name, targetuser.pw_uid); + error_exit(ERRCODE_UNKNOWN); } if (!use_supp_groups) { - if (setgroups(0, NULL)) - { - log_error("Could not set supplementary groups to null"); - error_exit(ERRCODE_UNKNOWN); - } + if (setgroups(0, NULL)) + { + log_error("Could not set supplementary groups to null"); + error_exit(ERRCODE_UNKNOWN); + } } #else - if (initgroups(targetuser->pw_name, targetuser->pw_gid)) + if (initgroups(targetuser.pw_name, targetuser.pw_gid)) { - log_error("Could not initialize supplementary groups for user %s (%d)", targetuser->pw_name, targetuser->pw_uid); - error_exit(ERRCODE_UNKNOWN); + log_error("Could not initialize supplementary groups for user %s (%d)", targetuser.pw_name, targetuser.pw_uid); + error_exit(ERRCODE_UNKNOWN); } #endif - if (setuid(targetuser->pw_uid)) + if (setuid(targetuser.pw_uid) != 0) { - log_error("Could not change UID to %d (%s)", targetuser->pw_uid, targetuser->pw_name); - error_exit(ERRCODE_UNKNOWN); + log_error("Could not change UID to %d (%s)", targetuser.pw_uid, targetuser.pw_name); + error_exit(ERRCODE_UNKNOWN); } - + + // Execute the script with PHP exec_script(path_translated);