/* Licensed to the Apache Software Foundation (ASF) under one or more *contributorlicenseagreements.SeetheNOTICEfiledistributedwith *thisworkforadditionalinformationregardingcopyrightownership. *TheASFlicensesthisfiletoYouundertheApacheLicense,Version2.0 *(the"License");youmaynotusethisfileexceptincompliancewith *theLicense.YoumayobtainacopyoftheLicenseat * *http://www.apache.org/licenses/LICENSE-2.0 * *Unlessrequiredbyapplicablelaworagreedtoinwriting,software *distributedundertheLicenseisdistributedonan"ASIS"BASIS, *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. *SeetheLicenseforthespecificlanguagegoverningpermissionsand *limitationsundertheLicense.
*/
staticvoid clean_env(void)
{ char **cleanenv; char **ep; int cidx = 0; int idx;
/* While cleaning the environment, the environment should be clean. *(e.g.malloc()maygetthenameofafileforwritingdebugginginfo. *BadnewsifMALLOC_DEBUG_FILEissetto/etc/passwd.Sprintf()maybe *susceptibletobadlocalesettings....) *(fromPR2790)
*/ char **envp = environ; char *empty_ptr = NULL;
environ = &empty_ptr; /* VERY safe environment */
if ((cleanenv = (char **) calloc(AP_ENVBUF, sizeof(char *))) == NULL) {
log_err("failed to malloc memory for environment\n"); exit(123);
}
cleanenv[cidx] = strdup("PATH=" AP_SAFE_PATH); if (cleanenv[cidx] == NULL) {
log_err("failed to malloc memory for environment\n"); exit(124);
}
cidx++;
int main(int argc, char *argv[])
{ int userdir = 0; /* ~userdir flag */
uid_t uid; /* user information */
gid_t gid; /* target group placeholder */ char *target_uname; /* target user name */ char *target_gname; /* target group name */ char *target_homedir; /* target home directory */ char *actual_uname; /* actual user name */ char *actual_gname; /* actual group name */ char *cmd; /* command to be executed */ char cwd[AP_MAXPATH]; /* current working directory */ char dwd[AP_MAXPATH]; /* docroot working directory */ struct passwd *pw; /* password entry holder */ struct group *gr; /* group entry holder */ struct stat dir_info; /* directory info holder */ struct stat prg_info; /* program info holder */
/* *setuid()tothetargetuser.Erroroutonfail.
*/ if ((setuid(uid)) != 0) {
log_err("failed to setuid (%lu: %s): %s\n",
(unsignedlong)uid, cmd, strerror(errno)); exit(110);
}
/* *Getthecurrentworkingdirectory,aswellastheproper *documentroot(dependentuponwhetherornotitisa *~userdirrequest).Erroroutifwecannotgeteitherone, *orifthecurrentworkingdirectoryisnotinthedocroot. *Usechdir()sandgetcwd()stoavoidproblemswithsymlinked *directories.Yuck.
*/ if (getcwd(cwd, AP_MAXPATH) == NULL) {
log_err("cannot get current working directory\n"); exit(111);
}
if (userdir) { if (((chdir(target_homedir)) != 0) ||
((chdir(AP_USERDIR_SUFFIX)) != 0) ||
((getcwd(dwd, AP_MAXPATH)) == NULL) ||
((chdir(cwd)) != 0)) {
log_err("cannot get docroot information (%s)\n", target_homedir); exit(112);
}
} else { if (((chdir(AP_DOC_ROOT)) != 0) ||
((getcwd(dwd, AP_MAXPATH)) == NULL) ||
((chdir(cwd)) != 0)) {
log_err("cannot get docroot information (%s)\n", AP_DOC_ROOT); exit(113);
}
}
if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
log_err("command not in docroot (%s/%s)\n", cwd, cmd); exit(114);
}
/* *Statthecwdandverifyitisadirectory,orerrorout.
*/ if (((lstat(cwd, &dir_info)) != 0) || !(S_ISDIR(dir_info.st_mode))) {
log_err("cannot stat directory: (%s)\n", cwd); exit(115);
}
/* *Erroroutifcwdiswritablebyothers.
*/ if ((dir_info.st_mode & S_IWOTH) || (dir_info.st_mode & S_IWGRP)) {
log_err("directory is writable by others: (%s)\n", cwd); exit(116);
}
/* *Erroroutifwecannotstattheprogram.
*/ if (((lstat(cmd, &prg_info)) != 0) || (S_ISLNK(prg_info.st_mode))) {
log_err("cannot stat program: (%s)\n", cmd); exit(117);
}
/* *Erroroutiftheprogramiswritablebyothers.
*/ if ((prg_info.st_mode & S_IWOTH) || (prg_info.st_mode & S_IWGRP)) {
log_err("file is writable by others: (%s/%s)\n", cwd, cmd); exit(118);
}
/* *Erroroutifthefileissetuidorsetgid.
*/ if ((prg_info.st_mode & S_ISUID) || (prg_info.st_mode & S_ISGID)) {
log_err("file is either setuid or setgid: (%s/%s)\n", cwd, cmd); exit(119);
}
/* *Erroroutifthetargetname/groupisdifferentfrom *thename/groupofthecwdortheprogram.
*/ if ((uid != dir_info.st_uid) ||
(gid != dir_info.st_gid) ||
(uid != prg_info.st_uid) ||
(gid != prg_info.st_gid)) {
log_err("target uid/gid (%lu/%lu) mismatch " "with directory (%lu/%lu) or program (%lu/%lu)\n",
(unsignedlong)uid, (unsignedlong)gid,
(unsignedlong)dir_info.st_uid, (unsignedlong)dir_info.st_gid,
(unsignedlong)prg_info.st_uid, (unsignedlong)prg_info.st_gid); exit(120);
} /* *Erroroutiftheprogramisnotexecutablefortheuser. *Otherwise,shewon'tfindanyerrorinthelogsexceptfor *"[error]Prematureendofscriptheaders:..."
*/ if (!(prg_info.st_mode & S_IXUSR)) {
log_err("file has no execute permission: (%s/%s)\n", cwd, cmd); exit(121);
}
#ifdef AP_SUEXEC_UMASK /* *umask()usesinverselogic;bitsareCLEARforallowedaccess.
*/ if ((~AP_SUEXEC_UMASK) & 0022) {
log_err("notice: AP_SUEXEC_UMASK of %03o allows " "write permission to group and/or other\n", AP_SUEXEC_UMASK);
}
umask(AP_SUEXEC_UMASK); #endif/* AP_SUEXEC_UMASK */
/* Be sure to close the log file so the CGI can't mess with it. */ #ifdef AP_LOG_SYSLOG if (log_open) {
closelog();
log_open = 0;
} #else if (log != NULL) { #if APR_HAVE_FCNTL_H /* *askfcntl(2)tosettheFD_CLOEXECflagonthelogfile, *soit'llbeautomagicallyclosediftheexec()callsucceeds.
*/
fflush(log);
setbuf(log, NULL); if ((fcntl(fileno(log), F_SETFD, FD_CLOEXEC) == -1)) {
log_err("error: can't set close-on-exec flag"); exit(122);
} #else /* *Inthiscase,exec()errorswon'tbeloggedbecausewehavealready *droppedprivilegesandwon'tbeabletoreopenthelogfile.
*/
fclose(log);
log = NULL; #endif
} #endif
/* *Executethecommand,replacingourimagewithitsown.
*/ #ifdef NEED_HASHBANG_EMUL /* We need the #! emulation when we want to execute scripts */
{ externchar **environ;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.